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 : #include "gimple-range.h"
70 :
71 :
72 : /* If this is nonzero, we do not bother generating VOLATILE
73 : around volatile memory references, and we are willing to
74 : output indirect addresses. If cse is to follow, we reject
75 : indirect addresses so a useful potential cse is generated;
76 : if it is used only once, instruction combination will produce
77 : the same indirect address eventually. */
78 : int cse_not_expected;
79 :
80 : /* Cache of the "extended" flag in the target's _BitInt description
81 : for use during expand. */
82 : int bitint_extended = -1;
83 :
84 : static bool block_move_libcall_safe_for_call_parm (void);
85 : static bool emit_block_move_via_pattern (rtx, rtx, rtx, unsigned, unsigned,
86 : HOST_WIDE_INT, unsigned HOST_WIDE_INT,
87 : unsigned HOST_WIDE_INT,
88 : unsigned HOST_WIDE_INT, bool);
89 : static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned, int);
90 : static void emit_block_move_via_sized_loop (rtx, rtx, rtx, unsigned, unsigned);
91 : static void emit_block_move_via_oriented_loop (rtx, rtx, rtx, unsigned, unsigned);
92 : static rtx emit_block_cmp_via_loop (rtx, rtx, rtx, tree, rtx, bool,
93 : unsigned, unsigned);
94 : static rtx_insn *compress_float_constant (rtx, rtx);
95 : static rtx get_subtarget (rtx);
96 : static rtx store_field (rtx, poly_int64, poly_int64, poly_uint64, poly_uint64,
97 : machine_mode, tree, alias_set_type, bool, bool);
98 :
99 : static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
100 :
101 : static bool is_aligning_offset (const_tree, const_tree);
102 : static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
103 : static rtx do_store_flag (const_sepops, rtx, machine_mode);
104 : #ifdef PUSH_ROUNDING
105 : static void emit_single_push_insn (machine_mode, rtx, tree);
106 : #endif
107 : static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx,
108 : profile_probability);
109 : static rtx const_vector_from_tree (tree);
110 : static tree tree_expr_size (const_tree);
111 : static void convert_mode_scalar (rtx, rtx, int);
112 :
113 :
114 : /* This is run to set up which modes can be used
115 : directly in memory and to initialize the block move optab. It is run
116 : at the beginning of compilation and when the target is reinitialized. */
117 :
118 : void
119 220178 : init_expr_target (void)
120 : {
121 220178 : rtx pat;
122 220178 : int num_clobbers;
123 220178 : rtx mem, mem1;
124 220178 : rtx reg;
125 :
126 : /* Try indexing by frame ptr and try by stack ptr.
127 : It is known that on the Convex the stack ptr isn't a valid index.
128 : With luck, one or the other is valid on any machine. */
129 220178 : mem = gen_rtx_MEM (word_mode, stack_pointer_rtx);
130 220178 : mem1 = gen_rtx_MEM (word_mode, frame_pointer_rtx);
131 :
132 : /* A scratch register we can modify in-place below to avoid
133 : useless RTL allocations. */
134 220178 : reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
135 :
136 220178 : rtx_insn *insn = as_a<rtx_insn *> (rtx_alloc (INSN));
137 220178 : pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
138 220178 : PATTERN (insn) = pat;
139 :
140 27522250 : for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
141 27302072 : mode = (machine_mode) ((int) mode + 1))
142 : {
143 27302072 : int regno;
144 :
145 27302072 : direct_load[(int) mode] = direct_store[(int) mode] = 0;
146 27302072 : PUT_MODE (mem, mode);
147 27302072 : PUT_MODE (mem1, mode);
148 :
149 : /* See if there is some register that can be used in this mode and
150 : directly loaded or stored from memory. */
151 :
152 27302072 : if (mode != VOIDmode && mode != BLKmode)
153 1840335905 : for (regno = 0; regno < FIRST_PSEUDO_REGISTER
154 1867197621 : && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
155 : regno++)
156 : {
157 1840335905 : if (!targetm.hard_regno_mode_ok (regno, mode))
158 1719829833 : continue;
159 :
160 120506072 : set_mode_and_regno (reg, mode, regno);
161 :
162 120506072 : SET_SRC (pat) = mem;
163 120506072 : SET_DEST (pat) = reg;
164 120506072 : if (recog (pat, insn, &num_clobbers) >= 0)
165 7402321 : direct_load[(int) mode] = 1;
166 :
167 120506072 : SET_SRC (pat) = mem1;
168 120506072 : SET_DEST (pat) = reg;
169 120506072 : if (recog (pat, insn, &num_clobbers) >= 0)
170 7402321 : direct_load[(int) mode] = 1;
171 :
172 120506072 : SET_SRC (pat) = reg;
173 120506072 : SET_DEST (pat) = mem;
174 120506072 : if (recog (pat, insn, &num_clobbers) >= 0)
175 7402321 : direct_store[(int) mode] = 1;
176 :
177 120506072 : SET_SRC (pat) = reg;
178 120506072 : SET_DEST (pat) = mem1;
179 120506072 : if (recog (pat, insn, &num_clobbers) >= 0)
180 7402321 : direct_store[(int) mode] = 1;
181 : }
182 : }
183 :
184 225887 : mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
185 :
186 220178 : opt_scalar_float_mode mode_iter;
187 1541246 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
188 : {
189 1321068 : scalar_float_mode mode = mode_iter.require ();
190 1321068 : scalar_float_mode srcmode;
191 4623738 : FOR_EACH_MODE_UNTIL (srcmode, mode)
192 : {
193 3302670 : enum insn_code ic;
194 :
195 3302670 : ic = can_extend_p (mode, srcmode, 0);
196 3302670 : if (ic == CODE_FOR_nothing)
197 2637396 : continue;
198 :
199 665274 : PUT_MODE (mem, srcmode);
200 :
201 665274 : if (insn_operand_matches (ic, 1, mem))
202 663123 : float_extend_from_mem[mode][srcmode] = true;
203 : }
204 : }
205 220178 : }
206 :
207 : /* This is run at the start of compiling a function. */
208 :
209 : void
210 1741754 : init_expr (void)
211 : {
212 1741754 : memset (&crtl->expr, 0, sizeof (crtl->expr));
213 1741754 : }
214 :
215 : /* Copy data from FROM to TO, where the machine modes are not the same.
216 : Both modes may be integer, or both may be floating, or both may be
217 : fixed-point.
218 : UNSIGNEDP should be nonzero if FROM is an unsigned type.
219 : This causes zero-extension instead of sign-extension. */
220 :
221 : void
222 2188466 : convert_move (rtx to, rtx from, int unsignedp)
223 : {
224 2188466 : machine_mode to_mode = GET_MODE (to);
225 2188466 : machine_mode from_mode = GET_MODE (from);
226 :
227 2188466 : gcc_assert (to_mode != BLKmode);
228 2188466 : gcc_assert (from_mode != BLKmode);
229 :
230 : /* If the source and destination are already the same, then there's
231 : nothing to do. */
232 2188466 : if (to == from)
233 2188466 : return;
234 :
235 : /* If FROM is a SUBREG that indicates that we have already done at least
236 : the required extension, strip it. We don't handle such SUBREGs as
237 : TO here. */
238 :
239 2188466 : scalar_int_mode to_int_mode;
240 2188466 : if (GET_CODE (from) == SUBREG
241 188315 : && SUBREG_PROMOTED_VAR_P (from)
242 2188473 : && is_a <scalar_int_mode> (to_mode, &to_int_mode)
243 2188473 : && (GET_MODE_PRECISION (subreg_promoted_mode (from))
244 7 : >= GET_MODE_PRECISION (to_int_mode))
245 2188473 : && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp))
246 : {
247 0 : scalar_int_mode int_orig_mode;
248 0 : scalar_int_mode int_inner_mode;
249 0 : machine_mode orig_mode = GET_MODE (from);
250 :
251 0 : from = gen_lowpart (to_int_mode, SUBREG_REG (from));
252 0 : from_mode = to_int_mode;
253 :
254 : /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
255 : the original mode, but narrower than the inner mode. */
256 0 : if (GET_CODE (from) == SUBREG
257 0 : && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
258 0 : && GET_MODE_PRECISION (to_int_mode)
259 0 : > GET_MODE_PRECISION (int_orig_mode)
260 0 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (from)),
261 : &int_inner_mode)
262 0 : && GET_MODE_PRECISION (int_inner_mode)
263 0 : > GET_MODE_PRECISION (to_int_mode))
264 : {
265 0 : SUBREG_PROMOTED_VAR_P (from) = 1;
266 0 : SUBREG_PROMOTED_SET (from, unsignedp);
267 : }
268 : }
269 :
270 2188466 : gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
271 :
272 2188466 : if (to_mode == from_mode
273 2131474 : || (from_mode == VOIDmode && CONSTANT_P (from)))
274 : {
275 57263 : emit_move_insn (to, from);
276 57263 : return;
277 : }
278 :
279 2131203 : if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
280 : {
281 30478 : if (GET_MODE_UNIT_PRECISION (to_mode)
282 15239 : > GET_MODE_UNIT_PRECISION (from_mode))
283 : {
284 5000 : optab op = unsignedp ? zext_optab : sext_optab;
285 5000 : insn_code icode = convert_optab_handler (op, to_mode, from_mode);
286 5000 : if (icode != CODE_FOR_nothing)
287 : {
288 1170 : emit_unop_insn (icode, to, from,
289 : unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
290 1170 : return;
291 : }
292 : }
293 :
294 28138 : if (GET_MODE_UNIT_PRECISION (to_mode)
295 14069 : < GET_MODE_UNIT_PRECISION (from_mode))
296 : {
297 2154 : insn_code icode = convert_optab_handler (trunc_optab,
298 : to_mode, from_mode);
299 2154 : if (icode != CODE_FOR_nothing)
300 : {
301 908 : emit_unop_insn (icode, to, from, TRUNCATE);
302 908 : return;
303 : }
304 : }
305 :
306 39483 : gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
307 : GET_MODE_BITSIZE (to_mode)));
308 :
309 13161 : if (VECTOR_MODE_P (to_mode))
310 13161 : from = force_subreg (to_mode, from, GET_MODE (from), 0);
311 : else
312 0 : to = simplify_gen_subreg (from_mode, to, GET_MODE (to), 0);
313 :
314 13161 : emit_move_insn (to, from);
315 13161 : return;
316 : }
317 :
318 2115964 : if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
319 : {
320 0 : convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
321 0 : convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
322 0 : return;
323 : }
324 :
325 2115964 : convert_mode_scalar (to, from, unsignedp);
326 : }
327 :
328 : /* Like convert_move, but deals only with scalar modes. */
329 :
330 : static void
331 2116026 : convert_mode_scalar (rtx to, rtx from, int unsignedp)
332 : {
333 : /* Both modes should be scalar types. */
334 2116031 : scalar_mode from_mode = as_a <scalar_mode> (GET_MODE (from));
335 2116031 : scalar_mode to_mode = as_a <scalar_mode> (GET_MODE (to));
336 2116031 : bool to_real = SCALAR_FLOAT_MODE_P (to_mode);
337 2116031 : bool from_real = SCALAR_FLOAT_MODE_P (from_mode);
338 2116031 : enum insn_code code;
339 2116031 : rtx libcall;
340 :
341 2116031 : gcc_assert (to_real == from_real);
342 :
343 : /* rtx code for making an equivalent value. */
344 3224342 : enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
345 2116031 : : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
346 :
347 2116031 : auto acceptable_same_precision_modes
348 580 : = [] (scalar_mode from_mode, scalar_mode to_mode) -> bool
349 : {
350 580 : if (DECIMAL_FLOAT_MODE_P (from_mode) != DECIMAL_FLOAT_MODE_P (to_mode))
351 : return true;
352 :
353 : /* arm_bfloat_half_format <-> ieee_half_format */
354 2 : if ((REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
355 1 : && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
356 2 : || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
357 1 : && REAL_MODE_FORMAT (from_mode) == &ieee_half_format))
358 : return true;
359 :
360 : /* ibm_extended_format <-> ieee_quad_format */
361 0 : if ((REAL_MODE_FORMAT (from_mode) == &ibm_extended_format
362 0 : && REAL_MODE_FORMAT (to_mode) == &ieee_quad_format)
363 0 : || (REAL_MODE_FORMAT (from_mode) == &ieee_quad_format
364 0 : && REAL_MODE_FORMAT (to_mode) == &ibm_extended_format))
365 0 : return true;
366 :
367 : return false;
368 : };
369 :
370 2116031 : if (to_real)
371 : {
372 189283 : rtx value;
373 189283 : rtx_insn *insns;
374 189283 : convert_optab tab;
375 :
376 189283 : gcc_assert ((GET_MODE_PRECISION (from_mode)
377 : != GET_MODE_PRECISION (to_mode))
378 : || acceptable_same_precision_modes (from_mode, to_mode));
379 :
380 189283 : if (GET_MODE_PRECISION (from_mode) == GET_MODE_PRECISION (to_mode))
381 : {
382 580 : if ((REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
383 1 : && REAL_MODE_FORMAT (from_mode) == &ieee_half_format)
384 580 : || (REAL_MODE_FORMAT (to_mode) == &ieee_quad_format
385 0 : && REAL_MODE_FORMAT (from_mode) == &ibm_extended_format))
386 : /* libgcc implements just __trunchfbf2, not __extendhfbf2;
387 : and __trunctfkf2, not __extendtfkf2. */
388 : tab = trunc_optab;
389 : else
390 : /* Conversion between decimal float and binary float, same
391 : size. */
392 579 : tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
393 : }
394 188703 : else if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode))
395 : tab = sext_optab;
396 : else
397 18761 : tab = trunc_optab;
398 :
399 : /* Try converting directly if the insn is supported. */
400 :
401 189283 : code = convert_optab_handler (tab, to_mode, from_mode);
402 189283 : if (code != CODE_FOR_nothing)
403 : {
404 161425 : emit_unop_insn (code, to, from,
405 : tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
406 161425 : return;
407 : }
408 :
409 : #ifdef HAVE_SFmode
410 27858 : if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
411 27858 : && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
412 : {
413 3245 : if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (SFmode))
414 : {
415 : /* To cut down on libgcc size, implement
416 : BFmode -> {DF,XF,TF}mode conversions by
417 : BFmode -> SFmode -> {DF,XF,TF}mode conversions. */
418 4 : rtx temp = gen_reg_rtx (SFmode);
419 4 : convert_mode_scalar (temp, from, unsignedp);
420 4 : convert_mode_scalar (to, temp, unsignedp);
421 4 : return;
422 : }
423 3241 : if (REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
424 : {
425 : /* Similarly, implement BFmode -> HFmode as
426 : BFmode -> SFmode -> HFmode conversion where SFmode
427 : has superset of BFmode values. We don't need
428 : to handle sNaNs by raising exception and turning
429 : it into qNaN though, as that can be done in the
430 : SFmode -> HFmode conversion too. */
431 1 : rtx temp = gen_reg_rtx (SFmode);
432 1 : int save_flag_finite_math_only = flag_finite_math_only;
433 1 : flag_finite_math_only = true;
434 1 : convert_mode_scalar (temp, from, unsignedp);
435 1 : flag_finite_math_only = save_flag_finite_math_only;
436 1 : convert_mode_scalar (to, temp, unsignedp);
437 1 : return;
438 : }
439 3240 : if (to_mode == SFmode
440 3240 : && !HONOR_NANS (from_mode)
441 58 : && !HONOR_NANS (to_mode)
442 3298 : && optimize_insn_for_speed_p ())
443 : {
444 : /* If we don't expect sNaNs, for BFmode -> SFmode we can just
445 : shift the bits up. */
446 57 : machine_mode fromi_mode, toi_mode;
447 114 : if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
448 57 : 0).exists (&fromi_mode)
449 57 : && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
450 0 : 0).exists (&toi_mode))
451 : {
452 57 : start_sequence ();
453 57 : rtx fromi = force_lowpart_subreg (fromi_mode, from,
454 : from_mode);
455 57 : rtx tof = NULL_RTX;
456 57 : if (fromi)
457 : {
458 57 : rtx toi;
459 57 : if (GET_MODE (fromi) == VOIDmode)
460 0 : toi = simplify_unary_operation (ZERO_EXTEND, toi_mode,
461 : fromi, fromi_mode);
462 : else
463 : {
464 57 : toi = gen_reg_rtx (toi_mode);
465 57 : convert_mode_scalar (toi, fromi, 1);
466 : }
467 57 : toi
468 114 : = maybe_expand_shift (LSHIFT_EXPR, toi_mode, toi,
469 57 : GET_MODE_PRECISION (to_mode)
470 57 : - GET_MODE_PRECISION (from_mode),
471 : NULL_RTX, 1);
472 57 : if (toi)
473 : {
474 57 : tof = force_lowpart_subreg (to_mode, toi, toi_mode);
475 57 : if (tof)
476 57 : emit_move_insn (to, tof);
477 : }
478 : }
479 57 : insns = end_sequence ();
480 57 : if (tof)
481 : {
482 57 : emit_insn (insns);
483 57 : return;
484 : }
485 : }
486 : }
487 : }
488 27796 : if (REAL_MODE_FORMAT (from_mode) == &ieee_single_format
489 4274 : && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
490 1572 : && !HONOR_NANS (from_mode)
491 0 : && !HONOR_NANS (to_mode)
492 0 : && !flag_rounding_math
493 27796 : && optimize_insn_for_speed_p ())
494 : {
495 : /* If we don't expect qNaNs nor sNaNs and can assume rounding
496 : to nearest, we can expand the conversion inline as
497 : (fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16. */
498 0 : machine_mode fromi_mode, toi_mode;
499 0 : if (int_mode_for_size (GET_MODE_BITSIZE (from_mode),
500 0 : 0).exists (&fromi_mode)
501 0 : && int_mode_for_size (GET_MODE_BITSIZE (to_mode),
502 0 : 0).exists (&toi_mode))
503 : {
504 0 : start_sequence ();
505 0 : rtx fromi = force_lowpart_subreg (fromi_mode, from, from_mode);
506 0 : rtx tof = NULL_RTX;
507 0 : do
508 : {
509 0 : if (!fromi)
510 : break;
511 0 : int shift = (GET_MODE_PRECISION (from_mode)
512 0 : - GET_MODE_PRECISION (to_mode));
513 0 : rtx temp1
514 0 : = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, fromi,
515 : shift, NULL_RTX, 1);
516 0 : if (!temp1)
517 : break;
518 0 : rtx temp2
519 0 : = expand_binop (fromi_mode, and_optab, temp1, const1_rtx,
520 : NULL_RTX, 1, OPTAB_DIRECT);
521 0 : if (!temp2)
522 : break;
523 0 : rtx temp3
524 0 : = expand_binop (fromi_mode, add_optab, fromi,
525 : gen_int_mode ((HOST_WIDE_INT_1U
526 0 : << (shift - 1)) - 1,
527 : fromi_mode), NULL_RTX,
528 : 1, OPTAB_DIRECT);
529 0 : if (!temp3)
530 : break;
531 0 : rtx temp4
532 0 : = expand_binop (fromi_mode, add_optab, temp3, temp2,
533 : NULL_RTX, 1, OPTAB_DIRECT);
534 0 : if (!temp4)
535 : break;
536 0 : rtx temp5 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode,
537 : temp4, shift, NULL_RTX, 1);
538 0 : if (!temp5)
539 : break;
540 0 : rtx temp6 = force_lowpart_subreg (toi_mode, temp5,
541 : fromi_mode);
542 0 : if (!temp6)
543 : break;
544 0 : tof = force_lowpart_subreg (to_mode, temp6, toi_mode);
545 0 : if (tof)
546 0 : emit_move_insn (to, tof);
547 : }
548 : while (0);
549 0 : insns = end_sequence ();
550 0 : if (tof)
551 : {
552 0 : emit_insn (insns);
553 0 : return;
554 : }
555 : }
556 : }
557 : #endif
558 :
559 : /* Otherwise use a libcall. */
560 27796 : libcall = convert_optab_libfunc (tab, to_mode, from_mode);
561 :
562 : /* Is this conversion implemented yet? */
563 27796 : gcc_assert (libcall);
564 :
565 27796 : start_sequence ();
566 27796 : value = emit_library_call_value (libcall, NULL_RTX, LCT_CONST, to_mode,
567 : from, from_mode);
568 27796 : insns = end_sequence ();
569 27796 : emit_libcall_block (insns, to, value,
570 6785 : tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
571 : from)
572 21011 : : gen_rtx_FLOAT_EXTEND (to_mode, from));
573 27796 : return;
574 : }
575 :
576 : /* Handle pointer conversion. */ /* SPEE 900220. */
577 : /* If the target has a converter from FROM_MODE to TO_MODE, use it. */
578 1926748 : {
579 1926748 : convert_optab ctab;
580 :
581 1926748 : if (GET_MODE_PRECISION (from_mode) > GET_MODE_PRECISION (to_mode))
582 : ctab = trunc_optab;
583 1723813 : else if (unsignedp)
584 : ctab = zext_optab;
585 : else
586 833450 : ctab = sext_optab;
587 :
588 1926748 : if (convert_optab_handler (ctab, to_mode, from_mode)
589 : != CODE_FOR_nothing)
590 : {
591 1653218 : emit_unop_insn (convert_optab_handler (ctab, to_mode, from_mode),
592 : to, from, UNKNOWN);
593 1653218 : return;
594 : }
595 : }
596 :
597 : /* Targets are expected to provide conversion insns between PxImode and
598 : xImode for all MODE_PARTIAL_INT modes they use, but no others. */
599 273530 : if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
600 : {
601 0 : scalar_int_mode full_mode
602 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (to_mode)).require ();
603 :
604 0 : gcc_assert (convert_optab_handler (trunc_optab, to_mode, full_mode)
605 : != CODE_FOR_nothing);
606 :
607 0 : if (full_mode != from_mode)
608 0 : from = convert_to_mode (full_mode, from, unsignedp);
609 0 : emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, full_mode),
610 : to, from, UNKNOWN);
611 0 : return;
612 : }
613 273530 : if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
614 : {
615 0 : rtx new_from;
616 0 : scalar_int_mode full_mode
617 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (from_mode)).require ();
618 0 : convert_optab ctab = unsignedp ? zext_optab : sext_optab;
619 0 : enum insn_code icode;
620 :
621 0 : icode = convert_optab_handler (ctab, full_mode, from_mode);
622 0 : gcc_assert (icode != CODE_FOR_nothing);
623 :
624 0 : if (to_mode == full_mode)
625 : {
626 0 : emit_unop_insn (icode, to, from, UNKNOWN);
627 0 : return;
628 : }
629 :
630 0 : new_from = gen_reg_rtx (full_mode);
631 0 : emit_unop_insn (icode, new_from, from, UNKNOWN);
632 :
633 : /* else proceed to integer conversions below. */
634 0 : from_mode = full_mode;
635 0 : from = new_from;
636 : }
637 :
638 : /* Make sure both are fixed-point modes or both are not. */
639 273530 : gcc_assert (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode) ==
640 : ALL_SCALAR_FIXED_POINT_MODE_P (to_mode));
641 273530 : if (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode))
642 : {
643 : /* If we widen from_mode to to_mode and they are in the same class,
644 : we won't saturate the result.
645 : Otherwise, always saturate the result to play safe. */
646 0 : if (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode)
647 0 : && GET_MODE_SIZE (from_mode) < GET_MODE_SIZE (to_mode))
648 0 : expand_fixed_convert (to, from, 0, 0);
649 : else
650 0 : expand_fixed_convert (to, from, 0, 1);
651 : return;
652 : }
653 :
654 : /* Now both modes are integers. */
655 :
656 : /* Handle expanding beyond a word. */
657 273530 : if (GET_MODE_PRECISION (from_mode) < GET_MODE_PRECISION (to_mode)
658 276073 : && GET_MODE_PRECISION (to_mode) > BITS_PER_WORD)
659 : {
660 70595 : rtx_insn *insns;
661 70595 : rtx lowpart;
662 70595 : rtx fill_value;
663 70595 : rtx lowfrom;
664 70595 : int i;
665 70595 : scalar_mode lowpart_mode;
666 141190 : int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
667 :
668 : /* Try converting directly if the insn is supported. */
669 70595 : if ((code = can_extend_p (to_mode, from_mode, unsignedp))
670 : != CODE_FOR_nothing)
671 : {
672 : /* If FROM is a SUBREG, put it into a register. Do this
673 : so that we always generate the same set of insns for
674 : better cse'ing; if an intermediate assignment occurred,
675 : we won't be doing the operation directly on the SUBREG. */
676 0 : if (optimize > 0 && GET_CODE (from) == SUBREG)
677 0 : from = force_reg (from_mode, from);
678 0 : emit_unop_insn (code, to, from, equiv_code);
679 0 : return;
680 : }
681 : /* Next, try converting via full word. */
682 70595 : else if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD
683 70595 : && ((code = can_extend_p (to_mode, word_mode, unsignedp))
684 : != CODE_FOR_nothing))
685 : {
686 70456 : rtx word_to = gen_reg_rtx (word_mode);
687 70456 : if (REG_P (to))
688 : {
689 70383 : if (reg_overlap_mentioned_p (to, from))
690 0 : from = force_reg (from_mode, from);
691 70383 : emit_clobber (to);
692 : }
693 70456 : convert_move (word_to, from, unsignedp);
694 70456 : emit_unop_insn (code, to, word_to, equiv_code);
695 70456 : return;
696 : }
697 :
698 : /* No special multiword conversion insn; do it by hand. */
699 139 : start_sequence ();
700 :
701 : /* Since we will turn this into a no conflict block, we must ensure
702 : the source does not overlap the target so force it into an isolated
703 : register when maybe so. Likewise for any MEM input, since the
704 : conversion sequence might require several references to it and we
705 : must ensure we're getting the same value every time. */
706 :
707 139 : if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
708 0 : from = force_reg (from_mode, from);
709 :
710 : /* Get a copy of FROM widened to a word, if necessary. */
711 278 : if (GET_MODE_PRECISION (from_mode) < BITS_PER_WORD)
712 0 : lowpart_mode = word_mode;
713 : else
714 : lowpart_mode = from_mode;
715 :
716 139 : lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
717 :
718 139 : lowpart = gen_lowpart (lowpart_mode, to);
719 139 : emit_move_insn (lowpart, lowfrom);
720 :
721 : /* Compute the value to put in each remaining word. */
722 139 : if (unsignedp)
723 117 : fill_value = const0_rtx;
724 : else
725 22 : fill_value = emit_store_flag_force (gen_reg_rtx (word_mode),
726 : LT, lowfrom, const0_rtx,
727 : lowpart_mode, 0, -1);
728 :
729 : /* Fill the remaining words. */
730 695 : for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
731 : {
732 278 : int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
733 278 : rtx subword = operand_subword (to, index, 1, to_mode);
734 :
735 278 : gcc_assert (subword);
736 :
737 278 : if (fill_value != subword)
738 278 : emit_move_insn (subword, fill_value);
739 : }
740 :
741 139 : insns = end_sequence ();
742 :
743 139 : emit_insn (insns);
744 139 : return;
745 : }
746 :
747 : /* Truncating multi-word to a word or less. */
748 202935 : if (GET_MODE_PRECISION (from_mode) > BITS_PER_WORD
749 202935 : && GET_MODE_PRECISION (to_mode) <= BITS_PER_WORD)
750 : {
751 78996 : if (!((MEM_P (from)
752 567 : && ! MEM_VOLATILE_P (from)
753 567 : && direct_load[(int) to_mode]
754 567 : && ! mode_dependent_address_p (XEXP (from, 0),
755 567 : MEM_ADDR_SPACE (from)))
756 48460 : || REG_P (from)
757 : || GET_CODE (from) == SUBREG))
758 0 : from = force_reg (from_mode, from);
759 49027 : convert_move (to, gen_lowpart (word_mode, from), 0);
760 49027 : return;
761 : }
762 :
763 : /* Now follow all the conversions between integers
764 : no more than a word long. */
765 :
766 : /* For truncation, usually we can just refer to FROM in a narrower mode. */
767 307816 : if (GET_MODE_BITSIZE (to_mode) < GET_MODE_BITSIZE (from_mode)
768 153908 : && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, from_mode))
769 : {
770 165965 : if (!((MEM_P (from)
771 13965 : && ! MEM_VOLATILE_P (from)
772 13906 : && direct_load[(int) to_mode]
773 13906 : && ! mode_dependent_address_p (XEXP (from, 0),
774 13906 : MEM_ADDR_SPACE (from)))
775 140002 : || REG_P (from)
776 : || GET_CODE (from) == SUBREG))
777 926 : from = force_reg (from_mode, from);
778 128871 : if (REG_P (from) && REGNO (from) < FIRST_PSEUDO_REGISTER
779 153909 : && !targetm.hard_regno_mode_ok (REGNO (from), to_mode))
780 0 : from = copy_to_reg (from);
781 153908 : emit_move_insn (to, gen_lowpart (to_mode, from));
782 153908 : return;
783 : }
784 :
785 : /* Handle extension. */
786 0 : if (GET_MODE_PRECISION (to_mode) > GET_MODE_PRECISION (from_mode))
787 : {
788 : /* Convert directly if that works. */
789 0 : if ((code = can_extend_p (to_mode, from_mode, unsignedp))
790 : != CODE_FOR_nothing)
791 : {
792 0 : emit_unop_insn (code, to, from, equiv_code);
793 0 : return;
794 : }
795 : else
796 : {
797 0 : rtx tmp;
798 0 : int shift_amount;
799 :
800 : /* Search for a mode to convert via. */
801 0 : opt_scalar_mode intermediate_iter;
802 0 : FOR_EACH_MODE_FROM (intermediate_iter, from_mode)
803 : {
804 0 : scalar_mode intermediate = intermediate_iter.require ();
805 0 : if (((can_extend_p (to_mode, intermediate, unsignedp)
806 : != CODE_FOR_nothing)
807 0 : || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
808 0 : && TRULY_NOOP_TRUNCATION_MODES_P (to_mode,
809 : intermediate)))
810 0 : && (can_extend_p (intermediate, from_mode, unsignedp)
811 : != CODE_FOR_nothing))
812 : {
813 0 : convert_move (to, convert_to_mode (intermediate, from,
814 : unsignedp), unsignedp);
815 0 : return;
816 : }
817 : }
818 :
819 : /* No suitable intermediate mode.
820 : Generate what we need with shifts. */
821 0 : shift_amount = (GET_MODE_PRECISION (to_mode)
822 0 : - GET_MODE_PRECISION (from_mode));
823 0 : from = gen_lowpart (to_mode, force_reg (from_mode, from));
824 0 : tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
825 : to, unsignedp);
826 0 : tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
827 : to, unsignedp);
828 0 : if (tmp != to)
829 0 : emit_move_insn (to, tmp);
830 : return;
831 : }
832 : }
833 :
834 : /* Support special truncate insns for certain modes. */
835 0 : if (convert_optab_handler (trunc_optab, to_mode,
836 : from_mode) != CODE_FOR_nothing)
837 : {
838 0 : emit_unop_insn (convert_optab_handler (trunc_optab, to_mode, from_mode),
839 : to, from, UNKNOWN);
840 0 : return;
841 : }
842 :
843 : /* Handle truncation of volatile memrefs, and so on;
844 : the things that couldn't be truncated directly,
845 : and for which there was no special instruction.
846 :
847 : ??? Code above formerly short-circuited this, for most integer
848 : mode pairs, with a force_reg in from_mode followed by a recursive
849 : call to this routine. Appears always to have been wrong. */
850 0 : if (GET_MODE_PRECISION (to_mode) < GET_MODE_PRECISION (from_mode))
851 : {
852 0 : rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
853 0 : emit_move_insn (to, temp);
854 0 : return;
855 : }
856 :
857 : /* Mode combination is not recognized. */
858 0 : gcc_unreachable ();
859 : }
860 :
861 : /* Return an rtx for a value that would result
862 : from converting X to mode MODE.
863 : Both X and MODE may be floating, or both integer.
864 : UNSIGNEDP is nonzero if X is an unsigned value.
865 : This can be done by referring to a part of X in place
866 : or by copying to a new temporary with conversion. */
867 :
868 : rtx
869 2395930 : convert_to_mode (machine_mode mode, rtx x, int unsignedp)
870 : {
871 2395930 : return convert_modes (mode, VOIDmode, x, unsignedp);
872 : }
873 :
874 : /* Return an rtx for a value that would result
875 : from converting X from mode OLDMODE to mode MODE.
876 : Both modes may be floating, or both integer.
877 : UNSIGNEDP is nonzero if X is an unsigned value.
878 :
879 : This can be done by referring to a part of X in place
880 : or by copying to a new temporary with conversion.
881 :
882 : You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode. */
883 :
884 : rtx
885 5226904 : convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
886 : {
887 5226904 : rtx temp;
888 5226904 : scalar_int_mode int_mode;
889 :
890 : /* If FROM is a SUBREG that indicates that we have already done at least
891 : the required extension, strip it. */
892 :
893 5226904 : if (GET_CODE (x) == SUBREG
894 141070 : && SUBREG_PROMOTED_VAR_P (x)
895 5226911 : && is_a <scalar_int_mode> (mode, &int_mode)
896 5226911 : && (GET_MODE_PRECISION (subreg_promoted_mode (x))
897 14 : >= GET_MODE_PRECISION (int_mode))
898 5226918 : && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
899 : {
900 7 : scalar_int_mode int_orig_mode;
901 7 : scalar_int_mode int_inner_mode;
902 7 : machine_mode orig_mode = GET_MODE (x);
903 7 : x = gen_lowpart (int_mode, SUBREG_REG (x));
904 :
905 : /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
906 : the original mode, but narrower than the inner mode. */
907 7 : if (GET_CODE (x) == SUBREG
908 0 : && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
909 0 : && GET_MODE_PRECISION (int_mode)
910 0 : > GET_MODE_PRECISION (int_orig_mode)
911 0 : && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)),
912 : &int_inner_mode)
913 7 : && GET_MODE_PRECISION (int_inner_mode)
914 0 : > GET_MODE_PRECISION (int_mode))
915 : {
916 0 : SUBREG_PROMOTED_VAR_P (x) = 1;
917 0 : SUBREG_PROMOTED_SET (x, unsignedp);
918 : }
919 : }
920 :
921 5226904 : if (GET_MODE (x) != VOIDmode)
922 2886415 : oldmode = GET_MODE (x);
923 :
924 5226904 : if (mode == oldmode)
925 : return x;
926 :
927 3781543 : if (CONST_SCALAR_INT_P (x)
928 3781543 : && is_a <scalar_int_mode> (mode, &int_mode))
929 : {
930 : /* If the caller did not tell us the old mode, then there is not
931 : much to do with respect to canonicalization. We have to
932 : assume that all the bits are significant. */
933 2019351 : if (!is_a <scalar_int_mode> (oldmode))
934 1690050 : oldmode = MAX_MODE_INT;
935 2019351 : wide_int w = wide_int::from (rtx_mode_t (x, oldmode),
936 2019351 : GET_MODE_PRECISION (int_mode),
937 2664355 : unsignedp ? UNSIGNED : SIGNED);
938 2019351 : return immed_wide_int_const (w, int_mode);
939 2019351 : }
940 :
941 : /* We can do this with a gen_lowpart if both desired and current modes
942 : are integer, and this is either a constant integer, a register, or a
943 : non-volatile MEM. */
944 1762192 : scalar_int_mode int_oldmode;
945 1762192 : if (is_int_mode (mode, &int_mode)
946 1667490 : && is_int_mode (oldmode, &int_oldmode)
947 1667490 : && GET_MODE_PRECISION (int_mode) <= GET_MODE_PRECISION (int_oldmode)
948 459124 : && ((MEM_P (x) && !MEM_VOLATILE_P (x) && direct_load[(int) int_mode])
949 13000 : || CONST_POLY_INT_P (x)
950 446124 : || (REG_P (x)
951 409932 : && (!HARD_REGISTER_P (x)
952 1069 : || targetm.hard_regno_mode_ok (REGNO (x), int_mode))
953 422932 : && TRULY_NOOP_TRUNCATION_MODES_P (int_mode, GET_MODE (x)))))
954 422932 : return gen_lowpart (int_mode, x);
955 :
956 : /* Converting from integer constant into mode is always equivalent to an
957 : subreg operation. */
958 1339260 : if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode)
959 : {
960 0 : gcc_assert (known_eq (GET_MODE_BITSIZE (mode),
961 : GET_MODE_BITSIZE (oldmode)));
962 0 : return force_subreg (mode, x, oldmode, 0);
963 : }
964 :
965 1339260 : temp = gen_reg_rtx (mode);
966 1339260 : convert_move (temp, x, unsignedp);
967 1339260 : return temp;
968 : }
969 :
970 : /* Variant of convert_modes for ABI parameter passing/return.
971 : Return an rtx for a value that would result from converting X from
972 : a floating point mode FMODE to wider integer mode MODE. */
973 :
974 : rtx
975 0 : convert_float_to_wider_int (machine_mode mode, machine_mode fmode, rtx x)
976 : {
977 0 : gcc_assert (SCALAR_INT_MODE_P (mode) && SCALAR_FLOAT_MODE_P (fmode));
978 0 : scalar_int_mode tmp_mode = int_mode_for_mode (fmode).require ();
979 0 : rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
980 0 : return convert_modes (mode, tmp_mode, tmp, 1);
981 : }
982 :
983 : /* Variant of convert_modes for ABI parameter passing/return.
984 : Return an rtx for a value that would result from converting X from
985 : an integer mode IMODE to a narrower floating point mode MODE. */
986 :
987 : rtx
988 0 : convert_wider_int_to_float (machine_mode mode, machine_mode imode, rtx x)
989 : {
990 0 : gcc_assert (SCALAR_FLOAT_MODE_P (mode) && SCALAR_INT_MODE_P (imode));
991 0 : scalar_int_mode tmp_mode = int_mode_for_mode (mode).require ();
992 0 : rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
993 0 : return gen_lowpart_SUBREG (mode, tmp);
994 : }
995 :
996 : /* Return the largest alignment we can use for doing a move (or store)
997 : of MAX_PIECES. ALIGN is the largest alignment we could use. */
998 :
999 : static unsigned int
1000 2775878 : alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
1001 : {
1002 2775878 : scalar_int_mode tmode
1003 2775878 : = int_mode_for_size (max_pieces * BITS_PER_UNIT, 0).require ();
1004 :
1005 2775878 : if (align >= GET_MODE_ALIGNMENT (tmode))
1006 2190818 : align = GET_MODE_ALIGNMENT (tmode);
1007 : else
1008 : {
1009 585060 : scalar_int_mode xmode = NARROWEST_INT_MODE;
1010 585060 : opt_scalar_int_mode mode_iter;
1011 3526799 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
1012 : {
1013 3521071 : tmode = mode_iter.require ();
1014 3521071 : if (GET_MODE_SIZE (tmode) > max_pieces
1015 3521071 : || targetm.slow_unaligned_access (tmode, align))
1016 : break;
1017 2941739 : xmode = tmode;
1018 : }
1019 :
1020 585060 : align = MAX (align, GET_MODE_ALIGNMENT (xmode));
1021 : }
1022 :
1023 2775878 : return align;
1024 : }
1025 :
1026 : /* Return true if we know how to implement OP using vectors of bytes. */
1027 : static bool
1028 5870172 : can_use_qi_vectors (by_pieces_operation op)
1029 : {
1030 5870172 : return (op == COMPARE_BY_PIECES
1031 0 : || op == SET_BY_PIECES
1032 0 : || op == CLEAR_BY_PIECES);
1033 : }
1034 :
1035 : /* Return true if optabs exists for the mode and certain by pieces
1036 : operations. */
1037 : static bool
1038 26003294 : by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
1039 : {
1040 26003294 : if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
1041 : return false;
1042 :
1043 24641398 : if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
1044 687418 : && VECTOR_MODE_P (mode)
1045 25135299 : && optab_handler (vec_duplicate_optab, mode) == CODE_FOR_nothing)
1046 : return false;
1047 :
1048 24592735 : if (op == COMPARE_BY_PIECES
1049 24592735 : && !can_compare_p (EQ, mode, ccp_jump))
1050 : return false;
1051 :
1052 : return true;
1053 : }
1054 :
1055 : /* Return the widest mode that can be used to perform part of an
1056 : operation OP on SIZE bytes. Try to use QI vector modes where
1057 : possible. */
1058 : static fixed_size_mode
1059 5376384 : widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
1060 : {
1061 5376384 : fixed_size_mode result = NARROWEST_INT_MODE;
1062 :
1063 5376384 : gcc_checking_assert (size > 1);
1064 :
1065 : /* Use QI vector only if size is wider than a WORD. */
1066 5376384 : if (can_use_qi_vectors (op))
1067 : {
1068 729469 : machine_mode mode;
1069 729469 : fixed_size_mode candidate;
1070 12046501 : FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1071 12046501 : if (is_a<fixed_size_mode> (mode, &candidate)
1072 13153007 : && GET_MODE_SIZE (candidate) > UNITS_PER_WORD
1073 12970690 : && GET_MODE_INNER (candidate) == QImode)
1074 : {
1075 5674516 : if (GET_MODE_SIZE (candidate) >= size)
1076 : break;
1077 2107789 : if (by_pieces_mode_supported_p (candidate, op))
1078 11317032 : result = candidate;
1079 : }
1080 :
1081 729469 : if (result != NARROWEST_INT_MODE)
1082 472430 : return result;
1083 : }
1084 :
1085 4903954 : opt_scalar_int_mode tmode;
1086 4903954 : scalar_int_mode mode;
1087 39231632 : FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
1088 : {
1089 34327678 : mode = tmode.require ();
1090 34327678 : if (GET_MODE_SIZE (mode) < size
1091 34327678 : && by_pieces_mode_supported_p (mode, op))
1092 23853760 : result = mode;
1093 : }
1094 :
1095 4903954 : return result;
1096 : }
1097 :
1098 : /* Determine whether an operation OP on LEN bytes with alignment ALIGN can
1099 : and should be performed piecewise. */
1100 :
1101 : static bool
1102 968412 : can_do_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align,
1103 : enum by_pieces_operation op)
1104 : {
1105 968412 : return targetm.use_by_pieces_infrastructure_p (len, align, op,
1106 968412 : optimize_insn_for_speed_p ());
1107 : }
1108 :
1109 : /* Determine whether the LEN bytes can be moved by using several move
1110 : instructions. Return nonzero if a call to move_by_pieces should
1111 : succeed. */
1112 :
1113 : bool
1114 898779 : can_move_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align)
1115 : {
1116 898779 : return can_do_by_pieces (len, align, MOVE_BY_PIECES);
1117 : }
1118 :
1119 : /* Return number of insns required to perform operation OP by pieces
1120 : for L bytes. ALIGN (in bits) is maximum alignment we can assume. */
1121 :
1122 : unsigned HOST_WIDE_INT
1123 1962707 : by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
1124 : unsigned int max_size, by_pieces_operation op)
1125 : {
1126 1962707 : unsigned HOST_WIDE_INT n_insns = 0;
1127 1962707 : fixed_size_mode mode;
1128 :
1129 1962707 : if (targetm.overlap_op_by_pieces_p ())
1130 : {
1131 : /* NB: Round up L and ALIGN to the widest integer mode for
1132 : MAX_SIZE. */
1133 1962707 : mode = widest_fixed_size_mode_for_size (max_size, op);
1134 1962707 : gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
1135 3925414 : unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
1136 1962707 : if (up > l)
1137 : l = up;
1138 1962707 : align = GET_MODE_ALIGNMENT (mode);
1139 : }
1140 :
1141 1962707 : align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1142 :
1143 5896468 : while (max_size > 1 && l > 0)
1144 : {
1145 1971054 : mode = widest_fixed_size_mode_for_size (max_size, op);
1146 1971054 : gcc_assert (optab_handler (mov_optab, mode) != CODE_FOR_nothing);
1147 :
1148 1971054 : unsigned int modesize = GET_MODE_SIZE (mode);
1149 :
1150 1971054 : if (align >= GET_MODE_ALIGNMENT (mode))
1151 : {
1152 1971054 : unsigned HOST_WIDE_INT n_pieces = l / modesize;
1153 1971054 : l %= modesize;
1154 1971054 : switch (op)
1155 : {
1156 1901421 : default:
1157 1901421 : n_insns += n_pieces;
1158 1901421 : break;
1159 :
1160 69633 : case COMPARE_BY_PIECES:
1161 69633 : int batch = targetm.compare_by_pieces_branch_ratio (mode);
1162 69633 : int batch_ops = 4 * batch - 1;
1163 69633 : unsigned HOST_WIDE_INT full = n_pieces / batch;
1164 69633 : n_insns += full * batch_ops;
1165 69633 : if (n_pieces % batch != 0)
1166 0 : n_insns++;
1167 : break;
1168 :
1169 : }
1170 : }
1171 1971054 : max_size = modesize;
1172 : }
1173 :
1174 1962707 : gcc_assert (!l);
1175 1962707 : return n_insns;
1176 : }
1177 :
1178 : /* Used when performing piecewise block operations, holds information
1179 : about one of the memory objects involved. The member functions
1180 : can be used to generate code for loading from the object and
1181 : updating the address when iterating. */
1182 :
1183 : class pieces_addr
1184 : {
1185 : /* The object being referenced, a MEM. Can be NULL_RTX to indicate
1186 : stack pushes. */
1187 : rtx m_obj;
1188 : /* The address of the object. Can differ from that seen in the
1189 : MEM rtx if we copied the address to a register. */
1190 : rtx m_addr;
1191 : /* Nonzero if the address on the object has an autoincrement already,
1192 : signifies whether that was an increment or decrement. */
1193 : signed char m_addr_inc;
1194 : /* Nonzero if we intend to use autoinc without the address already
1195 : having autoinc form. We will insert add insns around each memory
1196 : reference, expecting later passes to form autoinc addressing modes.
1197 : The only supported options are predecrement and postincrement. */
1198 : signed char m_explicit_inc;
1199 : /* True if we have either of the two possible cases of using
1200 : autoincrement. */
1201 : bool m_auto;
1202 : /* True if this is an address to be used for load operations rather
1203 : than stores. */
1204 : bool m_is_load;
1205 :
1206 : /* Optionally, a function to obtain constants for any given offset into
1207 : the objects, and data associated with it. */
1208 : by_pieces_constfn m_constfn;
1209 : void *m_cfndata;
1210 : public:
1211 : pieces_addr (rtx, bool, by_pieces_constfn, void *);
1212 : rtx adjust (fixed_size_mode, HOST_WIDE_INT, by_pieces_prev * = nullptr);
1213 : void increment_address (HOST_WIDE_INT);
1214 : void maybe_predec (HOST_WIDE_INT);
1215 : void maybe_postinc (HOST_WIDE_INT);
1216 : void decide_autoinc (machine_mode, bool, HOST_WIDE_INT);
1217 759205 : int get_addr_inc ()
1218 : {
1219 759205 : return m_addr_inc;
1220 : }
1221 : };
1222 :
1223 : /* Initialize a pieces_addr structure from an object OBJ. IS_LOAD is
1224 : true if the operation to be performed on this object is a load
1225 : rather than a store. For stores, OBJ can be NULL, in which case we
1226 : assume the operation is a stack push. For loads, the optional
1227 : CONSTFN and its associated CFNDATA can be used in place of the
1228 : memory load. */
1229 :
1230 1518410 : pieces_addr::pieces_addr (rtx obj, bool is_load, by_pieces_constfn constfn,
1231 : void *cfndata)
1232 1518410 : : m_obj (obj), m_is_load (is_load), m_constfn (constfn), m_cfndata (cfndata)
1233 : {
1234 1518410 : m_addr_inc = 0;
1235 1518410 : m_auto = false;
1236 1518410 : if (obj)
1237 : {
1238 1393148 : rtx addr = XEXP (obj, 0);
1239 1393148 : rtx_code code = GET_CODE (addr);
1240 1393148 : m_addr = addr;
1241 1393148 : bool dec = code == PRE_DEC || code == POST_DEC;
1242 1393148 : bool inc = code == PRE_INC || code == POST_INC;
1243 1393148 : m_auto = inc || dec;
1244 1393148 : if (m_auto)
1245 0 : m_addr_inc = dec ? -1 : 1;
1246 :
1247 : /* While we have always looked for these codes here, the code
1248 : implementing the memory operation has never handled them.
1249 : Support could be added later if necessary or beneficial. */
1250 1393148 : gcc_assert (code != PRE_INC && code != POST_DEC);
1251 : }
1252 : else
1253 : {
1254 125262 : m_addr = NULL_RTX;
1255 125262 : if (!is_load)
1256 : {
1257 45 : m_auto = true;
1258 45 : if (STACK_GROWS_DOWNWARD)
1259 45 : m_addr_inc = -1;
1260 : else
1261 : m_addr_inc = 1;
1262 : }
1263 : else
1264 125217 : gcc_assert (constfn != NULL);
1265 : }
1266 1518410 : m_explicit_inc = 0;
1267 1518410 : if (constfn)
1268 151462 : gcc_assert (is_load);
1269 1518410 : }
1270 :
1271 : /* Decide whether to use autoinc for an address involved in a memory op.
1272 : MODE is the mode of the accesses, REVERSE is true if we've decided to
1273 : perform the operation starting from the end, and LEN is the length of
1274 : the operation. Don't override an earlier decision to set m_auto. */
1275 :
1276 : void
1277 377220 : pieces_addr::decide_autoinc (machine_mode ARG_UNUSED (mode), bool reverse,
1278 : HOST_WIDE_INT len)
1279 : {
1280 377220 : if (m_auto || m_obj == NULL_RTX)
1281 : return;
1282 :
1283 345792 : bool use_predec = (m_is_load
1284 : ? USE_LOAD_PRE_DECREMENT (mode)
1285 : : USE_STORE_PRE_DECREMENT (mode));
1286 345792 : bool use_postinc = (m_is_load
1287 : ? USE_LOAD_POST_INCREMENT (mode)
1288 : : USE_STORE_POST_INCREMENT (mode));
1289 345792 : machine_mode addr_mode = get_address_mode (m_obj);
1290 :
1291 345792 : if (use_predec && reverse)
1292 : {
1293 : m_addr = copy_to_mode_reg (addr_mode,
1294 : plus_constant (addr_mode,
1295 : m_addr, len));
1296 : m_auto = true;
1297 : m_explicit_inc = -1;
1298 : }
1299 345792 : else if (use_postinc && !reverse)
1300 : {
1301 : m_addr = copy_to_mode_reg (addr_mode, m_addr);
1302 : m_auto = true;
1303 : m_explicit_inc = 1;
1304 : }
1305 345792 : else if (CONSTANT_P (m_addr))
1306 71982 : m_addr = copy_to_mode_reg (addr_mode, m_addr);
1307 : }
1308 :
1309 : /* Adjust the address to refer to the data at OFFSET in MODE. If we
1310 : are using autoincrement for this address, we don't add the offset,
1311 : but we still modify the MEM's properties. */
1312 :
1313 : rtx
1314 4143605 : pieces_addr::adjust (fixed_size_mode mode, HOST_WIDE_INT offset,
1315 : by_pieces_prev *prev)
1316 : {
1317 4143605 : if (m_constfn)
1318 : /* Pass the previous data to m_constfn. */
1319 371378 : return m_constfn (m_cfndata, prev, offset, mode);
1320 3772227 : if (m_obj == NULL_RTX)
1321 : return NULL_RTX;
1322 3772180 : if (m_auto)
1323 0 : return adjust_automodify_address (m_obj, mode, m_addr, offset);
1324 : else
1325 3772180 : return adjust_address (m_obj, mode, offset);
1326 : }
1327 :
1328 : /* Emit an add instruction to increment the address by SIZE. */
1329 :
1330 : void
1331 0 : pieces_addr::increment_address (HOST_WIDE_INT size)
1332 : {
1333 0 : rtx amount = gen_int_mode (size, GET_MODE (m_addr));
1334 0 : emit_insn (gen_add2_insn (m_addr, amount));
1335 0 : }
1336 :
1337 : /* If we are supposed to decrement the address after each access, emit code
1338 : to do so now. Increment by SIZE (which has should have the correct sign
1339 : already). */
1340 :
1341 : void
1342 4142958 : pieces_addr::maybe_predec (HOST_WIDE_INT size)
1343 : {
1344 4142958 : if (m_explicit_inc >= 0)
1345 4142958 : return;
1346 0 : gcc_assert (HAVE_PRE_DECREMENT);
1347 : increment_address (size);
1348 : }
1349 :
1350 : /* If we are supposed to decrement the address after each access, emit code
1351 : to do so now. Increment by SIZE. */
1352 :
1353 : void
1354 4142981 : pieces_addr::maybe_postinc (HOST_WIDE_INT size)
1355 : {
1356 4142981 : if (m_explicit_inc <= 0)
1357 4142981 : return;
1358 0 : gcc_assert (HAVE_POST_INCREMENT);
1359 : increment_address (size);
1360 : }
1361 :
1362 : /* This structure is used by do_op_by_pieces to describe the operation
1363 : to be performed. */
1364 :
1365 : class op_by_pieces_d
1366 : {
1367 : private:
1368 : fixed_size_mode get_usable_mode (fixed_size_mode, unsigned int);
1369 : fixed_size_mode smallest_fixed_size_mode_for_size (unsigned int);
1370 :
1371 : protected:
1372 : pieces_addr m_to, m_from;
1373 : /* Make m_len read-only so that smallest_fixed_size_mode_for_size can
1374 : use it to check the valid mode size. */
1375 : const unsigned HOST_WIDE_INT m_len;
1376 : HOST_WIDE_INT m_offset;
1377 : unsigned int m_align;
1378 : unsigned int m_max_size;
1379 : bool m_reverse;
1380 : /* True if this is a stack push. */
1381 : bool m_push;
1382 : /* True if targetm.overlap_op_by_pieces_p () returns true. */
1383 : bool m_overlap_op_by_pieces;
1384 : /* The type of operation that we're performing. */
1385 : by_pieces_operation m_op;
1386 :
1387 : /* Virtual functions, overridden by derived classes for the specific
1388 : operation. */
1389 : virtual void generate (rtx, rtx, machine_mode) = 0;
1390 : virtual bool prepare_mode (machine_mode, unsigned int) = 0;
1391 1151843 : virtual void finish_mode (machine_mode)
1392 : {
1393 1151843 : }
1394 :
1395 : public:
1396 : op_by_pieces_d (unsigned int, rtx, bool, rtx, bool, by_pieces_constfn,
1397 : void *, unsigned HOST_WIDE_INT, unsigned int, bool,
1398 : by_pieces_operation);
1399 : void run ();
1400 : };
1401 :
1402 : /* The constructor for an op_by_pieces_d structure. We require two
1403 : objects named TO and FROM, which are identified as loads or stores
1404 : by TO_LOAD and FROM_LOAD. If FROM is a load, the optional FROM_CFN
1405 : and its associated FROM_CFN_DATA can be used to replace loads with
1406 : constant values. MAX_PIECES describes the maximum number of bytes
1407 : at a time which can be moved efficiently. LEN describes the length
1408 : of the operation. */
1409 :
1410 759205 : op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
1411 : bool to_load, rtx from, bool from_load,
1412 : by_pieces_constfn from_cfn,
1413 : void *from_cfn_data,
1414 : unsigned HOST_WIDE_INT len,
1415 : unsigned int align, bool push,
1416 : by_pieces_operation op)
1417 759205 : : m_to (to, to_load, NULL, NULL),
1418 759205 : m_from (from, from_load, from_cfn, from_cfn_data),
1419 759205 : m_len (len), m_max_size (max_pieces + 1),
1420 759205 : m_push (push), m_op (op)
1421 : {
1422 759205 : int toi = m_to.get_addr_inc ();
1423 759205 : int fromi = m_from.get_addr_inc ();
1424 759205 : if (toi >= 0 && fromi >= 0)
1425 759160 : m_reverse = false;
1426 45 : else if (toi <= 0 && fromi <= 0)
1427 45 : m_reverse = true;
1428 : else
1429 0 : gcc_unreachable ();
1430 :
1431 759205 : m_offset = m_reverse ? len : 0;
1432 2786351 : align = MIN (to ? MEM_ALIGN (to) : align,
1433 : from ? MEM_ALIGN (from) : align);
1434 :
1435 : /* If copying requires more than two move insns,
1436 : copy addresses to registers (to make displacements shorter)
1437 : and use post-increment if available. */
1438 759205 : if (by_pieces_ninsns (len, align, m_max_size, MOVE_BY_PIECES) > 2)
1439 : {
1440 : /* Find the mode of the largest comparison. */
1441 188610 : fixed_size_mode mode
1442 188610 : = widest_fixed_size_mode_for_size (m_max_size, m_op);
1443 :
1444 188610 : m_from.decide_autoinc (mode, m_reverse, len);
1445 188610 : m_to.decide_autoinc (mode, m_reverse, len);
1446 : }
1447 :
1448 759215 : align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1449 759205 : m_align = align;
1450 :
1451 759205 : m_overlap_op_by_pieces = targetm.overlap_op_by_pieces_p ();
1452 759205 : }
1453 :
1454 : /* This function returns the largest usable integer mode for LEN bytes
1455 : whose size is no bigger than size of MODE. */
1456 :
1457 : fixed_size_mode
1458 1246637 : op_by_pieces_d::get_usable_mode (fixed_size_mode mode, unsigned int len)
1459 : {
1460 1546279 : unsigned int size;
1461 1845921 : do
1462 : {
1463 1546279 : size = GET_MODE_SIZE (mode);
1464 1546279 : if (len >= size && prepare_mode (mode, m_align))
1465 : break;
1466 : /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1467 299642 : mode = widest_fixed_size_mode_for_size (size, m_op);
1468 : }
1469 : while (1);
1470 1246637 : return mode;
1471 : }
1472 :
1473 : /* Return the smallest integer or QI vector mode that is not narrower
1474 : than SIZE bytes. */
1475 :
1476 : fixed_size_mode
1477 493788 : op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
1478 : {
1479 : /* Use QI vector only for > size of WORD. */
1480 505996 : if (can_use_qi_vectors (m_op) && size > UNITS_PER_WORD)
1481 : {
1482 8234 : machine_mode mode;
1483 8234 : fixed_size_mode candidate;
1484 111425 : FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1485 111425 : if (is_a<fixed_size_mode> (mode, &candidate)
1486 222850 : && GET_MODE_INNER (candidate) == QImode)
1487 : {
1488 : /* Don't return a mode wider than M_LEN. */
1489 103602 : if (GET_MODE_SIZE (candidate) > m_len)
1490 : break;
1491 :
1492 49865 : if (GET_MODE_SIZE (candidate) >= size
1493 49865 : && by_pieces_mode_supported_p (candidate, m_op))
1494 6298 : return candidate;
1495 : }
1496 : }
1497 :
1498 487490 : return smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
1499 : }
1500 :
1501 : /* This function contains the main loop used for expanding a block
1502 : operation. First move what we can in the largest integer mode,
1503 : then go to successively smaller modes. For every access, call
1504 : GENFUN with the two operands and the EXTRA_DATA. */
1505 :
1506 : void
1507 759205 : op_by_pieces_d::run ()
1508 : {
1509 759205 : if (m_len == 0)
1510 : return;
1511 :
1512 752849 : unsigned HOST_WIDE_INT length = m_len;
1513 :
1514 : /* widest_fixed_size_mode_for_size checks M_MAX_SIZE > 1. */
1515 752849 : fixed_size_mode mode
1516 752849 : = widest_fixed_size_mode_for_size (m_max_size, m_op);
1517 752849 : mode = get_usable_mode (mode, length);
1518 :
1519 752849 : by_pieces_prev to_prev = { nullptr, mode };
1520 752849 : by_pieces_prev from_prev = { nullptr, mode };
1521 :
1522 1246637 : do
1523 : {
1524 1246637 : unsigned int size = GET_MODE_SIZE (mode);
1525 1246637 : rtx to1 = NULL_RTX, from1;
1526 :
1527 3318116 : while (length >= size)
1528 : {
1529 2071479 : if (m_reverse)
1530 47 : m_offset -= size;
1531 :
1532 2071479 : to1 = m_to.adjust (mode, m_offset, &to_prev);
1533 2071479 : to_prev.data = to1;
1534 2071479 : to_prev.mode = mode;
1535 2071479 : from1 = m_from.adjust (mode, m_offset, &from_prev);
1536 2071479 : from_prev.data = from1;
1537 2071479 : from_prev.mode = mode;
1538 :
1539 2071479 : m_to.maybe_predec (-(HOST_WIDE_INT)size);
1540 2071479 : m_from.maybe_predec (-(HOST_WIDE_INT)size);
1541 :
1542 2071479 : generate (to1, from1, mode);
1543 :
1544 2071479 : m_to.maybe_postinc (size);
1545 2071479 : m_from.maybe_postinc (size);
1546 :
1547 2071479 : if (!m_reverse)
1548 2071432 : m_offset += size;
1549 :
1550 2071479 : length -= size;
1551 : }
1552 :
1553 1246637 : finish_mode (mode);
1554 :
1555 1246637 : if (length == 0)
1556 : return;
1557 :
1558 493788 : if (!m_push && m_overlap_op_by_pieces)
1559 : {
1560 : /* NB: Generate overlapping operations if it is not a stack
1561 : push since stack push must not overlap. Get the smallest
1562 : fixed size mode for M_LEN bytes. */
1563 493788 : mode = smallest_fixed_size_mode_for_size (length);
1564 987576 : mode = get_usable_mode (mode, GET_MODE_SIZE (mode));
1565 493788 : int gap = GET_MODE_SIZE (mode) - length;
1566 493788 : if (gap > 0)
1567 : {
1568 : /* If size of MODE > M_LEN, generate the last operation
1569 : in MODE for the remaining bytes with overlapping memory
1570 : from the previois operation. */
1571 49039 : if (m_reverse)
1572 0 : m_offset += gap;
1573 : else
1574 49039 : m_offset -= gap;
1575 49039 : length += gap;
1576 : }
1577 : }
1578 : else
1579 : {
1580 : /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1581 0 : mode = widest_fixed_size_mode_for_size (size, m_op);
1582 0 : mode = get_usable_mode (mode, length);
1583 : }
1584 : }
1585 : while (1);
1586 : }
1587 :
1588 : /* Derived class from op_by_pieces_d, providing support for block move
1589 : operations. */
1590 :
1591 : #ifdef PUSH_ROUNDING
1592 : #define PUSHG_P(to) ((to) == nullptr)
1593 : #else
1594 : #define PUSHG_P(to) false
1595 : #endif
1596 :
1597 : class move_by_pieces_d : public op_by_pieces_d
1598 : {
1599 : insn_gen_fn m_gen_fun;
1600 : void generate (rtx, rtx, machine_mode) final override;
1601 : bool prepare_mode (machine_mode, unsigned int) final override;
1602 :
1603 : public:
1604 571138 : move_by_pieces_d (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1605 : unsigned int align)
1606 571138 : : op_by_pieces_d (MOVE_MAX_PIECES, to, false, from, true, NULL,
1607 1142276 : NULL, len, align, PUSHG_P (to), MOVE_BY_PIECES)
1608 : {
1609 571138 : }
1610 : rtx finish_retmode (memop_ret);
1611 : };
1612 :
1613 : /* Return true if MODE can be used for a set of copies, given an
1614 : alignment ALIGN. Prepare whatever data is necessary for later
1615 : calls to generate. */
1616 :
1617 : bool
1618 952186 : move_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1619 : {
1620 952186 : insn_code icode = optab_handler (mov_optab, mode);
1621 952186 : m_gen_fun = GEN_FCN (icode);
1622 952186 : return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1623 : }
1624 :
1625 : /* A callback used when iterating for a compare_by_pieces_operation.
1626 : OP0 and OP1 are the values that have been loaded and should be
1627 : compared in MODE. If OP0 is NULL, this means we should generate a
1628 : push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1629 : gen function that should be used to generate the mode. */
1630 :
1631 : void
1632 1654582 : move_by_pieces_d::generate (rtx op0, rtx op1,
1633 : machine_mode mode ATTRIBUTE_UNUSED)
1634 : {
1635 : #ifdef PUSH_ROUNDING
1636 1654582 : if (op0 == NULL_RTX)
1637 : {
1638 47 : emit_single_push_insn (mode, op1, NULL);
1639 47 : return;
1640 : }
1641 : #endif
1642 1654535 : emit_insn (m_gen_fun (op0, op1));
1643 : }
1644 :
1645 : /* Perform the final adjustment at the end of a string to obtain the
1646 : correct return value for the block operation.
1647 : Return value is based on RETMODE argument. */
1648 :
1649 : rtx
1650 0 : move_by_pieces_d::finish_retmode (memop_ret retmode)
1651 : {
1652 0 : gcc_assert (!m_reverse);
1653 0 : if (retmode == RETURN_END_MINUS_ONE)
1654 : {
1655 0 : m_to.maybe_postinc (-1);
1656 0 : --m_offset;
1657 : }
1658 0 : return m_to.adjust (QImode, m_offset);
1659 : }
1660 :
1661 : /* Generate several move instructions to copy LEN bytes from block FROM to
1662 : block TO. (These are MEM rtx's with BLKmode).
1663 :
1664 : If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1665 : used to push FROM to the stack.
1666 :
1667 : ALIGN is maximum stack alignment we can assume.
1668 :
1669 : Return value is based on RETMODE argument. */
1670 :
1671 : rtx
1672 571138 : move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1673 : unsigned int align, memop_ret retmode)
1674 : {
1675 : #ifndef PUSH_ROUNDING
1676 : if (to == NULL)
1677 : gcc_unreachable ();
1678 : #endif
1679 :
1680 571138 : move_by_pieces_d data (to, from, len, align);
1681 :
1682 571138 : data.run ();
1683 :
1684 571138 : if (retmode != RETURN_BEGIN)
1685 0 : return data.finish_retmode (retmode);
1686 : else
1687 : return to;
1688 : }
1689 :
1690 : /* Derived class from op_by_pieces_d, providing support for block move
1691 : operations. */
1692 :
1693 : class store_by_pieces_d : public op_by_pieces_d
1694 : {
1695 : insn_gen_fn m_gen_fun;
1696 :
1697 : void generate (rtx, rtx, machine_mode) final override;
1698 : bool prepare_mode (machine_mode, unsigned int) final override;
1699 :
1700 : public:
1701 125217 : store_by_pieces_d (rtx to, by_pieces_constfn cfn, void *cfn_data,
1702 : unsigned HOST_WIDE_INT len, unsigned int align,
1703 : by_pieces_operation op)
1704 125217 : : op_by_pieces_d (STORE_MAX_PIECES, to, false, NULL_RTX, true, cfn,
1705 250434 : cfn_data, len, align, false, op)
1706 : {
1707 125217 : }
1708 : rtx finish_retmode (memop_ret);
1709 : };
1710 :
1711 : /* Return true if MODE can be used for a set of stores, given an
1712 : alignment ALIGN. Prepare whatever data is necessary for later
1713 : calls to generate. */
1714 :
1715 : bool
1716 199657 : store_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1717 : {
1718 199657 : insn_code icode = optab_handler (mov_optab, mode);
1719 199657 : m_gen_fun = GEN_FCN (icode);
1720 199657 : return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1721 : }
1722 :
1723 : /* A callback used when iterating for a store_by_pieces_operation.
1724 : OP0 and OP1 are the values that have been loaded and should be
1725 : compared in MODE. If OP0 is NULL, this means we should generate a
1726 : push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1727 : gen function that should be used to generate the mode. */
1728 :
1729 : void
1730 318846 : store_by_pieces_d::generate (rtx op0, rtx op1, machine_mode)
1731 : {
1732 318846 : emit_insn (m_gen_fun (op0, op1));
1733 318846 : }
1734 :
1735 : /* Perform the final adjustment at the end of a string to obtain the
1736 : correct return value for the block operation.
1737 : Return value is based on RETMODE argument. */
1738 :
1739 : rtx
1740 647 : store_by_pieces_d::finish_retmode (memop_ret retmode)
1741 : {
1742 647 : gcc_assert (!m_reverse);
1743 647 : if (retmode == RETURN_END_MINUS_ONE)
1744 : {
1745 23 : m_to.maybe_postinc (-1);
1746 23 : --m_offset;
1747 : }
1748 647 : return m_to.adjust (QImode, m_offset);
1749 : }
1750 :
1751 : /* Determine whether the LEN bytes generated by CONSTFUN can be
1752 : stored to memory using several move instructions. CONSTFUNDATA is
1753 : a pointer which will be passed as argument in every CONSTFUN call.
1754 : ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1755 : a memset operation and false if it's a copy of a constant string.
1756 : Return true if a call to store_by_pieces should succeed. */
1757 :
1758 : bool
1759 91082 : can_store_by_pieces (unsigned HOST_WIDE_INT len,
1760 : by_pieces_constfn constfun,
1761 : void *constfundata, unsigned int align, bool memsetp)
1762 : {
1763 91082 : unsigned HOST_WIDE_INT l;
1764 91082 : unsigned int max_size;
1765 91082 : HOST_WIDE_INT offset = 0;
1766 91082 : enum insn_code icode;
1767 91082 : int reverse;
1768 : /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it. */
1769 91082 : rtx cst ATTRIBUTE_UNUSED;
1770 :
1771 91082 : if (len == 0)
1772 : return true;
1773 :
1774 137859 : if (!targetm.use_by_pieces_infrastructure_p (len, align,
1775 : memsetp
1776 : ? SET_BY_PIECES
1777 : : STORE_BY_PIECES,
1778 : optimize_insn_for_speed_p ()))
1779 : return false;
1780 :
1781 53966 : align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
1782 :
1783 : /* We would first store what we can in the largest integer mode, then go to
1784 : successively smaller modes. */
1785 :
1786 53966 : for (reverse = 0;
1787 107932 : reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
1788 : reverse++)
1789 : {
1790 53966 : l = len;
1791 53990 : max_size = STORE_MAX_PIECES + 1;
1792 255488 : while (max_size > 1 && l > 0)
1793 : {
1794 201522 : auto op = memsetp ? SET_BY_PIECES : STORE_BY_PIECES;
1795 201522 : auto mode = widest_fixed_size_mode_for_size (max_size, op);
1796 :
1797 201522 : icode = optab_handler (mov_optab, mode);
1798 201522 : if (icode != CODE_FOR_nothing
1799 201522 : && align >= GET_MODE_ALIGNMENT (mode))
1800 : {
1801 201522 : unsigned int size = GET_MODE_SIZE (mode);
1802 :
1803 348710 : while (l >= size)
1804 : {
1805 147188 : if (reverse)
1806 : offset -= size;
1807 :
1808 147188 : cst = (*constfun) (constfundata, nullptr, offset, mode);
1809 : /* All CONST_VECTORs can be loaded for memset since
1810 : vec_duplicate_optab is a precondition to pick a
1811 : vector mode for the memset expander. */
1812 273589 : if (!((memsetp && VECTOR_MODE_P (mode))
1813 126401 : || targetm.legitimate_constant_p (mode, cst)))
1814 91082 : return false;
1815 :
1816 147188 : if (!reverse)
1817 147188 : offset += size;
1818 :
1819 147188 : l -= size;
1820 : }
1821 : }
1822 :
1823 403044 : max_size = GET_MODE_SIZE (mode);
1824 : }
1825 :
1826 : /* The code above should have handled everything. */
1827 53966 : gcc_assert (!l);
1828 : }
1829 :
1830 : return true;
1831 : }
1832 :
1833 : /* Generate several move instructions to store LEN bytes generated by
1834 : CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
1835 : pointer which will be passed as argument in every CONSTFUN call.
1836 : ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1837 : a memset operation and false if it's a copy of a constant string.
1838 : Return value is based on RETMODE argument. */
1839 :
1840 : rtx
1841 61177 : store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
1842 : by_pieces_constfn constfun,
1843 : void *constfundata, unsigned int align, bool memsetp,
1844 : memop_ret retmode)
1845 : {
1846 61177 : if (len == 0)
1847 : {
1848 7949 : gcc_assert (retmode != RETURN_END_MINUS_ONE);
1849 : return to;
1850 : }
1851 :
1852 95850 : gcc_assert (targetm.use_by_pieces_infrastructure_p
1853 : (len, align,
1854 : memsetp ? SET_BY_PIECES : STORE_BY_PIECES,
1855 : optimize_insn_for_speed_p ()));
1856 :
1857 53228 : store_by_pieces_d data (to, constfun, constfundata, len, align,
1858 53228 : memsetp ? SET_BY_PIECES : STORE_BY_PIECES);
1859 53228 : data.run ();
1860 :
1861 53228 : if (retmode != RETURN_BEGIN)
1862 647 : return data.finish_retmode (retmode);
1863 : else
1864 : return to;
1865 : }
1866 :
1867 : void
1868 71989 : clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
1869 : {
1870 71989 : if (len == 0)
1871 : return;
1872 :
1873 : /* Use builtin_memset_read_str to support vector mode broadcast. */
1874 71989 : char c = 0;
1875 71989 : store_by_pieces_d data (to, builtin_memset_read_str, &c, len, align,
1876 71989 : CLEAR_BY_PIECES);
1877 71989 : data.run ();
1878 : }
1879 :
1880 : /* Context used by compare_by_pieces_genfn. It stores the fail label
1881 : to jump to in case of miscomparison, and for branch ratios greater than 1,
1882 : it stores an accumulator and the current and maximum counts before
1883 : emitting another branch. */
1884 :
1885 : class compare_by_pieces_d : public op_by_pieces_d
1886 : {
1887 : rtx_code_label *m_fail_label;
1888 : rtx m_accumulator;
1889 : int m_count, m_batch;
1890 :
1891 : void generate (rtx, rtx, machine_mode) final override;
1892 : bool prepare_mode (machine_mode, unsigned int) final override;
1893 : void finish_mode (machine_mode) final override;
1894 :
1895 : public:
1896 62850 : compare_by_pieces_d (rtx op0, rtx op1, by_pieces_constfn op1_cfn,
1897 : void *op1_cfn_data, HOST_WIDE_INT len, int align,
1898 : rtx_code_label *fail_label)
1899 62850 : : op_by_pieces_d (COMPARE_MAX_PIECES, op0, true, op1, true, op1_cfn,
1900 125700 : op1_cfn_data, len, align, false, COMPARE_BY_PIECES)
1901 : {
1902 62850 : m_fail_label = fail_label;
1903 62850 : }
1904 : };
1905 :
1906 : /* A callback used when iterating for a compare_by_pieces_operation.
1907 : OP0 and OP1 are the values that have been loaded and should be
1908 : compared in MODE. DATA holds a pointer to the compare_by_pieces_data
1909 : context structure. */
1910 :
1911 : void
1912 98051 : compare_by_pieces_d::generate (rtx op0, rtx op1, machine_mode mode)
1913 : {
1914 98051 : if (m_batch > 1)
1915 : {
1916 0 : rtx temp = expand_binop (mode, sub_optab, op0, op1, NULL_RTX,
1917 : true, OPTAB_LIB_WIDEN);
1918 0 : if (m_count != 0)
1919 0 : temp = expand_binop (mode, ior_optab, m_accumulator, temp, temp,
1920 : true, OPTAB_LIB_WIDEN);
1921 0 : m_accumulator = temp;
1922 :
1923 0 : if (++m_count < m_batch)
1924 : return;
1925 :
1926 0 : m_count = 0;
1927 0 : op0 = m_accumulator;
1928 0 : op1 = const0_rtx;
1929 0 : m_accumulator = NULL_RTX;
1930 : }
1931 98051 : do_compare_rtx_and_jump (op0, op1, NE, true, mode, NULL_RTX, NULL,
1932 : m_fail_label, profile_probability::uninitialized ());
1933 : }
1934 :
1935 : /* Return true if MODE can be used for a set of moves and comparisons,
1936 : given an alignment ALIGN. Prepare whatever data is necessary for
1937 : later calls to generate. */
1938 :
1939 : bool
1940 94794 : compare_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1941 : {
1942 94794 : insn_code icode = optab_handler (mov_optab, mode);
1943 94794 : if (icode == CODE_FOR_nothing
1944 94794 : || align < GET_MODE_ALIGNMENT (mode)
1945 189588 : || !can_compare_p (EQ, mode, ccp_jump))
1946 : return false;
1947 94794 : m_batch = targetm.compare_by_pieces_branch_ratio (mode);
1948 94794 : if (m_batch < 0)
1949 : return false;
1950 94794 : m_accumulator = NULL_RTX;
1951 94794 : m_count = 0;
1952 94794 : return true;
1953 : }
1954 :
1955 : /* Called after expanding a series of comparisons in MODE. If we have
1956 : accumulated results for which we haven't emitted a branch yet, do
1957 : so now. */
1958 :
1959 : void
1960 94794 : compare_by_pieces_d::finish_mode (machine_mode mode)
1961 : {
1962 94794 : if (m_accumulator != NULL_RTX)
1963 0 : do_compare_rtx_and_jump (m_accumulator, const0_rtx, NE, true, mode,
1964 : NULL_RTX, NULL, m_fail_label,
1965 : profile_probability::uninitialized ());
1966 94794 : }
1967 :
1968 : /* Generate several move instructions to compare LEN bytes from blocks
1969 : ARG0 and ARG1. (These are MEM rtx's with BLKmode).
1970 :
1971 : If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1972 : used to push FROM to the stack.
1973 :
1974 : ALIGN is maximum stack alignment we can assume.
1975 :
1976 : Optionally, the caller can pass a constfn and associated data in A1_CFN
1977 : and A1_CFN_DATA. describing that the second operand being compared is a
1978 : known constant and how to obtain its data. */
1979 :
1980 : static rtx
1981 62850 : compare_by_pieces (rtx arg0, rtx arg1, unsigned HOST_WIDE_INT len,
1982 : rtx target, unsigned int align,
1983 : by_pieces_constfn a1_cfn, void *a1_cfn_data)
1984 : {
1985 62850 : rtx_code_label *fail_label = gen_label_rtx ();
1986 62850 : rtx_code_label *end_label = gen_label_rtx ();
1987 :
1988 62850 : if (target == NULL_RTX
1989 62850 : || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
1990 2 : target = gen_reg_rtx (TYPE_MODE (integer_type_node));
1991 :
1992 62850 : compare_by_pieces_d data (arg0, arg1, a1_cfn, a1_cfn_data, len, align,
1993 62850 : fail_label);
1994 :
1995 62850 : data.run ();
1996 :
1997 62850 : emit_move_insn (target, const0_rtx);
1998 62850 : emit_jump (end_label);
1999 62850 : emit_barrier ();
2000 62850 : emit_label (fail_label);
2001 62850 : emit_move_insn (target, const1_rtx);
2002 62850 : emit_label (end_label);
2003 :
2004 62850 : return target;
2005 : }
2006 :
2007 : /* Emit code to move a block Y to a block X. This may be done with
2008 : string-move instructions, with multiple scalar move instructions,
2009 : or with a library call.
2010 :
2011 : Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
2012 : SIZE is an rtx that says how long they are.
2013 : ALIGN is the maximum alignment we can assume they have.
2014 : METHOD describes what kind of copy this is, and what mechanisms may be used.
2015 : MIN_SIZE is the minimal size of block to move
2016 : MAX_SIZE is the maximal size of block to move, if it cannot be represented
2017 : in unsigned HOST_WIDE_INT, than it is mask of all ones.
2018 : CTZ_SIZE is the trailing-zeros count of SIZE; even a nonconstant SIZE is
2019 : known to be a multiple of 1<<CTZ_SIZE.
2020 :
2021 : Return the address of the new block, if memcpy is called and returns it,
2022 : 0 otherwise. */
2023 :
2024 : rtx
2025 671303 : emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
2026 : unsigned int expected_align, HOST_WIDE_INT expected_size,
2027 : unsigned HOST_WIDE_INT min_size,
2028 : unsigned HOST_WIDE_INT max_size,
2029 : unsigned HOST_WIDE_INT probable_max_size,
2030 : bool bail_out_libcall, bool *is_move_done,
2031 : bool might_overlap, unsigned ctz_size)
2032 : {
2033 671303 : int may_use_call;
2034 671303 : rtx retval = 0;
2035 671303 : unsigned int align;
2036 :
2037 671303 : if (is_move_done)
2038 98966 : *is_move_done = true;
2039 :
2040 671303 : gcc_assert (size);
2041 671303 : if (CONST_INT_P (size) && INTVAL (size) == 0)
2042 : return 0;
2043 :
2044 671026 : switch (method)
2045 : {
2046 : case BLOCK_OP_NORMAL:
2047 : case BLOCK_OP_TAILCALL:
2048 : may_use_call = 1;
2049 : break;
2050 :
2051 269022 : case BLOCK_OP_CALL_PARM:
2052 269022 : may_use_call = block_move_libcall_safe_for_call_parm ();
2053 :
2054 : /* Make inhibit_defer_pop nonzero around the library call
2055 : to force it to pop the arguments right away. */
2056 269022 : NO_DEFER_POP;
2057 269022 : break;
2058 :
2059 354 : case BLOCK_OP_NO_LIBCALL:
2060 354 : may_use_call = 0;
2061 354 : break;
2062 :
2063 1074 : case BLOCK_OP_NO_LIBCALL_RET:
2064 1074 : may_use_call = -1;
2065 1074 : break;
2066 :
2067 0 : default:
2068 0 : gcc_unreachable ();
2069 : }
2070 :
2071 671026 : gcc_assert (MEM_P (x) && MEM_P (y));
2072 671111 : align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2073 671026 : gcc_assert (align >= BITS_PER_UNIT);
2074 :
2075 : /* Make sure we've got BLKmode addresses; store_one_arg can decide that
2076 : block copy is more efficient for other large modes, e.g. DCmode. */
2077 671026 : x = adjust_address (x, BLKmode, 0);
2078 671026 : y = adjust_address (y, BLKmode, 0);
2079 :
2080 : /* If source and destination are the same, no need to copy anything. */
2081 671026 : if (rtx_equal_p (x, y)
2082 13 : && !MEM_VOLATILE_P (x)
2083 671039 : && !MEM_VOLATILE_P (y))
2084 : return 0;
2085 :
2086 : /* Set MEM_SIZE as appropriate for this block copy. The main place this
2087 : can be incorrect is coming from __builtin_memcpy. */
2088 671013 : poly_int64 const_size;
2089 671013 : if (poly_int_rtx_p (size, &const_size))
2090 : {
2091 591156 : x = shallow_copy_rtx (x);
2092 591156 : y = shallow_copy_rtx (y);
2093 591156 : set_mem_size (x, const_size);
2094 591156 : set_mem_size (y, const_size);
2095 : }
2096 :
2097 671013 : bool pieces_ok = CONST_INT_P (size)
2098 671013 : && can_move_by_pieces (INTVAL (size), align);
2099 671013 : bool pattern_ok = false;
2100 :
2101 671013 : if (!pieces_ok || might_overlap)
2102 : {
2103 106855 : pattern_ok
2104 106855 : = emit_block_move_via_pattern (x, y, size, align,
2105 : expected_align, expected_size,
2106 : min_size, max_size, probable_max_size,
2107 : might_overlap);
2108 106855 : if (!pattern_ok && might_overlap)
2109 : {
2110 : /* Do not try any of the other methods below as they are not safe
2111 : for overlapping moves. */
2112 12772 : *is_move_done = false;
2113 12772 : return retval;
2114 : }
2115 : }
2116 :
2117 94083 : bool dynamic_direction = false;
2118 94083 : if (!pattern_ok && !pieces_ok && may_use_call
2119 137120 : && (flag_inline_stringops & (might_overlap ? ILSOP_MEMMOVE : ILSOP_MEMCPY)))
2120 : {
2121 658241 : may_use_call = 0;
2122 658241 : dynamic_direction = might_overlap;
2123 : }
2124 :
2125 658241 : if (pattern_ok)
2126 : ;
2127 632718 : else if (pieces_ok)
2128 564158 : move_by_pieces (x, y, INTVAL (size), align, RETURN_BEGIN);
2129 68560 : else if (may_use_call && !might_overlap
2130 68512 : && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2131 137072 : && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
2132 : {
2133 68512 : if (bail_out_libcall)
2134 : {
2135 259 : if (is_move_done)
2136 259 : *is_move_done = false;
2137 : return retval;
2138 : }
2139 :
2140 68253 : if (may_use_call < 0)
2141 0 : return pc_rtx;
2142 :
2143 68253 : retval = emit_block_copy_via_libcall (x, y, size,
2144 : method == BLOCK_OP_TAILCALL);
2145 : }
2146 48 : else if (dynamic_direction)
2147 0 : emit_block_move_via_oriented_loop (x, y, size, align, ctz_size);
2148 48 : else if (might_overlap)
2149 0 : *is_move_done = false;
2150 : else
2151 48 : emit_block_move_via_sized_loop (x, y, size, align, ctz_size);
2152 :
2153 657982 : if (method == BLOCK_OP_CALL_PARM)
2154 269011 : OK_DEFER_POP;
2155 :
2156 : return retval;
2157 : }
2158 :
2159 : rtx
2160 572337 : emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method,
2161 : unsigned int ctz_size)
2162 : {
2163 572337 : unsigned HOST_WIDE_INT max, min = 0;
2164 572337 : if (GET_CODE (size) == CONST_INT)
2165 572117 : min = max = UINTVAL (size);
2166 : else
2167 220 : max = GET_MODE_MASK (GET_MODE (size));
2168 572337 : return emit_block_move_hints (x, y, size, method, 0, -1,
2169 : min, max, max,
2170 572337 : false, NULL, false, ctz_size);
2171 : }
2172 :
2173 : /* A subroutine of emit_block_move. Returns true if calling the
2174 : block move libcall will not clobber any parameters which may have
2175 : already been placed on the stack. */
2176 :
2177 : static bool
2178 269022 : block_move_libcall_safe_for_call_parm (void)
2179 : {
2180 269022 : tree fn;
2181 :
2182 : /* If arguments are pushed on the stack, then they're safe. */
2183 269022 : if (targetm.calls.push_argument (0))
2184 : return true;
2185 :
2186 : /* If registers go on the stack anyway, any argument is sure to clobber
2187 : an outgoing argument. */
2188 : #if defined (REG_PARM_STACK_SPACE)
2189 3 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2190 : /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't
2191 : depend on its argument. */
2192 3 : (void) fn;
2193 3 : if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn)))
2194 3 : && REG_PARM_STACK_SPACE (fn) != 0)
2195 : return false;
2196 : #endif
2197 :
2198 : /* If any argument goes in memory, then it might clobber an outgoing
2199 : argument. */
2200 3 : {
2201 3 : CUMULATIVE_ARGS args_so_far_v;
2202 3 : cumulative_args_t args_so_far;
2203 3 : tree arg;
2204 :
2205 3 : fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
2206 3 : INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3);
2207 3 : args_so_far = pack_cumulative_args (&args_so_far_v);
2208 :
2209 3 : arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
2210 12 : for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
2211 : {
2212 9 : machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
2213 9 : function_arg_info arg_info (mode, /*named=*/true);
2214 9 : rtx tmp = targetm.calls.function_arg (args_so_far, arg_info);
2215 9 : if (!tmp || !REG_P (tmp))
2216 0 : return false;
2217 9 : if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
2218 : return false;
2219 9 : targetm.calls.function_arg_advance (args_so_far, arg_info);
2220 : }
2221 : }
2222 3 : return true;
2223 : }
2224 :
2225 : /* A subroutine of emit_block_move. Expand a cpymem or movmem pattern;
2226 : return true if successful.
2227 :
2228 : X is the destination of the copy or move.
2229 : Y is the source of the copy or move.
2230 : SIZE is the size of the block to be moved.
2231 :
2232 : MIGHT_OVERLAP indicates this originated with expansion of a
2233 : builtin_memmove() and the source and destination blocks may
2234 : overlap.
2235 : */
2236 :
2237 : static bool
2238 106855 : emit_block_move_via_pattern (rtx x, rtx y, rtx size, unsigned int align,
2239 : unsigned int expected_align,
2240 : HOST_WIDE_INT expected_size,
2241 : unsigned HOST_WIDE_INT min_size,
2242 : unsigned HOST_WIDE_INT max_size,
2243 : unsigned HOST_WIDE_INT probable_max_size,
2244 : bool might_overlap)
2245 : {
2246 106855 : if (expected_align < align)
2247 : expected_align = align;
2248 106855 : if (expected_size != -1)
2249 : {
2250 22 : if ((unsigned HOST_WIDE_INT)expected_size > probable_max_size)
2251 0 : expected_size = probable_max_size;
2252 22 : if ((unsigned HOST_WIDE_INT)expected_size < min_size)
2253 0 : expected_size = min_size;
2254 : }
2255 :
2256 : /* Since this is a move insn, we don't care about volatility. */
2257 106855 : temporary_volatile_ok v (true);
2258 :
2259 : /* Try the most limited insn first, because there's no point
2260 : including more than one in the machine description unless
2261 : the more limited one has some advantage. */
2262 :
2263 106855 : opt_scalar_int_mode mode_iter;
2264 731215 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
2265 : {
2266 649883 : scalar_int_mode mode = mode_iter.require ();
2267 649883 : enum insn_code code;
2268 649883 : if (might_overlap)
2269 103583 : code = direct_optab_handler (movmem_optab, mode);
2270 : else
2271 546300 : code = direct_optab_handler (cpymem_optab, mode);
2272 :
2273 649883 : if (code != CODE_FOR_nothing
2274 : /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
2275 : here because if SIZE is less than the mode mask, as it is
2276 : returned by the macro, it will definitely be less than the
2277 : actual mode mask. Since SIZE is within the Pmode address
2278 : space, we limit MODE to Pmode. */
2279 649883 : && ((CONST_INT_P (size)
2280 41855 : && ((unsigned HOST_WIDE_INT) INTVAL (size)
2281 41855 : <= (GET_MODE_MASK (mode) >> 1)))
2282 145282 : || max_size <= (GET_MODE_MASK (mode) >> 1)
2283 181796 : || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
2284 : {
2285 123622 : class expand_operand ops[9];
2286 123622 : unsigned int nops;
2287 :
2288 : /* ??? When called via emit_block_move_for_call, it'd be
2289 : nice if there were some way to inform the backend, so
2290 : that it doesn't fail the expansion because it thinks
2291 : emitting the libcall would be more efficient. */
2292 123622 : nops = insn_data[(int) code].n_generator_args;
2293 123622 : gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
2294 :
2295 123622 : create_fixed_operand (&ops[0], x);
2296 123622 : create_fixed_operand (&ops[1], y);
2297 : /* The check above guarantees that this size conversion is valid. */
2298 123622 : create_convert_operand_to (&ops[2], size, mode, true);
2299 123622 : create_integer_operand (&ops[3], align / BITS_PER_UNIT);
2300 123622 : if (nops >= 6)
2301 : {
2302 123622 : create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
2303 123622 : create_integer_operand (&ops[5], expected_size);
2304 : }
2305 123622 : if (nops >= 8)
2306 : {
2307 123622 : create_integer_operand (&ops[6], min_size);
2308 : /* If we cannot represent the maximal size,
2309 : make parameter NULL. */
2310 123622 : if ((HOST_WIDE_INT) max_size != -1)
2311 106001 : create_integer_operand (&ops[7], max_size);
2312 : else
2313 17621 : create_fixed_operand (&ops[7], NULL);
2314 : }
2315 123622 : if (nops == 9)
2316 : {
2317 : /* If we cannot represent the maximal size,
2318 : make parameter NULL. */
2319 123622 : if ((HOST_WIDE_INT) probable_max_size != -1)
2320 108089 : create_integer_operand (&ops[8], probable_max_size);
2321 : else
2322 15533 : create_fixed_operand (&ops[8], NULL);
2323 : }
2324 123622 : gcc_assert (min_size != max_size
2325 : || rtx_equal_p (ops[2].value, GEN_INT (min_size)));
2326 123622 : if (maybe_expand_insn (code, nops, ops))
2327 25523 : return true;
2328 : }
2329 : }
2330 :
2331 : return false;
2332 106855 : }
2333 :
2334 : /* Like emit_block_move_via_loop, but choose a suitable INCR based on
2335 : ALIGN and CTZ_SIZE. */
2336 :
2337 : static void
2338 48 : emit_block_move_via_sized_loop (rtx x, rtx y, rtx size,
2339 : unsigned int align,
2340 : unsigned int ctz_size)
2341 : {
2342 48 : int incr = align / BITS_PER_UNIT;
2343 :
2344 48 : if (CONST_INT_P (size))
2345 0 : ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
2346 :
2347 48 : if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
2348 0 : incr = HOST_WIDE_INT_1U << ctz_size;
2349 :
2350 48 : while (incr > 1 && !can_move_by_pieces (incr, align))
2351 0 : incr >>= 1;
2352 :
2353 48 : gcc_checking_assert (incr);
2354 :
2355 48 : return emit_block_move_via_loop (x, y, size, align, incr);
2356 : }
2357 :
2358 : /* Like emit_block_move_via_sized_loop, but besides choosing INCR so
2359 : as to ensure safe moves even in case of overlap, output dynamic
2360 : tests to choose between two loops, one moving downwards, another
2361 : moving upwards. */
2362 :
2363 : static void
2364 0 : emit_block_move_via_oriented_loop (rtx x, rtx y, rtx size,
2365 : unsigned int align,
2366 : unsigned int ctz_size)
2367 : {
2368 0 : int incr = align / BITS_PER_UNIT;
2369 :
2370 0 : if (CONST_INT_P (size))
2371 0 : ctz_size = MAX (ctz_size, (unsigned) wi::ctz (UINTVAL (size)));
2372 :
2373 0 : if (HOST_WIDE_INT_1U << ctz_size < (unsigned HOST_WIDE_INT) incr)
2374 0 : incr = HOST_WIDE_INT_1U << ctz_size;
2375 :
2376 0 : while (incr > 1 && !int_mode_for_size (incr, 0).exists ())
2377 0 : incr >>= 1;
2378 :
2379 0 : gcc_checking_assert (incr);
2380 :
2381 0 : rtx_code_label *upw_label, *end_label;
2382 0 : upw_label = gen_label_rtx ();
2383 0 : end_label = gen_label_rtx ();
2384 :
2385 0 : rtx x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2386 0 : rtx y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2387 0 : do_pending_stack_adjust ();
2388 :
2389 0 : machine_mode mode = GET_MODE (x_addr);
2390 0 : if (mode != GET_MODE (y_addr))
2391 : {
2392 0 : scalar_int_mode xmode
2393 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE (mode)).require ();
2394 0 : scalar_int_mode ymode
2395 0 : = smallest_int_mode_for_size (GET_MODE_BITSIZE
2396 0 : (GET_MODE (y_addr))).require ();
2397 0 : if (GET_MODE_BITSIZE (xmode) < GET_MODE_BITSIZE (ymode))
2398 : mode = ymode;
2399 : else
2400 0 : mode = xmode;
2401 :
2402 : #ifndef POINTERS_EXTEND_UNSIGNED
2403 : const int POINTERS_EXTEND_UNSIGNED = 1;
2404 : #endif
2405 0 : x_addr = convert_modes (mode, GET_MODE (x_addr), x_addr,
2406 : POINTERS_EXTEND_UNSIGNED);
2407 0 : y_addr = convert_modes (mode, GET_MODE (y_addr), y_addr,
2408 : POINTERS_EXTEND_UNSIGNED);
2409 : }
2410 :
2411 : /* Test for overlap: if (x >= y || x + size <= y) goto upw_label. */
2412 0 : emit_cmp_and_jump_insns (x_addr, y_addr, GEU, NULL_RTX, mode,
2413 : true, upw_label,
2414 0 : profile_probability::guessed_always ()
2415 : .apply_scale (5, 10));
2416 0 : rtx tmp = convert_modes (GET_MODE (x_addr), GET_MODE (size), size, true);
2417 0 : tmp = simplify_gen_binary (PLUS, GET_MODE (x_addr), x_addr, tmp);
2418 :
2419 0 : emit_cmp_and_jump_insns (tmp, y_addr, LEU, NULL_RTX, mode,
2420 : true, upw_label,
2421 0 : profile_probability::guessed_always ()
2422 : .apply_scale (8, 10));
2423 :
2424 0 : emit_block_move_via_loop (x, y, size, align, -incr);
2425 :
2426 0 : emit_jump (end_label);
2427 0 : emit_label (upw_label);
2428 :
2429 0 : emit_block_move_via_loop (x, y, size, align, incr);
2430 :
2431 0 : emit_label (end_label);
2432 0 : }
2433 :
2434 : /* A subroutine of emit_block_move. Copy the data via an explicit
2435 : loop. This is used only when libcalls are forbidden, or when
2436 : inlining is required. INCR is the block size to be copied in each
2437 : loop iteration. If it is negative, the absolute value is used, and
2438 : the block is copied backwards. INCR must be a power of two, an
2439 : exact divisor for SIZE and ALIGN, and imply a mode that can be
2440 : safely copied per iteration assuming no overlap. */
2441 :
2442 : static void
2443 48 : emit_block_move_via_loop (rtx x, rtx y, rtx size,
2444 : unsigned int align, int incr)
2445 : {
2446 48 : rtx_code_label *cmp_label, *top_label;
2447 48 : rtx iter, x_addr, y_addr, tmp;
2448 48 : machine_mode x_addr_mode = get_address_mode (x);
2449 48 : machine_mode y_addr_mode = get_address_mode (y);
2450 48 : machine_mode iter_mode;
2451 :
2452 48 : iter_mode = GET_MODE (size);
2453 48 : if (iter_mode == VOIDmode)
2454 0 : iter_mode = word_mode;
2455 :
2456 48 : top_label = gen_label_rtx ();
2457 48 : cmp_label = gen_label_rtx ();
2458 48 : iter = gen_reg_rtx (iter_mode);
2459 :
2460 48 : bool downwards = incr < 0;
2461 48 : rtx iter_init;
2462 48 : rtx_code iter_cond;
2463 48 : rtx iter_limit;
2464 48 : rtx iter_incr;
2465 48 : machine_mode move_mode;
2466 48 : if (downwards)
2467 : {
2468 0 : incr = -incr;
2469 0 : iter_init = size;
2470 0 : iter_cond = GEU;
2471 0 : iter_limit = const0_rtx;
2472 0 : iter_incr = GEN_INT (incr);
2473 : }
2474 : else
2475 : {
2476 48 : iter_init = const0_rtx;
2477 48 : iter_cond = LTU;
2478 48 : iter_limit = size;
2479 48 : iter_incr = GEN_INT (incr);
2480 : }
2481 48 : emit_move_insn (iter, iter_init);
2482 :
2483 48 : opt_scalar_int_mode int_move_mode
2484 48 : = int_mode_for_size (incr * BITS_PER_UNIT, 1);
2485 48 : if (!int_move_mode.exists (&move_mode)
2486 96 : || GET_MODE_BITSIZE (int_move_mode.require ()) != incr * BITS_PER_UNIT)
2487 : {
2488 0 : move_mode = BLKmode;
2489 0 : gcc_checking_assert (can_move_by_pieces (incr, align));
2490 : }
2491 :
2492 48 : x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2493 48 : y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2494 48 : do_pending_stack_adjust ();
2495 :
2496 48 : emit_jump (cmp_label);
2497 48 : emit_label (top_label);
2498 :
2499 48 : tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
2500 48 : x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
2501 :
2502 48 : if (x_addr_mode != y_addr_mode)
2503 0 : tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
2504 48 : y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
2505 :
2506 48 : x = change_address (x, move_mode, x_addr);
2507 48 : y = change_address (y, move_mode, y_addr);
2508 :
2509 48 : if (move_mode == BLKmode)
2510 : {
2511 0 : bool done;
2512 0 : emit_block_move_hints (x, y, iter_incr, BLOCK_OP_NO_LIBCALL,
2513 : align, incr, incr, incr, incr,
2514 : false, &done, false);
2515 0 : gcc_checking_assert (done);
2516 : }
2517 : else
2518 48 : emit_move_insn (x, y);
2519 :
2520 48 : if (downwards)
2521 0 : emit_label (cmp_label);
2522 :
2523 48 : tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
2524 : true, OPTAB_LIB_WIDEN);
2525 48 : if (tmp != iter)
2526 0 : emit_move_insn (iter, tmp);
2527 :
2528 48 : if (!downwards)
2529 48 : emit_label (cmp_label);
2530 :
2531 48 : emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
2532 : true, top_label,
2533 48 : profile_probability::guessed_always ()
2534 : .apply_scale (9, 10));
2535 48 : }
2536 :
2537 : /* Expand a call to memcpy or memmove or memcmp, and return the result.
2538 : TAILCALL is true if this is a tail call. */
2539 :
2540 : rtx
2541 68254 : emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src,
2542 : rtx size, bool tailcall)
2543 : {
2544 68254 : rtx dst_addr, src_addr;
2545 68254 : tree call_expr, dst_tree, src_tree, size_tree;
2546 68254 : machine_mode size_mode;
2547 :
2548 : /* Since dst and src are passed to a libcall, mark the corresponding
2549 : tree EXPR as addressable. */
2550 68254 : tree dst_expr = MEM_EXPR (dst);
2551 68254 : tree src_expr = MEM_EXPR (src);
2552 68254 : if (dst_expr)
2553 61535 : mark_addressable (dst_expr);
2554 68254 : if (src_expr)
2555 66842 : mark_addressable (src_expr);
2556 :
2557 68254 : dst_addr = copy_addr_to_reg (XEXP (dst, 0));
2558 68254 : dst_addr = convert_memory_address (ptr_mode, dst_addr);
2559 68254 : dst_tree = make_tree (ptr_type_node, dst_addr);
2560 :
2561 68254 : src_addr = copy_addr_to_reg (XEXP (src, 0));
2562 68254 : src_addr = convert_memory_address (ptr_mode, src_addr);
2563 68254 : src_tree = make_tree (ptr_type_node, src_addr);
2564 :
2565 68254 : size_mode = TYPE_MODE (sizetype);
2566 68254 : size = convert_to_mode (size_mode, size, 1);
2567 68254 : size = copy_to_mode_reg (size_mode, size);
2568 68254 : size_tree = make_tree (sizetype, size);
2569 :
2570 : /* It is incorrect to use the libcall calling conventions for calls to
2571 : memcpy/memmove/memcmp because they can be provided by the user. */
2572 68254 : tree fn = builtin_decl_implicit (fncode);
2573 68254 : call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
2574 68254 : CALL_EXPR_TAILCALL (call_expr) = tailcall;
2575 :
2576 68254 : return expand_call (call_expr, NULL_RTX, false);
2577 : }
2578 :
2579 : /* Try to expand cmpstrn or cmpmem operation ICODE with the given operands.
2580 : ARG3_TYPE is the type of ARG3_RTX. Return the result rtx on success,
2581 : otherwise return null. */
2582 :
2583 : rtx
2584 171564 : expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx,
2585 : rtx arg2_rtx, tree arg3_type, rtx arg3_rtx,
2586 : HOST_WIDE_INT align)
2587 : {
2588 171564 : machine_mode insn_mode = insn_data[icode].operand[0].mode;
2589 :
2590 171564 : if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
2591 : target = NULL_RTX;
2592 :
2593 171564 : class expand_operand ops[5];
2594 171564 : create_output_operand (&ops[0], target, insn_mode);
2595 171564 : create_fixed_operand (&ops[1], arg1_rtx);
2596 171564 : create_fixed_operand (&ops[2], arg2_rtx);
2597 171564 : create_convert_operand_from (&ops[3], arg3_rtx, TYPE_MODE (arg3_type),
2598 171564 : TYPE_UNSIGNED (arg3_type));
2599 171564 : create_integer_operand (&ops[4], align);
2600 171564 : if (maybe_expand_insn (icode, 5, ops))
2601 5796 : return ops[0].value;
2602 : return NULL_RTX;
2603 : }
2604 :
2605 : /* Expand a block compare between X and Y with length LEN using the
2606 : cmpmem optab, placing the result in TARGET. LEN_TYPE is the type
2607 : of the expression that was used to calculate the length. ALIGN
2608 : gives the known minimum common alignment. */
2609 :
2610 : static rtx
2611 43626 : emit_block_cmp_via_cmpmem (rtx x, rtx y, rtx len, tree len_type, rtx target,
2612 : unsigned align)
2613 : {
2614 : /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
2615 : implementing memcmp because it will stop if it encounters two
2616 : zero bytes. */
2617 43626 : insn_code icode = direct_optab_handler (cmpmem_optab, SImode);
2618 :
2619 43626 : if (icode == CODE_FOR_nothing)
2620 : return NULL_RTX;
2621 :
2622 43626 : return expand_cmpstrn_or_cmpmem (icode, target, x, y, len_type, len, align);
2623 : }
2624 :
2625 : /* Emit code to compare a block Y to a block X. This may be done with
2626 : string-compare instructions, with multiple scalar instructions,
2627 : or with a library call.
2628 :
2629 : Both X and Y must be MEM rtx's. LEN is an rtx that says how long
2630 : they are. LEN_TYPE is the type of the expression that was used to
2631 : calculate it, and CTZ_LEN is the known trailing-zeros count of LEN,
2632 : so LEN must be a multiple of 1<<CTZ_LEN even if it's not constant.
2633 :
2634 : If EQUALITY_ONLY is true, it means we don't have to return the tri-state
2635 : value of a normal memcmp call, instead we can just compare for equality.
2636 : If FORCE_LIBCALL is true, we should emit a call to memcmp rather than
2637 : returning NULL_RTX.
2638 :
2639 : Optionally, the caller can pass a constfn and associated data in Y_CFN
2640 : and Y_CFN_DATA. describing that the second operand being compared is a
2641 : known constant and how to obtain its data.
2642 : Return the result of the comparison, or NULL_RTX if we failed to
2643 : perform the operation. */
2644 :
2645 : rtx
2646 106475 : emit_block_cmp_hints (rtx x, rtx y, rtx len, tree len_type, rtx target,
2647 : bool equality_only, by_pieces_constfn y_cfn,
2648 : void *y_cfndata, unsigned ctz_len)
2649 : {
2650 106475 : rtx result = 0;
2651 :
2652 106475 : if (CONST_INT_P (len) && INTVAL (len) == 0)
2653 0 : return const0_rtx;
2654 :
2655 106475 : gcc_assert (MEM_P (x) && MEM_P (y));
2656 106475 : unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2657 106475 : gcc_assert (align >= BITS_PER_UNIT);
2658 :
2659 106475 : x = adjust_address (x, BLKmode, 0);
2660 106475 : y = adjust_address (y, BLKmode, 0);
2661 :
2662 106475 : if (equality_only
2663 91612 : && CONST_INT_P (len)
2664 176062 : && can_do_by_pieces (INTVAL (len), align, COMPARE_BY_PIECES))
2665 62849 : result = compare_by_pieces (x, y, INTVAL (len), target, align,
2666 : y_cfn, y_cfndata);
2667 : else
2668 43626 : result = emit_block_cmp_via_cmpmem (x, y, len, len_type, target, align);
2669 :
2670 106475 : if (!result && (flag_inline_stringops & ILSOP_MEMCMP))
2671 361 : result = emit_block_cmp_via_loop (x, y, len, len_type,
2672 : target, equality_only,
2673 : align, ctz_len);
2674 :
2675 : return result;
2676 : }
2677 :
2678 : /* Like emit_block_cmp_hints, but with known alignment and no support
2679 : for constats. Always expand to a loop with iterations that compare
2680 : blocks of the largest compare-by-pieces size that divides both len
2681 : and align, and then, if !EQUALITY_ONLY, identify the word and then
2682 : the unit that first differs to return the result. */
2683 :
2684 : rtx
2685 403 : emit_block_cmp_via_loop (rtx x, rtx y, rtx len, tree len_type, rtx target,
2686 : bool equality_only, unsigned align, unsigned ctz_len)
2687 : {
2688 403 : unsigned incr = align / BITS_PER_UNIT;
2689 :
2690 403 : if (CONST_INT_P (len))
2691 319 : ctz_len = MAX (ctz_len, (unsigned) wi::ctz (UINTVAL (len)));
2692 :
2693 403 : if (HOST_WIDE_INT_1U << ctz_len < (unsigned HOST_WIDE_INT) incr)
2694 148 : incr = HOST_WIDE_INT_1U << ctz_len;
2695 :
2696 : while (incr > 1
2697 407 : && !can_do_by_pieces (incr, align, COMPARE_BY_PIECES))
2698 4 : incr >>= 1;
2699 :
2700 403 : rtx_code_label *cmp_label, *top_label, *ne_label, *res_label;
2701 403 : rtx iter, x_addr, y_addr, tmp;
2702 403 : machine_mode x_addr_mode = get_address_mode (x);
2703 403 : machine_mode y_addr_mode = get_address_mode (y);
2704 403 : machine_mode iter_mode;
2705 :
2706 403 : iter_mode = GET_MODE (len);
2707 403 : if (iter_mode == VOIDmode)
2708 319 : iter_mode = word_mode;
2709 :
2710 403 : rtx iter_init = const0_rtx;
2711 403 : rtx_code iter_cond = LTU;
2712 403 : rtx_code entry_cond = GEU;
2713 403 : rtx iter_limit = len;
2714 403 : rtx iter_incr = GEN_INT (incr);
2715 403 : machine_mode cmp_mode;
2716 :
2717 : /* We can drop the loop back edge if we know there's exactly one
2718 : iteration. */
2719 403 : top_label = (!rtx_equal_p (len, iter_incr)
2720 403 : ? gen_label_rtx ()
2721 : : NULL);
2722 : /* We need not test before entering the loop if len is known
2723 : nonzero. ??? This could be even stricter, testing whether a
2724 : nonconstant LEN could possibly be zero. */
2725 403 : cmp_label = (!CONSTANT_P (len) || rtx_equal_p (len, iter_init)
2726 403 : ? gen_label_rtx ()
2727 : : NULL);
2728 403 : ne_label = gen_label_rtx ();
2729 403 : res_label = gen_label_rtx ();
2730 :
2731 403 : iter = gen_reg_rtx (iter_mode);
2732 403 : emit_move_insn (iter, iter_init);
2733 :
2734 403 : opt_scalar_int_mode int_cmp_mode
2735 403 : = int_mode_for_size (incr * BITS_PER_UNIT, 1);
2736 403 : if (!int_cmp_mode.exists (&cmp_mode)
2737 1207 : || GET_MODE_BITSIZE (int_cmp_mode.require ()) != incr * BITS_PER_UNIT
2738 402 : || !can_compare_p (NE, cmp_mode, ccp_jump))
2739 : {
2740 1 : cmp_mode = BLKmode;
2741 1 : gcc_checking_assert (incr != 1);
2742 : }
2743 :
2744 : /* Save the base addresses. */
2745 403 : x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2746 403 : y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2747 403 : do_pending_stack_adjust ();
2748 :
2749 403 : if (cmp_label)
2750 : {
2751 84 : if (top_label)
2752 84 : emit_jump (cmp_label);
2753 : else
2754 0 : emit_cmp_and_jump_insns (iter, iter_limit, entry_cond,
2755 : NULL_RTX, iter_mode,
2756 : true, cmp_label,
2757 0 : profile_probability::guessed_always ()
2758 : .apply_scale (1, 10));
2759 : }
2760 403 : if (top_label)
2761 386 : emit_label (top_label);
2762 :
2763 : /* Offset the base addresses by ITER. */
2764 403 : tmp = convert_modes (x_addr_mode, iter_mode, iter, true);
2765 403 : x_addr = simplify_gen_binary (PLUS, x_addr_mode, x_addr, tmp);
2766 :
2767 403 : if (x_addr_mode != y_addr_mode)
2768 0 : tmp = convert_modes (y_addr_mode, iter_mode, iter, true);
2769 403 : y_addr = simplify_gen_binary (PLUS, y_addr_mode, y_addr, tmp);
2770 :
2771 403 : x = change_address (x, cmp_mode, x_addr);
2772 403 : y = change_address (y, cmp_mode, y_addr);
2773 :
2774 : /* Compare one block. */
2775 403 : rtx part_res;
2776 403 : if (cmp_mode == BLKmode)
2777 1 : part_res = compare_by_pieces (x, y, incr, target, align, 0, 0);
2778 : else
2779 402 : part_res = expand_binop (cmp_mode, sub_optab, x, y, NULL_RTX,
2780 : true, OPTAB_LIB_WIDEN);
2781 :
2782 : /* Stop if we found a difference. */
2783 806 : emit_cmp_and_jump_insns (part_res, GEN_INT (0), NE, NULL_RTX,
2784 403 : GET_MODE (part_res), true, ne_label,
2785 403 : profile_probability::guessed_always ()
2786 : .apply_scale (1, 10));
2787 :
2788 : /* Increment ITER. */
2789 403 : tmp = expand_simple_binop (iter_mode, PLUS, iter, iter_incr, iter,
2790 : true, OPTAB_LIB_WIDEN);
2791 403 : if (tmp != iter)
2792 0 : emit_move_insn (iter, tmp);
2793 :
2794 403 : if (cmp_label)
2795 84 : emit_label (cmp_label);
2796 : /* Loop until we reach the limit. */
2797 :
2798 403 : if (top_label)
2799 386 : emit_cmp_and_jump_insns (iter, iter_limit, iter_cond, NULL_RTX, iter_mode,
2800 : true, top_label,
2801 772 : profile_probability::guessed_always ()
2802 : .apply_scale (9, 10));
2803 :
2804 : /* We got to the end without differences, so the result is zero. */
2805 403 : if (target == NULL_RTX
2806 403 : || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
2807 49 : target = gen_reg_rtx (TYPE_MODE (integer_type_node));
2808 :
2809 403 : emit_move_insn (target, const0_rtx);
2810 403 : emit_jump (res_label);
2811 :
2812 403 : emit_label (ne_label);
2813 :
2814 : /* Return nonzero, or pinpoint the difference to return the expected
2815 : result for non-equality tests. */
2816 403 : if (equality_only)
2817 0 : emit_move_insn (target, const1_rtx);
2818 : else
2819 : {
2820 403 : if (incr > UNITS_PER_WORD)
2821 : /* ??? Re-compare the block found to be different one word at a
2822 : time. */
2823 5 : part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
2824 : target, equality_only,
2825 : BITS_PER_WORD, 0);
2826 398 : else if (incr > 1)
2827 : /* ??? Re-compare the block found to be different one byte at a
2828 : time. We could do better using part_res, and being careful
2829 : about endianness. */
2830 37 : part_res = emit_block_cmp_via_loop (x, y, GEN_INT (incr), len_type,
2831 : target, equality_only,
2832 : BITS_PER_UNIT, 0);
2833 1083 : else if (known_gt (GET_MODE_BITSIZE (GET_MODE (target)),
2834 : GET_MODE_BITSIZE (cmp_mode)))
2835 361 : part_res = expand_binop (GET_MODE (target), sub_optab, x, y, target,
2836 : true, OPTAB_LIB_WIDEN);
2837 : else
2838 : {
2839 : /* In the odd chance target is QImode, we can't count on
2840 : widening subtract to capture the result of the unsigned
2841 : compares. */
2842 0 : rtx_code_label *ltu_label;
2843 0 : ltu_label = gen_label_rtx ();
2844 0 : emit_cmp_and_jump_insns (x, y, LTU, NULL_RTX,
2845 : cmp_mode, true, ltu_label,
2846 0 : profile_probability::guessed_always ()
2847 : .apply_scale (5, 10));
2848 :
2849 0 : emit_move_insn (target, const1_rtx);
2850 0 : emit_jump (res_label);
2851 :
2852 0 : emit_label (ltu_label);
2853 0 : emit_move_insn (target, constm1_rtx);
2854 0 : part_res = target;
2855 : }
2856 :
2857 403 : if (target != part_res)
2858 0 : convert_move (target, part_res, false);
2859 : }
2860 :
2861 403 : emit_label (res_label);
2862 :
2863 403 : return target;
2864 : }
2865 :
2866 :
2867 : /* Copy all or part of a value X into registers starting at REGNO.
2868 : The number of registers to be filled is NREGS. */
2869 :
2870 : void
2871 434 : move_block_to_reg (int regno, rtx x, int nregs, machine_mode mode)
2872 : {
2873 434 : if (nregs == 0)
2874 : return;
2875 :
2876 420 : if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
2877 0 : x = validize_mem (force_const_mem (mode, x));
2878 :
2879 : /* See if the machine can do this with a load multiple insn. */
2880 420 : if (targetm.have_load_multiple ())
2881 : {
2882 0 : rtx_insn *last = get_last_insn ();
2883 0 : rtx first = gen_rtx_REG (word_mode, regno);
2884 0 : if (rtx_insn *pat = targetm.gen_load_multiple (first, x,
2885 : GEN_INT (nregs)))
2886 : {
2887 0 : emit_insn (pat);
2888 0 : return;
2889 : }
2890 : else
2891 0 : delete_insns_since (last);
2892 : }
2893 :
2894 848 : for (int i = 0; i < nregs; i++)
2895 428 : emit_move_insn (gen_rtx_REG (word_mode, regno + i),
2896 428 : operand_subword_force (x, i, mode));
2897 : }
2898 :
2899 : /* Copy all or part of a BLKmode value X out of registers starting at REGNO.
2900 : The number of registers to be filled is NREGS. */
2901 :
2902 : void
2903 1216 : move_block_from_reg (int regno, rtx x, int nregs)
2904 : {
2905 1216 : if (nregs == 0)
2906 : return;
2907 :
2908 : /* See if the machine can do this with a store multiple insn. */
2909 1216 : if (targetm.have_store_multiple ())
2910 : {
2911 0 : rtx_insn *last = get_last_insn ();
2912 0 : rtx first = gen_rtx_REG (word_mode, regno);
2913 0 : if (rtx_insn *pat = targetm.gen_store_multiple (x, first,
2914 : GEN_INT (nregs)))
2915 : {
2916 0 : emit_insn (pat);
2917 0 : return;
2918 : }
2919 : else
2920 0 : delete_insns_since (last);
2921 : }
2922 :
2923 2436 : for (int i = 0; i < nregs; i++)
2924 : {
2925 1220 : rtx tem = operand_subword (x, i, 1, BLKmode);
2926 :
2927 1220 : gcc_assert (tem);
2928 :
2929 1220 : emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
2930 : }
2931 : }
2932 :
2933 : /* Generate a PARALLEL rtx for a new non-consecutive group of registers from
2934 : ORIG, where ORIG is a non-consecutive group of registers represented by
2935 : a PARALLEL. The clone is identical to the original except in that the
2936 : original set of registers is replaced by a new set of pseudo registers.
2937 : The new set has the same modes as the original set. */
2938 :
2939 : rtx
2940 3418 : gen_group_rtx (rtx orig)
2941 : {
2942 3418 : int i, length;
2943 3418 : rtx *tmps;
2944 :
2945 3418 : gcc_assert (GET_CODE (orig) == PARALLEL);
2946 :
2947 3418 : length = XVECLEN (orig, 0);
2948 3418 : tmps = XALLOCAVEC (rtx, length);
2949 :
2950 : /* Skip a NULL entry in first slot. */
2951 3418 : i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
2952 :
2953 3418 : if (i)
2954 0 : tmps[0] = 0;
2955 :
2956 8334 : for (; i < length; i++)
2957 : {
2958 4916 : machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
2959 4916 : rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
2960 :
2961 4916 : tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
2962 : }
2963 :
2964 3418 : return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
2965 : }
2966 :
2967 : /* A subroutine of emit_group_load. Arguments as for emit_group_load,
2968 : except that values are placed in TMPS[i], and must later be moved
2969 : into corresponding XEXP (XVECEXP (DST, 0, i), 0) element. */
2970 :
2971 : static void
2972 299609 : emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type,
2973 : poly_int64 ssize)
2974 : {
2975 299612 : rtx src;
2976 299612 : int start, i;
2977 299612 : machine_mode m = GET_MODE (orig_src);
2978 :
2979 299612 : gcc_assert (GET_CODE (dst) == PARALLEL);
2980 :
2981 299612 : if (m != VOIDmode
2982 280727 : && !SCALAR_INT_MODE_P (m)
2983 19908 : && !MEM_P (orig_src)
2984 6078 : && GET_CODE (orig_src) != CONCAT)
2985 : {
2986 3 : scalar_int_mode imode;
2987 3 : if (int_mode_for_mode (GET_MODE (orig_src)).exists (&imode))
2988 : {
2989 3 : src = gen_reg_rtx (imode);
2990 3 : emit_move_insn (gen_lowpart (GET_MODE (orig_src), src), orig_src);
2991 : }
2992 : else
2993 : {
2994 0 : src = assign_stack_temp (GET_MODE (orig_src), ssize);
2995 0 : emit_move_insn (src, orig_src);
2996 : }
2997 3 : emit_group_load_1 (tmps, dst, src, type, ssize);
2998 : return;
2999 : }
3000 :
3001 : /* Check for a NULL entry, used to indicate that the parameter goes
3002 : both on the stack and in registers. */
3003 299609 : if (XEXP (XVECEXP (dst, 0, 0), 0))
3004 : start = 0;
3005 : else
3006 0 : start = 1;
3007 :
3008 : /* Process the pieces. */
3009 886958 : for (i = start; i < XVECLEN (dst, 0); i++)
3010 : {
3011 587349 : machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
3012 587349 : poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (dst, 0, i), 1));
3013 1174698 : poly_int64 bytelen = GET_MODE_SIZE (mode);
3014 587349 : poly_int64 shift = 0;
3015 :
3016 : /* Handle trailing fragments that run over the size of the struct.
3017 : It's the target's responsibility to make sure that the fragment
3018 : cannot be strictly smaller in some cases and strictly larger
3019 : in others. */
3020 587349 : gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
3021 587349 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3022 : {
3023 : /* Arrange to shift the fragment to where it belongs.
3024 : extract_bit_field loads to the lsb of the reg. */
3025 : if (
3026 : #ifdef BLOCK_REG_PADDING
3027 : BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
3028 : == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
3029 : #else
3030 : BYTES_BIG_ENDIAN
3031 : #endif
3032 : )
3033 : shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
3034 1839 : bytelen = ssize - bytepos;
3035 1839 : gcc_assert (maybe_gt (bytelen, 0));
3036 : }
3037 :
3038 : /* If we won't be loading directly from memory, protect the real source
3039 : from strange tricks we might play; but make sure that the source can
3040 : be loaded directly into the destination. */
3041 587349 : src = orig_src;
3042 587349 : if (!MEM_P (orig_src)
3043 485826 : && (!REG_P (orig_src) || HARD_REGISTER_P (orig_src))
3044 46986 : && GET_CODE (orig_src) != CONCAT
3045 625119 : && !CONSTANT_P (orig_src))
3046 : {
3047 0 : gcc_assert (GET_MODE (orig_src) != VOIDmode);
3048 0 : src = force_reg (GET_MODE (orig_src), orig_src);
3049 : }
3050 :
3051 : /* Optimize the access just a bit. */
3052 587349 : if (MEM_P (src)
3053 101523 : && (! targetm.slow_unaligned_access (mode, MEM_ALIGN (src))
3054 0 : || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
3055 203046 : && multiple_p (bytepos * BITS_PER_UNIT, GET_MODE_ALIGNMENT (mode))
3056 688872 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3057 : {
3058 99703 : tmps[i] = gen_reg_rtx (mode);
3059 99703 : emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
3060 : }
3061 487646 : else if (COMPLEX_MODE_P (mode)
3062 0 : && GET_MODE (src) == mode
3063 487646 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3064 : /* Let emit_move_complex do the bulk of the work. */
3065 0 : tmps[i] = src;
3066 487646 : else if (SCALAR_INT_MODE_P (mode)
3067 480737 : && COMPLEX_MODE_P (GET_MODE (src))
3068 9903 : && known_eq (GET_MODE_SIZE (mode),
3069 : GET_MODE_SIZE (GET_MODE (src)))
3070 490561 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3071 : {
3072 : /* When passing a complex value in an integer mode of the same
3073 : size, explicitly construct (highpart<<isize)+lowpart to
3074 : avoid spilling to memory before reload. */
3075 2915 : rtx tmp = read_complex_part (src, !BYTES_BIG_ENDIAN);
3076 2915 : scalar_int_mode imode = int_mode_for_mode (GET_MODE (tmp)).require();
3077 2915 : tmp = gen_lowpart (imode, tmp);
3078 2915 : tmp = simplify_gen_unary (ZERO_EXTEND, mode, tmp, imode);
3079 2915 : rtx result = force_reg (mode, tmp);
3080 5830 : result = expand_shift (LSHIFT_EXPR, mode, result,
3081 2915 : GET_MODE_BITSIZE (imode), NULL_RTX, 1);
3082 2915 : tmp = read_complex_part (src, BYTES_BIG_ENDIAN);
3083 2915 : tmp = gen_lowpart (imode, tmp);
3084 2915 : tmp = simplify_gen_unary (ZERO_EXTEND, mode, tmp, imode);
3085 2915 : result = simplify_gen_binary (PLUS, mode, result, tmp);
3086 2915 : tmps[i] = force_reg (mode, result);
3087 : }
3088 484731 : else if (GET_CODE (src) == CONCAT)
3089 : {
3090 12602 : poly_int64 slen = GET_MODE_SIZE (GET_MODE (src));
3091 12602 : poly_int64 slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
3092 6301 : unsigned int elt;
3093 6301 : poly_int64 subpos;
3094 :
3095 6301 : if (can_div_trunc_p (bytepos, slen0, &elt, &subpos)
3096 6301 : && known_le (subpos + bytelen, slen0))
3097 : {
3098 : /* The following assumes that the concatenated objects all
3099 : have the same size. In this case, a simple calculation
3100 : can be used to determine the object and the bit field
3101 : to be extracted. */
3102 6282 : tmps[i] = XEXP (src, elt);
3103 6282 : if (maybe_ne (subpos, 0)
3104 6282 : || maybe_ne (subpos + bytelen, slen0)
3105 12564 : || (!CONSTANT_P (tmps[i])
3106 6282 : && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
3107 0 : tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
3108 0 : subpos * BITS_PER_UNIT,
3109 : 1, NULL_RTX, mode, mode, false,
3110 : NULL);
3111 : }
3112 : else
3113 : {
3114 19 : rtx mem;
3115 :
3116 19 : gcc_assert (known_eq (bytepos, 0));
3117 19 : mem = assign_stack_temp (GET_MODE (src), slen);
3118 19 : emit_move_insn (mem, src);
3119 19 : tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
3120 : 0, 1, NULL_RTX, mode, mode, false,
3121 : NULL);
3122 : }
3123 : }
3124 478430 : else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
3125 37770 : && XVECLEN (dst, 0) > 1)
3126 37770 : tmps[i] = force_subreg (mode, src, GET_MODE (dst), bytepos);
3127 440660 : else if (CONSTANT_P (src))
3128 : {
3129 0 : if (known_eq (bytelen, ssize))
3130 0 : tmps[i] = src;
3131 : else
3132 : {
3133 : rtx first, second;
3134 :
3135 : /* TODO: const_wide_int can have sizes other than this... */
3136 0 : gcc_assert (known_eq (2 * bytelen, ssize));
3137 0 : split_double (src, &first, &second);
3138 0 : if (i)
3139 0 : tmps[i] = second;
3140 : else
3141 0 : tmps[i] = first;
3142 : }
3143 : }
3144 440660 : else if (REG_P (src) && GET_MODE (src) == mode)
3145 0 : tmps[i] = src;
3146 : else
3147 440660 : tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
3148 881320 : bytepos * BITS_PER_UNIT, 1, NULL_RTX,
3149 : mode, mode, false, NULL);
3150 :
3151 587349 : if (maybe_ne (shift, 0))
3152 : tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
3153 : shift, tmps[i], 0);
3154 : }
3155 : }
3156 :
3157 : /* Emit code to move a block SRC of type TYPE to a block DST,
3158 : where DST is non-consecutive registers represented by a PARALLEL.
3159 : SSIZE represents the total size of block ORIG_SRC in bytes, or -1
3160 : if not known. */
3161 :
3162 : void
3163 11216 : emit_group_load (rtx dst, rtx src, tree type, poly_int64 ssize)
3164 : {
3165 11216 : rtx *tmps;
3166 11216 : int i;
3167 :
3168 11216 : tmps = XALLOCAVEC (rtx, XVECLEN (dst, 0));
3169 11216 : emit_group_load_1 (tmps, dst, src, type, ssize);
3170 :
3171 : /* Copy the extracted pieces into the proper (probable) hard regs. */
3172 42404 : for (i = 0; i < XVECLEN (dst, 0); i++)
3173 : {
3174 19972 : rtx d = XEXP (XVECEXP (dst, 0, i), 0);
3175 19972 : if (d == NULL)
3176 0 : continue;
3177 19972 : emit_move_insn (d, tmps[i]);
3178 : }
3179 11216 : }
3180 :
3181 : /* Similar, but load SRC into new pseudos in a format that looks like
3182 : PARALLEL. This can later be fed to emit_group_move to get things
3183 : in the right place. */
3184 :
3185 : rtx
3186 288393 : emit_group_load_into_temps (rtx parallel, rtx src, tree type, poly_int64 ssize)
3187 : {
3188 288393 : rtvec vec;
3189 288393 : int i;
3190 :
3191 288393 : vec = rtvec_alloc (XVECLEN (parallel, 0));
3192 288393 : emit_group_load_1 (&RTVEC_ELT (vec, 0), parallel, src, type, ssize);
3193 :
3194 : /* Convert the vector to look just like the original PARALLEL, except
3195 : with the computed values. */
3196 1144163 : for (i = 0; i < XVECLEN (parallel, 0); i++)
3197 : {
3198 567377 : rtx e = XVECEXP (parallel, 0, i);
3199 567377 : rtx d = XEXP (e, 0);
3200 :
3201 567377 : if (d)
3202 : {
3203 567377 : d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i));
3204 567377 : e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1));
3205 : }
3206 567377 : RTVEC_ELT (vec, i) = e;
3207 : }
3208 :
3209 288393 : return gen_rtx_PARALLEL (GET_MODE (parallel), vec);
3210 : }
3211 :
3212 : /* Emit code to move a block SRC to block DST, where SRC and DST are
3213 : non-consecutive groups of registers, each represented by a PARALLEL. */
3214 :
3215 : void
3216 291811 : emit_group_move (rtx dst, rtx src)
3217 : {
3218 291811 : int i;
3219 :
3220 291811 : gcc_assert (GET_CODE (src) == PARALLEL
3221 : && GET_CODE (dst) == PARALLEL
3222 : && XVECLEN (src, 0) == XVECLEN (dst, 0));
3223 :
3224 : /* Skip first entry if NULL. */
3225 864104 : for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
3226 572293 : emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
3227 572293 : XEXP (XVECEXP (src, 0, i), 0));
3228 291811 : }
3229 :
3230 : /* Move a group of registers represented by a PARALLEL into pseudos. */
3231 :
3232 : rtx
3233 5803 : emit_group_move_into_temps (rtx src)
3234 : {
3235 5803 : rtvec vec = rtvec_alloc (XVECLEN (src, 0));
3236 5803 : int i;
3237 :
3238 19443 : for (i = 0; i < XVECLEN (src, 0); i++)
3239 : {
3240 7837 : rtx e = XVECEXP (src, 0, i);
3241 7837 : rtx d = XEXP (e, 0);
3242 :
3243 7837 : if (d)
3244 7837 : e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1));
3245 7837 : RTVEC_ELT (vec, i) = e;
3246 : }
3247 :
3248 5803 : return gen_rtx_PARALLEL (GET_MODE (src), vec);
3249 : }
3250 :
3251 : /* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
3252 : where SRC is non-consecutive registers represented by a PARALLEL.
3253 : SSIZE represents the total size of block ORIG_DST, or -1 if not
3254 : known. */
3255 :
3256 : void
3257 66230 : emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
3258 : poly_int64 ssize)
3259 : {
3260 66230 : rtx *tmps, dst;
3261 66230 : int start, finish, i;
3262 66230 : machine_mode m = GET_MODE (orig_dst);
3263 :
3264 66230 : gcc_assert (GET_CODE (src) == PARALLEL);
3265 :
3266 66230 : if (!SCALAR_INT_MODE_P (m)
3267 15052 : && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT)
3268 : {
3269 0 : scalar_int_mode imode;
3270 0 : if (int_mode_for_mode (GET_MODE (orig_dst)).exists (&imode))
3271 : {
3272 0 : dst = gen_reg_rtx (imode);
3273 0 : emit_group_store (dst, src, type, ssize);
3274 0 : dst = gen_lowpart (GET_MODE (orig_dst), dst);
3275 : }
3276 : else
3277 : {
3278 0 : dst = assign_stack_temp (GET_MODE (orig_dst), ssize);
3279 0 : emit_group_store (dst, src, type, ssize);
3280 : }
3281 0 : emit_move_insn (orig_dst, dst);
3282 0 : return;
3283 : }
3284 :
3285 : /* Check for a NULL entry, used to indicate that the parameter goes
3286 : both on the stack and in registers. */
3287 66230 : if (XEXP (XVECEXP (src, 0, 0), 0))
3288 : start = 0;
3289 : else
3290 0 : start = 1;
3291 66230 : finish = XVECLEN (src, 0);
3292 :
3293 66230 : tmps = XALLOCAVEC (rtx, finish);
3294 :
3295 : /* Copy the (probable) hard regs into pseudos. */
3296 190108 : for (i = start; i < finish; i++)
3297 : {
3298 123878 : rtx reg = XEXP (XVECEXP (src, 0, i), 0);
3299 123878 : if (!REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
3300 : {
3301 116041 : tmps[i] = gen_reg_rtx (GET_MODE (reg));
3302 116041 : emit_move_insn (tmps[i], reg);
3303 : }
3304 : else
3305 7837 : tmps[i] = reg;
3306 : }
3307 :
3308 : /* If we won't be storing directly into memory, protect the real destination
3309 : from strange tricks we might play. */
3310 66230 : dst = orig_dst;
3311 66230 : if (GET_CODE (dst) == PARALLEL)
3312 : {
3313 0 : rtx temp;
3314 :
3315 : /* We can get a PARALLEL dst if there is a conditional expression in
3316 : a return statement. In that case, the dst and src are the same,
3317 : so no action is necessary. */
3318 0 : if (rtx_equal_p (dst, src))
3319 : return;
3320 :
3321 : /* It is unclear if we can ever reach here, but we may as well handle
3322 : it. Allocate a temporary, and split this into a store/load to/from
3323 : the temporary. */
3324 0 : temp = assign_stack_temp (GET_MODE (dst), ssize);
3325 0 : emit_group_store (temp, src, type, ssize);
3326 0 : emit_group_load (dst, temp, type, ssize);
3327 0 : return;
3328 : }
3329 66230 : else if (!MEM_P (dst) && GET_CODE (dst) != CONCAT)
3330 : {
3331 50544 : machine_mode outer = GET_MODE (dst);
3332 50544 : machine_mode inner;
3333 50544 : poly_int64 bytepos;
3334 50544 : bool done = false;
3335 50544 : rtx temp;
3336 :
3337 50544 : if (!REG_P (dst) || REGNO (dst) < FIRST_PSEUDO_REGISTER)
3338 0 : dst = gen_reg_rtx (outer);
3339 :
3340 : /* Make life a bit easier for combine: if the first element of the
3341 : vector is the low part of the destination mode, use a paradoxical
3342 : subreg to initialize the destination. */
3343 50544 : if (start < finish)
3344 : {
3345 50544 : inner = GET_MODE (tmps[start]);
3346 50544 : bytepos = subreg_lowpart_offset (inner, outer);
3347 50544 : if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, start), 1)),
3348 : bytepos))
3349 : {
3350 50520 : temp = force_subreg (outer, tmps[start], inner, 0);
3351 50520 : if (temp)
3352 : {
3353 49848 : emit_move_insn (dst, temp);
3354 49848 : done = true;
3355 49848 : start++;
3356 : }
3357 : }
3358 : }
3359 :
3360 : /* If the first element wasn't the low part, try the last. */
3361 49848 : if (!done
3362 696 : && start < finish - 1)
3363 : {
3364 629 : inner = GET_MODE (tmps[finish - 1]);
3365 629 : bytepos = subreg_lowpart_offset (inner, outer);
3366 629 : if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
3367 : finish - 1), 1)),
3368 : bytepos))
3369 : {
3370 0 : temp = force_subreg (outer, tmps[finish - 1], inner, 0);
3371 0 : if (temp)
3372 : {
3373 0 : emit_move_insn (dst, temp);
3374 0 : done = true;
3375 0 : finish--;
3376 : }
3377 : }
3378 : }
3379 :
3380 : /* Otherwise, simply initialize the result to zero. */
3381 49848 : if (!done)
3382 696 : emit_move_insn (dst, CONST0_RTX (outer));
3383 : }
3384 :
3385 : /* Process the pieces. */
3386 136459 : for (i = start; i < finish; i++)
3387 : {
3388 74030 : poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, i), 1));
3389 74030 : machine_mode mode = GET_MODE (tmps[i]);
3390 148060 : poly_int64 bytelen = GET_MODE_SIZE (mode);
3391 74030 : poly_uint64 adj_bytelen;
3392 74030 : rtx dest = dst;
3393 :
3394 : /* Handle trailing fragments that run over the size of the struct.
3395 : It's the target's responsibility to make sure that the fragment
3396 : cannot be strictly smaller in some cases and strictly larger
3397 : in others. */
3398 74030 : gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
3399 147109 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3400 951 : adj_bytelen = ssize - bytepos;
3401 : else
3402 74030 : adj_bytelen = bytelen;
3403 :
3404 : /* Deal with destination CONCATs by either storing into one of the parts
3405 : or doing a copy after storing into a register or stack temporary. */
3406 74030 : if (GET_CODE (dst) == CONCAT)
3407 : {
3408 30490 : if (known_le (bytepos + adj_bytelen,
3409 : GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
3410 : dest = XEXP (dst, 0);
3411 :
3412 19046 : else if (known_ge (bytepos, GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
3413 : {
3414 11444 : bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
3415 5722 : dest = XEXP (dst, 1);
3416 : }
3417 :
3418 : else
3419 : {
3420 3801 : machine_mode dest_mode = GET_MODE (dest);
3421 3801 : machine_mode tmp_mode = GET_MODE (tmps[i]);
3422 3801 : scalar_int_mode dest_imode;
3423 :
3424 3801 : gcc_assert (known_eq (bytepos, 0) && XVECLEN (src, 0));
3425 :
3426 : /* If the source is a single scalar integer register, and the
3427 : destination has a complex mode for which a same-sized integer
3428 : mode exists, then we can take the left-justified part of the
3429 : source in the complex mode. */
3430 3801 : if (finish == start + 1
3431 3801 : && REG_P (tmps[i])
3432 3801 : && SCALAR_INT_MODE_P (tmp_mode)
3433 3801 : && COMPLEX_MODE_P (dest_mode)
3434 7602 : && int_mode_for_mode (dest_mode).exists (&dest_imode))
3435 : {
3436 3801 : const scalar_int_mode tmp_imode
3437 3801 : = as_a <scalar_int_mode> (tmp_mode);
3438 :
3439 7602 : if (GET_MODE_BITSIZE (dest_imode)
3440 3801 : < GET_MODE_BITSIZE (tmp_imode))
3441 : {
3442 59 : dest = gen_reg_rtx (dest_imode);
3443 59 : if (BYTES_BIG_ENDIAN)
3444 : tmps[i] = expand_shift (RSHIFT_EXPR, tmp_mode, tmps[i],
3445 : GET_MODE_BITSIZE (tmp_imode)
3446 : - GET_MODE_BITSIZE (dest_imode),
3447 : NULL_RTX, 1);
3448 59 : emit_move_insn (dest, gen_lowpart (dest_imode, tmps[i]));
3449 59 : dst = gen_lowpart (dest_mode, dest);
3450 : }
3451 : else
3452 3742 : dst = gen_lowpart (dest_mode, tmps[i]);
3453 : }
3454 :
3455 : /* Otherwise spill the source onto the stack using the more
3456 : aligned of the two modes. */
3457 0 : else if (GET_MODE_ALIGNMENT (dest_mode)
3458 0 : >= GET_MODE_ALIGNMENT (tmp_mode))
3459 : {
3460 0 : dest = assign_stack_temp (dest_mode,
3461 0 : GET_MODE_SIZE (dest_mode));
3462 0 : emit_move_insn (adjust_address (dest, tmp_mode, bytepos),
3463 : tmps[i]);
3464 0 : dst = dest;
3465 : }
3466 :
3467 : else
3468 : {
3469 0 : dest = assign_stack_temp (tmp_mode,
3470 0 : GET_MODE_SIZE (tmp_mode));
3471 0 : emit_move_insn (dest, tmps[i]);
3472 0 : dst = adjust_address (dest, dest_mode, bytepos);
3473 : }
3474 :
3475 : break;
3476 : }
3477 : }
3478 :
3479 : /* Handle trailing fragments that run over the size of the struct. */
3480 70229 : if (known_size_p (ssize) && maybe_gt (bytepos + bytelen, ssize))
3481 : {
3482 : /* store_bit_field always takes its value from the lsb.
3483 : Move the fragment to the lsb if it's not already there. */
3484 892 : if (
3485 : #ifdef BLOCK_REG_PADDING
3486 : BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
3487 : == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
3488 : #else
3489 : BYTES_BIG_ENDIAN
3490 : #endif
3491 : )
3492 : {
3493 : poly_int64 shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
3494 : tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
3495 : shift, tmps[i], 0);
3496 : }
3497 :
3498 : /* Make sure not to write past the end of the struct. */
3499 892 : store_bit_field (dest,
3500 892 : adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3501 3568 : bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
3502 : VOIDmode, tmps[i], false, false);
3503 : }
3504 :
3505 : /* Optimize the access just a bit. */
3506 69337 : else if (MEM_P (dest)
3507 7553 : && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (dest))
3508 0 : || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
3509 15106 : && multiple_p (bytepos * BITS_PER_UNIT,
3510 : GET_MODE_ALIGNMENT (mode))
3511 76890 : && known_eq (bytelen, GET_MODE_SIZE (mode)))
3512 7553 : emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
3513 :
3514 : else
3515 123568 : store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3516 : 0, 0, mode, tmps[i], false, false);
3517 : }
3518 :
3519 : /* Copy from the pseudo into the (probable) hard reg. */
3520 66230 : if (orig_dst != dst)
3521 3801 : emit_move_insn (orig_dst, dst);
3522 : }
3523 :
3524 : /* Return a form of X that does not use a PARALLEL. TYPE is the type
3525 : of the value stored in X. */
3526 :
3527 : rtx
3528 337319 : maybe_emit_group_store (rtx x, tree type)
3529 : {
3530 337319 : machine_mode mode = TYPE_MODE (type);
3531 337319 : gcc_checking_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);
3532 337319 : if (GET_CODE (x) == PARALLEL)
3533 : {
3534 0 : rtx result = gen_reg_rtx (mode);
3535 0 : emit_group_store (result, x, type, int_size_in_bytes (type));
3536 0 : return result;
3537 : }
3538 : return x;
3539 : }
3540 :
3541 : /* Copy a BLKmode object of TYPE out of a register SRCREG into TARGET.
3542 :
3543 : This is used on targets that return BLKmode values in registers. */
3544 :
3545 : static void
3546 256 : copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
3547 : {
3548 256 : unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
3549 256 : rtx src = NULL, dst = NULL;
3550 256 : unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
3551 256 : unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
3552 : /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3553 256 : fixed_size_mode mode = as_a <fixed_size_mode> (GET_MODE (srcreg));
3554 256 : fixed_size_mode tmode = as_a <fixed_size_mode> (GET_MODE (target));
3555 256 : fixed_size_mode copy_mode;
3556 :
3557 : /* BLKmode registers created in the back-end shouldn't have survived. */
3558 256 : gcc_assert (mode != BLKmode);
3559 :
3560 : /* If the structure doesn't take up a whole number of words, see whether
3561 : SRCREG is padded on the left or on the right. If it's on the left,
3562 : set PADDING_CORRECTION to the number of bits to skip.
3563 :
3564 : In most ABIs, the structure will be returned at the least end of
3565 : the register, which translates to right padding on little-endian
3566 : targets and left padding on big-endian targets. The opposite
3567 : holds if the structure is returned at the most significant
3568 : end of the register. */
3569 256 : if (bytes % UNITS_PER_WORD != 0
3570 256 : && (targetm.calls.return_in_msb (type)
3571 225 : ? !BYTES_BIG_ENDIAN
3572 : : BYTES_BIG_ENDIAN))
3573 0 : padding_correction
3574 0 : = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
3575 :
3576 : /* We can use a single move if we have an exact mode for the size. */
3577 256 : else if (MEM_P (target)
3578 256 : && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (target))
3579 0 : || MEM_ALIGN (target) >= GET_MODE_ALIGNMENT (mode))
3580 512 : && bytes == GET_MODE_SIZE (mode))
3581 : {
3582 38 : emit_move_insn (adjust_address (target, mode, 0), srcreg);
3583 38 : return;
3584 : }
3585 :
3586 : /* And if we additionally have the same mode for a register. */
3587 218 : else if (REG_P (target)
3588 0 : && GET_MODE (target) == mode
3589 218 : && bytes == GET_MODE_SIZE (mode))
3590 : {
3591 0 : emit_move_insn (target, srcreg);
3592 0 : return;
3593 : }
3594 :
3595 : /* This code assumes srcreg is at least a full word. If it isn't, copy it
3596 : into a new pseudo which is a full word. */
3597 436 : if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
3598 : {
3599 77 : srcreg = convert_to_mode (word_mode, srcreg, TYPE_UNSIGNED (type));
3600 77 : mode = word_mode;
3601 : }
3602 :
3603 : /* Copy the structure BITSIZE bits at a time. If the target lives in
3604 : memory, take care of not reading/writing past its end by selecting
3605 : a copy mode suited to BITSIZE. This should always be possible given
3606 : how it is computed.
3607 :
3608 : If the target lives in register, make sure not to select a copy mode
3609 : larger than the mode of the register.
3610 :
3611 : We could probably emit more efficient code for machines which do not use
3612 : strict alignment, but it doesn't seem worth the effort at the current
3613 : time. */
3614 :
3615 218 : copy_mode = word_mode;
3616 218 : if (MEM_P (target))
3617 : {
3618 218 : opt_scalar_int_mode mem_mode = int_mode_for_size (bitsize, 1);
3619 218 : if (mem_mode.exists ())
3620 218 : copy_mode = mem_mode.require ();
3621 : }
3622 0 : else if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3623 : copy_mode = tmode;
3624 :
3625 218 : for (bitpos = 0, xbitpos = padding_correction;
3626 1068 : bitpos < bytes * BITS_PER_UNIT;
3627 850 : bitpos += bitsize, xbitpos += bitsize)
3628 : {
3629 : /* We need a new source operand each time xbitpos is on a
3630 : word boundary and when xbitpos == padding_correction
3631 : (the first time through). */
3632 850 : if (xbitpos % BITS_PER_WORD == 0 || xbitpos == padding_correction)
3633 218 : src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD, mode);
3634 :
3635 : /* We need a new destination operand each time bitpos is on
3636 : a word boundary. */
3637 850 : if (REG_P (target) && GET_MODE_BITSIZE (tmode) < BITS_PER_WORD)
3638 : dst = target;
3639 850 : else if (bitpos % BITS_PER_WORD == 0)
3640 218 : dst = operand_subword (target, bitpos / BITS_PER_WORD, 1, tmode);
3641 :
3642 : /* Use xbitpos for the source extraction (right justified) and
3643 : bitpos for the destination store (left justified). */
3644 850 : store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, 0, 0, copy_mode,
3645 850 : extract_bit_field (src, bitsize,
3646 850 : xbitpos % BITS_PER_WORD, 1,
3647 : NULL_RTX, copy_mode, copy_mode,
3648 : false, NULL),
3649 : false, false);
3650 : }
3651 : }
3652 :
3653 : /* Copy BLKmode value SRC into a register of mode MODE_IN. Return the
3654 : register if it contains any data, otherwise return null.
3655 :
3656 : This is used on targets that return BLKmode values in registers. */
3657 :
3658 : rtx
3659 3588 : copy_blkmode_to_reg (machine_mode mode_in, tree src)
3660 : {
3661 3588 : int i, n_regs;
3662 3588 : unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
3663 3588 : unsigned int bitsize;
3664 3588 : rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
3665 : /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3666 3588 : fixed_size_mode mode = as_a <fixed_size_mode> (mode_in);
3667 3588 : fixed_size_mode dst_mode;
3668 3588 : scalar_int_mode min_mode;
3669 :
3670 3588 : gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
3671 :
3672 3588 : x = expand_normal (src);
3673 :
3674 3588 : bytes = arg_int_size_in_bytes (TREE_TYPE (src));
3675 3588 : if (bytes == 0)
3676 : return NULL_RTX;
3677 :
3678 : /* If the structure doesn't take up a whole number of words, see
3679 : whether the register value should be padded on the left or on
3680 : the right. Set PADDING_CORRECTION to the number of padding
3681 : bits needed on the left side.
3682 :
3683 : In most ABIs, the structure will be returned at the least end of
3684 : the register, which translates to right padding on little-endian
3685 : targets and left padding on big-endian targets. The opposite
3686 : holds if the structure is returned at the most significant
3687 : end of the register. */
3688 1224 : if (bytes % UNITS_PER_WORD != 0
3689 1224 : && (targetm.calls.return_in_msb (TREE_TYPE (src))
3690 1188 : ? !BYTES_BIG_ENDIAN
3691 : : BYTES_BIG_ENDIAN))
3692 0 : padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
3693 0 : * BITS_PER_UNIT));
3694 :
3695 1224 : n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3696 1224 : dst_words = XALLOCAVEC (rtx, n_regs);
3697 1224 : bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
3698 1224 : min_mode = smallest_int_mode_for_size (bitsize).require ();
3699 :
3700 : /* Copy the structure BITSIZE bits at a time. */
3701 1224 : for (bitpos = 0, xbitpos = padding_correction;
3702 3974 : bitpos < bytes * BITS_PER_UNIT;
3703 2750 : bitpos += bitsize, xbitpos += bitsize)
3704 : {
3705 : /* We need a new destination pseudo each time xbitpos is
3706 : on a word boundary and when xbitpos == padding_correction
3707 : (the first time through). */
3708 2750 : if (xbitpos % BITS_PER_WORD == 0
3709 1523 : || xbitpos == padding_correction)
3710 : {
3711 : /* Generate an appropriate register. */
3712 1227 : dst_word = gen_reg_rtx (word_mode);
3713 1227 : dst_words[xbitpos / BITS_PER_WORD] = dst_word;
3714 :
3715 : /* Clear the destination before we move anything into it. */
3716 1227 : emit_move_insn (dst_word, CONST0_RTX (word_mode));
3717 : }
3718 :
3719 : /* Find the largest integer mode that can be used to copy all or as
3720 : many bits as possible of the structure if the target supports larger
3721 : copies. There are too many corner cases here w.r.t to alignments on
3722 : the read/writes. So if there is any padding just use single byte
3723 : operations. */
3724 2750 : opt_scalar_int_mode mode_iter;
3725 2750 : if (padding_correction == 0 && !STRICT_ALIGNMENT)
3726 : {
3727 7488 : FOR_EACH_MODE_FROM (mode_iter, min_mode)
3728 : {
3729 7488 : unsigned int msize = GET_MODE_BITSIZE (mode_iter.require ());
3730 7488 : if (msize <= ((bytes * BITS_PER_UNIT) - bitpos)
3731 4741 : && msize <= BITS_PER_WORD)
3732 4738 : bitsize = msize;
3733 : else
3734 : break;
3735 : }
3736 : }
3737 :
3738 : /* We need a new source operand each time bitpos is on a word
3739 : boundary. */
3740 2750 : if (bitpos % BITS_PER_WORD == 0)
3741 1227 : src_word = operand_subword_force (x, bitpos / BITS_PER_WORD, BLKmode);
3742 :
3743 : /* Use bitpos for the source extraction (left justified) and
3744 : xbitpos for the destination store (right justified). */
3745 5500 : store_bit_field (dst_word, bitsize, xbitpos % BITS_PER_WORD,
3746 : 0, 0, word_mode,
3747 2750 : extract_bit_field (src_word, bitsize,
3748 2750 : bitpos % BITS_PER_WORD, 1,
3749 : NULL_RTX, word_mode, word_mode,
3750 : false, NULL),
3751 : false, false);
3752 : }
3753 :
3754 1224 : if (mode == BLKmode)
3755 : {
3756 : /* Find the smallest integer mode large enough to hold the
3757 : entire structure. */
3758 0 : opt_scalar_int_mode mode_iter;
3759 0 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
3760 0 : if (GET_MODE_SIZE (mode_iter.require ()) >= bytes)
3761 : break;
3762 :
3763 : /* A suitable mode should have been found. */
3764 0 : mode = mode_iter.require ();
3765 : }
3766 :
3767 3672 : if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
3768 : dst_mode = word_mode;
3769 : else
3770 498 : dst_mode = mode;
3771 1224 : dst = gen_reg_rtx (dst_mode);
3772 :
3773 3675 : for (i = 0; i < n_regs; i++)
3774 1227 : emit_move_insn (operand_subword (dst, i, 0, dst_mode), dst_words[i]);
3775 :
3776 1224 : if (mode != dst_mode)
3777 726 : dst = gen_lowpart (mode, dst);
3778 :
3779 : return dst;
3780 : }
3781 :
3782 : /* Add a USE expression for REG to the (possibly empty) list pointed
3783 : to by CALL_FUSAGE. REG must denote a hard register. */
3784 :
3785 : void
3786 11661220 : use_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3787 : {
3788 11661220 : gcc_assert (REG_P (reg));
3789 :
3790 11661220 : if (!HARD_REGISTER_P (reg))
3791 : return;
3792 :
3793 11661220 : *call_fusage
3794 11661220 : = gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
3795 : }
3796 :
3797 : /* Add a CLOBBER expression for REG to the (possibly empty) list pointed
3798 : to by CALL_FUSAGE. REG must denote a hard register. */
3799 :
3800 : void
3801 0 : clobber_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3802 : {
3803 0 : gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
3804 :
3805 0 : *call_fusage
3806 0 : = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
3807 0 : }
3808 :
3809 : /* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
3810 : starting at REGNO. All of these registers must be hard registers. */
3811 :
3812 : void
3813 1608 : use_regs (rtx *call_fusage, int regno, int nregs)
3814 : {
3815 1608 : int i;
3816 :
3817 1608 : gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
3818 :
3819 3224 : for (i = 0; i < nregs; i++)
3820 1616 : use_reg (call_fusage, regno_reg_rtx[regno + i]);
3821 1608 : }
3822 :
3823 : /* Add USE expressions to *CALL_FUSAGE for each REG contained in the
3824 : PARALLEL REGS. This is for calls that pass values in multiple
3825 : non-contiguous locations. The Irix 6 ABI has examples of this. */
3826 :
3827 : void
3828 295111 : use_group_regs (rtx *call_fusage, rtx regs)
3829 : {
3830 295111 : int i;
3831 :
3832 875924 : for (i = 0; i < XVECLEN (regs, 0); i++)
3833 : {
3834 580813 : rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
3835 :
3836 : /* A NULL entry means the parameter goes both on the stack and in
3837 : registers. This can also be a MEM for targets that pass values
3838 : partially on the stack and partially in registers. */
3839 580813 : if (reg != 0 && REG_P (reg))
3840 580813 : use_reg (call_fusage, reg);
3841 : }
3842 295111 : }
3843 :
3844 : /* Return the defining gimple statement for SSA_NAME NAME if it is an
3845 : assignment and the code of the expression on the RHS is CODE. Return
3846 : NULL otherwise. */
3847 :
3848 : static gimple *
3849 12112723 : get_def_for_expr (tree name, enum tree_code code)
3850 : {
3851 12112723 : gimple *def_stmt;
3852 :
3853 12112723 : if (TREE_CODE (name) != SSA_NAME)
3854 : return NULL;
3855 :
3856 9435795 : def_stmt = get_gimple_for_ssa_name (name);
3857 9435795 : if (!def_stmt
3858 2022148 : || !is_gimple_assign (def_stmt)
3859 11456468 : || gimple_assign_rhs_code (def_stmt) != code)
3860 9403520 : return NULL;
3861 :
3862 : return def_stmt;
3863 : }
3864 :
3865 : /* Return the defining gimple statement for SSA_NAME NAME if it is an
3866 : assignment and the class of the expression on the RHS is CLASS. Return
3867 : NULL otherwise. */
3868 :
3869 : static gimple *
3870 16660 : get_def_for_expr_class (tree name, enum tree_code_class tclass)
3871 : {
3872 16660 : gimple *def_stmt;
3873 :
3874 16660 : if (TREE_CODE (name) != SSA_NAME)
3875 : return NULL;
3876 :
3877 16660 : def_stmt = get_gimple_for_ssa_name (name);
3878 16660 : if (!def_stmt
3879 14561 : || !is_gimple_assign (def_stmt)
3880 31221 : || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass)
3881 2233 : return NULL;
3882 :
3883 : return def_stmt;
3884 : }
3885 :
3886 : /* Write zeros through the storage of OBJECT. If OBJECT has BLKmode, SIZE is
3887 : its length in bytes. */
3888 :
3889 : rtx
3890 158233 : clear_storage_hints (rtx object, rtx size, enum block_op_methods method,
3891 : unsigned int expected_align, HOST_WIDE_INT expected_size,
3892 : unsigned HOST_WIDE_INT min_size,
3893 : unsigned HOST_WIDE_INT max_size,
3894 : unsigned HOST_WIDE_INT probable_max_size,
3895 : unsigned ctz_size)
3896 : {
3897 158233 : machine_mode mode = GET_MODE (object);
3898 158233 : unsigned int align;
3899 :
3900 158233 : gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
3901 :
3902 : /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
3903 : just move a zero. Otherwise, do this a piece at a time. */
3904 158233 : poly_int64 size_val;
3905 158233 : if (mode != BLKmode
3906 57952 : && poly_int_rtx_p (size, &size_val)
3907 216185 : && known_eq (size_val, GET_MODE_SIZE (mode)))
3908 : {
3909 57952 : rtx zero = CONST0_RTX (mode);
3910 57952 : if (zero != NULL)
3911 : {
3912 57952 : emit_move_insn (object, zero);
3913 57952 : return NULL;
3914 : }
3915 :
3916 0 : if (COMPLEX_MODE_P (mode))
3917 : {
3918 0 : zero = CONST0_RTX (GET_MODE_INNER (mode));
3919 0 : if (zero != NULL)
3920 : {
3921 0 : write_complex_part (object, zero, 0, true);
3922 0 : write_complex_part (object, zero, 1, false);
3923 0 : return NULL;
3924 : }
3925 : }
3926 : }
3927 :
3928 100281 : if (size == const0_rtx)
3929 : return NULL;
3930 :
3931 100280 : align = MEM_ALIGN (object);
3932 :
3933 100280 : if (CONST_INT_P (size)
3934 100280 : && targetm.use_by_pieces_infrastructure_p (INTVAL (size), align,
3935 : CLEAR_BY_PIECES,
3936 : optimize_insn_for_speed_p ()))
3937 71989 : clear_by_pieces (object, INTVAL (size), align);
3938 28291 : else if (set_storage_via_setmem (object, size, const0_rtx, align,
3939 : expected_align, expected_size,
3940 : min_size, max_size, probable_max_size))
3941 : ;
3942 16122 : else if (try_store_by_multiple_pieces (object, size, ctz_size,
3943 : min_size, max_size,
3944 : NULL_RTX, 0, align))
3945 : ;
3946 15858 : else if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (object)))
3947 15858 : return set_storage_via_libcall (object, size, const0_rtx,
3948 15858 : method == BLOCK_OP_TAILCALL);
3949 : else
3950 0 : gcc_unreachable ();
3951 :
3952 : return NULL;
3953 : }
3954 :
3955 : rtx
3956 110513 : clear_storage (rtx object, rtx size, enum block_op_methods method)
3957 : {
3958 110513 : unsigned HOST_WIDE_INT max, min = 0;
3959 110513 : if (GET_CODE (size) == CONST_INT)
3960 110513 : min = max = UINTVAL (size);
3961 : else
3962 0 : max = GET_MODE_MASK (GET_MODE (size));
3963 110513 : return clear_storage_hints (object, size, method, 0, -1, min, max, max, 0);
3964 : }
3965 :
3966 :
3967 : /* A subroutine of clear_storage. Expand a call to memset.
3968 : Return the return value of memset, 0 otherwise. */
3969 :
3970 : rtx
3971 15859 : set_storage_via_libcall (rtx object, rtx size, rtx val, bool tailcall)
3972 : {
3973 15859 : tree call_expr, fn, object_tree, size_tree, val_tree;
3974 15859 : machine_mode size_mode;
3975 :
3976 15859 : object = copy_addr_to_reg (XEXP (object, 0));
3977 15859 : object_tree = make_tree (ptr_type_node, object);
3978 :
3979 15859 : if (!CONST_INT_P (val))
3980 0 : val = convert_to_mode (TYPE_MODE (integer_type_node), val, 1);
3981 15859 : val_tree = make_tree (integer_type_node, val);
3982 :
3983 15859 : size_mode = TYPE_MODE (sizetype);
3984 15859 : size = convert_to_mode (size_mode, size, 1);
3985 15859 : size = copy_to_mode_reg (size_mode, size);
3986 15859 : size_tree = make_tree (sizetype, size);
3987 :
3988 : /* It is incorrect to use the libcall calling conventions for calls to
3989 : memset because it can be provided by the user. */
3990 15859 : fn = builtin_decl_implicit (BUILT_IN_MEMSET);
3991 15859 : call_expr = build_call_expr (fn, 3, object_tree, val_tree, size_tree);
3992 15859 : CALL_EXPR_TAILCALL (call_expr) = tailcall;
3993 :
3994 15859 : return expand_call (call_expr, NULL_RTX, false);
3995 : }
3996 :
3997 : /* Expand a setmem pattern; return true if successful. */
3998 :
3999 : bool
4000 36913 : set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
4001 : unsigned int expected_align, HOST_WIDE_INT expected_size,
4002 : unsigned HOST_WIDE_INT min_size,
4003 : unsigned HOST_WIDE_INT max_size,
4004 : unsigned HOST_WIDE_INT probable_max_size)
4005 : {
4006 : /* Try the most limited insn first, because there's no point
4007 : including more than one in the machine description unless
4008 : the more limited one has some advantage. */
4009 :
4010 36913 : if (expected_align < align)
4011 : expected_align = align;
4012 36913 : if (expected_size != -1)
4013 : {
4014 8 : if ((unsigned HOST_WIDE_INT)expected_size > max_size)
4015 0 : expected_size = max_size;
4016 8 : if ((unsigned HOST_WIDE_INT)expected_size < min_size)
4017 0 : expected_size = min_size;
4018 : }
4019 :
4020 36913 : opt_scalar_int_mode mode_iter;
4021 223890 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
4022 : {
4023 201409 : scalar_int_mode mode = mode_iter.require ();
4024 201409 : enum insn_code code = direct_optab_handler (setmem_optab, mode);
4025 :
4026 201409 : if (code != CODE_FOR_nothing
4027 : /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
4028 : here because if SIZE is less than the mode mask, as it is
4029 : returned by the macro, it will definitely be less than the
4030 : actual mode mask. Since SIZE is within the Pmode address
4031 : space, we limit MODE to Pmode. */
4032 201409 : && ((CONST_INT_P (size)
4033 31777 : && ((unsigned HOST_WIDE_INT) INTVAL (size)
4034 31777 : <= (GET_MODE_MASK (mode) >> 1)))
4035 26733 : || max_size <= (GET_MODE_MASK (mode) >> 1)
4036 31988 : || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
4037 : {
4038 47829 : class expand_operand ops[9];
4039 47829 : unsigned int nops;
4040 :
4041 47829 : nops = insn_data[(int) code].n_generator_args;
4042 47829 : gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
4043 :
4044 47829 : create_fixed_operand (&ops[0], object);
4045 : /* The check above guarantees that this size conversion is valid. */
4046 47829 : create_convert_operand_to (&ops[1], size, mode, true);
4047 47829 : create_convert_operand_from (&ops[2], val, byte_mode, true);
4048 47829 : create_integer_operand (&ops[3], align / BITS_PER_UNIT);
4049 47829 : if (nops >= 6)
4050 : {
4051 47829 : create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
4052 47829 : create_integer_operand (&ops[5], expected_size);
4053 : }
4054 47829 : if (nops >= 8)
4055 : {
4056 47829 : create_integer_operand (&ops[6], min_size);
4057 : /* If we cannot represent the maximal size,
4058 : make parameter NULL. */
4059 47829 : if ((HOST_WIDE_INT) max_size != -1)
4060 44562 : create_integer_operand (&ops[7], max_size);
4061 : else
4062 3267 : create_fixed_operand (&ops[7], NULL);
4063 : }
4064 47829 : if (nops == 9)
4065 : {
4066 : /* If we cannot represent the maximal size,
4067 : make parameter NULL. */
4068 47829 : if ((HOST_WIDE_INT) probable_max_size != -1)
4069 44722 : create_integer_operand (&ops[8], probable_max_size);
4070 : else
4071 3107 : create_fixed_operand (&ops[8], NULL);
4072 : }
4073 47829 : gcc_assert (min_size != max_size
4074 : || rtx_equal_p (ops[1].value, GEN_INT (min_size)));
4075 47829 : if (maybe_expand_insn (code, nops, ops))
4076 14432 : return true;
4077 : }
4078 : }
4079 :
4080 : return false;
4081 : }
4082 :
4083 :
4084 : /* Write to one of the components of the complex value CPLX. Write VAL to
4085 : the real part if IMAG_P is false, and the imaginary part if its true.
4086 : If UNDEFINED_P then the value in CPLX is currently undefined. */
4087 :
4088 : void
4089 578083 : write_complex_part (rtx cplx, rtx val, bool imag_p, bool undefined_p)
4090 : {
4091 578083 : machine_mode cmode;
4092 578083 : scalar_mode imode;
4093 578083 : unsigned ibitsize;
4094 :
4095 578083 : if (GET_CODE (cplx) == CONCAT)
4096 : {
4097 518733 : emit_move_insn (XEXP (cplx, imag_p), val);
4098 518733 : return;
4099 : }
4100 :
4101 59350 : cmode = GET_MODE (cplx);
4102 59350 : imode = GET_MODE_INNER (cmode);
4103 59350 : ibitsize = GET_MODE_BITSIZE (imode);
4104 :
4105 : /* For MEMs simplify_gen_subreg may generate an invalid new address
4106 : because, e.g., the original address is considered mode-dependent
4107 : by the target, which restricts simplify_subreg from invoking
4108 : adjust_address_nv. Instead of preparing fallback support for an
4109 : invalid address, we call adjust_address_nv directly. */
4110 59350 : if (MEM_P (cplx))
4111 : {
4112 69588 : emit_move_insn (adjust_address_nv (cplx, imode,
4113 : imag_p ? GET_MODE_SIZE (imode) : 0),
4114 : val);
4115 46392 : return;
4116 : }
4117 :
4118 : /* If the sub-object is at least word sized, then we know that subregging
4119 : will work. This special case is important, since store_bit_field
4120 : wants to operate on integer modes, and there's rarely an OImode to
4121 : correspond to TCmode. */
4122 12958 : if (ibitsize >= BITS_PER_WORD
4123 : /* For hard regs we have exact predicates. Assume we can split
4124 : the original object if it spans an even number of hard regs.
4125 : This special case is important for SCmode on 64-bit platforms
4126 : where the natural size of floating-point regs is 32-bit. */
4127 12958 : || (REG_P (cplx)
4128 7324 : && REGNO (cplx) < FIRST_PSEUDO_REGISTER
4129 7122 : && REG_NREGS (cplx) % 2 == 0))
4130 : {
4131 5650 : rtx part = simplify_gen_subreg (imode, cplx, cmode,
4132 8475 : imag_p ? GET_MODE_SIZE (imode) : 0);
4133 5650 : if (part)
4134 : {
4135 5650 : emit_move_insn (part, val);
4136 5650 : return;
4137 : }
4138 : else
4139 : /* simplify_gen_subreg may fail for sub-word MEMs. */
4140 0 : gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
4141 : }
4142 :
4143 10962 : store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val,
4144 : false, undefined_p);
4145 : }
4146 :
4147 : /* Extract one of the components of the complex value CPLX. Extract the
4148 : real part if IMAG_P is false, and the imaginary part if it's true. */
4149 :
4150 : rtx
4151 566634 : read_complex_part (rtx cplx, bool imag_p)
4152 : {
4153 566634 : machine_mode cmode;
4154 566634 : scalar_mode imode;
4155 566634 : unsigned ibitsize;
4156 :
4157 566634 : if (GET_CODE (cplx) == CONCAT)
4158 349938 : return XEXP (cplx, imag_p);
4159 :
4160 216696 : cmode = GET_MODE (cplx);
4161 216696 : imode = GET_MODE_INNER (cmode);
4162 216696 : ibitsize = GET_MODE_BITSIZE (imode);
4163 :
4164 : /* Special case reads from complex constants that got spilled to memory. */
4165 216696 : if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF)
4166 : {
4167 37943 : tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0));
4168 37943 : if (decl && TREE_CODE (decl) == COMPLEX_CST)
4169 : {
4170 0 : tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
4171 0 : if (CONSTANT_CLASS_P (part))
4172 0 : return expand_expr (part, NULL_RTX, imode, EXPAND_NORMAL);
4173 : }
4174 : }
4175 :
4176 : /* For MEMs simplify_gen_subreg may generate an invalid new address
4177 : because, e.g., the original address is considered mode-dependent
4178 : by the target, which restricts simplify_subreg from invoking
4179 : adjust_address_nv. Instead of preparing fallback support for an
4180 : invalid address, we call adjust_address_nv directly. */
4181 216696 : if (MEM_P (cplx))
4182 238688 : return adjust_address_nv (cplx, imode,
4183 : imag_p ? GET_MODE_SIZE (imode) : 0);
4184 :
4185 : /* If the sub-object is at least word sized, then we know that subregging
4186 : will work. This special case is important, since extract_bit_field
4187 : wants to operate on integer modes, and there's rarely an OImode to
4188 : correspond to TCmode. */
4189 57404 : if (ibitsize >= BITS_PER_WORD
4190 : /* For hard regs we have exact predicates. Assume we can split
4191 : the original object if it spans an even number of hard regs.
4192 : This special case is important for SCmode on 64-bit platforms
4193 : where the natural size of floating-point regs is 32-bit. */
4194 57404 : || (REG_P (cplx)
4195 35412 : && REGNO (cplx) < FIRST_PSEUDO_REGISTER
4196 292 : && REG_NREGS (cplx) % 2 == 0))
4197 : {
4198 10869 : rtx ret = simplify_gen_subreg (imode, cplx, cmode,
4199 16303 : imag_p ? GET_MODE_SIZE (imode) : 0);
4200 10869 : if (ret)
4201 : return ret;
4202 : else
4203 : /* simplify_gen_subreg may fail for sub-word MEMs. */
4204 0 : gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
4205 : }
4206 :
4207 69800 : return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
4208 : true, NULL_RTX, imode, imode, false, NULL);
4209 : }
4210 :
4211 : /* A subroutine of emit_move_insn_1. Yet another lowpart generator.
4212 : NEW_MODE and OLD_MODE are the same size. Return NULL if X cannot be
4213 : represented in NEW_MODE. If FORCE is true, this will never happen, as
4214 : we'll force-create a SUBREG if needed. */
4215 :
4216 : static rtx
4217 278106 : emit_move_change_mode (machine_mode new_mode,
4218 : machine_mode old_mode, rtx x, bool force)
4219 : {
4220 278106 : rtx ret;
4221 :
4222 278106 : if (push_operand (x, GET_MODE (x)))
4223 : {
4224 1318 : ret = gen_rtx_MEM (new_mode, XEXP (x, 0));
4225 1318 : MEM_COPY_ATTRIBUTES (ret, x);
4226 : }
4227 276788 : else if (MEM_P (x))
4228 : {
4229 : /* We don't have to worry about changing the address since the
4230 : size in bytes is supposed to be the same. */
4231 52774 : if (reload_in_progress)
4232 : {
4233 : /* Copy the MEM to change the mode and move any
4234 : substitutions from the old MEM to the new one. */
4235 0 : ret = adjust_address_nv (x, new_mode, 0);
4236 0 : copy_replacements (x, ret);
4237 : }
4238 : else
4239 52774 : ret = adjust_address (x, new_mode, 0);
4240 : }
4241 : else
4242 : {
4243 : /* Note that we do want simplify_subreg's behavior of validating
4244 : that the new mode is ok for a hard register. If we were to use
4245 : simplify_gen_subreg, we would create the subreg, but would
4246 : probably run into the target not being able to implement it. */
4247 : /* Except, of course, when FORCE is true, when this is exactly what
4248 : we want. Which is needed for CCmodes on some targets. */
4249 224014 : if (force)
4250 224014 : ret = simplify_gen_subreg (new_mode, x, old_mode, 0);
4251 : else
4252 0 : ret = simplify_subreg (new_mode, x, old_mode, 0);
4253 : }
4254 :
4255 278106 : return ret;
4256 : }
4257 :
4258 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X using
4259 : an integer mode of the same size as MODE. Returns the instruction
4260 : emitted, or NULL if such a move could not be generated. */
4261 :
4262 : static rtx_insn *
4263 139053 : emit_move_via_integer (machine_mode mode, rtx x, rtx y, bool force)
4264 : {
4265 139053 : scalar_int_mode imode;
4266 139053 : enum insn_code code;
4267 :
4268 : /* There must exist a mode of the exact size we require. */
4269 139053 : if (!int_mode_for_mode (mode).exists (&imode))
4270 0 : return NULL;
4271 :
4272 : /* The target must support moves in this mode. */
4273 139053 : code = optab_handler (mov_optab, imode);
4274 139053 : if (code == CODE_FOR_nothing)
4275 : return NULL;
4276 :
4277 139053 : x = emit_move_change_mode (imode, mode, x, force);
4278 139053 : if (x == NULL_RTX)
4279 : return NULL;
4280 139053 : y = emit_move_change_mode (imode, mode, y, force);
4281 139053 : if (y == NULL_RTX)
4282 : return NULL;
4283 139053 : return emit_insn (GEN_FCN (code) (x, y));
4284 : }
4285 :
4286 : /* A subroutine of emit_move_insn_1. X is a push_operand in MODE.
4287 : Return an equivalent MEM that does not use an auto-increment. */
4288 :
4289 : rtx
4290 3637 : emit_move_resolve_push (machine_mode mode, rtx x)
4291 : {
4292 3637 : enum rtx_code code = GET_CODE (XEXP (x, 0));
4293 3637 : rtx temp;
4294 :
4295 7274 : poly_int64 adjust = GET_MODE_SIZE (mode);
4296 : #ifdef PUSH_ROUNDING
4297 3637 : adjust = PUSH_ROUNDING (adjust);
4298 : #endif
4299 3637 : if (code == PRE_DEC || code == POST_DEC)
4300 3241 : adjust = -adjust;
4301 396 : else if (code == PRE_MODIFY || code == POST_MODIFY)
4302 : {
4303 396 : rtx expr = XEXP (XEXP (x, 0), 1);
4304 :
4305 396 : gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
4306 396 : poly_int64 val = rtx_to_poly_int64 (XEXP (expr, 1));
4307 396 : if (GET_CODE (expr) == MINUS)
4308 0 : val = -val;
4309 396 : gcc_assert (known_eq (adjust, val) || known_eq (adjust, -val));
4310 : adjust = val;
4311 : }
4312 :
4313 : /* Do not use anti_adjust_stack, since we don't want to update
4314 : stack_pointer_delta. */
4315 3641 : temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
4316 3637 : gen_int_mode (adjust, Pmode), stack_pointer_rtx,
4317 : 0, OPTAB_LIB_WIDEN);
4318 3637 : if (temp != stack_pointer_rtx)
4319 0 : emit_move_insn (stack_pointer_rtx, temp);
4320 :
4321 3637 : switch (code)
4322 : {
4323 3637 : case PRE_INC:
4324 3637 : case PRE_DEC:
4325 3637 : case PRE_MODIFY:
4326 3637 : temp = stack_pointer_rtx;
4327 3637 : break;
4328 : case POST_INC:
4329 : case POST_DEC:
4330 : case POST_MODIFY:
4331 0 : temp = plus_constant (Pmode, stack_pointer_rtx, -adjust);
4332 0 : break;
4333 0 : default:
4334 0 : gcc_unreachable ();
4335 : }
4336 :
4337 3637 : return replace_equiv_address (x, temp);
4338 : }
4339 :
4340 : /* A subroutine of emit_move_complex. Generate a move from Y into X.
4341 : X is known to satisfy push_operand, and MODE is known to be complex.
4342 : Returns the last instruction emitted. */
4343 :
4344 : rtx_insn *
4345 5760 : emit_move_complex_push (machine_mode mode, rtx x, rtx y)
4346 : {
4347 5760 : scalar_mode submode = GET_MODE_INNER (mode);
4348 5760 : bool imag_first;
4349 :
4350 : #ifdef PUSH_ROUNDING
4351 11520 : poly_int64 submodesize = GET_MODE_SIZE (submode);
4352 :
4353 : /* In case we output to the stack, but the size is smaller than the
4354 : machine can push exactly, we need to use move instructions. */
4355 5760 : if (maybe_ne (PUSH_ROUNDING (submodesize), submodesize))
4356 : {
4357 718 : x = emit_move_resolve_push (mode, x);
4358 718 : return emit_move_insn (x, y);
4359 : }
4360 : #endif
4361 :
4362 : /* Note that the real part always precedes the imag part in memory
4363 : regardless of machine's endianness. */
4364 5042 : switch (GET_CODE (XEXP (x, 0)))
4365 : {
4366 : case PRE_DEC:
4367 : case POST_DEC:
4368 : imag_first = true;
4369 : break;
4370 0 : case PRE_INC:
4371 0 : case POST_INC:
4372 0 : imag_first = false;
4373 0 : break;
4374 0 : default:
4375 0 : gcc_unreachable ();
4376 : }
4377 :
4378 5042 : emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
4379 : read_complex_part (y, imag_first));
4380 5042 : return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
4381 5042 : read_complex_part (y, !imag_first));
4382 : }
4383 :
4384 : /* A subroutine of emit_move_complex. Perform the move from Y to X
4385 : via two moves of the parts. Returns the last instruction emitted. */
4386 :
4387 : rtx_insn *
4388 90125 : emit_move_complex_parts (rtx x, rtx y)
4389 : {
4390 : /* Show the output dies here. This is necessary for SUBREGs
4391 : of pseudos since we cannot track their lifetimes correctly;
4392 : hard regs shouldn't appear here except as return values. */
4393 90125 : if (!reload_completed && !reload_in_progress
4394 180250 : && REG_P (x) && !reg_overlap_mentioned_p (x, y))
4395 6472 : emit_clobber (x);
4396 :
4397 90125 : write_complex_part (x, read_complex_part (y, false), false, true);
4398 90125 : write_complex_part (x, read_complex_part (y, true), true, false);
4399 :
4400 90125 : return get_last_insn ();
4401 : }
4402 :
4403 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4404 : MODE is known to be complex. Returns the last instruction emitted. */
4405 :
4406 : static rtx_insn *
4407 112770 : emit_move_complex (machine_mode mode, rtx x, rtx y)
4408 : {
4409 112770 : bool try_int;
4410 :
4411 : /* Need to take special care for pushes, to maintain proper ordering
4412 : of the data, and possibly extra padding. */
4413 112770 : if (push_operand (x, mode))
4414 5152 : return emit_move_complex_push (mode, x, y);
4415 :
4416 : /* See if we can coerce the target into moving both values at once, except
4417 : for floating point where we favor moving as parts if this is easy. */
4418 107618 : if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
4419 64305 : && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing
4420 64305 : && !(REG_P (x)
4421 2549 : && HARD_REGISTER_P (x)
4422 740 : && REG_NREGS (x) == 1)
4423 171923 : && !(REG_P (y)
4424 3622 : && HARD_REGISTER_P (y)
4425 1811 : && REG_NREGS (y) == 1))
4426 : try_int = false;
4427 : /* Not possible if the values are inherently not adjacent. */
4428 43313 : else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
4429 : try_int = false;
4430 : /* Is possible if both are registers (or subregs of registers). */
4431 18302 : else if (register_operand (x, mode) && register_operand (y, mode))
4432 : try_int = true;
4433 : /* If one of the operands is a memory, and alignment constraints
4434 : are friendly enough, we may be able to do combined memory operations.
4435 : We do not attempt this if Y is a constant because that combination is
4436 : usually better with the by-parts thing below. */
4437 635 : else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
4438 : && (!STRICT_ALIGNMENT
4439 : || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
4440 : try_int = true;
4441 : else
4442 : try_int = false;
4443 :
4444 : if (try_int)
4445 : {
4446 18302 : rtx_insn *ret;
4447 :
4448 : /* For memory to memory moves, optimal behavior can be had with the
4449 : existing block move logic. But use normal expansion if optimizing
4450 : for size. */
4451 18302 : if (MEM_P (x) && MEM_P (y))
4452 : {
4453 726 : emit_block_move (x, y, gen_int_mode (GET_MODE_SIZE (mode), Pmode),
4454 360 : (optimize_insn_for_speed_p()
4455 : ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
4456 360 : return get_last_insn ();
4457 : }
4458 :
4459 17942 : ret = emit_move_via_integer (mode, x, y, true);
4460 17942 : if (ret)
4461 : return ret;
4462 : }
4463 :
4464 89316 : return emit_move_complex_parts (x, y);
4465 : }
4466 :
4467 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4468 : MODE is known to be MODE_CC. Returns the last instruction emitted. */
4469 :
4470 : static rtx_insn *
4471 0 : emit_move_ccmode (machine_mode mode, rtx x, rtx y)
4472 : {
4473 0 : rtx_insn *ret;
4474 :
4475 : /* Assume all MODE_CC modes are equivalent; if we have movcc, use it. */
4476 0 : if (mode != CCmode)
4477 : {
4478 0 : enum insn_code code = optab_handler (mov_optab, CCmode);
4479 0 : if (code != CODE_FOR_nothing)
4480 : {
4481 0 : x = emit_move_change_mode (CCmode, mode, x, true);
4482 0 : y = emit_move_change_mode (CCmode, mode, y, true);
4483 0 : return emit_insn (GEN_FCN (code) (x, y));
4484 : }
4485 : }
4486 :
4487 : /* Otherwise, find the MODE_INT mode of the same width. */
4488 0 : ret = emit_move_via_integer (mode, x, y, false);
4489 0 : gcc_assert (ret != NULL);
4490 : return ret;
4491 : }
4492 :
4493 : /* Return true if word I of OP lies entirely in the
4494 : undefined bits of a paradoxical subreg. */
4495 :
4496 : static bool
4497 0 : undefined_operand_subword_p (const_rtx op, int i)
4498 : {
4499 0 : if (GET_CODE (op) != SUBREG)
4500 : return false;
4501 0 : machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
4502 0 : poly_int64 offset = i * UNITS_PER_WORD + subreg_memory_offset (op);
4503 0 : return (known_ge (offset, GET_MODE_SIZE (innermostmode))
4504 0 : || known_le (offset, -UNITS_PER_WORD));
4505 : }
4506 :
4507 : /* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4508 : MODE is any multi-word or full-word mode that lacks a move_insn
4509 : pattern. Note that you will get better code if you define such
4510 : patterns, even if they must turn into multiple assembler instructions. */
4511 :
4512 : static rtx_insn *
4513 0 : emit_move_multi_word (machine_mode mode, rtx x, rtx y)
4514 : {
4515 0 : rtx_insn *last_insn = 0;
4516 0 : rtx_insn *seq;
4517 0 : rtx inner;
4518 0 : bool need_clobber;
4519 0 : int i, mode_size;
4520 :
4521 : /* This function can only handle cases where the number of words is
4522 : known at compile time. */
4523 0 : mode_size = GET_MODE_SIZE (mode).to_constant ();
4524 0 : gcc_assert (mode_size >= UNITS_PER_WORD);
4525 :
4526 : /* If X is a push on the stack, do the push now and replace
4527 : X with a reference to the stack pointer. */
4528 0 : if (push_operand (x, mode))
4529 0 : x = emit_move_resolve_push (mode, x);
4530 :
4531 : /* If we are in reload, see if either operand is a MEM whose address
4532 : is scheduled for replacement. */
4533 0 : if (reload_in_progress && MEM_P (x)
4534 0 : && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
4535 0 : x = replace_equiv_address_nv (x, inner);
4536 0 : if (reload_in_progress && MEM_P (y)
4537 0 : && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
4538 0 : y = replace_equiv_address_nv (y, inner);
4539 :
4540 0 : start_sequence ();
4541 :
4542 0 : need_clobber = false;
4543 0 : for (i = 0; i < CEIL (mode_size, UNITS_PER_WORD); i++)
4544 : {
4545 : /* Do not generate code for a move if it would go entirely
4546 : to the non-existing bits of a paradoxical subreg. */
4547 0 : if (undefined_operand_subword_p (x, i))
4548 0 : continue;
4549 :
4550 0 : rtx xpart = operand_subword (x, i, 1, mode);
4551 0 : rtx ypart;
4552 :
4553 : /* Do not generate code for a move if it would come entirely
4554 : from the undefined bits of a paradoxical subreg. */
4555 0 : if (undefined_operand_subword_p (y, i))
4556 0 : continue;
4557 :
4558 0 : ypart = operand_subword (y, i, 1, mode);
4559 :
4560 : /* If we can't get a part of Y, put Y into memory if it is a
4561 : constant. Otherwise, force it into a register. Then we must
4562 : be able to get a part of Y. */
4563 0 : if (ypart == 0 && CONSTANT_P (y))
4564 : {
4565 0 : y = use_anchored_address (force_const_mem (mode, y));
4566 0 : ypart = operand_subword (y, i, 1, mode);
4567 : }
4568 0 : else if (ypart == 0)
4569 0 : ypart = operand_subword_force (y, i, mode);
4570 :
4571 0 : gcc_assert (xpart && ypart);
4572 :
4573 0 : need_clobber |= (GET_CODE (xpart) == SUBREG);
4574 :
4575 0 : last_insn = emit_move_insn (xpart, ypart);
4576 : }
4577 :
4578 0 : seq = end_sequence ();
4579 :
4580 : /* Show the output dies here. This is necessary for SUBREGs
4581 : of pseudos since we cannot track their lifetimes correctly;
4582 : hard regs shouldn't appear here except as return values.
4583 : We never want to emit such a clobber after reload. */
4584 0 : if (x != y
4585 0 : && ! (reload_in_progress || reload_completed)
4586 0 : && need_clobber != 0)
4587 0 : emit_clobber (x);
4588 :
4589 0 : emit_insn (seq);
4590 :
4591 0 : return last_insn;
4592 : }
4593 :
4594 : /* Low level part of emit_move_insn.
4595 : Called just like emit_move_insn, but assumes X and Y
4596 : are basically valid. */
4597 :
4598 : rtx_insn *
4599 77813259 : emit_move_insn_1 (rtx x, rtx y)
4600 : {
4601 77813259 : machine_mode mode = GET_MODE (x);
4602 77813259 : enum insn_code code;
4603 :
4604 77813259 : gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);
4605 :
4606 77813259 : code = optab_handler (mov_optab, mode);
4607 77813259 : if (code != CODE_FOR_nothing)
4608 77579378 : return emit_insn (GEN_FCN (code) (x, y));
4609 :
4610 : /* Expand complex moves by moving real part and imag part. */
4611 233881 : if (COMPLEX_MODE_P (mode))
4612 112770 : return emit_move_complex (mode, x, y);
4613 :
4614 : if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT
4615 : || ALL_FIXED_POINT_MODE_P (mode))
4616 : {
4617 121111 : rtx_insn *result = emit_move_via_integer (mode, x, y, true);
4618 :
4619 : /* If we can't find an integer mode, use multi words. */
4620 121111 : if (result)
4621 : return result;
4622 : else
4623 0 : return emit_move_multi_word (mode, x, y);
4624 : }
4625 :
4626 : if (GET_MODE_CLASS (mode) == MODE_CC)
4627 0 : return emit_move_ccmode (mode, x, y);
4628 :
4629 : /* Try using a move pattern for the corresponding integer mode. This is
4630 : only safe when simplify_subreg can convert MODE constants into integer
4631 : constants. At present, it can only do this reliably if the value
4632 : fits within a HOST_WIDE_INT. */
4633 0 : if (!CONSTANT_P (y)
4634 0 : || known_le (GET_MODE_BITSIZE (mode), HOST_BITS_PER_WIDE_INT))
4635 : {
4636 0 : rtx_insn *ret = emit_move_via_integer (mode, x, y, lra_in_progress);
4637 :
4638 0 : if (ret)
4639 : {
4640 0 : if (! lra_in_progress || recog (PATTERN (ret), ret, 0) >= 0)
4641 : return ret;
4642 : }
4643 : }
4644 :
4645 0 : return emit_move_multi_word (mode, x, y);
4646 : }
4647 :
4648 : /* Generate code to copy Y into X.
4649 : Both Y and X must have the same mode, except that
4650 : Y can be a constant with VOIDmode.
4651 : This mode cannot be BLKmode; use emit_block_move for that.
4652 :
4653 : Return the last instruction emitted. */
4654 :
4655 : rtx_insn *
4656 71840981 : emit_move_insn (rtx x, rtx y)
4657 : {
4658 71840981 : machine_mode mode = GET_MODE (x);
4659 71840981 : rtx y_cst = NULL_RTX;
4660 71840981 : rtx_insn *last_insn;
4661 71840981 : rtx set;
4662 :
4663 71840981 : gcc_assert (mode != BLKmode
4664 : && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
4665 :
4666 : /* If we have a copy that looks like one of the following patterns:
4667 : (set (subreg:M1 (reg:M2 ...)) (subreg:M1 (reg:M2 ...)))
4668 : (set (subreg:M1 (reg:M2 ...)) (mem:M1 ADDR))
4669 : (set (mem:M1 ADDR) (subreg:M1 (reg:M2 ...)))
4670 : (set (subreg:M1 (reg:M2 ...)) (constant C))
4671 : where mode M1 is equal in size to M2, try to detect whether the
4672 : mode change involves an implicit round trip through memory.
4673 : If so, see if we can avoid that by removing the subregs and
4674 : doing the move in mode M2 instead. */
4675 :
4676 71840981 : rtx x_inner = NULL_RTX;
4677 71840981 : rtx y_inner = NULL_RTX;
4678 :
4679 74654363 : auto candidate_subreg_p = [&](rtx subreg) {
4680 2813382 : return (REG_P (SUBREG_REG (subreg))
4681 8438325 : && known_eq (GET_MODE_SIZE (GET_MODE (SUBREG_REG (subreg))),
4682 : GET_MODE_SIZE (GET_MODE (subreg)))
4683 3200277 : && optab_handler (mov_optab, GET_MODE (SUBREG_REG (subreg)))
4684 2813382 : != CODE_FOR_nothing);
4685 : };
4686 :
4687 71847213 : auto candidate_mem_p = [&](machine_mode innermode, rtx mem) {
4688 6232 : return (!targetm.can_change_mode_class (innermode, GET_MODE (mem), ALL_REGS)
4689 6232 : && !push_operand (mem, GET_MODE (mem))
4690 : /* Not a candidate if innermode requires too much alignment. */
4691 12404 : && (MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (innermode)
4692 232 : || targetm.slow_unaligned_access (GET_MODE (mem),
4693 116 : MEM_ALIGN (mem))
4694 232 : || !targetm.slow_unaligned_access (innermode,
4695 116 : MEM_ALIGN (mem))));
4696 : };
4697 :
4698 71840981 : if (SUBREG_P (x) && candidate_subreg_p (x))
4699 14587 : x_inner = SUBREG_REG (x);
4700 :
4701 71840981 : if (SUBREG_P (y) && candidate_subreg_p (y))
4702 335844 : y_inner = SUBREG_REG (y);
4703 :
4704 71840981 : if (x_inner != NULL_RTX
4705 71840981 : && y_inner != NULL_RTX
4706 1172 : && GET_MODE (x_inner) == GET_MODE (y_inner)
4707 71841734 : && !targetm.can_change_mode_class (GET_MODE (x_inner), mode, ALL_REGS))
4708 : {
4709 753 : x = x_inner;
4710 753 : y = y_inner;
4711 753 : mode = GET_MODE (x_inner);
4712 : }
4713 71840228 : else if (x_inner != NULL_RTX
4714 13834 : && MEM_P (y)
4715 71840552 : && candidate_mem_p (GET_MODE (x_inner), y))
4716 : {
4717 324 : x = x_inner;
4718 324 : y = adjust_address (y, GET_MODE (x_inner), 0);
4719 324 : mode = GET_MODE (x_inner);
4720 : }
4721 71839904 : else if (y_inner != NULL_RTX
4722 335091 : && MEM_P (x)
4723 71845812 : && candidate_mem_p (GET_MODE (y_inner), x))
4724 : {
4725 5848 : x = adjust_address (x, GET_MODE (y_inner), 0);
4726 5848 : y = y_inner;
4727 5848 : mode = GET_MODE (y_inner);
4728 : }
4729 71834056 : else if (x_inner != NULL_RTX
4730 13510 : && CONSTANT_P (y)
4731 475 : && !targetm.can_change_mode_class (GET_MODE (x_inner),
4732 : mode, ALL_REGS)
4733 71834531 : && (y_inner = simplify_subreg (GET_MODE (x_inner), y, mode, 0)))
4734 : {
4735 475 : x = x_inner;
4736 475 : y = y_inner;
4737 475 : mode = GET_MODE (x_inner);
4738 : }
4739 :
4740 71840981 : if (CONSTANT_P (y))
4741 : {
4742 16774983 : if (optimize
4743 13036296 : && SCALAR_FLOAT_MODE_P (GET_MODE (x))
4744 17550762 : && (last_insn = compress_float_constant (x, y)))
4745 : return last_insn;
4746 :
4747 16705565 : y_cst = y;
4748 :
4749 16705565 : if (!targetm.legitimate_constant_p (mode, y))
4750 : {
4751 513332 : y = force_const_mem (mode, y);
4752 :
4753 : /* If the target's cannot_force_const_mem prevented the spill,
4754 : assume that the target's move expanders will also take care
4755 : of the non-legitimate constant. */
4756 513332 : if (!y)
4757 : y = y_cst;
4758 : else
4759 493215 : y = use_anchored_address (y);
4760 : }
4761 : }
4762 :
4763 : /* If X or Y are memory references, verify that their addresses are valid
4764 : for the machine. */
4765 71771563 : if (MEM_P (x)
4766 88060273 : && (! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
4767 14026531 : MEM_ADDR_SPACE (x))
4768 2262353 : && ! push_operand (x, GET_MODE (x))))
4769 174 : x = validize_mem (x);
4770 :
4771 71771563 : if (MEM_P (y)
4772 89618987 : && ! memory_address_addr_space_p (GET_MODE (y), XEXP (y, 0),
4773 17847424 : MEM_ADDR_SPACE (y)))
4774 8710 : y = validize_mem (y);
4775 :
4776 71771563 : gcc_assert (mode != BLKmode);
4777 :
4778 71771563 : last_insn = emit_move_insn_1 (x, y);
4779 :
4780 16705565 : if (y_cst && REG_P (x)
4781 12267690 : && (set = single_set (last_insn)) != NULL_RTX
4782 12267690 : && SET_DEST (set) == x
4783 84024738 : && ! rtx_equal_p (y_cst, SET_SRC (set)))
4784 1275158 : set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));
4785 :
4786 : return last_insn;
4787 : }
4788 :
4789 : /* Generate the body of an instruction to copy Y into X.
4790 : It may be a list of insns, if one insn isn't enough. */
4791 :
4792 : rtx_insn *
4793 6041616 : gen_move_insn (rtx x, rtx y)
4794 : {
4795 6041616 : start_sequence ();
4796 6041616 : emit_move_insn_1 (x, y);
4797 6041616 : return end_sequence ();
4798 : }
4799 :
4800 : /* If Y is representable exactly in a narrower mode, and the target can
4801 : perform the extension directly from constant or memory, then emit the
4802 : move as an extension. */
4803 :
4804 : static rtx_insn *
4805 775779 : compress_float_constant (rtx x, rtx y)
4806 : {
4807 775779 : machine_mode dstmode = GET_MODE (x);
4808 775779 : machine_mode orig_srcmode = GET_MODE (y);
4809 775779 : machine_mode srcmode;
4810 775779 : const REAL_VALUE_TYPE *r;
4811 775779 : int oldcost, newcost;
4812 775779 : bool speed = optimize_insn_for_speed_p ();
4813 :
4814 775779 : r = CONST_DOUBLE_REAL_VALUE (y);
4815 :
4816 775779 : if (targetm.legitimate_constant_p (dstmode, y))
4817 773634 : oldcost = set_src_cost (y, orig_srcmode, speed);
4818 : else
4819 2145 : oldcost = set_src_cost (force_const_mem (dstmode, y), dstmode, speed);
4820 :
4821 2747240 : FOR_EACH_MODE_UNTIL (srcmode, orig_srcmode)
4822 : {
4823 2040879 : enum insn_code ic;
4824 2040879 : rtx trunc_y;
4825 2040879 : rtx_insn *last_insn;
4826 :
4827 : /* Skip if the target can't extend this way. */
4828 2040879 : ic = can_extend_p (dstmode, srcmode, 0);
4829 2040879 : if (ic == CODE_FOR_nothing)
4830 1615652 : continue;
4831 :
4832 : /* Skip if the narrowed value isn't exact. */
4833 425227 : if (! exact_real_truncate (srcmode, r))
4834 52640 : continue;
4835 :
4836 372587 : trunc_y = const_double_from_real_value (*r, srcmode);
4837 :
4838 372587 : if (targetm.legitimate_constant_p (srcmode, trunc_y))
4839 : {
4840 : /* Skip if the target needs extra instructions to perform
4841 : the extension. */
4842 368618 : if (!insn_operand_matches (ic, 1, trunc_y))
4843 3995 : continue;
4844 : /* This is valid, but may not be cheaper than the original. */
4845 364623 : newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4846 : dstmode, speed);
4847 364623 : if (oldcost < newcost)
4848 295205 : continue;
4849 : }
4850 3969 : else if (float_extend_from_mem[dstmode][srcmode])
4851 : {
4852 0 : trunc_y = force_const_mem (srcmode, trunc_y);
4853 : /* This is valid, but may not be cheaper than the original. */
4854 0 : newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4855 : dstmode, speed);
4856 0 : if (oldcost < newcost)
4857 0 : continue;
4858 0 : trunc_y = validize_mem (trunc_y);
4859 : }
4860 : else
4861 3969 : continue;
4862 :
4863 : /* For CSE's benefit, force the compressed constant pool entry
4864 : into a new pseudo. This constant may be used in different modes,
4865 : and if not, combine will put things back together for us. */
4866 69418 : trunc_y = force_reg (srcmode, trunc_y);
4867 :
4868 : /* If x is a hard register, perform the extension into a pseudo,
4869 : so that e.g. stack realignment code is aware of it. */
4870 69418 : rtx target = x;
4871 69418 : if (REG_P (x) && HARD_REGISTER_P (x))
4872 1 : target = gen_reg_rtx (dstmode);
4873 :
4874 69418 : emit_unop_insn (ic, target, trunc_y, UNKNOWN);
4875 69418 : last_insn = get_last_insn ();
4876 :
4877 69418 : if (REG_P (target))
4878 58625 : set_unique_reg_note (last_insn, REG_EQUAL, y);
4879 :
4880 69418 : if (target != x)
4881 1 : return emit_move_insn (x, target);
4882 : return last_insn;
4883 : }
4884 :
4885 : return NULL;
4886 : }
4887 :
4888 : /* Pushing data onto the stack. */
4889 :
4890 : /* Push a block of length SIZE (perhaps variable)
4891 : and return an rtx to address the beginning of the block.
4892 : The value may be virtual_outgoing_args_rtx.
4893 :
4894 : EXTRA is the number of bytes of padding to push in addition to SIZE.
4895 : BELOW nonzero means this padding comes at low addresses;
4896 : otherwise, the padding comes at high addresses. */
4897 :
4898 : rtx
4899 268980 : push_block (rtx size, poly_int64 extra, int below)
4900 : {
4901 268980 : rtx temp;
4902 :
4903 333939 : size = convert_modes (Pmode, ptr_mode, size, 1);
4904 268980 : if (CONSTANT_P (size))
4905 333939 : anti_adjust_stack (plus_constant (Pmode, size, extra));
4906 0 : else if (REG_P (size) && known_eq (extra, 0))
4907 0 : anti_adjust_stack (size);
4908 : else
4909 : {
4910 0 : temp = copy_to_mode_reg (Pmode, size);
4911 0 : if (maybe_ne (extra, 0))
4912 0 : temp = expand_binop (Pmode, add_optab, temp,
4913 0 : gen_int_mode (extra, Pmode),
4914 : temp, 0, OPTAB_LIB_WIDEN);
4915 0 : anti_adjust_stack (temp);
4916 : }
4917 :
4918 268980 : if (STACK_GROWS_DOWNWARD)
4919 : {
4920 268980 : temp = virtual_outgoing_args_rtx;
4921 268980 : if (maybe_ne (extra, 0) && below)
4922 0 : temp = plus_constant (Pmode, temp, extra);
4923 : }
4924 : else
4925 : {
4926 : poly_int64 csize;
4927 : if (poly_int_rtx_p (size, &csize))
4928 : temp = plus_constant (Pmode, virtual_outgoing_args_rtx,
4929 : -csize - (below ? 0 : extra));
4930 : else if (maybe_ne (extra, 0) && !below)
4931 : temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4932 : negate_rtx (Pmode, plus_constant (Pmode, size,
4933 : extra)));
4934 : else
4935 : temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4936 : negate_rtx (Pmode, size));
4937 : }
4938 :
4939 268980 : return memory_address (NARROWEST_INT_MODE, temp);
4940 : }
4941 :
4942 : /* A utility routine that returns the base of an auto-inc memory, or NULL. */
4943 :
4944 : static rtx
4945 2576154 : mem_autoinc_base (rtx mem)
4946 : {
4947 0 : if (MEM_P (mem))
4948 : {
4949 1572521 : rtx addr = XEXP (mem, 0);
4950 1572521 : if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
4951 1029003 : return XEXP (addr, 0);
4952 : }
4953 : return NULL;
4954 : }
4955 :
4956 : /* A utility routine used here, in reload, and in try_split. The insns
4957 : after PREV up to and including LAST are known to adjust the stack,
4958 : with a final value of END_ARGS_SIZE. Iterate backward from LAST
4959 : placing notes as appropriate. PREV may be NULL, indicating the
4960 : entire insn sequence prior to LAST should be scanned.
4961 :
4962 : The set of allowed stack pointer modifications is small:
4963 : (1) One or more auto-inc style memory references (aka pushes),
4964 : (2) One or more addition/subtraction with the SP as destination,
4965 : (3) A single move insn with the SP as destination,
4966 : (4) A call_pop insn,
4967 : (5) Noreturn call insns if !ACCUMULATE_OUTGOING_ARGS.
4968 :
4969 : Insns in the sequence that do not modify the SP are ignored,
4970 : except for noreturn calls.
4971 :
4972 : The return value is the amount of adjustment that can be trivially
4973 : verified, via immediate operand or auto-inc. If the adjustment
4974 : cannot be trivially extracted, the return value is HOST_WIDE_INT_MIN. */
4975 :
4976 : poly_int64
4977 4642846 : find_args_size_adjust (rtx_insn *insn)
4978 : {
4979 4642846 : rtx dest, set, pat;
4980 4642846 : int i;
4981 :
4982 4642846 : pat = PATTERN (insn);
4983 4642846 : set = NULL;
4984 :
4985 : /* Look for a call_pop pattern. */
4986 4642846 : if (CALL_P (insn))
4987 : {
4988 : /* We have to allow non-call_pop patterns for the case
4989 : of emit_single_push_insn of a TLS address. */
4990 2993178 : if (GET_CODE (pat) != PARALLEL)
4991 2978301 : return 0;
4992 :
4993 : /* All call_pop have a stack pointer adjust in the parallel.
4994 : The call itself is always first, and the stack adjust is
4995 : usually last, so search from the end. */
4996 14877 : for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
4997 : {
4998 14877 : set = XVECEXP (pat, 0, i);
4999 14877 : if (GET_CODE (set) != SET)
5000 0 : continue;
5001 14877 : dest = SET_DEST (set);
5002 14877 : if (dest == stack_pointer_rtx)
5003 : break;
5004 : }
5005 : /* We'd better have found the stack pointer adjust. */
5006 14877 : if (i == 0)
5007 0 : return 0;
5008 : /* Fall through to process the extracted SET and DEST
5009 : as if it was a standalone insn. */
5010 : }
5011 1649668 : else if (GET_CODE (pat) == SET)
5012 : set = pat;
5013 259105 : else if ((set = single_set (insn)) != NULL)
5014 : ;
5015 46950 : else if (GET_CODE (pat) == PARALLEL)
5016 : {
5017 : /* ??? Some older ports use a parallel with a stack adjust
5018 : and a store for a PUSH_ROUNDING pattern, rather than a
5019 : PRE/POST_MODIFY rtx. Don't force them to update yet... */
5020 : /* ??? See h8300 and m68k, pushqi1. */
5021 0 : for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
5022 : {
5023 0 : set = XVECEXP (pat, 0, i);
5024 0 : if (GET_CODE (set) != SET)
5025 0 : continue;
5026 0 : dest = SET_DEST (set);
5027 0 : if (dest == stack_pointer_rtx)
5028 : break;
5029 :
5030 : /* We do not expect an auto-inc of the sp in the parallel. */
5031 0 : gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
5032 0 : gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
5033 : != stack_pointer_rtx);
5034 : }
5035 0 : if (i < 0)
5036 0 : return 0;
5037 : }
5038 : else
5039 46950 : return 0;
5040 :
5041 1617595 : dest = SET_DEST (set);
5042 :
5043 : /* Look for direct modifications of the stack pointer. */
5044 1617595 : if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
5045 : {
5046 : /* Look for a trivial adjustment, otherwise assume nothing. */
5047 : /* Note that the SPU restore_stack_block pattern refers to
5048 : the stack pointer in V4SImode. Consider that non-trivial. */
5049 329518 : poly_int64 offset;
5050 329518 : if (SCALAR_INT_MODE_P (GET_MODE (dest))
5051 329518 : && strip_offset (SET_SRC (set), &offset) == stack_pointer_rtx)
5052 327077 : return offset;
5053 : /* ??? Reload can generate no-op moves, which will be cleaned
5054 : up later. Recognize it and continue searching. */
5055 2441 : else if (rtx_equal_p (dest, SET_SRC (set)))
5056 0 : return 0;
5057 : else
5058 2441 : return HOST_WIDE_INT_MIN;
5059 : }
5060 : else
5061 : {
5062 1288077 : rtx mem, addr;
5063 :
5064 : /* Otherwise only think about autoinc patterns. */
5065 2329693 : if (mem_autoinc_base (dest) == stack_pointer_rtx)
5066 : {
5067 920217 : mem = dest;
5068 1273705 : gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
5069 : != stack_pointer_rtx);
5070 : }
5071 545277 : else if (mem_autoinc_base (SET_SRC (set)) == stack_pointer_rtx)
5072 : mem = SET_SRC (set);
5073 : else
5074 259074 : return 0;
5075 :
5076 1029003 : addr = XEXP (mem, 0);
5077 1029003 : switch (GET_CODE (addr))
5078 : {
5079 108786 : case PRE_INC:
5080 108786 : case POST_INC:
5081 217572 : return GET_MODE_SIZE (GET_MODE (mem));
5082 902156 : case PRE_DEC:
5083 902156 : case POST_DEC:
5084 1804312 : return -GET_MODE_SIZE (GET_MODE (mem));
5085 18061 : case PRE_MODIFY:
5086 18061 : case POST_MODIFY:
5087 18061 : addr = XEXP (addr, 1);
5088 18061 : gcc_assert (GET_CODE (addr) == PLUS);
5089 18061 : gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
5090 18061 : return rtx_to_poly_int64 (XEXP (addr, 1));
5091 0 : default:
5092 0 : gcc_unreachable ();
5093 : }
5094 : }
5095 : }
5096 :
5097 : poly_int64
5098 667438 : fixup_args_size_notes (rtx_insn *prev, rtx_insn *last,
5099 : poly_int64 end_args_size)
5100 : {
5101 667438 : poly_int64 args_size = end_args_size;
5102 667438 : bool saw_unknown = false;
5103 667438 : rtx_insn *insn;
5104 :
5105 1903849 : for (insn = last; insn != prev; insn = PREV_INSN (insn))
5106 : {
5107 1236411 : if (!NONDEBUG_INSN_P (insn))
5108 0 : continue;
5109 :
5110 : /* We might have existing REG_ARGS_SIZE notes, e.g. when pushing
5111 : a call argument containing a TLS address that itself requires
5112 : a call to __tls_get_addr. The handling of stack_pointer_delta
5113 : in emit_single_push_insn is supposed to ensure that any such
5114 : notes are already correct. */
5115 1236411 : rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
5116 1236411 : gcc_assert (!note || known_eq (args_size, get_args_size (note)));
5117 :
5118 1236411 : poly_int64 this_delta = find_args_size_adjust (insn);
5119 1236411 : if (known_eq (this_delta, 0))
5120 : {
5121 607803 : if (!CALL_P (insn)
5122 9 : || ACCUMULATE_OUTGOING_ARGS
5123 303915 : || find_reg_note (insn, REG_NORETURN, NULL_RTX) == NULL_RTX)
5124 303897 : continue;
5125 : }
5126 :
5127 932514 : gcc_assert (!saw_unknown);
5128 932514 : if (known_eq (this_delta, HOST_WIDE_INT_MIN))
5129 2419 : saw_unknown = true;
5130 :
5131 932514 : if (!note)
5132 932514 : add_args_size_note (insn, args_size);
5133 932514 : if (STACK_GROWS_DOWNWARD)
5134 1865028 : this_delta = -poly_uint64 (this_delta);
5135 :
5136 932514 : if (saw_unknown)
5137 : args_size = HOST_WIDE_INT_MIN;
5138 : else
5139 1236411 : args_size -= this_delta;
5140 : }
5141 :
5142 667438 : return args_size;
5143 : }
5144 :
5145 : #ifdef PUSH_ROUNDING
5146 : /* Emit single push insn. */
5147 :
5148 : static void
5149 1847231 : emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
5150 : {
5151 1847231 : rtx dest_addr;
5152 3694462 : poly_int64 rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
5153 1847231 : rtx dest;
5154 1847231 : enum insn_code icode;
5155 :
5156 : /* If there is push pattern, use it. Otherwise try old way of throwing
5157 : MEM representing push operation to move expander. */
5158 1847231 : icode = optab_handler (push_optab, mode);
5159 1847231 : if (icode != CODE_FOR_nothing)
5160 : {
5161 0 : class expand_operand ops[1];
5162 :
5163 0 : create_input_operand (&ops[0], x, mode);
5164 0 : if (maybe_expand_insn (icode, 1, ops))
5165 0 : return;
5166 : }
5167 3694462 : if (known_eq (GET_MODE_SIZE (mode), rounded_size))
5168 3189031 : dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
5169 : /* If we are to pad downward, adjust the stack pointer first and
5170 : then store X into the stack location using an offset. This is
5171 : because emit_move_insn does not know how to pad; it does not have
5172 : access to type. */
5173 104835 : else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
5174 : {
5175 0 : emit_move_insn (stack_pointer_rtx,
5176 0 : expand_binop (Pmode,
5177 : STACK_GROWS_DOWNWARD ? sub_optab
5178 : : add_optab,
5179 : stack_pointer_rtx,
5180 0 : gen_int_mode (rounded_size, Pmode),
5181 : NULL_RTX, 0, OPTAB_LIB_WIDEN));
5182 :
5183 0 : poly_int64 offset = rounded_size - GET_MODE_SIZE (mode);
5184 0 : if (STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_DEC)
5185 : /* We have already decremented the stack pointer, so get the
5186 : previous value. */
5187 : offset += rounded_size;
5188 :
5189 0 : if (!STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_INC)
5190 : /* We have already incremented the stack pointer, so get the
5191 : previous value. */
5192 : offset -= rounded_size;
5193 :
5194 0 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, offset);
5195 : }
5196 : else
5197 : {
5198 : if (STACK_GROWS_DOWNWARD)
5199 : /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */
5200 105409 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
5201 : else
5202 : /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */
5203 : dest_addr = plus_constant (Pmode, stack_pointer_rtx, rounded_size);
5204 :
5205 105409 : dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
5206 : }
5207 :
5208 1847231 : dest = gen_rtx_MEM (mode, dest_addr);
5209 :
5210 1847231 : if (type != 0)
5211 : {
5212 1847184 : set_mem_attributes (dest, type, 1);
5213 :
5214 1847184 : if (cfun->tail_call_marked)
5215 : /* Function incoming arguments may overlap with sibling call
5216 : outgoing arguments and we cannot allow reordering of reads
5217 : from function arguments with stores to outgoing arguments
5218 : of sibling calls. */
5219 142776 : set_mem_alias_set (dest, 0);
5220 : }
5221 1847231 : emit_move_insn (dest, x);
5222 : }
5223 :
5224 : /* Emit and annotate a single push insn. */
5225 :
5226 : static void
5227 1847231 : emit_single_push_insn (machine_mode mode, rtx x, tree type)
5228 : {
5229 1847231 : poly_int64 delta, old_delta = stack_pointer_delta;
5230 1847231 : rtx_insn *prev = get_last_insn ();
5231 1847231 : rtx_insn *last;
5232 :
5233 1847231 : emit_single_push_insn_1 (mode, x, type);
5234 :
5235 : /* Adjust stack_pointer_delta to describe the situation after the push
5236 : we just performed. Note that we must do this after the push rather
5237 : than before the push in case calculating X needs pushes and pops of
5238 : its own (e.g. if calling __tls_get_addr). The REG_ARGS_SIZE notes
5239 : for such pushes and pops must not include the effect of the future
5240 : push of X. */
5241 3694462 : stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
5242 :
5243 1847231 : last = get_last_insn ();
5244 :
5245 : /* Notice the common case where we emitted exactly one insn. */
5246 1847231 : if (PREV_INSN (last) == prev)
5247 : {
5248 1736101 : add_args_size_note (last, stack_pointer_delta);
5249 1736101 : return;
5250 : }
5251 :
5252 111130 : delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
5253 111130 : gcc_assert (known_eq (delta, HOST_WIDE_INT_MIN)
5254 : || known_eq (delta, old_delta));
5255 : }
5256 : #endif
5257 :
5258 : /* If reading SIZE bytes from X will end up reading from
5259 : Y return the number of bytes that overlap. Return -1
5260 : if there is no overlap or -2 if we can't determine
5261 : (for example when X and Y have different base registers). */
5262 :
5263 : static int
5264 0 : memory_load_overlap (rtx x, rtx y, HOST_WIDE_INT size)
5265 : {
5266 0 : rtx tmp = plus_constant (Pmode, x, size);
5267 0 : rtx sub = simplify_gen_binary (MINUS, Pmode, tmp, y);
5268 :
5269 0 : if (!CONST_INT_P (sub))
5270 : return -2;
5271 :
5272 0 : HOST_WIDE_INT val = INTVAL (sub);
5273 :
5274 0 : return IN_RANGE (val, 1, size) ? val : -1;
5275 : }
5276 :
5277 : /* Generate code to push X onto the stack, assuming it has mode MODE and
5278 : type TYPE.
5279 : MODE is redundant except when X is a CONST_INT (since they don't
5280 : carry mode info).
5281 : SIZE is an rtx for the size of data to be copied (in bytes),
5282 : needed only if X is BLKmode.
5283 : Return true if successful. May return false if asked to push a
5284 : partial argument during a sibcall optimization (as specified by
5285 : SIBCALL_P) and the incoming and outgoing pointers cannot be shown
5286 : to not overlap.
5287 :
5288 : ALIGN (in bits) is maximum alignment we can assume.
5289 :
5290 : If PARTIAL and REG are both nonzero, then copy that many of the first
5291 : bytes of X into registers starting with REG, and push the rest of X.
5292 : The amount of space pushed is decreased by PARTIAL bytes.
5293 : REG must be a hard register in this case.
5294 : If REG is zero but PARTIAL is not, take any all others actions for an
5295 : argument partially in registers, but do not actually load any
5296 : registers.
5297 :
5298 : EXTRA is the amount in bytes of extra space to leave next to this arg.
5299 : This is ignored if an argument block has already been allocated.
5300 :
5301 : On a machine that lacks real push insns, ARGS_ADDR is the address of
5302 : the bottom of the argument block for this call. We use indexing off there
5303 : to store the arg. On machines with push insns, ARGS_ADDR is 0 when a
5304 : argument block has not been preallocated.
5305 :
5306 : ARGS_SO_FAR is the size of args previously pushed for this call.
5307 :
5308 : REG_PARM_STACK_SPACE is nonzero if functions require stack space
5309 : for arguments passed in registers. If nonzero, it will be the number
5310 : of bytes required. */
5311 :
5312 : bool
5313 2171651 : emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
5314 : unsigned int align, int partial, rtx reg, poly_int64 extra,
5315 : rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
5316 : rtx alignment_pad, bool sibcall_p)
5317 : {
5318 2171651 : rtx xinner;
5319 2171651 : pad_direction stack_direction
5320 : = STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
5321 :
5322 : /* Decide where to pad the argument: PAD_DOWNWARD for below,
5323 : PAD_UPWARD for above, or PAD_NONE for don't pad it.
5324 : Default is below for small data on big-endian machines; else above. */
5325 2171651 : pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
5326 :
5327 : /* Invert direction if stack is post-decrement.
5328 : FIXME: why? */
5329 2171651 : if (STACK_PUSH_CODE == POST_DEC)
5330 : if (where_pad != PAD_NONE)
5331 : where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
5332 :
5333 2171651 : xinner = x;
5334 :
5335 2171651 : int nregs = partial / UNITS_PER_WORD;
5336 2171651 : rtx *tmp_regs = NULL;
5337 2171651 : int overlapping = 0;
5338 :
5339 2171651 : if (mode == BLKmode
5340 : || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
5341 : {
5342 : /* Copy a block into the stack, entirely or partially. */
5343 :
5344 269070 : rtx temp;
5345 269070 : int used;
5346 269070 : int offset;
5347 269070 : int skip;
5348 :
5349 269070 : offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
5350 269070 : used = partial - offset;
5351 :
5352 269070 : if (mode != BLKmode)
5353 : {
5354 : /* A value is to be stored in an insufficiently aligned
5355 : stack slot; copy via a suitably aligned slot if
5356 : necessary. */
5357 : size = gen_int_mode (GET_MODE_SIZE (mode), Pmode);
5358 : if (!MEM_P (xinner))
5359 : {
5360 : temp = assign_temp (type, 1, 1);
5361 : emit_move_insn (temp, xinner);
5362 : xinner = temp;
5363 : }
5364 : }
5365 :
5366 269070 : gcc_assert (size);
5367 :
5368 : /* USED is now the # of bytes we need not copy to the stack
5369 : because registers will take care of them. */
5370 :
5371 269070 : if (partial != 0)
5372 0 : xinner = adjust_address (xinner, BLKmode, used);
5373 :
5374 : /* If the partial register-part of the arg counts in its stack size,
5375 : skip the part of stack space corresponding to the registers.
5376 : Otherwise, start copying to the beginning of the stack space,
5377 : by setting SKIP to 0. */
5378 269070 : skip = (reg_parm_stack_space == 0) ? 0 : used;
5379 :
5380 : #ifdef PUSH_ROUNDING
5381 : /* NB: Let the backend known the number of bytes to push and
5382 : decide if push insns should be generated. */
5383 269070 : unsigned int push_size;
5384 269070 : if (CONST_INT_P (size))
5385 269070 : push_size = INTVAL (size);
5386 : else
5387 : push_size = 0;
5388 :
5389 : /* Do it with several push insns if that doesn't take lots of insns
5390 : and if there is no difficulty with push insns that skip bytes
5391 : on the stack for alignment purposes. */
5392 269070 : if (args_addr == 0
5393 269016 : && targetm.calls.push_argument (push_size)
5394 3783 : && CONST_INT_P (size)
5395 3783 : && skip == 0
5396 3783 : && MEM_ALIGN (xinner) >= align
5397 2937 : && can_move_by_pieces ((unsigned) INTVAL (size) - used, align)
5398 : /* Here we avoid the case of a structure whose weak alignment
5399 : forces many pushes of a small amount of data,
5400 : and such small pushes do rounding that causes trouble. */
5401 2937 : && ((!targetm.slow_unaligned_access (word_mode, align))
5402 0 : || align >= BIGGEST_ALIGNMENT
5403 0 : || known_eq (PUSH_ROUNDING (align / BITS_PER_UNIT),
5404 : align / BITS_PER_UNIT))
5405 272007 : && known_eq (PUSH_ROUNDING (INTVAL (size)), INTVAL (size)))
5406 : {
5407 : /* Push padding now if padding above and stack grows down,
5408 : or if padding below and stack grows up.
5409 : But if space already allocated, this has already been done. */
5410 45 : if (maybe_ne (extra, 0)
5411 : && args_addr == 0
5412 0 : && where_pad != PAD_NONE
5413 45 : && where_pad != stack_direction)
5414 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5415 :
5416 45 : move_by_pieces (NULL, xinner, INTVAL (size) - used, align,
5417 : RETURN_BEGIN);
5418 : }
5419 : else
5420 : #endif /* PUSH_ROUNDING */
5421 : {
5422 269025 : rtx target;
5423 :
5424 : /* Otherwise make space on the stack and copy the data
5425 : to the address of that space. */
5426 :
5427 : /* Deduct words put into registers from the size we must copy. */
5428 269025 : if (partial != 0)
5429 : {
5430 0 : if (CONST_INT_P (size))
5431 0 : size = GEN_INT (INTVAL (size) - used);
5432 : else
5433 0 : size = expand_binop (GET_MODE (size), sub_optab, size,
5434 0 : gen_int_mode (used, GET_MODE (size)),
5435 : NULL_RTX, 0, OPTAB_LIB_WIDEN);
5436 : }
5437 :
5438 : /* Get the address of the stack space.
5439 : In this case, we do not deal with EXTRA separately.
5440 : A single stack adjust will do. */
5441 269025 : poly_int64 const_args_so_far;
5442 269025 : if (! args_addr)
5443 : {
5444 268971 : temp = push_block (size, extra, where_pad == PAD_DOWNWARD);
5445 268971 : extra = 0;
5446 : }
5447 54 : else if (poly_int_rtx_p (args_so_far, &const_args_so_far))
5448 72 : temp = memory_address (BLKmode,
5449 : plus_constant (Pmode, args_addr,
5450 : skip + const_args_so_far));
5451 : else
5452 0 : temp = memory_address (BLKmode,
5453 : plus_constant (Pmode,
5454 : gen_rtx_PLUS (Pmode,
5455 : args_addr,
5456 : args_so_far),
5457 : skip));
5458 :
5459 269025 : if (!ACCUMULATE_OUTGOING_ARGS)
5460 : {
5461 : /* If the source is referenced relative to the stack pointer,
5462 : copy it to another register to stabilize it. We do not need
5463 : to do this if we know that we won't be changing sp. */
5464 :
5465 269025 : if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
5466 269025 : || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
5467 268971 : temp = copy_to_reg (temp);
5468 : }
5469 :
5470 269025 : target = gen_rtx_MEM (BLKmode, temp);
5471 :
5472 : /* We do *not* set_mem_attributes here, because incoming arguments
5473 : may overlap with sibling call outgoing arguments and we cannot
5474 : allow reordering of reads from function arguments with stores
5475 : to outgoing arguments of sibling calls. We do, however, want
5476 : to record the alignment of the stack slot. */
5477 : /* ALIGN may well be better aligned than TYPE, e.g. due to
5478 : PARM_BOUNDARY. Assume the caller isn't lying. */
5479 269025 : set_mem_align (target, align);
5480 :
5481 : /* If part should go in registers and pushing to that part would
5482 : overwrite some of the values that need to go into regs, load the
5483 : overlapping values into temporary pseudos to be moved into the hard
5484 : regs at the end after the stack pushing has completed.
5485 : We cannot load them directly into the hard regs here because
5486 : they can be clobbered by the block move expansions.
5487 : See PR 65358. */
5488 :
5489 269025 : if (partial > 0 && reg != 0 && mode == BLKmode
5490 0 : && GET_CODE (reg) != PARALLEL)
5491 : {
5492 0 : overlapping = memory_load_overlap (XEXP (x, 0), temp, partial);
5493 0 : if (overlapping > 0)
5494 : {
5495 0 : gcc_assert (overlapping % UNITS_PER_WORD == 0);
5496 0 : overlapping /= UNITS_PER_WORD;
5497 :
5498 0 : tmp_regs = XALLOCAVEC (rtx, overlapping);
5499 :
5500 0 : for (int i = 0; i < overlapping; i++)
5501 0 : tmp_regs[i] = gen_reg_rtx (word_mode);
5502 :
5503 0 : for (int i = 0; i < overlapping; i++)
5504 0 : emit_move_insn (tmp_regs[i],
5505 0 : operand_subword_force (target, i, mode));
5506 : }
5507 0 : else if (overlapping == -1)
5508 : overlapping = 0;
5509 : /* Could not determine whether there is overlap.
5510 : Fail the sibcall. */
5511 : else
5512 : {
5513 0 : overlapping = 0;
5514 0 : if (sibcall_p)
5515 2171651 : return false;
5516 : }
5517 : }
5518 :
5519 : /* If source is a constant VAR_DECL with a simple constructor,
5520 : store the constructor to the stack instead of moving it. */
5521 269025 : const_tree decl;
5522 269025 : HOST_WIDE_INT sz;
5523 269025 : if (partial == 0
5524 269025 : && MEM_P (xinner)
5525 269025 : && SYMBOL_REF_P (XEXP (xinner, 0))
5526 82600 : && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE
5527 82600 : && VAR_P (decl)
5528 82600 : && TREE_READONLY (decl)
5529 5229 : && !TREE_SIDE_EFFECTS (decl)
5530 5229 : && immediate_const_ctor_p (DECL_INITIAL (decl), 2)
5531 9 : && (sz = int_expr_size (DECL_INITIAL (decl))) > 0
5532 9 : && CONST_INT_P (size)
5533 269034 : && INTVAL (size) == sz)
5534 3 : store_constructor (DECL_INITIAL (decl), target, 0, sz, false);
5535 : else
5536 269022 : emit_block_move (target, xinner, size, BLOCK_OP_CALL_PARM);
5537 : }
5538 : }
5539 1902581 : else if (partial > 0)
5540 : {
5541 : /* Scalar partly in registers. This case is only supported
5542 : for fixed-wdth modes. */
5543 0 : int num_words = GET_MODE_SIZE (mode).to_constant ();
5544 0 : num_words /= UNITS_PER_WORD;
5545 0 : int i;
5546 0 : int not_stack;
5547 : /* # bytes of start of argument
5548 : that we must make space for but need not store. */
5549 0 : int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
5550 0 : int args_offset = INTVAL (args_so_far);
5551 0 : int skip;
5552 :
5553 : /* Push padding now if padding above and stack grows down,
5554 : or if padding below and stack grows up.
5555 : But if space already allocated, this has already been done. */
5556 0 : if (maybe_ne (extra, 0)
5557 0 : && args_addr == 0
5558 0 : && where_pad != PAD_NONE
5559 0 : && where_pad != stack_direction)
5560 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5561 :
5562 : /* If we make space by pushing it, we might as well push
5563 : the real data. Otherwise, we can leave OFFSET nonzero
5564 : and leave the space uninitialized. */
5565 0 : if (args_addr == 0)
5566 0 : offset = 0;
5567 :
5568 : /* Now NOT_STACK gets the number of words that we don't need to
5569 : allocate on the stack. Convert OFFSET to words too. */
5570 0 : not_stack = (partial - offset) / UNITS_PER_WORD;
5571 0 : offset /= UNITS_PER_WORD;
5572 :
5573 : /* If the partial register-part of the arg counts in its stack size,
5574 : skip the part of stack space corresponding to the registers.
5575 : Otherwise, start copying to the beginning of the stack space,
5576 : by setting SKIP to 0. */
5577 0 : skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
5578 :
5579 0 : if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
5580 0 : x = validize_mem (force_const_mem (mode, x));
5581 :
5582 : /* If X is a hard register in a non-integer mode, copy it into a pseudo;
5583 : SUBREGs of such registers are not allowed. */
5584 0 : if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
5585 0 : && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
5586 0 : x = copy_to_reg (x);
5587 :
5588 : /* Loop over all the words allocated on the stack for this arg. */
5589 : /* We can do it by words, because any scalar bigger than a word
5590 : has a size a multiple of a word. */
5591 0 : tree word_mode_type = lang_hooks.types.type_for_mode (word_mode, 1);
5592 0 : for (i = num_words - 1; i >= not_stack; i--)
5593 0 : if (i >= not_stack + offset)
5594 0 : if (!emit_push_insn (operand_subword_force (x, i, mode),
5595 : word_mode, word_mode_type, NULL_RTX, align, 0,
5596 : NULL_RTX, 0, args_addr,
5597 0 : GEN_INT (args_offset + ((i - not_stack + skip)
5598 : * UNITS_PER_WORD)),
5599 : reg_parm_stack_space, alignment_pad, sibcall_p))
5600 2171651 : return false;
5601 : }
5602 : else
5603 : {
5604 1902581 : rtx addr;
5605 1902581 : rtx dest;
5606 :
5607 : /* Push padding now if padding above and stack grows down,
5608 : or if padding below and stack grows up.
5609 : But if space already allocated, this has already been done. */
5610 1902581 : if (maybe_ne (extra, 0)
5611 0 : && args_addr == 0
5612 0 : && where_pad != PAD_NONE
5613 1902581 : && where_pad != stack_direction)
5614 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5615 :
5616 : #ifdef PUSH_ROUNDING
5617 1902581 : if (args_addr == 0 && targetm.calls.push_argument (0))
5618 1847184 : emit_single_push_insn (mode, x, type);
5619 : else
5620 : #endif
5621 : {
5622 63644 : addr = simplify_gen_binary (PLUS, Pmode, args_addr, args_so_far);
5623 55397 : dest = gen_rtx_MEM (mode, memory_address (mode, addr));
5624 :
5625 : /* We do *not* set_mem_attributes here, because incoming arguments
5626 : may overlap with sibling call outgoing arguments and we cannot
5627 : allow reordering of reads from function arguments with stores
5628 : to outgoing arguments of sibling calls. We do, however, want
5629 : to record the alignment of the stack slot. */
5630 : /* ALIGN may well be better aligned than TYPE, e.g. due to
5631 : PARM_BOUNDARY. Assume the caller isn't lying. */
5632 55397 : set_mem_align (dest, align);
5633 :
5634 55397 : emit_move_insn (dest, x);
5635 : }
5636 : }
5637 :
5638 : /* Move the partial arguments into the registers and any overlapping
5639 : values that we moved into the pseudos in tmp_regs. */
5640 2171651 : if (partial > 0 && reg != 0)
5641 : {
5642 : /* Handle calls that pass values in multiple non-contiguous locations.
5643 : The Irix 6 ABI has examples of this. */
5644 0 : if (GET_CODE (reg) == PARALLEL)
5645 0 : emit_group_load (reg, x, type, -1);
5646 : else
5647 : {
5648 0 : gcc_assert (partial % UNITS_PER_WORD == 0);
5649 0 : move_block_to_reg (REGNO (reg), x, nregs - overlapping, mode);
5650 :
5651 0 : for (int i = 0; i < overlapping; i++)
5652 0 : emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg)
5653 0 : + nregs - overlapping + i),
5654 0 : tmp_regs[i]);
5655 :
5656 : }
5657 : }
5658 :
5659 2171651 : if (maybe_ne (extra, 0) && args_addr == 0 && where_pad == stack_direction)
5660 0 : anti_adjust_stack (gen_int_mode (extra, Pmode));
5661 :
5662 2171651 : if (alignment_pad && args_addr == 0)
5663 2116200 : anti_adjust_stack (alignment_pad);
5664 :
5665 : return true;
5666 : }
5667 :
5668 : /* Return X if X can be used as a subtarget in a sequence of arithmetic
5669 : operations. */
5670 :
5671 : static rtx
5672 205435495 : get_subtarget (rtx x)
5673 : {
5674 205435495 : return (optimize
5675 53129735 : || x == 0
5676 : /* Only registers can be subtargets. */
5677 17794248 : || !REG_P (x)
5678 : /* Don't use hard regs to avoid extending their life. */
5679 12102305 : || REGNO (x) < FIRST_PSEUDO_REGISTER
5680 205435495 : ? 0 : x);
5681 : }
5682 :
5683 : /* A subroutine of expand_assignment. Optimize FIELD op= VAL, where
5684 : FIELD is a bitfield. Returns true if the optimization was successful,
5685 : and there's nothing else to do. */
5686 :
5687 : static bool
5688 4799577 : optimize_bitfield_assignment_op (poly_uint64 pbitsize,
5689 : poly_uint64 pbitpos,
5690 : poly_uint64 pbitregion_start,
5691 : poly_uint64 pbitregion_end,
5692 : machine_mode mode1, rtx str_rtx,
5693 : tree to, tree src, bool reverse)
5694 : {
5695 : /* str_mode is not guaranteed to be a scalar type. */
5696 4799577 : machine_mode str_mode = GET_MODE (str_rtx);
5697 4799577 : unsigned int str_bitsize;
5698 4799577 : tree op0, op1;
5699 4799577 : rtx value, result;
5700 4799577 : optab binop;
5701 4799577 : gimple *srcstmt;
5702 4799577 : enum tree_code code;
5703 :
5704 4799577 : unsigned HOST_WIDE_INT bitsize, bitpos, bitregion_start, bitregion_end;
5705 4799577 : if (mode1 != VOIDmode
5706 67225 : || !pbitsize.is_constant (&bitsize)
5707 67225 : || !pbitpos.is_constant (&bitpos)
5708 67225 : || !pbitregion_start.is_constant (&bitregion_start)
5709 67225 : || !pbitregion_end.is_constant (&bitregion_end)
5710 67909 : || bitsize >= BITS_PER_WORD
5711 66954 : || !GET_MODE_BITSIZE (str_mode).is_constant (&str_bitsize)
5712 67638 : || str_bitsize > BITS_PER_WORD
5713 61558 : || TREE_SIDE_EFFECTS (to)
5714 4861006 : || TREE_THIS_VOLATILE (to))
5715 : return false;
5716 :
5717 61429 : STRIP_NOPS (src);
5718 61429 : if (TREE_CODE (src) != SSA_NAME)
5719 : return false;
5720 20191 : if (TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
5721 : return false;
5722 :
5723 18594 : srcstmt = get_gimple_for_ssa_name (src);
5724 18594 : if (!srcstmt
5725 4952 : || !is_gimple_assign (srcstmt)
5726 23546 : || TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
5727 : return false;
5728 :
5729 845 : code = gimple_assign_rhs_code (srcstmt);
5730 :
5731 845 : op0 = gimple_assign_rhs1 (srcstmt);
5732 :
5733 : /* If OP0 is an SSA_NAME, then we want to walk the use-def chain
5734 : to find its initialization. Hopefully the initialization will
5735 : be from a bitfield load. */
5736 845 : if (TREE_CODE (op0) == SSA_NAME)
5737 : {
5738 845 : gimple *op0stmt = get_gimple_for_ssa_name (op0);
5739 :
5740 : /* We want to eventually have OP0 be the same as TO, which
5741 : should be a bitfield. */
5742 845 : if (!op0stmt
5743 775 : || !is_gimple_assign (op0stmt)
5744 1620 : || gimple_assign_rhs_code (op0stmt) != TREE_CODE (to))
5745 : return false;
5746 548 : op0 = gimple_assign_rhs1 (op0stmt);
5747 : }
5748 :
5749 548 : op1 = gimple_assign_rhs2 (srcstmt);
5750 :
5751 548 : if (!operand_equal_p (to, op0, 0))
5752 : return false;
5753 :
5754 463 : if (MEM_P (str_rtx))
5755 : {
5756 422 : unsigned HOST_WIDE_INT offset1;
5757 :
5758 422 : if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
5759 82 : str_bitsize = BITS_PER_WORD;
5760 :
5761 422 : scalar_int_mode best_mode;
5762 422 : if (!get_best_mode (bitsize, bitpos, bitregion_start, bitregion_end,
5763 422 : MEM_ALIGN (str_rtx), str_bitsize, false, &best_mode))
5764 0 : return false;
5765 422 : str_mode = best_mode;
5766 422 : str_bitsize = GET_MODE_BITSIZE (best_mode);
5767 :
5768 422 : offset1 = bitpos;
5769 422 : bitpos %= str_bitsize;
5770 422 : offset1 = (offset1 - bitpos) / BITS_PER_UNIT;
5771 422 : str_rtx = adjust_address (str_rtx, str_mode, offset1);
5772 : }
5773 41 : else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
5774 : return false;
5775 :
5776 : /* If the bit field covers the whole REG/MEM, store_field
5777 : will likely generate better code. */
5778 463 : if (bitsize >= str_bitsize)
5779 : return false;
5780 :
5781 : /* We can't handle fields split across multiple entities. */
5782 463 : if (bitpos + bitsize > str_bitsize)
5783 : return false;
5784 :
5785 463 : if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
5786 0 : bitpos = str_bitsize - bitpos - bitsize;
5787 :
5788 463 : switch (code)
5789 : {
5790 140 : case PLUS_EXPR:
5791 140 : case MINUS_EXPR:
5792 : /* For now, just optimize the case of the topmost bitfield
5793 : where we don't need to do any masking and also
5794 : 1 bit bitfields where xor can be used.
5795 : We might win by one instruction for the other bitfields
5796 : too if insv/extv instructions aren't used, so that
5797 : can be added later. */
5798 140 : if ((reverse || bitpos + bitsize != str_bitsize)
5799 96 : && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
5800 : break;
5801 :
5802 69 : value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
5803 69 : value = convert_modes (str_mode,
5804 69 : TYPE_MODE (TREE_TYPE (op1)), value,
5805 69 : TYPE_UNSIGNED (TREE_TYPE (op1)));
5806 :
5807 : /* We may be accessing data outside the field, which means
5808 : we can alias adjacent data. */
5809 69 : if (MEM_P (str_rtx))
5810 : {
5811 69 : str_rtx = shallow_copy_rtx (str_rtx);
5812 69 : set_mem_alias_set (str_rtx, 0);
5813 69 : set_mem_expr (str_rtx, 0);
5814 : }
5815 :
5816 69 : if (bitsize == 1 && (reverse || bitpos + bitsize != str_bitsize))
5817 : {
5818 25 : value = expand_and (str_mode, value, const1_rtx, NULL);
5819 25 : binop = xor_optab;
5820 : }
5821 : else
5822 44 : binop = code == PLUS_EXPR ? add_optab : sub_optab;
5823 :
5824 69 : value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5825 69 : if (reverse)
5826 0 : value = flip_storage_order (str_mode, value);
5827 69 : result = expand_binop (str_mode, binop, str_rtx,
5828 : value, str_rtx, 1, OPTAB_WIDEN);
5829 69 : if (result != str_rtx)
5830 0 : emit_move_insn (str_rtx, result);
5831 : return true;
5832 :
5833 255 : case BIT_IOR_EXPR:
5834 255 : case BIT_XOR_EXPR:
5835 255 : if (TREE_CODE (op1) != INTEGER_CST)
5836 : break;
5837 97 : value = expand_expr (op1, NULL_RTX, str_mode, EXPAND_NORMAL);
5838 97 : value = convert_modes (str_mode,
5839 97 : TYPE_MODE (TREE_TYPE (op1)), value,
5840 97 : TYPE_UNSIGNED (TREE_TYPE (op1)));
5841 :
5842 : /* We may be accessing data outside the field, which means
5843 : we can alias adjacent data. */
5844 97 : if (MEM_P (str_rtx))
5845 : {
5846 61 : str_rtx = shallow_copy_rtx (str_rtx);
5847 61 : set_mem_alias_set (str_rtx, 0);
5848 61 : set_mem_expr (str_rtx, 0);
5849 : }
5850 :
5851 97 : binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab;
5852 97 : if (bitpos + bitsize != str_bitsize)
5853 : {
5854 55 : rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << bitsize) - 1,
5855 : str_mode);
5856 55 : value = expand_and (str_mode, value, mask, NULL_RTX);
5857 : }
5858 97 : value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5859 97 : if (reverse)
5860 0 : value = flip_storage_order (str_mode, value);
5861 97 : result = expand_binop (str_mode, binop, str_rtx,
5862 : value, str_rtx, 1, OPTAB_WIDEN);
5863 97 : if (result != str_rtx)
5864 0 : emit_move_insn (str_rtx, result);
5865 : return true;
5866 :
5867 : default:
5868 : break;
5869 : }
5870 :
5871 : return false;
5872 : }
5873 :
5874 : /* In the C++ memory model, consecutive bit fields in a structure are
5875 : considered one memory location.
5876 :
5877 : Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
5878 : returns the bit range of consecutive bits in which this COMPONENT_REF
5879 : belongs. The values are returned in *BITSTART and *BITEND. *BITPOS
5880 : and *OFFSET may be adjusted in the process.
5881 :
5882 : If the access does not need to be restricted, 0 is returned in both
5883 : *BITSTART and *BITEND. */
5884 :
5885 : void
5886 935590 : get_bit_range (poly_uint64 *bitstart, poly_uint64 *bitend, tree exp,
5887 : poly_int64 *bitpos, tree *offset)
5888 : {
5889 935590 : poly_int64 bitoffset;
5890 935590 : tree field, repr;
5891 :
5892 935590 : gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
5893 :
5894 935590 : field = TREE_OPERAND (exp, 1);
5895 935590 : repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
5896 : /* If we do not have a DECL_BIT_FIELD_REPRESENTATIVE there is no
5897 : need to limit the range we can access. */
5898 935590 : if (!repr)
5899 : {
5900 65 : *bitstart = *bitend = 0;
5901 65 : return;
5902 : }
5903 :
5904 : /* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is
5905 : part of a larger bit field, then the representative does not serve any
5906 : useful purpose. This can occur in Ada. */
5907 935525 : if (handled_component_p (TREE_OPERAND (exp, 0)))
5908 : {
5909 505436 : machine_mode rmode;
5910 505436 : poly_int64 rbitsize, rbitpos;
5911 505436 : tree roffset;
5912 505436 : int unsignedp, reversep, volatilep = 0;
5913 505436 : get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
5914 : &roffset, &rmode, &unsignedp, &reversep,
5915 : &volatilep);
5916 1010872 : if (!multiple_p (rbitpos, BITS_PER_UNIT))
5917 : {
5918 0 : *bitstart = *bitend = 0;
5919 0 : return;
5920 : }
5921 : }
5922 :
5923 : /* Compute the adjustment to bitpos from the offset of the field
5924 : relative to the representative. DECL_FIELD_OFFSET of field and
5925 : repr are the same by construction if they are not constants,
5926 : see finish_bitfield_layout. */
5927 935525 : poly_uint64 field_offset, repr_offset;
5928 935525 : if (poly_int_tree_p (DECL_FIELD_OFFSET (field), &field_offset)
5929 1871045 : && poly_int_tree_p (DECL_FIELD_OFFSET (repr), &repr_offset))
5930 935520 : bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
5931 : else
5932 : bitoffset = 0;
5933 935525 : bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
5934 935525 : - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
5935 :
5936 : /* If the adjustment is larger than bitpos, we would have a negative bit
5937 : position for the lower bound and this may wreak havoc later. Adjust
5938 : offset and bitpos to make the lower bound non-negative in that case. */
5939 935525 : if (maybe_gt (bitoffset, *bitpos))
5940 : {
5941 9 : poly_int64 adjust_bits = upper_bound (bitoffset, *bitpos) - *bitpos;
5942 9 : poly_int64 adjust_bytes = exact_div (adjust_bits, BITS_PER_UNIT);
5943 :
5944 9 : *bitpos += adjust_bits;
5945 9 : if (*offset == NULL_TREE)
5946 5 : *offset = size_int (-adjust_bytes);
5947 : else
5948 4 : *offset = size_binop (MINUS_EXPR, *offset, size_int (adjust_bytes));
5949 9 : *bitstart = 0;
5950 : }
5951 : else
5952 935516 : *bitstart = *bitpos - bitoffset;
5953 :
5954 935525 : *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1;
5955 : }
5956 :
5957 : /* Returns true if BASE is a DECL that does not reside in memory and
5958 : has non-BLKmode. DECL_RTL must not be a MEM; if
5959 : DECL_RTL was not set yet, return false. */
5960 :
5961 : bool
5962 5550996 : non_mem_decl_p (tree base)
5963 : {
5964 5550996 : if (!DECL_P (base)
5965 5550599 : || TREE_ADDRESSABLE (base)
5966 8013608 : || DECL_MODE (base) == BLKmode)
5967 : return false;
5968 :
5969 1595868 : if (!DECL_RTL_SET_P (base))
5970 : return false;
5971 :
5972 1477127 : return (!MEM_P (DECL_RTL (base)));
5973 : }
5974 :
5975 : /* Returns true if REF refers to an object that does not
5976 : reside in memory and has non-BLKmode. */
5977 :
5978 : bool
5979 12131219 : mem_ref_refers_to_non_mem_p (tree ref)
5980 : {
5981 12131219 : tree base;
5982 :
5983 12131219 : if (TREE_CODE (ref) == MEM_REF
5984 12131219 : || TREE_CODE (ref) == TARGET_MEM_REF)
5985 : {
5986 10597837 : tree addr = TREE_OPERAND (ref, 0);
5987 :
5988 10597837 : if (TREE_CODE (addr) != ADDR_EXPR)
5989 : return false;
5990 :
5991 3991471 : base = TREE_OPERAND (addr, 0);
5992 : }
5993 : else
5994 : base = ref;
5995 :
5996 5524853 : return non_mem_decl_p (base);
5997 : }
5998 :
5999 : /* Helper function of expand_assignment. Check if storing field of
6000 : size BITSIZE at position BITPOS overlaps with the most significant
6001 : bit of TO_RTX, known to be SUBREG_PROMOTED_VAR_P.
6002 : Updating this field requires an explicit extension. */
6003 : static bool
6004 0 : store_field_updates_msb_p (poly_int64 bitpos, poly_int64 bitsize, rtx to_rtx)
6005 : {
6006 0 : return (BYTES_BIG_ENDIAN
6007 : ? maybe_le (bitpos, 0)
6008 0 : : maybe_ge (bitpos + bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))));
6009 : }
6010 :
6011 : /* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL
6012 : is true, try generating a nontemporal store. */
6013 :
6014 : void
6015 18735514 : expand_assignment (tree to, tree from, bool nontemporal)
6016 : {
6017 18735514 : rtx to_rtx = 0;
6018 18735514 : rtx result;
6019 18735514 : machine_mode mode;
6020 18735514 : unsigned int align;
6021 18735514 : enum insn_code icode;
6022 :
6023 : /* Don't crash if the lhs of the assignment was erroneous. */
6024 18735514 : if (TREE_CODE (to) == ERROR_MARK)
6025 : {
6026 0 : expand_normal (from);
6027 0 : return;
6028 : }
6029 :
6030 : /* Optimize away no-op moves without side-effects. */
6031 18735514 : if (operand_equal_p (to, from, 0))
6032 : return;
6033 :
6034 : /* Handle misaligned stores. */
6035 18735359 : mode = TYPE_MODE (TREE_TYPE (to));
6036 18735359 : if ((TREE_CODE (to) == MEM_REF
6037 18735359 : || TREE_CODE (to) == TARGET_MEM_REF
6038 16502718 : || DECL_P (to))
6039 4094859 : && mode != BLKmode
6040 3627954 : && !mem_ref_refers_to_non_mem_p (to)
6041 6505276 : && ((align = get_object_alignment (to))
6042 3252638 : < GET_MODE_ALIGNMENT (mode))
6043 19169469 : && (((icode = optab_handler (movmisalign_optab, mode))
6044 : != CODE_FOR_nothing)
6045 97205 : || targetm.slow_unaligned_access (mode, align)))
6046 : {
6047 336905 : rtx reg, mem;
6048 :
6049 336905 : reg = expand_expr (from, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6050 : /* Handle PARALLEL. */
6051 336905 : reg = maybe_emit_group_store (reg, TREE_TYPE (from));
6052 336905 : reg = force_not_mem (reg);
6053 336905 : mem = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6054 336905 : if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))
6055 0 : reg = flip_storage_order (mode, reg);
6056 :
6057 336905 : if (icode != CODE_FOR_nothing)
6058 : {
6059 336905 : class expand_operand ops[2];
6060 :
6061 336905 : create_fixed_operand (&ops[0], mem);
6062 336905 : create_input_operand (&ops[1], reg, mode);
6063 : /* The movmisalign<mode> pattern cannot fail, else the assignment
6064 : would silently be omitted. */
6065 336905 : expand_insn (icode, 2, ops);
6066 : }
6067 : else
6068 0 : store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg,
6069 : false, false);
6070 : return;
6071 : }
6072 :
6073 : /* Assignment of a structure component needs special treatment
6074 : if the structure component's rtx is not simply a MEM.
6075 : Assignment of an array element at a constant index, and assignment of
6076 : an array element in an unaligned packed structure field, has the same
6077 : problem. Same for (partially) storing into a non-memory object. */
6078 18398454 : if (handled_component_p (to)
6079 13830151 : || (TREE_CODE (to) == MEM_REF
6080 1660068 : && (REF_REVERSE_STORAGE_ORDER (to)
6081 1659988 : || mem_ref_refers_to_non_mem_p (to)))
6082 13720478 : || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
6083 : {
6084 4799708 : machine_mode mode1;
6085 4799708 : poly_int64 bitsize, bitpos;
6086 4799708 : poly_uint64 bitregion_start = 0;
6087 4799708 : poly_uint64 bitregion_end = 0;
6088 4799708 : tree offset;
6089 4799708 : int unsignedp, reversep, volatilep = 0;
6090 4799708 : tree tem;
6091 :
6092 4799708 : push_temp_slots ();
6093 4799708 : tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
6094 : &unsignedp, &reversep, &volatilep);
6095 :
6096 : /* Make sure bitpos is not negative, it can wreak havoc later. */
6097 4799708 : if (maybe_lt (bitpos, 0))
6098 : {
6099 199 : gcc_assert (offset == NULL_TREE);
6100 199 : offset = size_int (bits_to_bytes_round_down (bitpos));
6101 199 : bitpos = num_trailing_bits (bitpos);
6102 : }
6103 :
6104 4799708 : if (TREE_CODE (to) == COMPONENT_REF
6105 4799708 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
6106 85400 : get_bit_range (&bitregion_start, &bitregion_end, to, &bitpos, &offset);
6107 : /* The C++ memory model naturally applies to byte-aligned fields.
6108 : However, if we do not have a DECL_BIT_FIELD_TYPE but BITPOS or
6109 : BITSIZE are not byte-aligned, there is no need to limit the range
6110 : we can access. This can occur with packed structures in Ada. */
6111 4714308 : else if (maybe_gt (bitsize, 0)
6112 4714293 : && multiple_p (bitsize, BITS_PER_UNIT)
6113 9428334 : && multiple_p (bitpos, BITS_PER_UNIT))
6114 : {
6115 4714026 : bitregion_start = bitpos;
6116 4714026 : bitregion_end = bitpos + bitsize - 1;
6117 : }
6118 :
6119 4799708 : to_rtx = expand_expr (tem, NULL_RTX, VOIDmode, EXPAND_WRITE);
6120 :
6121 : /* If the field has a mode, we want to access it in the
6122 : field's mode, not the computed mode.
6123 : If a MEM has VOIDmode (external with incomplete type),
6124 : use BLKmode for it instead. */
6125 4799708 : if (MEM_P (to_rtx))
6126 : {
6127 4108772 : if (mode1 != VOIDmode)
6128 4042266 : to_rtx = adjust_address (to_rtx, mode1, 0);
6129 66506 : else if (GET_MODE (to_rtx) == VOIDmode)
6130 0 : to_rtx = adjust_address (to_rtx, BLKmode, 0);
6131 : }
6132 :
6133 4799708 : rtx stemp = NULL_RTX, old_to_rtx = NULL_RTX;
6134 4799708 : if (offset != 0)
6135 : {
6136 179408 : machine_mode address_mode;
6137 179408 : rtx offset_rtx;
6138 :
6139 179408 : if (!MEM_P (to_rtx))
6140 : {
6141 : /* We can get constant negative offsets into arrays with broken
6142 : user code. Translate this to a trap instead of ICEing. */
6143 5 : if (TREE_CODE (offset) == INTEGER_CST)
6144 : {
6145 2 : expand_builtin_trap ();
6146 2 : to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
6147 : }
6148 : /* Else spill for variable offset to the destination. We expect
6149 : to run into this only for hard registers. */
6150 : else
6151 : {
6152 3 : gcc_assert (VAR_P (tem) && DECL_HARD_REGISTER (tem));
6153 3 : stemp = assign_stack_temp (GET_MODE (to_rtx),
6154 6 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6155 3 : emit_move_insn (stemp, to_rtx);
6156 3 : old_to_rtx = to_rtx;
6157 3 : to_rtx = stemp;
6158 : }
6159 : }
6160 :
6161 179408 : offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, EXPAND_SUM);
6162 179408 : address_mode = get_address_mode (to_rtx);
6163 179408 : if (GET_MODE (offset_rtx) != address_mode)
6164 : {
6165 : /* We cannot be sure that the RTL in offset_rtx is valid outside
6166 : of a memory address context, so force it into a register
6167 : before attempting to convert it to the desired mode. */
6168 224 : offset_rtx = force_operand (offset_rtx, NULL_RTX);
6169 224 : offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
6170 : }
6171 :
6172 : /* If we have an expression in OFFSET_RTX and a non-zero
6173 : byte offset in BITPOS, adding the byte offset before the
6174 : OFFSET_RTX results in better intermediate code, which makes
6175 : later rtl optimization passes perform better.
6176 :
6177 : We prefer intermediate code like this:
6178 :
6179 : r124:DI=r123:DI+0x18
6180 : [r124:DI]=r121:DI
6181 :
6182 : ... instead of ...
6183 :
6184 : r124:DI=r123:DI+0x10
6185 : [r124:DI+0x8]=r121:DI
6186 :
6187 : This is only done for aligned data values, as these can
6188 : be expected to result in single move instructions. */
6189 179408 : poly_int64 bytepos;
6190 179408 : if (mode1 != VOIDmode
6191 179300 : && maybe_ne (bitpos, 0)
6192 47762 : && maybe_gt (bitsize, 0)
6193 227044 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
6194 227044 : && multiple_p (bitpos, bitsize)
6195 95272 : && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
6196 227044 : && MEM_ALIGN (to_rtx) >= GET_MODE_ALIGNMENT (mode1))
6197 : {
6198 47387 : to_rtx = adjust_address (to_rtx, mode1, bytepos);
6199 47387 : bitregion_start = 0;
6200 47387 : if (known_ge (bitregion_end, poly_uint64 (bitpos)))
6201 47387 : bitregion_end -= bitpos;
6202 47387 : bitpos = 0;
6203 : }
6204 :
6205 179408 : to_rtx = offset_address (to_rtx, offset_rtx,
6206 : highest_pow2_factor_for_target (to,
6207 : offset));
6208 : }
6209 :
6210 : /* No action is needed if the target is not a memory and the field
6211 : lies completely outside that target. This can occur if the source
6212 : code contains an out-of-bounds access to a small array. */
6213 4799708 : if (!MEM_P (to_rtx)
6214 690931 : && GET_MODE (to_rtx) != BLKmode
6215 5490639 : && known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (to_rtx))))
6216 : {
6217 3 : expand_normal (from);
6218 3 : result = NULL;
6219 : }
6220 : /* Handle expand_expr of a complex value returning a CONCAT. */
6221 4799705 : else if (GET_CODE (to_rtx) == CONCAT)
6222 : {
6223 122 : machine_mode to_mode = GET_MODE (to_rtx);
6224 122 : gcc_checking_assert (COMPLEX_MODE_P (to_mode));
6225 244 : poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode);
6226 122 : unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode);
6227 122 : if (TYPE_MODE (TREE_TYPE (from)) == to_mode
6228 0 : && known_eq (bitpos, 0)
6229 122 : && known_eq (bitsize, mode_bitsize))
6230 0 : result = store_expr (from, to_rtx, false, nontemporal, reversep);
6231 122 : else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode)
6232 70 : && known_eq (bitsize, inner_bitsize)
6233 192 : && (known_eq (bitpos, 0)
6234 31 : || known_eq (bitpos, inner_bitsize)))
6235 70 : result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)),
6236 : false, nontemporal, reversep);
6237 52 : else if (known_le (bitpos + bitsize, inner_bitsize))
6238 5 : result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
6239 : bitregion_start, bitregion_end,
6240 : mode1, from, get_alias_set (to),
6241 : nontemporal, reversep);
6242 47 : else if (known_ge (bitpos, inner_bitsize))
6243 3 : result = store_field (XEXP (to_rtx, 1), bitsize,
6244 : bitpos - inner_bitsize,
6245 : bitregion_start, bitregion_end,
6246 : mode1, from, get_alias_set (to),
6247 : nontemporal, reversep);
6248 44 : else if (known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize))
6249 : {
6250 37 : result = expand_normal (from);
6251 37 : if (GET_CODE (result) == CONCAT)
6252 : {
6253 0 : to_mode = GET_MODE_INNER (to_mode);
6254 0 : machine_mode from_mode = GET_MODE_INNER (GET_MODE (result));
6255 0 : rtx from_real
6256 0 : = force_subreg (to_mode, XEXP (result, 0), from_mode, 0);
6257 0 : rtx from_imag
6258 0 : = force_subreg (to_mode, XEXP (result, 1), from_mode, 0);
6259 0 : if (!from_real || !from_imag)
6260 0 : goto concat_store_slow;
6261 0 : emit_move_insn (XEXP (to_rtx, 0), from_real);
6262 0 : emit_move_insn (XEXP (to_rtx, 1), from_imag);
6263 : }
6264 : else
6265 : {
6266 37 : machine_mode from_mode
6267 37 : = GET_MODE (result) == VOIDmode
6268 37 : ? TYPE_MODE (TREE_TYPE (from))
6269 37 : : GET_MODE (result);
6270 37 : rtx from_rtx;
6271 37 : if (MEM_P (result))
6272 1 : from_rtx = change_address (result, to_mode, NULL_RTX);
6273 : else
6274 36 : from_rtx = force_subreg (to_mode, result, from_mode, 0);
6275 37 : if (from_rtx)
6276 : {
6277 37 : emit_move_insn (XEXP (to_rtx, 0),
6278 : read_complex_part (from_rtx, false));
6279 37 : emit_move_insn (XEXP (to_rtx, 1),
6280 : read_complex_part (from_rtx, true));
6281 : }
6282 : else
6283 : {
6284 0 : to_mode = GET_MODE_INNER (to_mode);
6285 0 : rtx from_real
6286 0 : = force_subreg (to_mode, result, from_mode, 0);
6287 0 : rtx from_imag
6288 0 : = force_subreg (to_mode, result, from_mode,
6289 0 : GET_MODE_SIZE (to_mode));
6290 0 : if (!from_real || !from_imag)
6291 0 : goto concat_store_slow;
6292 0 : emit_move_insn (XEXP (to_rtx, 0), from_real);
6293 0 : emit_move_insn (XEXP (to_rtx, 1), from_imag);
6294 : }
6295 : }
6296 : }
6297 : else
6298 : {
6299 7 : concat_store_slow:;
6300 7 : rtx temp = assign_stack_temp (GET_MODE (to_rtx),
6301 14 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6302 7 : write_complex_part (temp, XEXP (to_rtx, 0), false, true);
6303 7 : write_complex_part (temp, XEXP (to_rtx, 1), true, false);
6304 7 : result = store_field (temp, bitsize, bitpos,
6305 : bitregion_start, bitregion_end,
6306 : mode1, from, get_alias_set (to),
6307 : nontemporal, reversep);
6308 7 : emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false));
6309 7 : emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
6310 : }
6311 : }
6312 : /* For calls to functions returning variable length structures, if TO_RTX
6313 : is not a MEM, go through a MEM because we must not create temporaries
6314 : of the VLA type. */
6315 4799583 : else if (!MEM_P (to_rtx)
6316 690806 : && TREE_CODE (from) == CALL_EXPR
6317 235 : && COMPLETE_TYPE_P (TREE_TYPE (from))
6318 4799818 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
6319 : {
6320 6 : rtx temp = assign_stack_temp (GET_MODE (to_rtx),
6321 12 : GET_MODE_SIZE (GET_MODE (to_rtx)));
6322 6 : result = store_field (temp, bitsize, bitpos, bitregion_start,
6323 : bitregion_end, mode1, from, get_alias_set (to),
6324 : nontemporal, reversep);
6325 6 : emit_move_insn (to_rtx, temp);
6326 : }
6327 : else
6328 : {
6329 4799577 : if (MEM_P (to_rtx))
6330 : {
6331 : /* If the field is at offset zero, we could have been given the
6332 : DECL_RTX of the parent struct. Don't munge it. */
6333 4108777 : to_rtx = shallow_copy_rtx (to_rtx);
6334 4108777 : set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos);
6335 4108777 : if (volatilep)
6336 8722 : MEM_VOLATILE_P (to_rtx) = 1;
6337 : }
6338 :
6339 4799577 : gcc_checking_assert (known_ge (bitpos, 0));
6340 9599154 : if (optimize_bitfield_assignment_op (bitsize, bitpos,
6341 : bitregion_start, bitregion_end,
6342 : mode1, to_rtx, to, from,
6343 : reversep))
6344 : result = NULL;
6345 4799411 : else if (SUBREG_P (to_rtx)
6346 4799411 : && SUBREG_PROMOTED_VAR_P (to_rtx))
6347 : {
6348 : /* If to_rtx is a promoted subreg, we need to zero or sign
6349 : extend the value afterwards. */
6350 0 : if (TREE_CODE (to) == MEM_REF
6351 0 : && TYPE_MODE (TREE_TYPE (from)) != BLKmode
6352 0 : && !REF_REVERSE_STORAGE_ORDER (to)
6353 0 : && known_eq (bitpos, 0)
6354 0 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))))
6355 0 : result = store_expr (from, to_rtx, 0, nontemporal, false);
6356 : /* Check if the field overlaps the MSB, requiring extension. */
6357 0 : else if (store_field_updates_msb_p (bitpos, bitsize, to_rtx))
6358 : {
6359 0 : scalar_int_mode imode = subreg_unpromoted_mode (to_rtx);
6360 0 : scalar_int_mode omode = subreg_promoted_mode (to_rtx);
6361 0 : rtx to_rtx1 = lowpart_subreg (imode, SUBREG_REG (to_rtx),
6362 : omode);
6363 0 : result = store_field (to_rtx1, bitsize, bitpos,
6364 : bitregion_start, bitregion_end,
6365 : mode1, from, get_alias_set (to),
6366 : nontemporal, reversep);
6367 : /* If the target usually keeps IMODE appropriately
6368 : extended in OMODE it's unsafe to refer to it using
6369 : a SUBREG whilst this invariant doesn't hold. */
6370 0 : if (targetm.mode_rep_extended (imode, omode) != UNKNOWN)
6371 0 : to_rtx1 = simplify_gen_unary (TRUNCATE, imode,
6372 : SUBREG_REG (to_rtx), omode);
6373 0 : convert_move (SUBREG_REG (to_rtx), to_rtx1,
6374 0 : SUBREG_PROMOTED_SIGN (to_rtx));
6375 : }
6376 : else
6377 0 : result = store_field (to_rtx, bitsize, bitpos,
6378 : bitregion_start, bitregion_end,
6379 : mode1, from, get_alias_set (to),
6380 : nontemporal, reversep);
6381 : }
6382 : else
6383 4799411 : result = store_field (to_rtx, bitsize, bitpos,
6384 : bitregion_start, bitregion_end,
6385 : mode1, from, get_alias_set (to),
6386 : nontemporal, reversep);
6387 : /* Move the temporary storage back to the non-MEM_P. */
6388 4799577 : if (stemp)
6389 3 : emit_move_insn (old_to_rtx, stemp);
6390 : }
6391 :
6392 4799708 : if (result)
6393 832245 : preserve_temp_slots (result);
6394 4799708 : pop_temp_slots ();
6395 4799708 : return;
6396 : }
6397 :
6398 : /* If the rhs is a function call and its value is not an aggregate,
6399 : call the function before we start to compute the lhs.
6400 : This is needed for correct code for cases such as
6401 : val = setjmp (buf) on machines where reference to val
6402 : requires loading up part of an address in a separate insn.
6403 :
6404 : Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
6405 : since it might be a promoted variable where the zero- or sign- extension
6406 : needs to be done. Handling this in the normal way is safe because no
6407 : computation is done before the call. The same is true for SSA names. */
6408 2360529 : if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
6409 2161231 : && COMPLETE_TYPE_P (TREE_TYPE (from))
6410 2161231 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
6411 15759977 : && ! (((VAR_P (to)
6412 : || TREE_CODE (to) == PARM_DECL
6413 : || TREE_CODE (to) == RESULT_DECL)
6414 122301 : && REG_P (DECL_RTL (to)))
6415 2049063 : || TREE_CODE (to) == SSA_NAME))
6416 : {
6417 10465 : rtx value;
6418 :
6419 10465 : push_temp_slots ();
6420 10465 : value = expand_normal (from);
6421 :
6422 10465 : if (to_rtx == 0)
6423 10465 : to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6424 :
6425 : /* Handle calls that return values in multiple non-contiguous locations.
6426 : The Irix 6 ABI has examples of this. */
6427 10465 : if (GET_CODE (to_rtx) == PARALLEL)
6428 : {
6429 0 : if (GET_CODE (value) == PARALLEL)
6430 0 : emit_group_move (to_rtx, value);
6431 : else
6432 0 : emit_group_load (to_rtx, value, TREE_TYPE (from),
6433 0 : int_size_in_bytes (TREE_TYPE (from)));
6434 : }
6435 10465 : else if (GET_CODE (value) == PARALLEL)
6436 1957 : emit_group_store (to_rtx, value, TREE_TYPE (from),
6437 1957 : int_size_in_bytes (TREE_TYPE (from)));
6438 8508 : else if (GET_MODE (to_rtx) == BLKmode)
6439 : {
6440 : /* Handle calls that return BLKmode values in registers. */
6441 254 : if (REG_P (value))
6442 254 : copy_blkmode_from_reg (to_rtx, value, TREE_TYPE (from));
6443 : else
6444 0 : emit_block_move (to_rtx, value, expr_size (from), BLOCK_OP_NORMAL);
6445 : }
6446 : else
6447 : {
6448 8254 : if (POINTER_TYPE_P (TREE_TYPE (to)))
6449 0 : value = convert_memory_address_addr_space
6450 0 : (as_a <scalar_int_mode> (GET_MODE (to_rtx)), value,
6451 0 : TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
6452 :
6453 8254 : emit_move_insn (to_rtx, value);
6454 : }
6455 :
6456 10465 : preserve_temp_slots (to_rtx);
6457 10465 : pop_temp_slots ();
6458 10465 : return;
6459 : }
6460 :
6461 : /* Ordinary treatment. Expand TO to get a REG or MEM rtx. */
6462 13588281 : to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_WRITE);
6463 :
6464 : /* Don't move directly into a return register. */
6465 13588281 : if (TREE_CODE (to) == RESULT_DECL
6466 29433 : && (REG_P (to_rtx) || GET_CODE (to_rtx) == PARALLEL))
6467 : {
6468 0 : rtx temp;
6469 :
6470 0 : push_temp_slots ();
6471 :
6472 : /* If the source is itself a return value, it still is in a pseudo at
6473 : this point so we can move it back to the return register directly. */
6474 0 : if (REG_P (to_rtx)
6475 0 : && TYPE_MODE (TREE_TYPE (from)) == BLKmode
6476 0 : && TREE_CODE (from) != CALL_EXPR)
6477 0 : temp = copy_blkmode_to_reg (GET_MODE (to_rtx), from);
6478 : else
6479 0 : temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
6480 :
6481 : /* Handle calls that return values in multiple non-contiguous locations.
6482 : The Irix 6 ABI has examples of this. */
6483 0 : if (GET_CODE (to_rtx) == PARALLEL)
6484 : {
6485 0 : if (GET_CODE (temp) == PARALLEL)
6486 0 : emit_group_move (to_rtx, temp);
6487 : else
6488 0 : emit_group_load (to_rtx, temp, TREE_TYPE (from),
6489 0 : int_size_in_bytes (TREE_TYPE (from)));
6490 : }
6491 0 : else if (temp)
6492 0 : emit_move_insn (to_rtx, temp);
6493 :
6494 0 : preserve_temp_slots (to_rtx);
6495 0 : pop_temp_slots ();
6496 0 : return;
6497 : }
6498 :
6499 : /* In case we are returning the contents of an object which overlaps
6500 : the place the value is being stored, use a safe function when copying
6501 : a value through a pointer into a structure value return block. */
6502 13588281 : if (TREE_CODE (to) == RESULT_DECL
6503 29433 : && TREE_CODE (from) == INDIRECT_REF
6504 0 : && ADDR_SPACE_GENERIC_P
6505 : (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0)))))
6506 0 : && refs_may_alias_p (to, from)
6507 0 : && cfun->returns_struct
6508 13588281 : && !cfun->returns_pcc_struct)
6509 : {
6510 0 : rtx from_rtx, size;
6511 :
6512 0 : push_temp_slots ();
6513 0 : size = expr_size (from);
6514 0 : from_rtx = expand_normal (from);
6515 :
6516 0 : emit_block_move_via_libcall (XEXP (to_rtx, 0), XEXP (from_rtx, 0), size);
6517 :
6518 0 : preserve_temp_slots (to_rtx);
6519 0 : pop_temp_slots ();
6520 0 : return;
6521 : }
6522 :
6523 : /* Compute FROM and store the value in the rtx we got. */
6524 :
6525 13588281 : push_temp_slots ();
6526 13588281 : result = store_expr (from, to_rtx, 0, nontemporal, false);
6527 13588279 : preserve_temp_slots (result);
6528 13588279 : pop_temp_slots ();
6529 13588279 : return;
6530 : }
6531 :
6532 : /* Emits nontemporal store insn that moves FROM to TO. Returns true if this
6533 : succeeded, false otherwise. */
6534 :
6535 : bool
6536 17 : emit_storent_insn (rtx to, rtx from)
6537 : {
6538 17 : class expand_operand ops[2];
6539 17 : machine_mode mode = GET_MODE (to);
6540 17 : enum insn_code code = optab_handler (storent_optab, mode);
6541 :
6542 17 : if (code == CODE_FOR_nothing)
6543 : return false;
6544 :
6545 17 : create_fixed_operand (&ops[0], to);
6546 17 : create_input_operand (&ops[1], from, mode);
6547 17 : return maybe_expand_insn (code, 2, ops);
6548 : }
6549 :
6550 : /* Helper function for store_expr storing of STRING_CST. */
6551 :
6552 : static rtx
6553 80362 : string_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
6554 : fixed_size_mode mode)
6555 : {
6556 80362 : tree str = (tree) data;
6557 :
6558 80362 : gcc_assert (offset >= 0);
6559 80362 : if (offset >= TREE_STRING_LENGTH (str))
6560 3344 : return const0_rtx;
6561 :
6562 77018 : if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
6563 77018 : > (unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (str))
6564 : {
6565 2476 : char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
6566 2476 : size_t l = TREE_STRING_LENGTH (str) - offset;
6567 2476 : memcpy (p, TREE_STRING_POINTER (str) + offset, l);
6568 2476 : memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
6569 2476 : return c_readstr (p, mode, false);
6570 : }
6571 :
6572 74542 : return c_readstr (TREE_STRING_POINTER (str) + offset, mode, false);
6573 : }
6574 :
6575 : /* Helper function for store_expr storing of RAW_DATA_CST. */
6576 :
6577 : static rtx
6578 36 : raw_data_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
6579 : fixed_size_mode mode)
6580 : {
6581 36 : tree cst = (tree) data;
6582 :
6583 36 : gcc_assert (offset >= 0);
6584 36 : if (offset >= RAW_DATA_LENGTH (cst))
6585 0 : return const0_rtx;
6586 :
6587 36 : if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
6588 36 : > (unsigned HOST_WIDE_INT) RAW_DATA_LENGTH (cst))
6589 : {
6590 0 : char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
6591 0 : size_t l = RAW_DATA_LENGTH (cst) - offset;
6592 0 : memcpy (p, RAW_DATA_POINTER (cst) + offset, l);
6593 0 : memset (p + l, '\0', GET_MODE_SIZE (mode) - l);
6594 0 : return c_readstr (p, mode, false);
6595 : }
6596 :
6597 36 : return c_readstr (RAW_DATA_POINTER (cst) + offset, mode, false);
6598 : }
6599 :
6600 : /* Generate code for computing expression EXP,
6601 : and storing the value into TARGET.
6602 :
6603 : If the mode is BLKmode then we may return TARGET itself.
6604 : It turns out that in BLKmode it doesn't cause a problem.
6605 : because C has no operators that could combine two different
6606 : assignments into the same BLKmode object with different values
6607 : with no sequence point. Will other languages need this to
6608 : be more thorough?
6609 :
6610 : If CALL_PARAM_P is nonzero, this is a store into a call param on the
6611 : stack, and block moves may need to be treated specially.
6612 :
6613 : If NONTEMPORAL is true, try using a nontemporal store instruction.
6614 :
6615 : If REVERSE is true, the store is to be done in reverse order. */
6616 :
6617 : rtx
6618 17598205 : store_expr (tree exp, rtx target, int call_param_p,
6619 : bool nontemporal, bool reverse)
6620 : {
6621 17598205 : rtx temp;
6622 17598205 : rtx alt_rtl = NULL_RTX;
6623 17598205 : location_t loc = curr_insn_location ();
6624 17598205 : bool shortened_string_cst = false;
6625 :
6626 17598205 : if (VOID_TYPE_P (TREE_TYPE (exp)))
6627 : {
6628 : /* C++ can generate ?: expressions with a throw expression in one
6629 : branch and an rvalue in the other. Here, we resolve attempts to
6630 : store the throw expression's nonexistent result. */
6631 0 : gcc_assert (!call_param_p);
6632 0 : expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
6633 0 : return NULL_RTX;
6634 : }
6635 17598205 : if (TREE_CODE (exp) == COMPOUND_EXPR)
6636 : {
6637 : /* Perform first part of compound expression, then assign from second
6638 : part. */
6639 0 : expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
6640 : call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6641 0 : return store_expr (TREE_OPERAND (exp, 1), target,
6642 0 : call_param_p, nontemporal, reverse);
6643 : }
6644 17598205 : else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
6645 : {
6646 : /* For conditional expression, get safe form of the target. Then
6647 : test the condition, doing the appropriate assignment on either
6648 : side. This avoids the creation of unnecessary temporaries.
6649 : For non-BLKmode, it is more efficient not to do this. */
6650 :
6651 0 : rtx_code_label *lab1 = gen_label_rtx (), *lab2 = gen_label_rtx ();
6652 :
6653 0 : do_pending_stack_adjust ();
6654 0 : NO_DEFER_POP;
6655 0 : jumpifnot (TREE_OPERAND (exp, 0), lab1,
6656 : profile_probability::uninitialized ());
6657 0 : store_expr (TREE_OPERAND (exp, 1), target, call_param_p,
6658 : nontemporal, reverse);
6659 0 : emit_jump_insn (targetm.gen_jump (lab2));
6660 0 : emit_barrier ();
6661 0 : emit_label (lab1);
6662 0 : store_expr (TREE_OPERAND (exp, 2), target, call_param_p,
6663 : nontemporal, reverse);
6664 0 : emit_label (lab2);
6665 0 : OK_DEFER_POP;
6666 :
6667 0 : return NULL_RTX;
6668 : }
6669 17598205 : else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
6670 : /* If this is a scalar in a register that is stored in a wider mode
6671 : than the declared mode, compute the result into its declared mode
6672 : and then convert to the wider mode. Our value is the computed
6673 : expression. */
6674 : {
6675 7 : rtx inner_target = 0;
6676 7 : scalar_int_mode outer_mode = subreg_unpromoted_mode (target);
6677 7 : scalar_int_mode inner_mode = subreg_promoted_mode (target);
6678 :
6679 : /* We can do the conversion inside EXP, which will often result
6680 : in some optimizations. Do the conversion in two steps: first
6681 : change the signedness, if needed, then the extend. But don't
6682 : do this if the type of EXP is a subtype of something else
6683 : since then the conversion might involve more than just
6684 : converting modes. */
6685 14 : if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
6686 0 : && TREE_TYPE (TREE_TYPE (exp)) == 0
6687 7 : && GET_MODE_PRECISION (outer_mode)
6688 0 : == TYPE_PRECISION (TREE_TYPE (exp)))
6689 : {
6690 0 : if (!SUBREG_CHECK_PROMOTED_SIGN (target,
6691 : TYPE_UNSIGNED (TREE_TYPE (exp))))
6692 : {
6693 : /* Some types, e.g. Fortran's logical*4, won't have a signed
6694 : version, so use the mode instead. */
6695 0 : tree ntype
6696 : = (signed_or_unsigned_type_for
6697 0 : (SUBREG_PROMOTED_SIGN (target), TREE_TYPE (exp)));
6698 0 : if (ntype == NULL)
6699 0 : ntype = lang_hooks.types.type_for_mode
6700 0 : (TYPE_MODE (TREE_TYPE (exp)),
6701 0 : SUBREG_PROMOTED_SIGN (target));
6702 :
6703 0 : exp = fold_convert_loc (loc, ntype, exp);
6704 : }
6705 :
6706 0 : exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode
6707 0 : (inner_mode, SUBREG_PROMOTED_SIGN (target)),
6708 : exp);
6709 :
6710 0 : inner_target = SUBREG_REG (target);
6711 : }
6712 :
6713 7 : temp = expand_expr (exp, inner_target, VOIDmode,
6714 : call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6715 :
6716 :
6717 : /* If TEMP is a VOIDmode constant, use convert_modes to make
6718 : sure that we properly convert it. */
6719 7 : if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
6720 : {
6721 0 : temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6722 0 : temp, SUBREG_PROMOTED_SIGN (target));
6723 0 : temp = convert_modes (inner_mode, outer_mode, temp,
6724 0 : SUBREG_PROMOTED_SIGN (target));
6725 0 : }
6726 7 : else if (!SCALAR_INT_MODE_P (GET_MODE (temp)))
6727 0 : temp = convert_modes (outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6728 0 : temp, SUBREG_PROMOTED_SIGN (target));
6729 :
6730 21 : convert_move (SUBREG_REG (target), temp,
6731 7 : SUBREG_PROMOTED_SIGN (target));
6732 :
6733 7 : return NULL_RTX;
6734 : }
6735 17598198 : else if ((TREE_CODE (exp) == STRING_CST
6736 17590902 : || (TREE_CODE (exp) == MEM_REF
6737 1360708 : && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
6738 443685 : && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
6739 : == STRING_CST
6740 6545 : && integer_zerop (TREE_OPERAND (exp, 1))))
6741 13841 : && !nontemporal && !call_param_p
6742 17612039 : && MEM_P (target))
6743 : {
6744 : /* Optimize initialization of an array with a STRING_CST. */
6745 13823 : HOST_WIDE_INT exp_len, str_copy_len;
6746 13823 : rtx dest_mem;
6747 13823 : tree str = TREE_CODE (exp) == STRING_CST
6748 13823 : ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6749 :
6750 13823 : exp_len = int_expr_size (exp);
6751 13823 : if (exp_len <= 0)
6752 0 : goto normal_expr;
6753 :
6754 13823 : if (TREE_STRING_LENGTH (str) <= 0)
6755 0 : goto normal_expr;
6756 :
6757 27646 : if (can_store_by_pieces (exp_len, string_cst_read_str, (void *) str,
6758 13823 : MEM_ALIGN (target), false))
6759 : {
6760 13627 : store_by_pieces (target, exp_len, string_cst_read_str, (void *) str,
6761 13627 : MEM_ALIGN (target), false, RETURN_BEGIN);
6762 13627 : return NULL_RTX;
6763 : }
6764 :
6765 196 : str_copy_len = TREE_STRING_LENGTH (str);
6766 :
6767 : /* Trailing NUL bytes in EXP will be handled by the call to
6768 : clear_storage, which is more efficient than copying them from
6769 : the STRING_CST, so trim those from STR_COPY_LEN. */
6770 329 : while (str_copy_len)
6771 : {
6772 276 : if (TREE_STRING_POINTER (str)[str_copy_len - 1])
6773 : break;
6774 133 : str_copy_len--;
6775 : }
6776 :
6777 196 : if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
6778 : {
6779 196 : str_copy_len += STORE_MAX_PIECES - 1;
6780 196 : str_copy_len &= ~(STORE_MAX_PIECES - 1);
6781 : }
6782 196 : if (str_copy_len >= exp_len)
6783 135 : goto normal_expr;
6784 :
6785 122 : if (!can_store_by_pieces (str_copy_len, string_cst_read_str,
6786 61 : (void *) str, MEM_ALIGN (target), false))
6787 2 : goto normal_expr;
6788 :
6789 59 : dest_mem = store_by_pieces (target, str_copy_len, string_cst_read_str,
6790 59 : (void *) str, MEM_ALIGN (target), false,
6791 : RETURN_END);
6792 59 : clear_storage (adjust_address_1 (dest_mem, BLKmode, 0, 1, 1, 0,
6793 59 : exp_len - str_copy_len),
6794 : GEN_INT (exp_len - str_copy_len), BLOCK_OP_NORMAL);
6795 59 : return NULL_RTX;
6796 : }
6797 : else
6798 : {
6799 17584512 : rtx tmp_target;
6800 :
6801 17584512 : normal_expr:
6802 : /* If we want to use a nontemporal or a reverse order store, force the
6803 : value into a register first. */
6804 17584512 : tmp_target = nontemporal || reverse ? NULL_RTX : target;
6805 17584512 : tree rexp = exp;
6806 17584512 : if (TREE_CODE (exp) == STRING_CST
6807 20 : && tmp_target == target
6808 20 : && GET_MODE (target) == BLKmode
6809 17584532 : && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
6810 : {
6811 20 : rtx size = expr_size (exp);
6812 20 : if (CONST_INT_P (size)
6813 20 : && size != const0_rtx
6814 40 : && (UINTVAL (size)
6815 20 : > ((unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (exp) + 32)))
6816 : {
6817 : /* If the STRING_CST has much larger array type than
6818 : TREE_STRING_LENGTH, only emit the TREE_STRING_LENGTH part of
6819 : it into the rodata section as the code later on will use
6820 : memset zero for the remainder anyway. See PR95052. */
6821 2 : tmp_target = NULL_RTX;
6822 2 : rexp = copy_node (exp);
6823 2 : tree index
6824 2 : = build_index_type (size_int (TREE_STRING_LENGTH (exp) - 1));
6825 2 : TREE_TYPE (rexp) = build_array_type (TREE_TYPE (TREE_TYPE (exp)),
6826 : index);
6827 2 : shortened_string_cst = true;
6828 : }
6829 : }
6830 35169024 : temp = expand_expr_real (rexp, tmp_target, GET_MODE (target),
6831 : (call_param_p
6832 : ? EXPAND_STACK_PARM : EXPAND_NORMAL),
6833 : &alt_rtl, false);
6834 17584510 : if (shortened_string_cst)
6835 : {
6836 2 : gcc_assert (MEM_P (temp));
6837 2 : temp = change_address (temp, BLKmode, NULL_RTX);
6838 : }
6839 : }
6840 :
6841 : /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
6842 : the same as that of TARGET, adjust the constant. This is needed, for
6843 : example, in case it is a CONST_DOUBLE or CONST_WIDE_INT and we want
6844 : only a word-sized value. */
6845 3633841 : if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
6846 2623384 : && TREE_CODE (exp) != ERROR_MARK
6847 20207894 : && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
6848 : {
6849 0 : gcc_assert (!shortened_string_cst);
6850 0 : if (GET_MODE_CLASS (GET_MODE (target))
6851 0 : != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp)))
6852 0 : && known_eq (GET_MODE_BITSIZE (GET_MODE (target)),
6853 : GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))))
6854 : {
6855 0 : rtx t = simplify_gen_subreg (GET_MODE (target), temp,
6856 0 : TYPE_MODE (TREE_TYPE (exp)), 0);
6857 0 : if (t)
6858 0 : temp = t;
6859 : }
6860 0 : if (GET_MODE (temp) == VOIDmode)
6861 0 : temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
6862 0 : temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6863 : }
6864 :
6865 : /* If value was not generated in the target, store it there.
6866 : Convert the value to TARGET's type first if necessary and emit the
6867 : pending incrementations that have been queued when expanding EXP.
6868 : Note that we cannot emit the whole queue blindly because this will
6869 : effectively disable the POST_INC optimization later.
6870 :
6871 : If TEMP and TARGET compare equal according to rtx_equal_p, but
6872 : one or both of them are volatile memory refs, we have to distinguish
6873 : two cases:
6874 : - expand_expr has used TARGET. In this case, we must not generate
6875 : another copy. This can be detected by TARGET being equal according
6876 : to == .
6877 : - expand_expr has not used TARGET - that means that the source just
6878 : happens to have the same RTX form. Since temp will have been created
6879 : by expand_expr, it will compare unequal according to == .
6880 : We must generate a copy in this case, to reach the correct number
6881 : of volatile memory references. */
6882 :
6883 17584510 : if ((! rtx_equal_p (temp, target)
6884 3133118 : || (temp != target && (side_effects_p (temp)
6885 47135 : || side_effects_p (target)
6886 47135 : || (MEM_P (temp)
6887 46656 : && !mems_same_for_tbaa_p (temp, target)))))
6888 14451396 : && TREE_CODE (exp) != ERROR_MARK
6889 : /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
6890 : but TARGET is not valid memory reference, TEMP will differ
6891 : from TARGET although it is really the same location. */
6892 14451396 : && !(alt_rtl
6893 1985462 : && rtx_equal_p (alt_rtl, target)
6894 1 : && !side_effects_p (alt_rtl)
6895 0 : && !side_effects_p (target))
6896 : /* If there's nothing to copy, don't bother. Don't call
6897 : expr_size unless necessary, because some front-ends (C++)
6898 : expr_size-hook must not be given objects that are not
6899 : supposed to be bit-copied or bit-initialized. */
6900 32035906 : && expr_size (exp) != const0_rtx)
6901 : {
6902 14451396 : if (GET_MODE (temp) != GET_MODE (target) && GET_MODE (temp) != VOIDmode)
6903 : {
6904 1378 : gcc_assert (!shortened_string_cst);
6905 1378 : if (GET_MODE (target) == BLKmode)
6906 : {
6907 : /* Handle calls that return BLKmode values in registers. */
6908 2 : if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
6909 2 : copy_blkmode_from_reg (target, temp, TREE_TYPE (exp));
6910 : else
6911 0 : store_bit_field (target,
6912 0 : rtx_to_poly_int64 (expr_size (exp))
6913 0 : * BITS_PER_UNIT,
6914 : 0, 0, 0, GET_MODE (temp), temp, reverse,
6915 : false);
6916 : }
6917 : else
6918 1376 : convert_move (target, temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6919 : }
6920 :
6921 14450018 : else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
6922 : {
6923 : /* Handle copying a string constant into an array. The string
6924 : constant may be shorter than the array. So copy just the string's
6925 : actual length, and clear the rest. First get the size of the data
6926 : type of the string, which is actually the size of the target. */
6927 20 : rtx size = expr_size (exp);
6928 :
6929 20 : if (CONST_INT_P (size)
6930 20 : && INTVAL (size) < TREE_STRING_LENGTH (exp))
6931 0 : emit_block_move (target, temp, size,
6932 : (call_param_p
6933 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6934 : else
6935 : {
6936 20 : machine_mode pointer_mode
6937 20 : = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
6938 20 : machine_mode address_mode = get_address_mode (target);
6939 :
6940 : /* Compute the size of the data to copy from the string. */
6941 20 : tree copy_size
6942 20 : = size_binop_loc (loc, MIN_EXPR,
6943 : make_tree (sizetype, size),
6944 20 : size_int (TREE_STRING_LENGTH (exp)));
6945 20 : rtx copy_size_rtx
6946 20 : = expand_expr (copy_size, NULL_RTX, VOIDmode,
6947 : (call_param_p
6948 : ? EXPAND_STACK_PARM : EXPAND_NORMAL));
6949 20 : rtx_code_label *label = 0;
6950 :
6951 : /* Copy that much. */
6952 60 : copy_size_rtx = convert_to_mode (pointer_mode, copy_size_rtx,
6953 20 : TYPE_UNSIGNED (sizetype));
6954 40 : emit_block_move (target, temp, copy_size_rtx,
6955 : (call_param_p
6956 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6957 :
6958 : /* Figure out how much is left in TARGET that we have to clear.
6959 : Do all calculations in pointer_mode. */
6960 20 : poly_int64 const_copy_size;
6961 20 : if (poly_int_rtx_p (copy_size_rtx, &const_copy_size))
6962 : {
6963 20 : size = plus_constant (address_mode, size, -const_copy_size);
6964 20 : target = adjust_address (target, BLKmode, const_copy_size);
6965 : }
6966 : else
6967 : {
6968 0 : size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
6969 : copy_size_rtx, NULL_RTX, 0,
6970 : OPTAB_LIB_WIDEN);
6971 :
6972 0 : if (GET_MODE (copy_size_rtx) != address_mode)
6973 0 : copy_size_rtx = convert_to_mode (address_mode,
6974 : copy_size_rtx,
6975 0 : TYPE_UNSIGNED (sizetype));
6976 :
6977 0 : target = offset_address (target, copy_size_rtx,
6978 : highest_pow2_factor (copy_size));
6979 0 : label = gen_label_rtx ();
6980 0 : emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
6981 0 : GET_MODE (size), 0, label);
6982 : }
6983 :
6984 20 : if (size != const0_rtx)
6985 2 : clear_storage (target, size, BLOCK_OP_NORMAL);
6986 :
6987 20 : if (label)
6988 0 : emit_label (label);
6989 : }
6990 : }
6991 14449998 : else if (shortened_string_cst)
6992 0 : gcc_unreachable ();
6993 : /* Handle calls that return values in multiple non-contiguous locations.
6994 : The Irix 6 ABI has examples of this. */
6995 14449998 : else if (GET_CODE (target) == PARALLEL)
6996 : {
6997 0 : if (GET_CODE (temp) == PARALLEL)
6998 0 : emit_group_move (target, temp);
6999 : else
7000 0 : emit_group_load (target, temp, TREE_TYPE (exp),
7001 0 : int_size_in_bytes (TREE_TYPE (exp)));
7002 : }
7003 14449998 : else if (GET_CODE (temp) == PARALLEL)
7004 0 : emit_group_store (target, temp, TREE_TYPE (exp),
7005 0 : int_size_in_bytes (TREE_TYPE (exp)));
7006 14449998 : else if (GET_MODE (temp) == BLKmode)
7007 603616 : emit_block_move (target, temp, expr_size (exp),
7008 : (call_param_p
7009 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
7010 : /* If we emit a nontemporal store, there is nothing else to do. */
7011 14148190 : else if (nontemporal && emit_storent_insn (target, temp))
7012 : ;
7013 : else
7014 : {
7015 14148173 : if (reverse)
7016 727 : temp = flip_storage_order (GET_MODE (target), temp);
7017 14148173 : temp = force_operand (temp, target);
7018 14148173 : if (temp != target)
7019 14146580 : emit_move_insn (target, temp);
7020 : }
7021 : }
7022 : else
7023 3133114 : gcc_assert (!shortened_string_cst);
7024 :
7025 : return NULL_RTX;
7026 : }
7027 :
7028 : /* Return true if field F of structure TYPE is a flexible array. */
7029 :
7030 : static bool
7031 3943396 : flexible_array_member_p (const_tree f, const_tree type)
7032 : {
7033 3943396 : const_tree tf;
7034 :
7035 3943396 : tf = TREE_TYPE (f);
7036 3943396 : return (DECL_CHAIN (f) == NULL
7037 1082244 : && TREE_CODE (tf) == ARRAY_TYPE
7038 2525 : && TYPE_DOMAIN (tf)
7039 2525 : && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
7040 2525 : && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
7041 2525 : && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
7042 3943435 : && int_size_in_bytes (type) >= 0);
7043 : }
7044 :
7045 : /* If FOR_CTOR_P, return the number of top-level elements that a constructor
7046 : must have in order for it to completely initialize a value of type TYPE.
7047 : Return -1 if the number isn't known.
7048 :
7049 : If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE. */
7050 :
7051 : static HOST_WIDE_INT
7052 3727980 : count_type_elements (const_tree type, bool for_ctor_p)
7053 : {
7054 3729320 : switch (TREE_CODE (type))
7055 : {
7056 155455 : case ARRAY_TYPE:
7057 155455 : {
7058 155455 : tree nelts_minus_one;
7059 :
7060 155455 : nelts_minus_one = array_type_nelts_minus_one (type);
7061 155455 : if (nelts_minus_one && tree_fits_uhwi_p (nelts_minus_one))
7062 : {
7063 155444 : unsigned HOST_WIDE_INT n;
7064 :
7065 155444 : n = tree_to_uhwi (nelts_minus_one) + 1;
7066 155444 : if (n == 0 || for_ctor_p)
7067 154104 : return n;
7068 : else
7069 1340 : return n * count_type_elements (TREE_TYPE (type), false);
7070 : }
7071 11 : return for_ctor_p ? -1 : 1;
7072 : }
7073 :
7074 1822868 : case RECORD_TYPE:
7075 1822868 : {
7076 1822868 : unsigned HOST_WIDE_INT n;
7077 1822868 : tree f;
7078 :
7079 1822868 : n = 0;
7080 17319852 : for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7081 15496984 : if (TREE_CODE (f) == FIELD_DECL)
7082 : {
7083 4407404 : if (!for_ctor_p)
7084 464008 : n += count_type_elements (TREE_TYPE (f), false);
7085 3943396 : else if (!flexible_array_member_p (f, type))
7086 : /* Don't count flexible arrays, which are not supposed
7087 : to be initialized. */
7088 3943357 : n += 1;
7089 : }
7090 :
7091 1822868 : return n;
7092 : }
7093 :
7094 3356 : case UNION_TYPE:
7095 3356 : case QUAL_UNION_TYPE:
7096 3356 : {
7097 3356 : tree f;
7098 3356 : HOST_WIDE_INT n, m;
7099 :
7100 3356 : gcc_assert (!for_ctor_p);
7101 : /* Estimate the number of scalars in each field and pick the
7102 : maximum. Other estimates would do instead; the idea is simply
7103 : to make sure that the estimate is not sensitive to the ordering
7104 : of the fields. */
7105 3356 : n = 1;
7106 76281 : for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
7107 72925 : if (TREE_CODE (f) == FIELD_DECL)
7108 : {
7109 68442 : m = count_type_elements (TREE_TYPE (f), false);
7110 : /* If the field doesn't span the whole union, add an extra
7111 : scalar for the rest. */
7112 68442 : if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
7113 68442 : TYPE_SIZE (type)) != 1)
7114 48780 : m++;
7115 68442 : if (n < m)
7116 72925 : n = m;
7117 : }
7118 : return n;
7119 : }
7120 :
7121 : case COMPLEX_TYPE:
7122 : return 2;
7123 :
7124 421 : case VECTOR_TYPE:
7125 421 : {
7126 421 : unsigned HOST_WIDE_INT nelts;
7127 421 : if (TYPE_VECTOR_SUBPARTS (type).is_constant (&nelts))
7128 421 : return nelts;
7129 : else
7130 : return -1;
7131 : }
7132 :
7133 : case INTEGER_TYPE:
7134 : case REAL_TYPE:
7135 : case FIXED_POINT_TYPE:
7136 : case ENUMERAL_TYPE:
7137 : case BOOLEAN_TYPE:
7138 : case POINTER_TYPE:
7139 : case OFFSET_TYPE:
7140 : case REFERENCE_TYPE:
7141 : case NULLPTR_TYPE:
7142 : case OPAQUE_TYPE:
7143 : case BITINT_TYPE:
7144 : return 1;
7145 :
7146 0 : case ERROR_MARK:
7147 0 : return 0;
7148 :
7149 0 : case VOID_TYPE:
7150 0 : case METHOD_TYPE:
7151 0 : case FUNCTION_TYPE:
7152 0 : case LANG_TYPE:
7153 0 : default:
7154 0 : gcc_unreachable ();
7155 : }
7156 : }
7157 :
7158 : /* Helper for categorize_ctor_elements. Identical interface. */
7159 :
7160 : static bool
7161 1550016 : categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
7162 : HOST_WIDE_INT *p_unique_nz_elts,
7163 : HOST_WIDE_INT *p_init_elts,
7164 : ctor_completeness *p_complete)
7165 : {
7166 1550016 : unsigned HOST_WIDE_INT idx;
7167 1550016 : HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
7168 1550016 : tree value, purpose, elt_type;
7169 :
7170 : /* Whether CTOR is a valid constant initializer, in accordance with what
7171 : initializer_constant_valid_p does. If inferred from the constructor
7172 : elements, true until proven otherwise. */
7173 1550016 : bool const_from_elts_p = constructor_static_from_elts_p (ctor);
7174 1550016 : bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
7175 :
7176 1550016 : nz_elts = 0;
7177 1550016 : unique_nz_elts = 0;
7178 1550016 : init_elts = 0;
7179 1550016 : num_fields = 0;
7180 1550016 : elt_type = NULL_TREE;
7181 :
7182 5877670 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
7183 : {
7184 4327654 : HOST_WIDE_INT mult = 1;
7185 :
7186 4327654 : if (purpose && TREE_CODE (purpose) == RANGE_EXPR)
7187 : {
7188 821 : tree lo_index = TREE_OPERAND (purpose, 0);
7189 821 : tree hi_index = TREE_OPERAND (purpose, 1);
7190 :
7191 821 : if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
7192 821 : mult = (tree_to_uhwi (hi_index)
7193 821 : - tree_to_uhwi (lo_index) + 1);
7194 : }
7195 4327654 : num_fields += mult;
7196 4327654 : elt_type = TREE_TYPE (value);
7197 :
7198 4327654 : switch (TREE_CODE (value))
7199 : {
7200 546198 : case CONSTRUCTOR:
7201 546198 : {
7202 546198 : HOST_WIDE_INT nz = 0, unz = 0, ic = 0;
7203 :
7204 546198 : bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &unz,
7205 : &ic, p_complete);
7206 :
7207 546198 : nz_elts += mult * nz;
7208 546198 : unique_nz_elts += unz;
7209 546198 : init_elts += mult * ic;
7210 :
7211 546198 : if (const_from_elts_p && const_p)
7212 333038 : const_p = const_elt_p;
7213 : }
7214 546198 : break;
7215 :
7216 2311554 : case INTEGER_CST:
7217 2311554 : case REAL_CST:
7218 2311554 : case FIXED_CST:
7219 2311554 : if (!initializer_zerop (value))
7220 : {
7221 1691160 : nz_elts += mult;
7222 1691160 : unique_nz_elts++;
7223 : }
7224 2311554 : init_elts += mult;
7225 2311554 : break;
7226 :
7227 6298 : case STRING_CST:
7228 6298 : nz_elts += mult * TREE_STRING_LENGTH (value);
7229 6298 : unique_nz_elts += TREE_STRING_LENGTH (value);
7230 6298 : init_elts += mult * TREE_STRING_LENGTH (value);
7231 6298 : break;
7232 :
7233 166 : case RAW_DATA_CST:
7234 166 : nz_elts += mult * RAW_DATA_LENGTH (value);
7235 166 : unique_nz_elts += RAW_DATA_LENGTH (value);
7236 166 : init_elts += mult * RAW_DATA_LENGTH (value);
7237 166 : num_fields += mult * (RAW_DATA_LENGTH (value) - 1);
7238 166 : break;
7239 :
7240 3234 : case COMPLEX_CST:
7241 3234 : if (!initializer_zerop (TREE_REALPART (value)))
7242 : {
7243 2630 : nz_elts += mult;
7244 2630 : unique_nz_elts++;
7245 : }
7246 3234 : if (!initializer_zerop (TREE_IMAGPART (value)))
7247 : {
7248 2272 : nz_elts += mult;
7249 2272 : unique_nz_elts++;
7250 : }
7251 3234 : init_elts += 2 * mult;
7252 3234 : break;
7253 :
7254 6420 : case VECTOR_CST:
7255 6420 : {
7256 6420 : unsigned int nunits
7257 : = constant_lower_bound
7258 6420 : (TYPE_VECTOR_SUBPARTS (TREE_TYPE (value)));
7259 39931 : for (unsigned int i = 0; i < nunits; ++i)
7260 : {
7261 33511 : tree v = VECTOR_CST_ELT (value, i);
7262 33511 : if (!initializer_zerop (v))
7263 : {
7264 19057 : nz_elts += mult;
7265 19057 : unique_nz_elts++;
7266 : }
7267 33511 : init_elts += mult;
7268 : }
7269 : }
7270 : break;
7271 :
7272 1453784 : default:
7273 1453784 : {
7274 1453784 : HOST_WIDE_INT tc = count_type_elements (elt_type, false);
7275 1453784 : nz_elts += mult * tc;
7276 1453784 : unique_nz_elts += tc;
7277 1453784 : init_elts += mult * tc;
7278 :
7279 1453784 : if (const_from_elts_p && const_p)
7280 599892 : const_p
7281 599892 : = initializer_constant_valid_p (value,
7282 : elt_type,
7283 599892 : TYPE_REVERSE_STORAGE_ORDER
7284 : (TREE_TYPE (ctor)))
7285 : != NULL_TREE;
7286 : }
7287 : break;
7288 : }
7289 : }
7290 :
7291 1550016 : if (!p_complete->sparse && !complete_ctor_at_level_p (TREE_TYPE (ctor),
7292 : num_fields, elt_type))
7293 186651 : p_complete->sparse = true;
7294 1363365 : else if (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE
7295 1363365 : || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)
7296 : {
7297 12112 : if (!p_complete->sparse
7298 7877 : && CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
7299 22193 : && (num_fields
7300 5042 : ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
7301 5039 : TYPE_SIZE (elt_type)) != 1
7302 3 : : type_has_padding_at_level_p (TREE_TYPE (ctor))))
7303 3367 : p_complete->sparse = true;
7304 4510 : else if (!p_complete->sparse && !p_complete->padded_union
7305 17757 : && (num_fields
7306 4506 : ? simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)),
7307 4506 : TYPE_SIZE (elt_type)) != 1
7308 0 : : type_has_padding_at_level_p (TREE_TYPE (ctor))))
7309 380 : p_complete->padded_union = true;
7310 : }
7311 1351253 : else if (!p_complete->sparse
7312 1233435 : && (CONSTRUCTOR_ZERO_PADDING_BITS (ctor)
7313 1214484 : || flag_zero_init_padding_bits == ZERO_INIT_PADDING_BITS_ALL)
7314 1370233 : && type_has_padding_at_level_p (TREE_TYPE (ctor)))
7315 2200 : p_complete->sparse = true;
7316 1231235 : else if (!p_complete->sparse && !p_complete->padded_non_union
7317 2532554 : && type_has_padding_at_level_p (TREE_TYPE (ctor)))
7318 15460 : p_complete->padded_non_union = true;
7319 :
7320 1550016 : *p_nz_elts += nz_elts;
7321 1550016 : *p_unique_nz_elts += unique_nz_elts;
7322 1550016 : *p_init_elts += init_elts;
7323 :
7324 1550016 : return const_p;
7325 : }
7326 :
7327 : /* Examine CTOR to discover:
7328 : * how many scalar fields are set to nonzero values,
7329 : and place it in *P_NZ_ELTS;
7330 : * the same, but counting RANGE_EXPRs as multiplier of 1 instead of
7331 : high - low + 1 (this can be useful for callers to determine ctors
7332 : that could be cheaply initialized with - perhaps nested - loops
7333 : compared to copied from huge read-only data),
7334 : and place it in *P_UNIQUE_NZ_ELTS;
7335 : * how many scalar fields in total are in CTOR,
7336 : and place it in *P_ELT_COUNT.
7337 : * whether the constructor is complete -- in the sense that every
7338 : meaningful byte is explicitly given a value --
7339 : and place it in *P_COMPLETE:
7340 :
7341 : Return whether or not CTOR is a valid static constant initializer, the same
7342 : as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
7343 :
7344 : bool
7345 1003818 : categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
7346 : HOST_WIDE_INT *p_unique_nz_elts,
7347 : HOST_WIDE_INT *p_init_elts,
7348 : ctor_completeness *p_complete)
7349 : {
7350 1003818 : *p_nz_elts = 0;
7351 1003818 : *p_unique_nz_elts = 0;
7352 1003818 : *p_init_elts = 0;
7353 1003818 : *p_complete = {};
7354 :
7355 1003818 : return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
7356 1003818 : p_init_elts, p_complete);
7357 : }
7358 :
7359 : /* Return true if constructor CTOR is simple enough to be materialized
7360 : in an integer mode register. Limit the size to WORDS words, which
7361 : is 1 by default. */
7362 :
7363 : bool
7364 23879 : immediate_const_ctor_p (const_tree ctor, unsigned int words)
7365 : {
7366 : /* Allow function to be called with a VAR_DECL's DECL_INITIAL. */
7367 23879 : if (!ctor || TREE_CODE (ctor) != CONSTRUCTOR)
7368 : return false;
7369 :
7370 2820 : return TREE_CONSTANT (ctor)
7371 2820 : && !TREE_ADDRESSABLE (ctor)
7372 2714 : && CONSTRUCTOR_NELTS (ctor)
7373 2688 : && TREE_CODE (TREE_TYPE (ctor)) != ARRAY_TYPE
7374 633 : && int_expr_size (ctor) <= words * UNITS_PER_WORD
7375 3009 : && initializer_constant_valid_for_bitfield_p (ctor);
7376 : }
7377 :
7378 : /* TYPE is initialized by a constructor with NUM_ELTS elements, the last
7379 : of which had type LAST_TYPE. Each element was itself a complete
7380 : initializer, in the sense that every meaningful byte was explicitly
7381 : given a value. Return true if the same is true for the constructor
7382 : as a whole. */
7383 :
7384 : bool
7385 1750843 : complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
7386 : const_tree last_type)
7387 : {
7388 1750843 : if (TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE)
7389 : {
7390 9097 : if (num_elts == 0)
7391 : {
7392 24 : if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
7393 : return false;
7394 :
7395 : /* If the CONSTRUCTOR doesn't have any elts, it is
7396 : incomplete if the union has at least one field. */
7397 327 : for (tree f = TYPE_FIELDS (type); f; f = DECL_CHAIN (f))
7398 324 : if (TREE_CODE (f) == FIELD_DECL)
7399 : return false;
7400 :
7401 : return true;
7402 : }
7403 :
7404 9073 : gcc_assert (num_elts == 1 && last_type);
7405 :
7406 9073 : if (flag_zero_init_padding_bits >= ZERO_INIT_PADDING_BITS_UNIONS)
7407 : /* ??? We could look at each element of the union, and find the
7408 : largest element. Which would avoid comparing the size of the
7409 : initialized element against any tail padding in the union.
7410 : Doesn't seem worth the effort... */
7411 102 : return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
7412 :
7413 : return true;
7414 : }
7415 :
7416 1741746 : return count_type_elements (type, true) == num_elts;
7417 : }
7418 :
7419 : /* Return true if EXP contains mostly (3/4) zeros. */
7420 :
7421 : static bool
7422 367234 : mostly_zeros_p (const_tree exp)
7423 : {
7424 367234 : if (TREE_CODE (exp) == CONSTRUCTOR)
7425 : {
7426 197 : HOST_WIDE_INT nz_elts, unz_elts, init_elts;
7427 197 : ctor_completeness complete_p;
7428 :
7429 197 : categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
7430 : &complete_p);
7431 197 : return complete_p.sparse || nz_elts < init_elts / 4;
7432 : }
7433 :
7434 367037 : return initializer_zerop (exp);
7435 : }
7436 :
7437 : /* Return true if EXP contains all zeros. */
7438 :
7439 : static bool
7440 1108 : all_zeros_p (const_tree exp)
7441 : {
7442 1108 : if (TREE_CODE (exp) == CONSTRUCTOR)
7443 : {
7444 1108 : HOST_WIDE_INT nz_elts, unz_elts, init_elts;
7445 1108 : ctor_completeness complete_p;
7446 :
7447 1108 : categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
7448 : &complete_p);
7449 1108 : return nz_elts == 0;
7450 : }
7451 :
7452 0 : return initializer_zerop (exp);
7453 : }
7454 :
7455 : /* Helper function for store_constructor.
7456 : TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
7457 : CLEARED is as for store_constructor.
7458 : ALIAS_SET is the alias set to use for any stores.
7459 : If REVERSE is true, the store is to be done in reverse order.
7460 :
7461 : This provides a recursive shortcut back to store_constructor when it isn't
7462 : necessary to go through store_field. This is so that we can pass through
7463 : the cleared field to let store_constructor know that we may not have to
7464 : clear a substructure if the outer structure has already been cleared. */
7465 :
7466 : static void
7467 36934 : store_constructor_field (rtx target, poly_uint64 bitsize, poly_int64 bitpos,
7468 : poly_uint64 bitregion_start,
7469 : poly_uint64 bitregion_end,
7470 : machine_mode mode,
7471 : tree exp, int cleared,
7472 : alias_set_type alias_set, bool reverse)
7473 : {
7474 36934 : poly_int64 bytepos;
7475 36934 : poly_uint64 bytesize;
7476 36934 : if (TREE_CODE (exp) == CONSTRUCTOR
7477 : /* We can only call store_constructor recursively if the size and
7478 : bit position are on a byte boundary. */
7479 36934 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
7480 82 : && maybe_ne (bitsize, 0U)
7481 36852 : && multiple_p (bitsize, BITS_PER_UNIT, &bytesize)
7482 : /* If we have a nonzero bitpos for a register target, then we just
7483 : let store_field do the bitfield handling. This is unlikely to
7484 : generate unnecessary clear instructions anyways. */
7485 37016 : && (known_eq (bitpos, 0) || MEM_P (target)))
7486 : {
7487 82 : if (MEM_P (target))
7488 : {
7489 40 : machine_mode target_mode = GET_MODE (target);
7490 40 : if (target_mode != BLKmode
7491 40 : && !multiple_p (bitpos, GET_MODE_ALIGNMENT (target_mode)))
7492 : target_mode = BLKmode;
7493 40 : target = adjust_address (target, target_mode, bytepos);
7494 : }
7495 :
7496 :
7497 : /* Update the alias set, if required. */
7498 40 : if (MEM_P (target) && ! MEM_KEEP_ALIAS_SET_P (target)
7499 122 : && MEM_ALIAS_SET (target) != 0)
7500 : {
7501 36 : target = copy_rtx (target);
7502 36 : set_mem_alias_set (target, alias_set);
7503 : }
7504 :
7505 82 : store_constructor (exp, target, cleared, bytesize, reverse);
7506 : }
7507 : else
7508 36852 : store_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode,
7509 : exp, alias_set, false, reverse);
7510 36934 : }
7511 :
7512 :
7513 : /* Returns the number of FIELD_DECLs in TYPE. */
7514 :
7515 : static int
7516 68761 : fields_length (const_tree type)
7517 : {
7518 68761 : tree t = TYPE_FIELDS (type);
7519 68761 : int count = 0;
7520 :
7521 902195 : for (; t; t = DECL_CHAIN (t))
7522 833434 : if (TREE_CODE (t) == FIELD_DECL)
7523 299806 : ++count;
7524 :
7525 68761 : return count;
7526 : }
7527 :
7528 : /* Store the value of constructor EXP into the rtx TARGET.
7529 : TARGET is either a REG or a MEM; we know it cannot conflict, since
7530 : safe_from_p has been called.
7531 : CLEARED is true if TARGET is known to have been zero'd.
7532 : If the constructor EXP has a vector type then elements of TARGET for which
7533 : there is no corresponding element in EXP are zero'd. For a variable-length
7534 : vector type, only elements up to the minimum number of subparts of the type
7535 : are explicitly zero'd; any elements beyond that are implicitly zero.
7536 : SIZE is the number of bytes of TARGET we are allowed to modify: this
7537 : may not be the same as the size of EXP if we are assigning to a field
7538 : which has been packed to exclude padding bits.
7539 : If REVERSE is true, the store is to be done in reverse order. */
7540 :
7541 : void
7542 248692 : store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
7543 : bool reverse)
7544 : {
7545 248692 : tree type = TREE_TYPE (exp);
7546 248692 : HOST_WIDE_INT exp_size = int_size_in_bytes (type);
7547 248692 : poly_int64 bitregion_end = known_gt (size, 0) ? size * BITS_PER_UNIT - 1 : 0;
7548 :
7549 248692 : switch (TREE_CODE (type))
7550 : {
7551 69250 : case RECORD_TYPE:
7552 69250 : case UNION_TYPE:
7553 69250 : case QUAL_UNION_TYPE:
7554 69250 : {
7555 69250 : unsigned HOST_WIDE_INT idx;
7556 69250 : tree field, value;
7557 :
7558 : /* The storage order is specified for every aggregate type. */
7559 69250 : reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7560 :
7561 : /* If size is zero or the target is already cleared, do nothing. */
7562 69250 : if (known_eq (size, 0) || cleared)
7563 : cleared = 1;
7564 : /* We either clear the aggregate or indicate the value is dead. */
7565 69250 : else if ((TREE_CODE (type) == UNION_TYPE
7566 69250 : || TREE_CODE (type) == QUAL_UNION_TYPE)
7567 69554 : && ! CONSTRUCTOR_ELTS (exp))
7568 : /* If the constructor is empty, clear the union. */
7569 : {
7570 255 : clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
7571 255 : cleared = 1;
7572 : }
7573 :
7574 : /* If we are building a static constructor into a register,
7575 : set the initial value as zero so we can fold the value into
7576 : a constant. But if more than one register is involved,
7577 : this probably loses. */
7578 4248 : else if (REG_P (target) && TREE_STATIC (exp)
7579 69585 : && known_le (GET_MODE_SIZE (GET_MODE (target)),
7580 : REGMODE_NATURAL_SIZE (GET_MODE (target))))
7581 : {
7582 234 : emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
7583 234 : cleared = 1;
7584 : }
7585 :
7586 : /* If the constructor has fewer fields than the structure or
7587 : if we are initializing the structure to mostly zeros, clear
7588 : the whole structure first. Don't do this if TARGET is a
7589 : register whose mode size isn't equal to SIZE since
7590 : clear_storage can't handle this case. */
7591 68761 : else if (known_size_p (size)
7592 68930 : && (((int) CONSTRUCTOR_NELTS (exp) != fields_length (type))
7593 156 : || mostly_zeros_p (exp))
7594 137370 : && (!REG_P (target)
7595 8018 : || known_eq (GET_MODE_SIZE (GET_MODE (target)), size)))
7596 : {
7597 79322 : clear_storage (target, gen_int_mode (size, Pmode),
7598 : BLOCK_OP_NORMAL);
7599 68609 : cleared = 1;
7600 : }
7601 :
7602 69250 : if (REG_P (target) && !cleared)
7603 5 : emit_clobber (target);
7604 :
7605 : /* Store each element of the constructor into the
7606 : corresponding field of TARGET. */
7607 69596 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, field, value)
7608 : {
7609 346 : machine_mode mode;
7610 346 : HOST_WIDE_INT bitsize;
7611 346 : HOST_WIDE_INT bitpos = 0;
7612 346 : tree offset;
7613 346 : rtx to_rtx = target;
7614 :
7615 : /* Just ignore missing fields. We cleared the whole
7616 : structure, above, if any fields are missing. */
7617 346 : if (field == 0)
7618 346 : continue;
7619 :
7620 346 : if (cleared && initializer_zerop (value))
7621 17 : continue;
7622 :
7623 : /* Variable sized arrays are ignored. */
7624 329 : tree decl_size = DECL_SIZE (field);
7625 329 : if (!decl_size)
7626 4 : continue;
7627 :
7628 325 : if (tree_fits_uhwi_p (decl_size))
7629 325 : bitsize = tree_to_uhwi (decl_size);
7630 : else
7631 0 : gcc_unreachable ();
7632 :
7633 325 : mode = DECL_MODE (field);
7634 325 : if (DECL_BIT_FIELD (field))
7635 24 : mode = VOIDmode;
7636 :
7637 325 : offset = DECL_FIELD_OFFSET (field);
7638 325 : if (tree_fits_shwi_p (offset)
7639 325 : && tree_fits_shwi_p (bit_position (field)))
7640 : {
7641 325 : bitpos = int_bit_position (field);
7642 325 : offset = NULL_TREE;
7643 : }
7644 : else
7645 0 : gcc_unreachable ();
7646 :
7647 : /* If this initializes a field that is smaller than a
7648 : word, at the start of a word, try to widen it to a full
7649 : word. This special case allows us to output C++ member
7650 : function initializations in a form that the optimizers
7651 : can understand. */
7652 325 : if (WORD_REGISTER_OPERATIONS
7653 : && REG_P (target)
7654 : && bitsize < BITS_PER_WORD
7655 : && bitpos % BITS_PER_WORD == 0
7656 : && GET_MODE_CLASS (mode) == MODE_INT
7657 : && TREE_CODE (value) == INTEGER_CST
7658 : && exp_size >= 0
7659 : && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
7660 : {
7661 : type = TREE_TYPE (value);
7662 :
7663 : if (TYPE_PRECISION (type) < BITS_PER_WORD)
7664 : {
7665 : type = lang_hooks.types.type_for_mode
7666 : (word_mode, TYPE_UNSIGNED (type));
7667 : value = fold_convert (type, value);
7668 : /* Make sure the bits beyond the original bitsize are zero
7669 : so that we can correctly avoid extra zeroing stores in
7670 : later constructor elements. */
7671 : tree bitsize_mask
7672 : = wide_int_to_tree (type, wi::mask (bitsize, false,
7673 : BITS_PER_WORD));
7674 : value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
7675 : }
7676 :
7677 : if (BYTES_BIG_ENDIAN)
7678 : value
7679 : = fold_build2 (LSHIFT_EXPR, type, value,
7680 : build_int_cst (type,
7681 : BITS_PER_WORD - bitsize));
7682 : bitsize = BITS_PER_WORD;
7683 : mode = word_mode;
7684 : }
7685 :
7686 207 : if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
7687 532 : && DECL_NONADDRESSABLE_P (field))
7688 : {
7689 0 : to_rtx = copy_rtx (to_rtx);
7690 0 : MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
7691 : }
7692 :
7693 325 : store_constructor_field (to_rtx, bitsize, bitpos,
7694 325 : 0, bitregion_end, mode,
7695 : value, cleared,
7696 325 : get_alias_set (TREE_TYPE (field)),
7697 : reverse);
7698 : }
7699 : break;
7700 : }
7701 39043 : case ARRAY_TYPE:
7702 39043 : {
7703 39043 : tree value, index;
7704 39043 : unsigned HOST_WIDE_INT i, j = 0;
7705 39043 : bool need_to_clear;
7706 39043 : tree domain;
7707 39043 : tree elttype = TREE_TYPE (type);
7708 39043 : bool const_bounds_p;
7709 39043 : unsigned HOST_WIDE_INT minelt = 0;
7710 39043 : unsigned HOST_WIDE_INT maxelt = 0;
7711 :
7712 : /* The storage order is specified for every aggregate type. */
7713 39043 : reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7714 :
7715 39043 : domain = TYPE_DOMAIN (type);
7716 39043 : const_bounds_p = (TYPE_MIN_VALUE (domain)
7717 39043 : && TYPE_MAX_VALUE (domain)
7718 39043 : && tree_fits_uhwi_p (TYPE_MIN_VALUE (domain))
7719 78086 : && tree_fits_uhwi_p (TYPE_MAX_VALUE (domain)));
7720 :
7721 : /* If we have constant bounds for the range of the type, get them. */
7722 39043 : if (const_bounds_p)
7723 : {
7724 39043 : minelt = tree_to_uhwi (TYPE_MIN_VALUE (domain));
7725 39043 : maxelt = tree_to_uhwi (TYPE_MAX_VALUE (domain));
7726 : }
7727 :
7728 : /* If the constructor has fewer elements than the array, clear
7729 : the whole array first. Similarly if this is static
7730 : constructor of a non-BLKmode object. */
7731 39043 : if (cleared)
7732 : need_to_clear = false;
7733 38997 : else if (REG_P (target) && TREE_STATIC (exp))
7734 : need_to_clear = true;
7735 : else
7736 : {
7737 38890 : unsigned HOST_WIDE_INT idx;
7738 38890 : unsigned HOST_WIDE_INT count = 0, zero_count = 0;
7739 38890 : need_to_clear = ! const_bounds_p;
7740 :
7741 : /* This loop is a more accurate version of the loop in
7742 : mostly_zeros_p (it handles RANGE_EXPR in an index). It
7743 : is also needed to check for missing elements. */
7744 38898 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, index, value)
7745 : {
7746 8 : unsigned HOST_WIDE_INT this_node_count;
7747 :
7748 8 : if (need_to_clear)
7749 : break;
7750 :
7751 8 : if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7752 : {
7753 0 : tree lo_index = TREE_OPERAND (index, 0);
7754 0 : tree hi_index = TREE_OPERAND (index, 1);
7755 :
7756 0 : if (! tree_fits_uhwi_p (lo_index)
7757 0 : || ! tree_fits_uhwi_p (hi_index))
7758 : {
7759 : need_to_clear = true;
7760 : break;
7761 : }
7762 :
7763 0 : this_node_count = (tree_to_uhwi (hi_index)
7764 0 : - tree_to_uhwi (lo_index) + 1);
7765 0 : }
7766 8 : else if (TREE_CODE (value) == RAW_DATA_CST)
7767 0 : this_node_count = RAW_DATA_LENGTH (value);
7768 : else
7769 : this_node_count = 1;
7770 :
7771 8 : count += this_node_count;
7772 8 : if (mostly_zeros_p (value))
7773 0 : zero_count += this_node_count;
7774 : }
7775 :
7776 : /* Clear the entire array first if there are any missing
7777 : elements, or if the incidence of zero elements is >=
7778 : 75%. */
7779 38890 : if (! need_to_clear
7780 38890 : && (count < maxelt - minelt + 1
7781 1 : || 4 * zero_count >= 3 * count))
7782 : need_to_clear = true;
7783 : }
7784 :
7785 38996 : if (need_to_clear && maybe_gt (size, 0))
7786 : {
7787 38996 : if (REG_P (target))
7788 1639 : emit_move_insn (target, CONST0_RTX (GET_MODE (target)));
7789 : else
7790 42121 : clear_storage (target, gen_int_mode (size, Pmode),
7791 : BLOCK_OP_NORMAL);
7792 : cleared = 1;
7793 : }
7794 :
7795 39043 : if (!cleared && REG_P (target))
7796 : /* Inform later passes that the old value is dead. */
7797 0 : emit_clobber (target);
7798 :
7799 : /* Store each element of the constructor into the
7800 : corresponding element of TARGET, determined by counting the
7801 : elements. */
7802 40159 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), i, index, value)
7803 : {
7804 1116 : machine_mode mode;
7805 1116 : poly_int64 bitsize;
7806 1116 : HOST_WIDE_INT bitpos;
7807 1116 : rtx xtarget = target;
7808 :
7809 1116 : if (cleared && initializer_zerop (value))
7810 : {
7811 672 : if (TREE_CODE (value) == RAW_DATA_CST)
7812 0 : j += RAW_DATA_LENGTH (value) - 1;
7813 674 : continue;
7814 : }
7815 :
7816 444 : mode = TYPE_MODE (elttype);
7817 444 : if (mode != BLKmode)
7818 888 : bitsize = GET_MODE_BITSIZE (mode);
7819 0 : else if (!poly_int_tree_p (TYPE_SIZE (elttype), &bitsize))
7820 0 : bitsize = -1;
7821 :
7822 444 : if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7823 : {
7824 0 : tree lo_index = TREE_OPERAND (index, 0);
7825 0 : tree hi_index = TREE_OPERAND (index, 1);
7826 0 : rtx index_r;
7827 0 : unsigned HOST_WIDE_INT lo, hi, count;
7828 0 : tree offset;
7829 :
7830 0 : gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
7831 :
7832 : /* If the range is constant and "small", unroll the loop. */
7833 0 : if (const_bounds_p
7834 0 : && tree_fits_uhwi_p (lo_index)
7835 0 : && tree_fits_uhwi_p (hi_index)
7836 0 : && (lo = tree_to_uhwi (lo_index),
7837 0 : hi = tree_to_uhwi (hi_index),
7838 0 : count = hi - lo + 1,
7839 0 : (!MEM_P (target)
7840 0 : || count <= 2
7841 0 : || (tree_fits_uhwi_p (TYPE_SIZE (elttype))
7842 0 : && (tree_to_uhwi (TYPE_SIZE (elttype)) * count
7843 : <= 40 * 8)))))
7844 : {
7845 0 : lo -= minelt; hi -= minelt;
7846 0 : for (; lo <= hi; lo++)
7847 : {
7848 0 : bitpos = lo * tree_to_uhwi (TYPE_SIZE (elttype));
7849 :
7850 0 : if (MEM_P (target)
7851 0 : && !MEM_KEEP_ALIAS_SET_P (target)
7852 0 : && TREE_CODE (type) == ARRAY_TYPE
7853 0 : && TYPE_NONALIASED_COMPONENT (type))
7854 : {
7855 0 : target = copy_rtx (target);
7856 0 : MEM_KEEP_ALIAS_SET_P (target) = 1;
7857 : }
7858 :
7859 0 : store_constructor_field
7860 0 : (target, bitsize, bitpos, 0, bitregion_end,
7861 : mode, value, cleared,
7862 : get_alias_set (elttype), reverse);
7863 : }
7864 : }
7865 : else
7866 : {
7867 0 : rtx_code_label *loop_start = gen_label_rtx ();
7868 0 : rtx_code_label *loop_end = gen_label_rtx ();
7869 0 : tree exit_cond;
7870 :
7871 0 : expand_normal (hi_index);
7872 :
7873 0 : index = build_decl (EXPR_LOCATION (exp),
7874 : VAR_DECL, NULL_TREE, domain);
7875 0 : index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
7876 0 : SET_DECL_RTL (index, index_r);
7877 0 : store_expr (lo_index, index_r, 0, false, reverse);
7878 :
7879 : /* Build the head of the loop. */
7880 0 : do_pending_stack_adjust ();
7881 0 : emit_label (loop_start);
7882 :
7883 : /* Assign value to element index. */
7884 0 : offset = fold_build2 (MINUS_EXPR,
7885 : TREE_TYPE (index),
7886 : index,
7887 : TYPE_MIN_VALUE (domain));
7888 :
7889 0 : offset = size_binop (MULT_EXPR,
7890 : fold_convert (sizetype, offset),
7891 : TYPE_SIZE_UNIT (elttype));
7892 :
7893 0 : xtarget = offset_address (target,
7894 : expand_normal (offset),
7895 : highest_pow2_factor (offset));
7896 0 : xtarget = adjust_address (xtarget, mode, 0);
7897 0 : if (TREE_CODE (value) == CONSTRUCTOR)
7898 0 : store_constructor (value, xtarget, cleared,
7899 : exact_div (bitsize, BITS_PER_UNIT),
7900 : reverse);
7901 : else
7902 0 : store_expr (value, xtarget, 0, false, reverse);
7903 :
7904 : /* Generate a conditional jump to exit the loop. */
7905 0 : exit_cond = build2 (LT_EXPR, integer_type_node,
7906 : index, hi_index);
7907 0 : jumpif (exit_cond, loop_end,
7908 : profile_probability::uninitialized ());
7909 :
7910 : /* Update the loop counter, and jump to the head of
7911 : the loop. */
7912 0 : expand_assignment (index,
7913 0 : build2 (PLUS_EXPR, TREE_TYPE (index),
7914 : index, integer_one_node),
7915 : false);
7916 :
7917 0 : emit_jump (loop_start);
7918 :
7919 : /* Build the end of the loop. */
7920 0 : emit_label (loop_end);
7921 : }
7922 : }
7923 444 : else if ((index && !tree_fits_uhwi_p (index))
7924 444 : || !tree_fits_uhwi_p (TYPE_SIZE (elttype)))
7925 : {
7926 0 : tree offset;
7927 :
7928 0 : gcc_assert (TREE_CODE (value) != RAW_DATA_CST);
7929 0 : if (index)
7930 0 : offset = fold_build2 (MINUS_EXPR,
7931 : TREE_TYPE (index),
7932 : index,
7933 : TYPE_MIN_VALUE (domain));
7934 : else
7935 0 : offset = size_int (i + j);
7936 :
7937 0 : offset = size_binop (MULT_EXPR,
7938 : fold_convert (sizetype, offset),
7939 : TYPE_SIZE_UNIT (elttype));
7940 0 : xtarget = offset_address (target,
7941 : expand_normal (offset),
7942 : highest_pow2_factor (offset));
7943 0 : xtarget = adjust_address (xtarget, mode, 0);
7944 0 : store_expr (value, xtarget, 0, false, reverse);
7945 : }
7946 : else
7947 : {
7948 444 : if (index)
7949 888 : bitpos = ((tree_to_uhwi (index) - minelt)
7950 444 : * tree_to_uhwi (TYPE_SIZE (elttype)));
7951 : else
7952 0 : bitpos = ((i + j) * tree_to_uhwi (TYPE_SIZE (elttype)));
7953 :
7954 12 : if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
7955 12 : && TREE_CODE (type) == ARRAY_TYPE
7956 456 : && TYPE_NONALIASED_COMPONENT (type))
7957 : {
7958 0 : target = copy_rtx (target);
7959 0 : MEM_KEEP_ALIAS_SET_P (target) = 1;
7960 : }
7961 444 : if (TREE_CODE (value) != RAW_DATA_CST)
7962 440 : store_constructor_field (target, bitsize, bitpos, 0,
7963 440 : bitregion_end, mode, value,
7964 : cleared, get_alias_set (elttype),
7965 : reverse);
7966 : else
7967 : {
7968 4 : j += RAW_DATA_LENGTH (value) - 1;
7969 4 : gcc_assert (known_eq (bitsize, BITS_PER_UNIT));
7970 4 : rtx to_rtx = adjust_address (target, mode,
7971 : bitpos / BITS_PER_UNIT);
7972 :
7973 4 : if (to_rtx == target)
7974 0 : to_rtx = copy_rtx (to_rtx);
7975 :
7976 4 : if (!MEM_KEEP_ALIAS_SET_P (to_rtx)
7977 8 : && MEM_ALIAS_SET (to_rtx) != 0)
7978 0 : set_mem_alias_set (to_rtx, get_alias_set (elttype));
7979 :
7980 8 : if (can_store_by_pieces (RAW_DATA_LENGTH (value),
7981 : raw_data_cst_read_str,
7982 : (void *) value,
7983 4 : MEM_ALIGN (target), false))
7984 : {
7985 4 : store_by_pieces (target, RAW_DATA_LENGTH (value),
7986 : raw_data_cst_read_str, (void *) value,
7987 2 : MEM_ALIGN (target), false,
7988 : RETURN_BEGIN);
7989 2 : continue;
7990 : }
7991 :
7992 2 : elttype
7993 2 : = build_array_type_nelts (TREE_TYPE (value),
7994 2 : RAW_DATA_LENGTH (value));
7995 2 : tree ctor = build_constructor_single (elttype, NULL_TREE,
7996 : value);
7997 2 : ctor = tree_output_constant_def (ctor);
7998 2 : mode = TYPE_MODE (type);
7999 2 : store_constructor_field (target,
8000 2 : bitsize * RAW_DATA_LENGTH (value),
8001 2 : bitpos, 0, bitregion_end, mode,
8002 : ctor, cleared,
8003 : get_alias_set (elttype), reverse);
8004 : }
8005 : }
8006 : }
8007 : break;
8008 : }
8009 :
8010 140399 : case VECTOR_TYPE:
8011 140399 : {
8012 140399 : unsigned HOST_WIDE_INT idx;
8013 140399 : constructor_elt *ce;
8014 140399 : bool need_to_clear;
8015 140399 : insn_code icode = CODE_FOR_nothing;
8016 140399 : tree elt;
8017 140399 : tree elttype = TREE_TYPE (type);
8018 140399 : int elt_size = vector_element_bits (type);
8019 140399 : machine_mode eltmode = TYPE_MODE (elttype);
8020 140399 : poly_int64 bitsize;
8021 140399 : poly_int64 bitpos;
8022 140399 : rtvec vector = NULL;
8023 140399 : poly_uint64 n_elts;
8024 140399 : unsigned HOST_WIDE_INT const_n_elts;
8025 140399 : alias_set_type alias;
8026 140399 : bool vec_vec_init_p = false;
8027 140399 : machine_mode mode = GET_MODE (target);
8028 :
8029 140399 : gcc_assert (eltmode != BLKmode);
8030 :
8031 : /* Try using vec_duplicate_optab for uniform vectors. */
8032 140399 : icode = optab_handler (vec_duplicate_optab, mode);
8033 140399 : if (!TREE_SIDE_EFFECTS (exp)
8034 140399 : && VECTOR_MODE_P (mode)
8035 136843 : && icode != CODE_FOR_nothing
8036 : /* If the vec_duplicate target pattern does not specify an element
8037 : mode check that eltmode is the normal inner mode of the
8038 : requested vector mode. But if the target allows eltmode
8039 : explicitly go ahead and use it. */
8040 93343 : && (eltmode == GET_MODE_INNER (mode)
8041 0 : || insn_data[icode].operand[1].mode == eltmode)
8042 93343 : && (elt = uniform_vector_p (exp))
8043 158114 : && !VECTOR_TYPE_P (TREE_TYPE (elt)))
8044 : {
8045 17715 : class expand_operand ops[2];
8046 17715 : create_output_operand (&ops[0], target, mode);
8047 17715 : create_input_operand (&ops[1], expand_normal (elt), eltmode);
8048 17715 : expand_insn (icode, 2, ops);
8049 17715 : if (!rtx_equal_p (target, ops[0].value))
8050 0 : emit_move_insn (target, ops[0].value);
8051 17715 : break;
8052 : }
8053 : /* Use sign-extension for uniform boolean vectors with
8054 : integer modes and single-bit mask entries.
8055 : Effectively "vec_duplicate" for bitmasks. */
8056 122684 : if (elt_size == 1
8057 146 : && !TREE_SIDE_EFFECTS (exp)
8058 146 : && VECTOR_BOOLEAN_TYPE_P (type)
8059 146 : && SCALAR_INT_MODE_P (TYPE_MODE (type))
8060 146 : && (elt = uniform_vector_p (exp))
8061 143 : && !VECTOR_TYPE_P (TREE_TYPE (elt))
8062 122684 : && !BYTES_BIG_ENDIAN)
8063 : {
8064 143 : rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)),
8065 : expand_normal (elt));
8066 143 : rtx tmp = gen_reg_rtx (mode);
8067 143 : convert_move (tmp, op0, 0);
8068 :
8069 : /* Ensure no excess bits are set.
8070 : GCN needs this for nunits < 64.
8071 : x86 needs this for nunits < 8. */
8072 143 : unsigned int nunits = TYPE_VECTOR_SUBPARTS (type).to_constant ();
8073 143 : if (maybe_ne (GET_MODE_PRECISION (mode), nunits))
8074 2 : tmp = expand_binop (mode, and_optab, tmp,
8075 2 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
8076 : target, true, OPTAB_WIDEN);
8077 143 : if (tmp != target)
8078 141 : emit_move_insn (target, tmp);
8079 : break;
8080 : }
8081 :
8082 122541 : n_elts = TYPE_VECTOR_SUBPARTS (type);
8083 122541 : if (REG_P (target)
8084 119322 : && VECTOR_MODE_P (mode))
8085 : {
8086 119128 : const_n_elts = 0;
8087 119128 : if (CONSTRUCTOR_NELTS (exp)
8088 119128 : && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
8089 : == VECTOR_TYPE))
8090 : {
8091 1438 : tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value);
8092 1438 : gcc_assert (known_eq (CONSTRUCTOR_NELTS (exp)
8093 : * TYPE_VECTOR_SUBPARTS (etype),
8094 : n_elts));
8095 :
8096 4314 : icode = convert_optab_handler (vec_init_optab, mode,
8097 1438 : TYPE_MODE (etype));
8098 1438 : const_n_elts = CONSTRUCTOR_NELTS (exp);
8099 1438 : vec_vec_init_p = icode != CODE_FOR_nothing;
8100 : }
8101 235380 : else if (exact_div (n_elts, GET_MODE_NUNITS (eltmode))
8102 117690 : .is_constant (&const_n_elts))
8103 : {
8104 : /* For a non-const type vector, we check it is made up of
8105 : similarly non-const type vectors. */
8106 117690 : icode = convert_optab_handler (vec_init_optab, mode, eltmode);
8107 : }
8108 : else
8109 : {
8110 : /* Handle variable-length vector types. */
8111 : icode = convert_optab_handler (vec_init_optab, mode, eltmode);
8112 : const_n_elts = constant_lower_bound (n_elts);
8113 : }
8114 :
8115 119128 : if (const_n_elts && icode != CODE_FOR_nothing)
8116 : {
8117 118393 : vector = rtvec_alloc (const_n_elts);
8118 559914 : for (unsigned int k = 0; k < const_n_elts; k++)
8119 323128 : RTVEC_ELT (vector, k) = CONST0_RTX (eltmode);
8120 : }
8121 : }
8122 : else
8123 : gcc_assert (n_elts.is_constant ());
8124 :
8125 : /* Compute the size of the elements in the CTOR. It differs
8126 : from the size of the vector type elements only when the
8127 : CTOR elements are vectors themselves. */
8128 122541 : tree val_type = (CONSTRUCTOR_NELTS (exp) != 0
8129 122541 : ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)
8130 122541 : : elttype);
8131 122541 : if (VECTOR_TYPE_P (val_type))
8132 1788 : bitsize = tree_to_poly_uint64 (TYPE_SIZE (val_type));
8133 : else
8134 120753 : bitsize = elt_size;
8135 :
8136 : /* If the constructor has fewer elements than the vector,
8137 : clear the whole array first. Similarly if this is static
8138 : constructor of a non-BLKmode object. */
8139 122541 : if (cleared)
8140 : need_to_clear = false;
8141 122541 : else if (REG_P (target) && TREE_STATIC (exp))
8142 : need_to_clear = true;
8143 : else
8144 : {
8145 : poly_uint64 count = 0, zero_count = 0;
8146 : tree value;
8147 :
8148 489570 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
8149 : {
8150 367029 : poly_int64 n_elts_here = exact_div (bitsize, elt_size);
8151 367029 : count += n_elts_here;
8152 367029 : if (mostly_zeros_p (value))
8153 367029 : zero_count += n_elts_here;
8154 : }
8155 :
8156 : /* Clear the entire vector first if there are any missing elements,
8157 : or if the incidence of zero elements is >= 75%. */
8158 122541 : need_to_clear = (maybe_lt (count, n_elts)
8159 122541 : || maybe_gt (4 * zero_count, 3 * count));
8160 : }
8161 :
8162 1307 : if (need_to_clear && maybe_gt (size, 0) && !vector)
8163 : {
8164 761 : if (REG_P (target))
8165 25 : emit_move_insn (target, CONST0_RTX (mode));
8166 : else
8167 736 : clear_storage (target, gen_int_mode (size, Pmode),
8168 : BLOCK_OP_NORMAL);
8169 : cleared = 1;
8170 : }
8171 :
8172 : /* Inform later passes that the old value is dead. */
8173 122541 : if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
8174 : {
8175 587 : emit_move_insn (target, CONST0_RTX (mode));
8176 587 : cleared = 1;
8177 : }
8178 :
8179 122541 : if (MEM_P (target))
8180 3219 : alias = MEM_ALIAS_SET (target);
8181 : else
8182 119322 : alias = get_alias_set (elttype);
8183 :
8184 : /* Store each element of the constructor into the corresponding
8185 : element of TARGET, determined by counting the elements. */
8186 122541 : HOST_WIDE_INT chunk_size = 0;
8187 122541 : bool chunk_multiple_p = constant_multiple_p (bitsize, elt_size,
8188 : &chunk_size);
8189 122541 : gcc_assert (chunk_multiple_p || vec_vec_init_p);
8190 :
8191 489570 : for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (exp), idx, &ce);
8192 : idx++)
8193 : {
8194 367029 : HOST_WIDE_INT eltpos;
8195 367029 : tree value = ce->value;
8196 :
8197 367029 : if (cleared && initializer_zerop (value))
8198 8817 : continue;
8199 :
8200 358212 : if (ce->index)
8201 49538 : eltpos = tree_to_uhwi (ce->index);
8202 : else
8203 308674 : eltpos = idx * chunk_size;
8204 :
8205 358212 : if (vector)
8206 : {
8207 322045 : if (vec_vec_init_p)
8208 : {
8209 2772 : gcc_assert (ce->index == NULL_TREE);
8210 2772 : gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE);
8211 2772 : eltpos = idx;
8212 : }
8213 : else
8214 319273 : gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);
8215 322045 : RTVEC_ELT (vector, eltpos) = expand_normal (value);
8216 : }
8217 : else
8218 : {
8219 36167 : machine_mode value_mode
8220 36167 : = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE
8221 36167 : ? TYPE_MODE (TREE_TYPE (value)) : eltmode);
8222 36167 : bitpos = eltpos * elt_size;
8223 36167 : store_constructor_field (target, bitsize, bitpos, 0,
8224 36167 : bitregion_end, value_mode,
8225 : value, cleared, alias, reverse);
8226 : }
8227 : }
8228 :
8229 122541 : if (vector)
8230 118393 : emit_insn (GEN_FCN (icode) (target,
8231 : gen_rtx_PARALLEL (mode, vector)));
8232 : break;
8233 : }
8234 :
8235 0 : default:
8236 0 : gcc_unreachable ();
8237 : }
8238 248692 : }
8239 :
8240 : /* Store the value of EXP (an expression tree)
8241 : into a subfield of TARGET which has mode MODE and occupies
8242 : BITSIZE bits, starting BITPOS bits from the start of TARGET.
8243 : If MODE is VOIDmode, it means that we are storing into a bit-field.
8244 :
8245 : BITREGION_START is bitpos of the first bitfield in this region.
8246 : BITREGION_END is the bitpos of the ending bitfield in this region.
8247 : These two fields are 0, if the C++ memory model does not apply,
8248 : or we are not interested in keeping track of bitfield regions.
8249 :
8250 : Always return const0_rtx unless we have something particular to
8251 : return.
8252 :
8253 : ALIAS_SET is the alias set for the destination. This value will
8254 : (in general) be different from that for TARGET, since TARGET is a
8255 : reference to the containing structure.
8256 :
8257 : If NONTEMPORAL is true, try generating a nontemporal store.
8258 :
8259 : If REVERSE is true, the store is to be done in reverse order. */
8260 :
8261 : static rtx
8262 4836284 : store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
8263 : poly_uint64 bitregion_start, poly_uint64 bitregion_end,
8264 : machine_mode mode, tree exp,
8265 : alias_set_type alias_set, bool nontemporal, bool reverse)
8266 : {
8267 4836284 : if (TREE_CODE (exp) == ERROR_MARK)
8268 0 : return const0_rtx;
8269 :
8270 : /* If we have nothing to store, do nothing unless the expression has
8271 : side-effects. Don't do that for zero sized addressable lhs of
8272 : calls. */
8273 4836284 : if (known_eq (bitsize, 0)
8274 4836284 : && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
8275 3 : || TREE_CODE (exp) != CALL_EXPR))
8276 0 : return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL);
8277 :
8278 4836284 : if (GET_CODE (target) == CONCAT)
8279 : {
8280 : /* We're storing into a struct containing a single __complex. */
8281 :
8282 0 : gcc_assert (known_eq (bitpos, 0));
8283 0 : return store_expr (exp, target, 0, nontemporal, reverse);
8284 : }
8285 :
8286 : /* If the structure is in a register or if the component
8287 : is a bit field, we cannot use addressing to access it.
8288 : Use bit-field techniques or SUBREG to store in it. */
8289 :
8290 4836284 : poly_int64 decl_bitsize;
8291 4836284 : if (mode == VOIDmode
8292 4769201 : || (mode != BLKmode && ! direct_store[(int) mode]
8293 5338 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
8294 5336 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
8295 4763894 : || REG_P (target)
8296 4071639 : || GET_CODE (target) == SUBREG
8297 : /* If the field isn't aligned enough to store as an ordinary memref,
8298 : store it as a bit field. */
8299 4071639 : || (mode != BLKmode
8300 3956217 : && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
8301 7823016 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
8302 47421 : && targetm.slow_unaligned_access (mode, MEM_ALIGN (target)))
8303 3956217 : || !multiple_p (bitpos, BITS_PER_UNIT)))
8304 4071639 : || (known_size_p (bitsize)
8305 4071627 : && mode != BLKmode
8306 3956217 : && maybe_gt (GET_MODE_BITSIZE (mode), bitsize))
8307 : /* If the RHS and field are a constant size and the size of the
8308 : RHS isn't the same size as the bitfield, we must use bitfield
8309 : operations. */
8310 4071630 : || (known_size_p (bitsize)
8311 4071618 : && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
8312 4836558 : && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
8313 : bitsize)
8314 : /* Except for initialization of full bytes from a CONSTRUCTOR, which
8315 : we will handle specially below. */
8316 34 : && !(TREE_CODE (exp) == CONSTRUCTOR
8317 11 : && multiple_p (bitsize, BITS_PER_UNIT))
8318 : /* And except for bitwise copying of TREE_ADDRESSABLE types,
8319 : where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
8320 : includes some extra padding. store_expr / expand_expr will in
8321 : that case call get_inner_reference that will have the bitsize
8322 : we check here and thus the block move will not clobber the
8323 : padding that shouldn't be clobbered. In the future we could
8324 : replace the TREE_ADDRESSABLE check with a check that
8325 : get_base_address needs to live in memory. */
8326 23 : && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
8327 9 : || TREE_CODE (exp) != COMPONENT_REF
8328 6 : || !multiple_p (bitsize, BITS_PER_UNIT)
8329 6 : || !multiple_p (bitpos, BITS_PER_UNIT)
8330 6 : || !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
8331 : &decl_bitsize)
8332 6 : || maybe_ne (decl_bitsize, bitsize))
8333 : /* A call with an addressable return type and return-slot
8334 : optimization must not need bitfield operations but we must
8335 : pass down the original target. */
8336 17 : && (TREE_CODE (exp) != CALL_EXPR
8337 6 : || !TREE_ADDRESSABLE (TREE_TYPE (exp))
8338 0 : || !CALL_EXPR_RETURN_SLOT_OPT (exp)))
8339 : /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
8340 : decl we must use bitfield operations. */
8341 8907897 : || (known_size_p (bitsize)
8342 4071601 : && TREE_CODE (exp) == MEM_REF
8343 32829 : && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
8344 26873 : && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
8345 20360 : && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
8346 5687 : && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
8347 : {
8348 764940 : rtx temp;
8349 764940 : gimple *nop_def;
8350 :
8351 : /* If EXP is a NOP_EXPR of precision less than its mode, then that
8352 : implies a mask operation. If the precision is the same size as
8353 : the field we're storing into, that mask is redundant. This is
8354 : particularly common with bit field assignments generated by the
8355 : C front end. */
8356 764940 : nop_def = get_def_for_expr (exp, NOP_EXPR);
8357 764940 : if (nop_def)
8358 : {
8359 5527 : tree type = TREE_TYPE (exp);
8360 5527 : if (INTEGRAL_TYPE_P (type)
8361 5317 : && maybe_ne (TYPE_PRECISION (type),
8362 10634 : GET_MODE_BITSIZE (TYPE_MODE (type)))
8363 8810 : && known_eq (bitsize, TYPE_PRECISION (type)))
8364 : {
8365 3283 : tree op = gimple_assign_rhs1 (nop_def);
8366 3283 : type = TREE_TYPE (op);
8367 3283 : if (INTEGRAL_TYPE_P (type)
8368 3283 : && known_ge (TYPE_PRECISION (type), bitsize))
8369 : exp = op;
8370 : }
8371 : }
8372 :
8373 764940 : temp = expand_normal (exp);
8374 :
8375 : /* We don't support variable-sized BLKmode bitfields, since our
8376 : handling of BLKmode is bound up with the ability to break
8377 : things into words. */
8378 764940 : gcc_assert (mode != BLKmode || bitsize.is_constant ());
8379 :
8380 : /* Handle calls that return values in multiple non-contiguous locations.
8381 : The Irix 6 ABI has examples of this. */
8382 764940 : if (GET_CODE (temp) == PARALLEL)
8383 : {
8384 6 : HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
8385 6 : machine_mode temp_mode = GET_MODE (temp);
8386 6 : if (temp_mode == BLKmode || temp_mode == VOIDmode)
8387 6 : temp_mode
8388 6 : = smallest_int_mode_for_size (size * BITS_PER_UNIT).require ();
8389 6 : rtx temp_target = gen_reg_rtx (temp_mode);
8390 6 : emit_group_store (temp_target, temp, TREE_TYPE (exp), size);
8391 6 : temp = temp_target;
8392 : }
8393 :
8394 : /* Handle calls that return BLKmode values in registers. */
8395 764934 : else if (mode == BLKmode && REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
8396 : {
8397 0 : rtx temp_target = gen_reg_rtx (GET_MODE (temp));
8398 0 : copy_blkmode_from_reg (temp_target, temp, TREE_TYPE (exp));
8399 0 : temp = temp_target;
8400 : }
8401 :
8402 : /* If the value has aggregate type and an integral mode then, if BITSIZE
8403 : is narrower than this mode and this is for big-endian data, we first
8404 : need to put the value into the low-order bits for store_bit_field,
8405 : except when MODE is BLKmode and BITSIZE larger than the word size
8406 : (see the handling of fields larger than a word in store_bit_field).
8407 : Moreover, the field may be not aligned on a byte boundary; in this
8408 : case, if it has reverse storage order, it needs to be accessed as a
8409 : scalar field with reverse storage order and we must first put the
8410 : value into target order. */
8411 764940 : scalar_int_mode temp_mode;
8412 1527810 : if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
8413 765691 : && is_int_mode (GET_MODE (temp), &temp_mode))
8414 : {
8415 2494 : HOST_WIDE_INT size = GET_MODE_BITSIZE (temp_mode);
8416 :
8417 2494 : reverse = TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (exp));
8418 :
8419 2494 : if (reverse)
8420 0 : temp = flip_storage_order (temp_mode, temp);
8421 :
8422 2494 : gcc_checking_assert (known_le (bitsize, size));
8423 2494 : if (maybe_lt (bitsize, size)
8424 2494 : && reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN
8425 : /* Use of to_constant for BLKmode was checked above. */
8426 : && !(mode == BLKmode && bitsize.to_constant () > BITS_PER_WORD))
8427 0 : temp = expand_shift (RSHIFT_EXPR, temp_mode, temp,
8428 : size - bitsize, NULL_RTX, 1);
8429 : }
8430 :
8431 : /* Unless MODE is VOIDmode or BLKmode, convert TEMP to MODE. */
8432 697857 : if (mode != VOIDmode && mode != BLKmode
8433 1462520 : && mode != TYPE_MODE (TREE_TYPE (exp)))
8434 4 : temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), temp, 1);
8435 :
8436 : /* If the mode of TEMP and TARGET is BLKmode, both must be in memory
8437 : and BITPOS must be aligned on a byte boundary. If so, we simply do
8438 : a block copy. Likewise for a BLKmode-like TARGET. */
8439 764940 : if (GET_MODE (temp) == BLKmode
8440 764940 : && (GET_MODE (target) == BLKmode
8441 182 : || (MEM_P (target)
8442 0 : && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT
8443 0 : && multiple_p (bitpos, BITS_PER_UNIT)
8444 0 : && multiple_p (bitsize, BITS_PER_UNIT))))
8445 : {
8446 89 : gcc_assert (MEM_P (target) && MEM_P (temp));
8447 89 : poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
8448 89 : poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
8449 :
8450 89 : target = adjust_address (target, VOIDmode, bytepos);
8451 89 : emit_block_move (target, temp,
8452 89 : gen_int_mode (bytesize, Pmode),
8453 : BLOCK_OP_NORMAL);
8454 :
8455 89 : return const0_rtx;
8456 : }
8457 :
8458 : /* If the mode of TEMP is still BLKmode and BITSIZE not larger than the
8459 : word size, we need to load the value (see again store_bit_field). */
8460 764869 : if (GET_MODE (temp) == BLKmode && known_le (bitsize, BITS_PER_WORD))
8461 : {
8462 61 : temp_mode = smallest_int_mode_for_size (bitsize).require ();
8463 61 : temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
8464 : temp_mode, false, NULL);
8465 : }
8466 :
8467 : /* Store the value in the bitfield. */
8468 764851 : gcc_checking_assert (known_ge (bitpos, 0));
8469 764851 : store_bit_field (target, bitsize, bitpos,
8470 : bitregion_start, bitregion_end,
8471 : mode, temp, reverse, false);
8472 :
8473 764851 : return const0_rtx;
8474 : }
8475 : else
8476 : {
8477 : /* Now build a reference to just the desired component. */
8478 4071344 : rtx to_rtx = adjust_address (target, mode,
8479 : exact_div (bitpos, BITS_PER_UNIT));
8480 :
8481 4071344 : if (to_rtx == target)
8482 1299134 : to_rtx = copy_rtx (to_rtx);
8483 :
8484 7866499 : if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
8485 3535718 : set_mem_alias_set (to_rtx, alias_set);
8486 :
8487 : /* Above we avoided using bitfield operations for storing a CONSTRUCTOR
8488 : into a target smaller than its type; handle that case now. */
8489 4071344 : if (TREE_CODE (exp) == CONSTRUCTOR && known_size_p (bitsize))
8490 : {
8491 69777 : poly_int64 bytesize = exact_div (bitsize, BITS_PER_UNIT);
8492 69777 : store_constructor (exp, to_rtx, 0, bytesize, reverse);
8493 69777 : return to_rtx;
8494 : }
8495 :
8496 4001567 : return store_expr (exp, to_rtx, 0, nontemporal, reverse);
8497 : }
8498 : }
8499 :
8500 : /* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
8501 : an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
8502 : codes and find the ultimate containing object, which we return.
8503 :
8504 : We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
8505 : bit position, *PUNSIGNEDP to the signedness and *PREVERSEP to the
8506 : storage order of the field.
8507 : If the position of the field is variable, we store a tree
8508 : giving the variable offset (in units) in *POFFSET.
8509 : This offset is in addition to the bit position.
8510 : If the position is not variable, we store 0 in *POFFSET.
8511 :
8512 : If any of the extraction expressions is volatile,
8513 : we store 1 in *PVOLATILEP. Otherwise we don't change that.
8514 :
8515 : If the field is a non-BLKmode bit-field, *PMODE is set to VOIDmode.
8516 : Otherwise, it is a mode that can be used to access the field.
8517 :
8518 : If the field describes a variable-sized object, *PMODE is set to
8519 : BLKmode and *PBITSIZE is set to -1. An access cannot be made in
8520 : this case, but the address of the object can be found. */
8521 :
8522 : tree
8523 296681317 : get_inner_reference (tree exp, poly_int64 *pbitsize,
8524 : poly_int64 *pbitpos, tree *poffset,
8525 : machine_mode *pmode, int *punsignedp,
8526 : int *preversep, int *pvolatilep)
8527 : {
8528 296681317 : tree size_tree = 0;
8529 296681317 : machine_mode mode = VOIDmode;
8530 296681317 : bool blkmode_bitfield = false;
8531 296681317 : tree offset = size_zero_node;
8532 296681317 : poly_offset_int bit_offset = 0;
8533 :
8534 : /* First get the mode, signedness, storage order and size. We do this from
8535 : just the outermost expression. */
8536 296681317 : *pbitsize = -1;
8537 296681317 : if (TREE_CODE (exp) == COMPONENT_REF)
8538 : {
8539 127371209 : tree field = TREE_OPERAND (exp, 1);
8540 127371209 : size_tree = DECL_SIZE (field);
8541 127371209 : if (flag_strict_volatile_bitfields > 0
8542 58 : && TREE_THIS_VOLATILE (exp)
8543 40 : && DECL_BIT_FIELD_TYPE (field)
8544 127371231 : && DECL_MODE (field) != BLKmode)
8545 : /* Volatile bitfields should be accessed in the mode of the
8546 : field's type, not the mode computed based on the bit
8547 : size. */
8548 22 : mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
8549 127371187 : else if (!DECL_BIT_FIELD (field))
8550 : {
8551 126030280 : mode = DECL_MODE (field);
8552 : /* For vector fields re-check the target flags, as DECL_MODE
8553 : could have been set with different target flags than
8554 : the current function has. */
8555 126030280 : if (VECTOR_TYPE_P (TREE_TYPE (field))
8556 126030280 : && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
8557 380589 : mode = TYPE_MODE (TREE_TYPE (field));
8558 : }
8559 1340907 : else if (DECL_MODE (field) == BLKmode)
8560 624 : blkmode_bitfield = true;
8561 :
8562 127371209 : *punsignedp = DECL_UNSIGNED (field);
8563 : }
8564 169310108 : else if (TREE_CODE (exp) == BIT_FIELD_REF)
8565 : {
8566 613860 : size_tree = TREE_OPERAND (exp, 1);
8567 1227301 : *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp))
8568 1077353 : || TYPE_UNSIGNED (TREE_TYPE (exp)));
8569 :
8570 : /* For vector element types with the correct size of access or for
8571 : vector typed accesses use the mode of the access type. */
8572 613860 : if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
8573 461155 : && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
8574 414492 : && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
8575 660558 : || VECTOR_TYPE_P (TREE_TYPE (exp)))
8576 438709 : mode = TYPE_MODE (TREE_TYPE (exp));
8577 : }
8578 : else
8579 : {
8580 168696248 : mode = TYPE_MODE (TREE_TYPE (exp));
8581 168696248 : *punsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
8582 :
8583 168696248 : if (mode == BLKmode)
8584 74687481 : size_tree = TYPE_SIZE (TREE_TYPE (exp));
8585 : else
8586 188017534 : *pbitsize = GET_MODE_BITSIZE (mode);
8587 : }
8588 :
8589 296681317 : if (size_tree != 0)
8590 : {
8591 201842557 : if (!poly_int_tree_p (size_tree, pbitsize))
8592 487998 : mode = BLKmode, *pbitsize = -1;
8593 : }
8594 :
8595 296681317 : *preversep = reverse_storage_order_for_component_p (exp);
8596 :
8597 : /* Compute cumulative bit-offset for nested component-refs and array-refs,
8598 : and find the ultimate containing object. */
8599 758366183 : while (1)
8600 : {
8601 527523750 : switch (TREE_CODE (exp))
8602 : {
8603 613860 : case BIT_FIELD_REF:
8604 613860 : bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
8605 613860 : break;
8606 :
8607 194198123 : case COMPONENT_REF:
8608 194198123 : {
8609 194198123 : tree field = TREE_OPERAND (exp, 1);
8610 194198123 : tree this_offset = component_ref_field_offset (exp);
8611 :
8612 : /* If this field hasn't been filled in yet, don't go past it.
8613 : This should only happen when folding expressions made during
8614 : type construction. */
8615 194198123 : if (this_offset == 0)
8616 : break;
8617 :
8618 194198123 : offset = size_binop (PLUS_EXPR, offset, this_offset);
8619 194198123 : bit_offset += wi::to_poly_offset (DECL_FIELD_BIT_OFFSET (field));
8620 :
8621 : /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */
8622 : }
8623 194198123 : break;
8624 :
8625 32723949 : case ARRAY_REF:
8626 32723949 : case ARRAY_RANGE_REF:
8627 32723949 : {
8628 32723949 : tree index = TREE_OPERAND (exp, 1);
8629 32723949 : tree low_bound = array_ref_low_bound (exp);
8630 32723949 : tree unit_size = array_ref_element_size (exp);
8631 :
8632 : /* We assume all arrays have sizes that are a multiple of a byte.
8633 : First subtract the lower bound, if any, in the type of the
8634 : index, then convert to sizetype and multiply by the size of
8635 : the array element. */
8636 32723949 : if (! integer_zerop (low_bound))
8637 969143 : index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
8638 : index, low_bound);
8639 :
8640 32723949 : offset = size_binop (PLUS_EXPR, offset,
8641 : size_binop (MULT_EXPR,
8642 : fold_convert (sizetype, index),
8643 : unit_size));
8644 : }
8645 32723949 : break;
8646 :
8647 : case REALPART_EXPR:
8648 : break;
8649 :
8650 : case IMAGPART_EXPR:
8651 230842433 : bit_offset += *pbitsize;
8652 : break;
8653 :
8654 : case VIEW_CONVERT_EXPR:
8655 : break;
8656 :
8657 93189413 : case MEM_REF:
8658 : /* Hand back the decl for MEM[&decl, off]. */
8659 93189413 : if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
8660 : {
8661 21928393 : tree off = TREE_OPERAND (exp, 1);
8662 21928393 : if (!integer_zerop (off))
8663 : {
8664 12435824 : poly_offset_int boff = mem_ref_offset (exp);
8665 12435824 : boff <<= LOG2_BITS_PER_UNIT;
8666 12435824 : bit_offset += boff;
8667 : }
8668 21928393 : exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8669 : }
8670 93189413 : goto done;
8671 :
8672 203491904 : default:
8673 203491904 : goto done;
8674 : }
8675 :
8676 : /* If any reference in the chain is volatile, the effect is volatile. */
8677 230842433 : if (TREE_THIS_VOLATILE (exp))
8678 566716 : *pvolatilep = 1;
8679 :
8680 230842433 : exp = TREE_OPERAND (exp, 0);
8681 230842433 : }
8682 296681317 : done:
8683 :
8684 : /* If OFFSET is constant, see if we can return the whole thing as a
8685 : constant bit position. Make sure to handle overflow during
8686 : this conversion. */
8687 296681317 : if (poly_int_tree_p (offset))
8688 : {
8689 282935394 : poly_offset_int tem = wi::sext (wi::to_poly_offset (offset),
8690 282935394 : TYPE_PRECISION (sizetype));
8691 282935394 : tem <<= LOG2_BITS_PER_UNIT;
8692 282935394 : tem += bit_offset;
8693 282935394 : if (tem.to_shwi (pbitpos))
8694 282933966 : *poffset = offset = NULL_TREE;
8695 : }
8696 :
8697 : /* Otherwise, split it up. */
8698 282935394 : if (offset)
8699 : {
8700 : /* Avoid returning a negative bitpos as this may wreak havoc later. */
8701 13747351 : if (!bit_offset.to_shwi (pbitpos) || maybe_lt (*pbitpos, 0))
8702 : {
8703 303 : *pbitpos = num_trailing_bits (bit_offset.force_shwi ());
8704 303 : poly_offset_int bytes = bits_to_bytes_round_down (bit_offset);
8705 303 : offset = size_binop (PLUS_EXPR, offset,
8706 : build_int_cst (sizetype, bytes.force_shwi ()));
8707 : }
8708 :
8709 13747351 : *poffset = offset;
8710 : }
8711 :
8712 : /* We can use BLKmode for a byte-aligned BLKmode bitfield. */
8713 296681317 : if (mode == VOIDmode
8714 5672675 : && blkmode_bitfield
8715 624 : && multiple_p (*pbitpos, BITS_PER_UNIT)
8716 296681805 : && multiple_p (*pbitsize, BITS_PER_UNIT))
8717 5 : *pmode = BLKmode;
8718 : else
8719 296681312 : *pmode = mode;
8720 :
8721 296681317 : return exp;
8722 : }
8723 :
8724 : /* Alignment in bits the TARGET of an assignment may be assumed to have. */
8725 :
8726 : static unsigned HOST_WIDE_INT
8727 514884 : target_align (const_tree target)
8728 : {
8729 : /* We might have a chain of nested references with intermediate misaligning
8730 : bitfields components, so need to recurse to find out. */
8731 :
8732 514884 : unsigned HOST_WIDE_INT this_align, outer_align;
8733 :
8734 514884 : switch (TREE_CODE (target))
8735 : {
8736 : case BIT_FIELD_REF:
8737 : return 1;
8738 :
8739 140117 : case COMPONENT_REF:
8740 140117 : this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
8741 140117 : outer_align = target_align (TREE_OPERAND (target, 0));
8742 140117 : return MIN (this_align, outer_align);
8743 :
8744 190659 : case ARRAY_REF:
8745 190659 : case ARRAY_RANGE_REF:
8746 190659 : this_align = TYPE_ALIGN (TREE_TYPE (target));
8747 190659 : outer_align = target_align (TREE_OPERAND (target, 0));
8748 190659 : return MIN (this_align, outer_align);
8749 :
8750 4700 : CASE_CONVERT:
8751 4700 : case NON_LVALUE_EXPR:
8752 4700 : case VIEW_CONVERT_EXPR:
8753 4700 : this_align = TYPE_ALIGN (TREE_TYPE (target));
8754 4700 : outer_align = target_align (TREE_OPERAND (target, 0));
8755 4700 : return MAX (this_align, outer_align);
8756 :
8757 179403 : default:
8758 179403 : return TYPE_ALIGN (TREE_TYPE (target));
8759 : }
8760 : }
8761 :
8762 :
8763 : /* Given an rtx VALUE that may contain additions and multiplications, return
8764 : an equivalent value that just refers to a register, memory, or constant.
8765 : This is done by generating instructions to perform the arithmetic and
8766 : returning a pseudo-register containing the value.
8767 :
8768 : The returned value may be a REG, SUBREG, MEM or constant. */
8769 :
8770 : rtx
8771 31624161 : force_operand (rtx value, rtx target)
8772 : {
8773 31624161 : rtx op1, op2;
8774 : /* Use subtarget as the target for operand 0 of a binary operation. */
8775 31624161 : rtx subtarget = get_subtarget (target);
8776 31624161 : enum rtx_code code = GET_CODE (value);
8777 :
8778 : /* Check for subreg applied to an expression produced by loop optimizer. */
8779 31624161 : if (code == SUBREG
8780 306255 : && !REG_P (SUBREG_REG (value))
8781 182 : && !MEM_P (SUBREG_REG (value)))
8782 : {
8783 182 : value
8784 182 : = simplify_gen_subreg (GET_MODE (value),
8785 182 : force_reg (GET_MODE (SUBREG_REG (value)),
8786 : force_operand (SUBREG_REG (value),
8787 : NULL_RTX)),
8788 182 : GET_MODE (SUBREG_REG (value)),
8789 182 : SUBREG_BYTE (value));
8790 182 : code = GET_CODE (value);
8791 : }
8792 :
8793 : /* Check for a PIC address load. */
8794 31624161 : if ((code == PLUS || code == MINUS)
8795 3736559 : && XEXP (value, 0) == pic_offset_table_rtx
8796 1926 : && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
8797 1926 : || GET_CODE (XEXP (value, 1)) == LABEL_REF
8798 1926 : || GET_CODE (XEXP (value, 1)) == CONST))
8799 : {
8800 184 : if (!subtarget)
8801 184 : subtarget = gen_reg_rtx (GET_MODE (value));
8802 184 : emit_move_insn (subtarget, value);
8803 184 : return subtarget;
8804 : }
8805 :
8806 31623977 : if (ARITHMETIC_P (value))
8807 : {
8808 3848945 : op2 = XEXP (value, 1);
8809 3848945 : if (!CONSTANT_P (op2) && !(REG_P (op2) && op2 != subtarget))
8810 3848945 : subtarget = 0;
8811 3848945 : if (code == MINUS && CONST_INT_P (op2))
8812 : {
8813 0 : code = PLUS;
8814 0 : op2 = negate_rtx (GET_MODE (value), op2);
8815 : }
8816 :
8817 : /* Check for an addition with OP2 a constant integer and our first
8818 : operand a PLUS of a virtual register and something else. In that
8819 : case, we want to emit the sum of the virtual register and the
8820 : constant first and then add the other value. This allows virtual
8821 : register instantiation to simply modify the constant rather than
8822 : creating another one around this addition. */
8823 3677240 : if (code == PLUS && CONST_INT_P (op2)
8824 3306940 : && GET_CODE (XEXP (value, 0)) == PLUS
8825 64552 : && REG_P (XEXP (XEXP (value, 0), 0))
8826 3856292 : && VIRTUAL_REGISTER_P (XEXP (XEXP (value, 0), 0)))
8827 : {
8828 1150 : rtx temp = expand_simple_binop (GET_MODE (value), code,
8829 : XEXP (XEXP (value, 0), 0), op2,
8830 : subtarget, 0, OPTAB_LIB_WIDEN);
8831 1150 : return expand_simple_binop (GET_MODE (value), code, temp,
8832 1150 : force_operand (XEXP (XEXP (value,
8833 : 0), 1), 0),
8834 1150 : target, 0, OPTAB_LIB_WIDEN);
8835 : }
8836 :
8837 3847795 : op1 = force_operand (XEXP (value, 0), subtarget);
8838 3847795 : op2 = force_operand (op2, NULL_RTX);
8839 3847795 : switch (code)
8840 : {
8841 96974 : case MULT:
8842 96974 : return expand_mult (GET_MODE (value), op1, op2, target, 1);
8843 222 : case DIV:
8844 222 : if (!INTEGRAL_MODE_P (GET_MODE (value)))
8845 222 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8846 222 : target, 1, OPTAB_LIB_WIDEN);
8847 : else
8848 0 : return expand_divmod (0,
8849 : FLOAT_MODE_P (GET_MODE (value))
8850 : ? RDIV_EXPR : TRUNC_DIV_EXPR,
8851 0 : GET_MODE (value), op1, op2, target, 0);
8852 0 : case MOD:
8853 0 : return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8854 0 : target, 0);
8855 348 : case UDIV:
8856 348 : return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
8857 348 : target, 1);
8858 0 : case UMOD:
8859 0 : return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8860 0 : target, 1);
8861 42 : case ASHIFTRT:
8862 42 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8863 42 : target, 0, OPTAB_LIB_WIDEN);
8864 3750209 : default:
8865 3750209 : return expand_simple_binop (GET_MODE (value), code, op1, op2,
8866 3750209 : target, 1, OPTAB_LIB_WIDEN);
8867 : }
8868 : }
8869 27775032 : if (UNARY_P (value))
8870 : {
8871 21755 : if (!target)
8872 11805 : target = gen_reg_rtx (GET_MODE (value));
8873 : /* FIX or UNSIGNED_FIX with integral mode has unspecified rounding,
8874 : while FIX with floating point mode rounds toward zero. So, some
8875 : targets use expressions like (fix:SI (fix:DF (reg:DF ...)))
8876 : to express rounding toward zero during the conversion to int.
8877 : expand_fix isn't able to handle that, it can only handle
8878 : FIX/UNSIGNED_FIX from floating point mode to integral one. */
8879 21755 : if ((code == FIX || code == UNSIGNED_FIX)
8880 8 : && GET_CODE (XEXP (value, 0)) == FIX
8881 0 : && (GET_MODE (XEXP (value, 0))
8882 0 : == GET_MODE (XEXP (XEXP (value, 0), 0))))
8883 0 : op1 = force_operand (XEXP (XEXP (value, 0), 0), NULL_RTX);
8884 : else
8885 21755 : op1 = force_operand (XEXP (value, 0), NULL_RTX);
8886 21755 : switch (code)
8887 : {
8888 10491 : case ZERO_EXTEND:
8889 10491 : case SIGN_EXTEND:
8890 10491 : case TRUNCATE:
8891 10491 : case FLOAT_EXTEND:
8892 10491 : case FLOAT_TRUNCATE:
8893 10491 : convert_move (target, op1, code == ZERO_EXTEND);
8894 10491 : return target;
8895 :
8896 8 : case FIX:
8897 8 : case UNSIGNED_FIX:
8898 8 : expand_fix (target, op1, code == UNSIGNED_FIX);
8899 8 : return target;
8900 :
8901 48 : case FLOAT:
8902 48 : case UNSIGNED_FLOAT:
8903 48 : expand_float (target, op1, code == UNSIGNED_FLOAT);
8904 48 : return target;
8905 :
8906 11208 : default:
8907 11208 : return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
8908 : }
8909 : }
8910 :
8911 : #ifdef INSN_SCHEDULING
8912 : /* On machines that have insn scheduling, we want all memory reference to be
8913 : explicit, so we need to deal with such paradoxical SUBREGs. */
8914 27753277 : if (paradoxical_subreg_p (value) && MEM_P (SUBREG_REG (value)))
8915 0 : value
8916 0 : = simplify_gen_subreg (GET_MODE (value),
8917 0 : force_reg (GET_MODE (SUBREG_REG (value)),
8918 : force_operand (SUBREG_REG (value),
8919 : NULL_RTX)),
8920 : GET_MODE (SUBREG_REG (value)),
8921 0 : SUBREG_BYTE (value));
8922 : #endif
8923 :
8924 : return value;
8925 : }
8926 :
8927 : /* Subroutine of expand_expr: return true iff there is no way that
8928 : EXP can reference X, which is being modified. TOP_P is nonzero if this
8929 : call is going to be used to determine whether we need a temporary
8930 : for EXP, as opposed to a recursive call to this function.
8931 :
8932 : It is always safe for this routine to return false since it merely
8933 : searches for optimization opportunities. */
8934 :
8935 : bool
8936 8938871 : safe_from_p (const_rtx x, tree exp, int top_p)
8937 : {
8938 8938887 : rtx exp_rtl = 0;
8939 8938887 : int i, nops;
8940 :
8941 8938887 : if (x == 0
8942 : /* If EXP has varying size, we MUST use a target since we currently
8943 : have no way of allocating temporaries of variable size
8944 : (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
8945 : So we assume here that something at a higher level has prevented a
8946 : clash. This is somewhat bogus, but the best we can do. Only
8947 : do this when X is BLKmode and when we are at the top level. */
8948 2025958 : || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
8949 1888560 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
8950 0 : && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
8951 0 : || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
8952 0 : || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
8953 : != INTEGER_CST)
8954 0 : && GET_MODE (x) == BLKmode)
8955 : /* If X is in the outgoing argument area, it is always safe. */
8956 10964845 : || (MEM_P (x)
8957 180978 : && (XEXP (x, 0) == virtual_outgoing_args_rtx
8958 180978 : || (GET_CODE (XEXP (x, 0)) == PLUS
8959 132926 : && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
8960 : return true;
8961 :
8962 : /* If this is a subreg of a hard register, declare it unsafe, otherwise,
8963 : find the underlying pseudo. */
8964 2025958 : if (GET_CODE (x) == SUBREG)
8965 : {
8966 0 : x = SUBREG_REG (x);
8967 0 : if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
8968 : return false;
8969 : }
8970 :
8971 : /* Now look at our tree code and possibly recurse. */
8972 2025958 : switch (TREE_CODE_CLASS (TREE_CODE (exp)))
8973 : {
8974 600 : case tcc_declaration:
8975 600 : exp_rtl = DECL_RTL_IF_SET (exp);
8976 : break;
8977 :
8978 : case tcc_constant:
8979 : return true;
8980 :
8981 878427 : case tcc_exceptional:
8982 878427 : if (TREE_CODE (exp) == TREE_LIST)
8983 : {
8984 0 : while (1)
8985 : {
8986 0 : if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), 0))
8987 : return false;
8988 0 : exp = TREE_CHAIN (exp);
8989 0 : if (!exp)
8990 : return true;
8991 0 : if (TREE_CODE (exp) != TREE_LIST)
8992 : return safe_from_p (x, exp, 0);
8993 : }
8994 : }
8995 878427 : else if (TREE_CODE (exp) == CONSTRUCTOR)
8996 : {
8997 : constructor_elt *ce;
8998 : unsigned HOST_WIDE_INT idx;
8999 :
9000 8230667 : FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (exp), idx, ce)
9001 5825 : if ((ce->index != NULL_TREE && !safe_from_p (x, ce->index, 0))
9002 136973 : || !safe_from_p (x, ce->value, 0))
9003 : return false;
9004 : return true;
9005 : }
9006 733735 : else if (TREE_CODE (exp) == ERROR_MARK)
9007 : return true; /* An already-visited SAVE_EXPR? */
9008 : else
9009 : return false;
9010 :
9011 0 : case tcc_statement:
9012 : /* The only case we look at here is the DECL_INITIAL inside a
9013 : DECL_EXPR. */
9014 0 : return (TREE_CODE (exp) != DECL_EXPR
9015 0 : || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
9016 0 : || !DECL_INITIAL (DECL_EXPR_DECL (exp))
9017 0 : || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), 0));
9018 :
9019 0 : case tcc_binary:
9020 0 : case tcc_comparison:
9021 0 : if (!safe_from_p (x, TREE_OPERAND (exp, 1), 0))
9022 : return false;
9023 : /* Fall through. */
9024 :
9025 16 : case tcc_unary:
9026 16 : return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
9027 :
9028 471 : case tcc_expression:
9029 471 : case tcc_reference:
9030 471 : case tcc_vl_exp:
9031 : /* Now do code-specific tests. EXP_RTL is set to any rtx we find in
9032 : the expression. If it is set, we conflict iff we are that rtx or
9033 : both are in memory. Otherwise, we check all operands of the
9034 : expression recursively. */
9035 :
9036 471 : switch (TREE_CODE (exp))
9037 : {
9038 383 : case ADDR_EXPR:
9039 : /* If the operand is static or we are static, we can't conflict.
9040 : Likewise if we don't conflict with the operand at all. */
9041 383 : if (staticp (TREE_OPERAND (exp, 0))
9042 233 : || TREE_STATIC (exp)
9043 616 : || safe_from_p (x, TREE_OPERAND (exp, 0), 0))
9044 : return true;
9045 :
9046 : /* Otherwise, the only way this can conflict is if we are taking
9047 : the address of a DECL a that address if part of X, which is
9048 : very rare. */
9049 0 : exp = TREE_OPERAND (exp, 0);
9050 0 : if (DECL_P (exp))
9051 : {
9052 0 : if (!DECL_RTL_SET_P (exp)
9053 0 : || !MEM_P (DECL_RTL (exp)))
9054 : return false;
9055 : else
9056 0 : exp_rtl = XEXP (DECL_RTL (exp), 0);
9057 : }
9058 : break;
9059 :
9060 73 : case MEM_REF:
9061 73 : if (MEM_P (x)
9062 73 : && alias_sets_conflict_p (MEM_ALIAS_SET (x),
9063 : get_alias_set (exp)))
9064 : return false;
9065 : break;
9066 :
9067 0 : case CALL_EXPR:
9068 : /* Assume that the call will clobber all hard registers and
9069 : all of memory. */
9070 0 : if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
9071 0 : || MEM_P (x))
9072 : return false;
9073 : break;
9074 :
9075 0 : case WITH_CLEANUP_EXPR:
9076 0 : case CLEANUP_POINT_EXPR:
9077 : /* Lowered by gimplify.cc. */
9078 0 : gcc_unreachable ();
9079 :
9080 0 : case SAVE_EXPR:
9081 0 : return safe_from_p (x, TREE_OPERAND (exp, 0), 0);
9082 :
9083 : default:
9084 : break;
9085 : }
9086 :
9087 : /* If we have an rtx, we do not need to scan our operands. */
9088 0 : if (exp_rtl)
9089 : break;
9090 :
9091 88 : nops = TREE_OPERAND_LENGTH (exp);
9092 371 : for (i = 0; i < nops; i++)
9093 195 : if (TREE_OPERAND (exp, i) != 0
9094 195 : && ! safe_from_p (x, TREE_OPERAND (exp, i), 0))
9095 : return false;
9096 :
9097 : break;
9098 :
9099 0 : case tcc_type:
9100 : /* Should never get a type here. */
9101 0 : gcc_unreachable ();
9102 : }
9103 :
9104 : /* If we have an rtl, find any enclosed object. Then see if we conflict
9105 : with it. */
9106 392 : if (exp_rtl)
9107 : {
9108 304 : if (GET_CODE (exp_rtl) == SUBREG)
9109 : {
9110 0 : exp_rtl = SUBREG_REG (exp_rtl);
9111 0 : if (REG_P (exp_rtl)
9112 0 : && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
9113 : return false;
9114 : }
9115 :
9116 : /* If the rtl is X, then it is not safe. Otherwise, it is unless both
9117 : are memory and they conflict. */
9118 304 : return ! (rtx_equal_p (x, exp_rtl)
9119 304 : || (MEM_P (x) && MEM_P (exp_rtl)
9120 4 : && true_dependence (exp_rtl, VOIDmode, x)));
9121 : }
9122 :
9123 : /* If we reach here, it is safe. */
9124 : return true;
9125 : }
9126 :
9127 :
9128 : /* Return the highest power of two that EXP is known to be a multiple of.
9129 : This is used in updating alignment of MEMs in array references. */
9130 :
9131 : unsigned HOST_WIDE_INT
9132 33425973 : highest_pow2_factor (const_tree exp)
9133 : {
9134 33425973 : unsigned HOST_WIDE_INT ret;
9135 33425973 : int trailing_zeros = tree_ctz (exp);
9136 33425973 : if (trailing_zeros >= HOST_BITS_PER_WIDE_INT)
9137 23464010 : return BIGGEST_ALIGNMENT;
9138 9961963 : ret = HOST_WIDE_INT_1U << trailing_zeros;
9139 19458262 : if (ret > BIGGEST_ALIGNMENT)
9140 6627173 : return BIGGEST_ALIGNMENT;
9141 : return ret;
9142 : }
9143 :
9144 : /* Similar, except that the alignment requirements of TARGET are
9145 : taken into account. Assume it is at least as aligned as its
9146 : type, unless it is a COMPONENT_REF in which case the layout of
9147 : the structure gives the alignment. */
9148 :
9149 : static unsigned HOST_WIDE_INT
9150 179408 : highest_pow2_factor_for_target (const_tree target, const_tree exp)
9151 : {
9152 179408 : unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
9153 179408 : unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
9154 :
9155 179408 : return MAX (factor, talign);
9156 : }
9157 :
9158 : /* Convert the tree comparison code TCODE to the rtl one where the
9159 : signedness is UNSIGNEDP. */
9160 :
9161 : enum rtx_code
9162 21181 : convert_tree_comp_to_rtx (enum tree_code tcode, int unsignedp)
9163 : {
9164 21181 : enum rtx_code code;
9165 21181 : switch (tcode)
9166 : {
9167 : case EQ_EXPR:
9168 : code = EQ;
9169 : break;
9170 2408 : case NE_EXPR:
9171 2408 : code = NE;
9172 2408 : break;
9173 4055 : case LT_EXPR:
9174 4055 : code = unsignedp ? LTU : LT;
9175 : break;
9176 2735 : case LE_EXPR:
9177 2735 : code = unsignedp ? LEU : LE;
9178 : break;
9179 3207 : case GT_EXPR:
9180 3207 : code = unsignedp ? GTU : GT;
9181 : break;
9182 4386 : case GE_EXPR:
9183 4386 : code = unsignedp ? GEU : GE;
9184 : break;
9185 31 : case UNORDERED_EXPR:
9186 31 : code = UNORDERED;
9187 31 : break;
9188 31 : case ORDERED_EXPR:
9189 31 : code = ORDERED;
9190 31 : break;
9191 10 : case UNLT_EXPR:
9192 10 : code = UNLT;
9193 10 : break;
9194 19 : case UNLE_EXPR:
9195 19 : code = UNLE;
9196 19 : break;
9197 10 : case UNGT_EXPR:
9198 10 : code = UNGT;
9199 10 : break;
9200 11 : case UNGE_EXPR:
9201 11 : code = UNGE;
9202 11 : break;
9203 4 : case UNEQ_EXPR:
9204 4 : code = UNEQ;
9205 4 : break;
9206 4 : case LTGT_EXPR:
9207 4 : code = LTGT;
9208 4 : break;
9209 :
9210 0 : default:
9211 0 : gcc_unreachable ();
9212 : }
9213 21181 : return code;
9214 : }
9215 :
9216 : /* Subroutine of expand_expr. Expand the two operands of a binary
9217 : expression EXP0 and EXP1 placing the results in OP0 and OP1.
9218 : The value may be stored in TARGET if TARGET is nonzero. The
9219 : MODIFIER argument is as documented by expand_expr. */
9220 :
9221 : void
9222 8321113 : expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
9223 : enum expand_modifier modifier)
9224 : {
9225 8321113 : if (! safe_from_p (target, exp1, 1))
9226 609583 : target = 0;
9227 8321113 : if (operand_equal_p (exp0, exp1, 0))
9228 : {
9229 47886 : *op0 = expand_expr (exp0, target, VOIDmode, modifier);
9230 47886 : *op1 = copy_rtx (*op0);
9231 : }
9232 : else
9233 : {
9234 8273227 : *op0 = expand_expr (exp0, target, VOIDmode, modifier);
9235 8273227 : *op1 = expand_expr (exp1, NULL_RTX, VOIDmode, modifier);
9236 : }
9237 8321113 : }
9238 :
9239 :
9240 : /* Return a MEM that contains constant EXP. DEFER is as for
9241 : output_constant_def and MODIFIER is as for expand_expr. */
9242 :
9243 : static rtx
9244 2985765 : expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
9245 : {
9246 2985765 : rtx mem;
9247 :
9248 2985765 : mem = output_constant_def (exp, defer);
9249 2985765 : if (modifier != EXPAND_INITIALIZER)
9250 1908257 : mem = use_anchored_address (mem);
9251 2985765 : return mem;
9252 : }
9253 :
9254 : /* A subroutine of expand_expr_addr_expr. Evaluate the address of EXP.
9255 : The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
9256 :
9257 : static rtx
9258 14586912 : expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
9259 : enum expand_modifier modifier, addr_space_t as)
9260 : {
9261 14586912 : rtx result, subtarget;
9262 14586912 : tree inner, offset;
9263 14586912 : poly_int64 bitsize, bitpos;
9264 14586912 : int unsignedp, reversep, volatilep = 0;
9265 14586912 : machine_mode mode1;
9266 :
9267 : /* If we are taking the address of a constant and are at the top level,
9268 : we have to use output_constant_def since we can't call force_const_mem
9269 : at top level. */
9270 : /* ??? This should be considered a front-end bug. We should not be
9271 : generating ADDR_EXPR of something that isn't an LVALUE. The only
9272 : exception here is STRING_CST. */
9273 14586912 : if (CONSTANT_CLASS_P (exp))
9274 : {
9275 2722717 : result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
9276 2722717 : if (modifier < EXPAND_SUM)
9277 1816598 : result = force_operand (result, target);
9278 : return result;
9279 : }
9280 :
9281 : /* Everything must be something allowed by is_gimple_addressable. */
9282 11864195 : switch (TREE_CODE (exp))
9283 : {
9284 46 : case INDIRECT_REF:
9285 : /* This case will happen via recursion for &a->b. */
9286 46 : return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier);
9287 :
9288 579251 : case MEM_REF:
9289 579251 : {
9290 579251 : tree tem = TREE_OPERAND (exp, 0);
9291 579251 : if (!integer_zerop (TREE_OPERAND (exp, 1)))
9292 304790 : tem = fold_build_pointer_plus (tem, TREE_OPERAND (exp, 1));
9293 579251 : return expand_expr (tem, target, tmode, modifier);
9294 : }
9295 :
9296 1270 : case TARGET_MEM_REF:
9297 1270 : return addr_for_mem_ref (exp, as, true);
9298 :
9299 60127 : case CONST_DECL:
9300 : /* Expand the initializer like constants above. */
9301 60127 : result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
9302 : 0, modifier), 0);
9303 60127 : if (modifier < EXPAND_SUM)
9304 60121 : result = force_operand (result, target);
9305 : return result;
9306 :
9307 209 : case REALPART_EXPR:
9308 : /* The real part of the complex number is always first, therefore
9309 : the address is the same as the address of the parent object. */
9310 209 : offset = 0;
9311 209 : bitpos = 0;
9312 209 : inner = TREE_OPERAND (exp, 0);
9313 209 : break;
9314 :
9315 126 : case IMAGPART_EXPR:
9316 : /* The imaginary part of the complex number is always second.
9317 : The expression is therefore always offset by the size of the
9318 : scalar type. */
9319 126 : offset = 0;
9320 252 : bitpos = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (exp)));
9321 126 : inner = TREE_OPERAND (exp, 0);
9322 126 : break;
9323 :
9324 13 : case COMPOUND_LITERAL_EXPR:
9325 : /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from
9326 : initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL
9327 : with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static
9328 : array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL;
9329 : the initializers aren't gimplified. */
9330 13 : if (COMPOUND_LITERAL_EXPR_DECL (exp)
9331 13 : && is_global_var (COMPOUND_LITERAL_EXPR_DECL (exp)))
9332 13 : return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
9333 13 : target, tmode, modifier, as);
9334 : /* FALLTHRU */
9335 11223153 : default:
9336 : /* If the object is a DECL, then expand it for its rtl. Don't bypass
9337 : expand_expr, as that can have various side effects; LABEL_DECLs for
9338 : example, may not have their DECL_RTL set yet. Expand the rtl of
9339 : CONSTRUCTORs too, which should yield a memory reference for the
9340 : constructor's contents. Assume language specific tree nodes can
9341 : be expanded in some interesting way. */
9342 11223153 : gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
9343 11223153 : if (DECL_P (exp)
9344 1338380 : || TREE_CODE (exp) == CONSTRUCTOR
9345 1338380 : || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
9346 : {
9347 16253696 : result = expand_expr (exp, target, tmode,
9348 : modifier == EXPAND_INITIALIZER
9349 : ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
9350 :
9351 : /* If the DECL isn't in memory, then the DECL wasn't properly
9352 : marked TREE_ADDRESSABLE, which will be either a front-end
9353 : or a tree optimizer bug. */
9354 :
9355 9884773 : gcc_assert (MEM_P (result));
9356 9884771 : result = XEXP (result, 0);
9357 :
9358 : /* ??? Is this needed anymore? */
9359 9884771 : if (DECL_P (exp))
9360 9884771 : TREE_USED (exp) = 1;
9361 :
9362 9884771 : if (modifier != EXPAND_INITIALIZER
9363 : && modifier != EXPAND_CONST_ADDRESS
9364 9884771 : && modifier != EXPAND_SUM)
9365 4317183 : result = force_operand (result, target);
9366 : return result;
9367 : }
9368 :
9369 : /* Pass FALSE as the last argument to get_inner_reference although
9370 : we are expanding to RTL. The rationale is that we know how to
9371 : handle "aligning nodes" here: we can just bypass them because
9372 : they won't change the final object whose address will be returned
9373 : (they actually exist only for that purpose). */
9374 1338380 : inner = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
9375 : &unsignedp, &reversep, &volatilep);
9376 1338380 : break;
9377 : }
9378 :
9379 : /* We must have made progress. */
9380 1338715 : gcc_assert (inner != exp);
9381 :
9382 1338715 : subtarget = offset || maybe_ne (bitpos, 0) ? NULL_RTX : target;
9383 : /* For VIEW_CONVERT_EXPR, where the outer alignment is bigger than
9384 : inner alignment, force the inner to be sufficiently aligned. */
9385 1338715 : if (CONSTANT_CLASS_P (inner)
9386 1338715 : && TYPE_ALIGN (TREE_TYPE (inner)) < TYPE_ALIGN (TREE_TYPE (exp)))
9387 : {
9388 0 : inner = copy_node (inner);
9389 0 : TREE_TYPE (inner) = copy_node (TREE_TYPE (inner));
9390 0 : SET_TYPE_ALIGN (TREE_TYPE (inner), TYPE_ALIGN (TREE_TYPE (exp)));
9391 0 : TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
9392 : }
9393 1338715 : result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
9394 :
9395 1338715 : if (offset)
9396 : {
9397 55417 : rtx tmp;
9398 :
9399 55417 : if (modifier != EXPAND_NORMAL)
9400 1662 : result = force_operand (result, NULL);
9401 57079 : tmp = expand_expr (offset, NULL_RTX, tmode,
9402 : modifier == EXPAND_INITIALIZER
9403 : ? EXPAND_INITIALIZER : EXPAND_NORMAL);
9404 :
9405 : /* expand_expr is allowed to return an object in a mode other
9406 : than TMODE. If it did, we need to convert. */
9407 55417 : if (GET_MODE (tmp) != VOIDmode && tmode != GET_MODE (tmp))
9408 0 : tmp = convert_modes (tmode, GET_MODE (tmp),
9409 0 : tmp, TYPE_UNSIGNED (TREE_TYPE (offset)));
9410 55417 : result = convert_memory_address_addr_space (tmode, result, as);
9411 55417 : tmp = convert_memory_address_addr_space (tmode, tmp, as);
9412 :
9413 55417 : if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
9414 1662 : result = simplify_gen_binary (PLUS, tmode, result, tmp);
9415 : else
9416 : {
9417 53755 : subtarget = maybe_ne (bitpos, 0) ? NULL_RTX : target;
9418 53755 : result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
9419 : 1, OPTAB_LIB_WIDEN);
9420 : }
9421 : }
9422 :
9423 1338715 : if (maybe_ne (bitpos, 0))
9424 : {
9425 : /* Someone beforehand should have rejected taking the address
9426 : of an object that isn't byte-aligned. */
9427 634388 : poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);
9428 634388 : result = convert_memory_address_addr_space (tmode, result, as);
9429 634388 : result = plus_constant (tmode, result, bytepos);
9430 634388 : if (modifier < EXPAND_SUM)
9431 596883 : result = force_operand (result, target);
9432 : }
9433 :
9434 : return result;
9435 : }
9436 :
9437 : /* A subroutine of expand_expr. Evaluate EXP, which is an ADDR_EXPR.
9438 : The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
9439 :
9440 : static rtx
9441 13248182 : expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
9442 : enum expand_modifier modifier)
9443 : {
9444 13248182 : addr_space_t as = ADDR_SPACE_GENERIC;
9445 13248182 : scalar_int_mode address_mode = Pmode;
9446 13248182 : scalar_int_mode pointer_mode = ptr_mode;
9447 13248182 : machine_mode rmode;
9448 13248182 : rtx result;
9449 :
9450 : /* Target mode of VOIDmode says "whatever's natural". */
9451 13248182 : if (tmode == VOIDmode)
9452 11274860 : tmode = TYPE_MODE (TREE_TYPE (exp));
9453 :
9454 13248182 : if (POINTER_TYPE_P (TREE_TYPE (exp)))
9455 : {
9456 13248182 : as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
9457 13248182 : address_mode = targetm.addr_space.address_mode (as);
9458 13248182 : pointer_mode = targetm.addr_space.pointer_mode (as);
9459 : }
9460 :
9461 : /* We can get called with some Weird Things if the user does silliness
9462 : like "(short) &a". In that case, convert_memory_address won't do
9463 : the right thing, so ignore the given target mode. */
9464 13248182 : scalar_int_mode new_tmode = (tmode == pointer_mode
9465 13248182 : ? pointer_mode
9466 13248182 : : address_mode);
9467 :
9468 13248182 : result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
9469 : new_tmode, modifier, as);
9470 :
9471 : /* Despite expand_expr claims concerning ignoring TMODE when not
9472 : strictly convenient, stuff breaks if we don't honor it. Note
9473 : that combined with the above, we only do this for pointer modes. */
9474 13248180 : rmode = GET_MODE (result);
9475 13248180 : if (rmode == VOIDmode)
9476 6 : rmode = new_tmode;
9477 13248180 : if (rmode != new_tmode)
9478 74 : result = convert_memory_address_addr_space (new_tmode, result, as);
9479 :
9480 13248180 : return result;
9481 : }
9482 :
9483 : /* Generate code for computing CONSTRUCTOR EXP.
9484 : An rtx for the computed value is returned. If AVOID_TEMP_MEM
9485 : is TRUE, instead of creating a temporary variable in memory
9486 : NULL is returned and the caller needs to handle it differently. */
9487 :
9488 : static rtx
9489 179905 : expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
9490 : bool avoid_temp_mem)
9491 : {
9492 179905 : tree type = TREE_TYPE (exp);
9493 179905 : machine_mode mode = TYPE_MODE (type);
9494 :
9495 : /* Try to avoid creating a temporary at all. This is possible
9496 : if all of the initializer is zero.
9497 : FIXME: try to handle all [0..255] initializers we can handle
9498 : with memset. */
9499 179905 : if (TREE_STATIC (exp)
9500 2237 : && !TREE_ADDRESSABLE (exp)
9501 2237 : && target != 0 && mode == BLKmode
9502 181013 : && all_zeros_p (exp))
9503 : {
9504 1099 : clear_storage (target, expr_size (exp), BLOCK_OP_NORMAL);
9505 1099 : return target;
9506 : }
9507 :
9508 : /* All elts simple constants => refer to a constant in memory. But
9509 : if this is a non-BLKmode mode, let it store a field at a time
9510 : since that should make a CONST_INT, CONST_WIDE_INT or
9511 : CONST_DOUBLE when we fold. Likewise, if we have a target we can
9512 : use, it is best to store directly into the target unless the type
9513 : is large enough that memcpy will be used. If we are making an
9514 : initializer and all operands are constant, put it in memory as
9515 : well.
9516 :
9517 : FIXME: Avoid trying to fill vector constructors piece-meal.
9518 : Output them with output_constant_def below unless we're sure
9519 : they're zeros. This should go away when vector initializers
9520 : are treated like VECTOR_CST instead of arrays. */
9521 178806 : if ((TREE_STATIC (exp)
9522 1138 : && ((mode == BLKmode
9523 46 : && ! (target != 0 && safe_from_p (target, exp, 1)))
9524 1101 : || TREE_ADDRESSABLE (exp)
9525 1101 : || (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
9526 1101 : && (! can_move_by_pieces
9527 1101 : (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
9528 1101 : TYPE_ALIGN (type)))
9529 4 : && ! mostly_zeros_p (exp))))
9530 179905 : || ((modifier == EXPAND_INITIALIZER || modifier == EXPAND_CONST_ADDRESS)
9531 0 : && TREE_CONSTANT (exp)))
9532 : {
9533 39 : rtx constructor;
9534 :
9535 39 : if (avoid_temp_mem)
9536 : return NULL_RTX;
9537 :
9538 37 : constructor = expand_expr_constant (exp, 1, modifier);
9539 :
9540 37 : if (modifier != EXPAND_CONST_ADDRESS
9541 : && modifier != EXPAND_INITIALIZER
9542 37 : && modifier != EXPAND_SUM)
9543 37 : constructor = validize_mem (constructor);
9544 :
9545 : return constructor;
9546 : }
9547 :
9548 : /* If the CTOR is available in static storage and not mostly
9549 : zeros and we can move it by pieces prefer to do so since
9550 : that's usually more efficient than performing a series of
9551 : stores from immediates. */
9552 178767 : if (avoid_temp_mem
9553 97 : && TREE_STATIC (exp)
9554 38 : && TREE_CONSTANT (exp)
9555 38 : && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
9556 38 : && can_move_by_pieces (tree_to_uhwi (TYPE_SIZE_UNIT (type)),
9557 38 : TYPE_ALIGN (type))
9558 178804 : && ! mostly_zeros_p (exp))
9559 : return NULL_RTX;
9560 :
9561 : /* Handle calls that pass values in multiple non-contiguous
9562 : locations. The Irix 6 ABI has examples of this. */
9563 144639 : if (target == 0 || ! safe_from_p (target, exp, 1)
9564 37723 : || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
9565 : /* Also make a temporary if the store is to volatile memory, to
9566 : avoid individual accesses to aggregate members. */
9567 216448 : || (GET_CODE (target) == MEM
9568 33583 : && MEM_VOLATILE_P (target)
9569 134 : && !TREE_ADDRESSABLE (TREE_TYPE (exp))))
9570 : {
9571 141154 : if (avoid_temp_mem)
9572 : return NULL_RTX;
9573 :
9574 141143 : target = assign_temp (type, TREE_ADDRESSABLE (exp), 1);
9575 : }
9576 :
9577 178726 : store_constructor (exp, target, 0, int_expr_size (exp), false);
9578 178726 : return target;
9579 : }
9580 :
9581 :
9582 : /* expand_expr: generate code for computing expression EXP.
9583 : An rtx for the computed value is returned. The value is never null.
9584 : In the case of a void EXP, const0_rtx is returned.
9585 :
9586 : The value may be stored in TARGET if TARGET is nonzero.
9587 : TARGET is just a suggestion; callers must assume that
9588 : the rtx returned may not be the same as TARGET.
9589 :
9590 : If TARGET is CONST0_RTX, it means that the value will be ignored.
9591 :
9592 : If TMODE is not VOIDmode, it suggests generating the
9593 : result in mode TMODE. But this is done only when convenient.
9594 : Otherwise, TMODE is ignored and the value generated in its natural mode.
9595 : TMODE is just a suggestion; callers must assume that
9596 : the rtx returned may not have mode TMODE.
9597 :
9598 : Note that TARGET may have neither TMODE nor MODE. In that case, it
9599 : probably will not be used.
9600 :
9601 : If MODIFIER is EXPAND_SUM then when EXP is an addition
9602 : we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
9603 : or a nest of (PLUS ...) and (MINUS ...) where the terms are
9604 : products as above, or REG or MEM, or constant.
9605 : Ordinarily in such cases we would output mul or add instructions
9606 : and then return a pseudo reg containing the sum.
9607 :
9608 : EXPAND_INITIALIZER is much like EXPAND_SUM except that
9609 : it also marks a label as absolutely required (it can't be dead).
9610 : It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
9611 : This is used for outputting expressions used in initializers.
9612 :
9613 : EXPAND_CONST_ADDRESS says that it is okay to return a MEM
9614 : with a constant address even if that address is not normally legitimate.
9615 : EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
9616 :
9617 : EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
9618 : a call parameter. Such targets require special care as we haven't yet
9619 : marked TARGET so that it's safe from being trashed by libcalls. We
9620 : don't want to use TARGET for anything but the final result;
9621 : Intermediate values must go elsewhere. Additionally, calls to
9622 : emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
9623 :
9624 : If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
9625 : address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
9626 : DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
9627 : COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
9628 : recursively.
9629 : If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9630 : then *ALT_RTL is set to TARGET (before legitimziation).
9631 :
9632 : If INNER_REFERENCE_P is true, we are expanding an inner reference.
9633 : In this case, we don't adjust a returned MEM rtx that wouldn't be
9634 : sufficiently aligned for its mode; instead, it's up to the caller
9635 : to deal with it afterwards. This is used to make sure that unaligned
9636 : base objects for which out-of-bounds accesses are supported, for
9637 : example record types with trailing arrays, aren't realigned behind
9638 : the back of the caller.
9639 : The normal operating mode is to pass FALSE for this parameter. */
9640 :
9641 : rtx
9642 159541205 : expand_expr_real (tree exp, rtx target, machine_mode tmode,
9643 : enum expand_modifier modifier, rtx *alt_rtl,
9644 : bool inner_reference_p)
9645 : {
9646 159541205 : rtx ret;
9647 :
9648 : /* Handle ERROR_MARK before anybody tries to access its type. */
9649 159541205 : if (TREE_CODE (exp) == ERROR_MARK
9650 159541205 : || (TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
9651 : {
9652 0 : ret = CONST0_RTX (tmode);
9653 0 : return ret ? ret : const0_rtx;
9654 : }
9655 :
9656 159541205 : ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl,
9657 : inner_reference_p);
9658 159541205 : return ret;
9659 : }
9660 :
9661 : /* Try to expand the conditional expression which is represented by
9662 : TREEOP0 ? TREEOP1 : TREEOP2 using conditional moves. If it succeeds
9663 : return the rtl reg which represents the result. Otherwise return
9664 : NULL_RTX. */
9665 :
9666 : static rtx
9667 18096 : expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED,
9668 : tree treeop1 ATTRIBUTE_UNUSED,
9669 : tree treeop2 ATTRIBUTE_UNUSED)
9670 : {
9671 18096 : rtx insn;
9672 18096 : rtx op00, op01, op1, op2;
9673 18096 : enum rtx_code comparison_code;
9674 18096 : machine_mode comparison_mode;
9675 18096 : gimple *srcstmt;
9676 18096 : rtx temp;
9677 18096 : tree type = TREE_TYPE (treeop1);
9678 18096 : int unsignedp = TYPE_UNSIGNED (type);
9679 18096 : machine_mode mode = TYPE_MODE (type);
9680 18096 : machine_mode orig_mode = mode;
9681 18096 : static bool expanding_cond_expr_using_cmove = false;
9682 :
9683 : /* Conditional move expansion can end up TERing two operands which,
9684 : when recursively hitting conditional expressions can result in
9685 : exponential behavior if the cmove expansion ultimatively fails.
9686 : It's hardly profitable to TER a cmove into a cmove so avoid doing
9687 : that by failing early if we end up recursing. */
9688 18096 : if (expanding_cond_expr_using_cmove)
9689 : return NULL_RTX;
9690 :
9691 : /* If we cannot do a conditional move on the mode, try doing it
9692 : with the promoted mode. */
9693 17110 : if (!can_conditionally_move_p (mode))
9694 : {
9695 287 : mode = promote_mode (type, mode, &unsignedp);
9696 287 : if (!can_conditionally_move_p (mode))
9697 : return NULL_RTX;
9698 0 : temp = assign_temp (type, 0, 0); /* Use promoted mode for temp. */
9699 : }
9700 : else
9701 16823 : temp = assign_temp (type, 0, 1);
9702 :
9703 16823 : expanding_cond_expr_using_cmove = true;
9704 16823 : start_sequence ();
9705 16823 : expand_operands (treeop1, treeop2,
9706 : mode == orig_mode ? temp : NULL_RTX, &op1, &op2,
9707 : EXPAND_NORMAL);
9708 :
9709 16823 : if (TREE_CODE (treeop0) == SSA_NAME
9710 16660 : && (srcstmt = get_def_for_expr_class (treeop0, tcc_comparison))
9711 31250 : && !VECTOR_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (srcstmt))))
9712 : {
9713 14424 : type = TREE_TYPE (gimple_assign_rhs1 (srcstmt));
9714 14424 : enum tree_code cmpcode = gimple_assign_rhs_code (srcstmt);
9715 14424 : op00 = expand_normal (gimple_assign_rhs1 (srcstmt));
9716 14424 : op01 = expand_normal (gimple_assign_rhs2 (srcstmt));
9717 14424 : comparison_mode = TYPE_MODE (type);
9718 14424 : unsignedp = TYPE_UNSIGNED (type);
9719 14424 : comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
9720 : }
9721 2399 : else if (COMPARISON_CLASS_P (treeop0)
9722 2399 : && !VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (treeop0, 0))))
9723 : {
9724 163 : type = TREE_TYPE (TREE_OPERAND (treeop0, 0));
9725 163 : enum tree_code cmpcode = TREE_CODE (treeop0);
9726 163 : op00 = expand_normal (TREE_OPERAND (treeop0, 0));
9727 163 : op01 = expand_normal (TREE_OPERAND (treeop0, 1));
9728 163 : unsignedp = TYPE_UNSIGNED (type);
9729 163 : comparison_mode = TYPE_MODE (type);
9730 163 : comparison_code = convert_tree_comp_to_rtx (cmpcode, unsignedp);
9731 : }
9732 : else
9733 : {
9734 2236 : op00 = expand_normal (treeop0);
9735 2236 : op01 = const0_rtx;
9736 2236 : comparison_code = NE;
9737 2236 : comparison_mode = GET_MODE (op00);
9738 2236 : if (comparison_mode == VOIDmode)
9739 0 : comparison_mode = TYPE_MODE (TREE_TYPE (treeop0));
9740 : }
9741 16823 : expanding_cond_expr_using_cmove = false;
9742 :
9743 16823 : if (GET_MODE (op1) != mode)
9744 2369 : op1 = gen_lowpart (mode, op1);
9745 :
9746 16823 : if (GET_MODE (op2) != mode)
9747 9067 : op2 = gen_lowpart (mode, op2);
9748 :
9749 : /* Try to emit the conditional move. */
9750 16823 : insn = emit_conditional_move (temp,
9751 : { comparison_code, op00, op01,
9752 : comparison_mode },
9753 : op1, op2, mode,
9754 : unsignedp);
9755 :
9756 : /* If we could do the conditional move, emit the sequence,
9757 : and return. */
9758 16823 : if (insn)
9759 : {
9760 14257 : rtx_insn *seq = end_sequence ();
9761 14257 : emit_insn (seq);
9762 14257 : return convert_modes (orig_mode, mode, temp, 0);
9763 : }
9764 :
9765 : /* Otherwise discard the sequence and fall back to code with
9766 : branches. */
9767 2566 : end_sequence ();
9768 2566 : return NULL_RTX;
9769 : }
9770 :
9771 : /* A helper function for expand_expr_real_2 to be used with a
9772 : misaligned mem_ref TEMP. Assume an unsigned type if UNSIGNEDP
9773 : is nonzero, with alignment ALIGN in bits.
9774 : Store the value at TARGET if possible (if TARGET is nonzero).
9775 : Regardless of TARGET, we return the rtx for where the value is placed.
9776 : If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9777 : then *ALT_RTL is set to TARGET (before legitimziation). */
9778 :
9779 : static rtx
9780 211467 : expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp,
9781 : unsigned int align, rtx target, rtx *alt_rtl)
9782 : {
9783 211467 : enum insn_code icode;
9784 :
9785 211467 : if ((icode = optab_handler (movmisalign_optab, mode))
9786 : != CODE_FOR_nothing)
9787 : {
9788 135551 : class expand_operand ops[2];
9789 :
9790 : /* We've already validated the memory, and we're creating a
9791 : new pseudo destination. The predicates really can't fail,
9792 : nor can the generator. */
9793 135551 : create_output_operand (&ops[0], NULL_RTX, mode);
9794 135551 : create_fixed_operand (&ops[1], temp);
9795 135551 : expand_insn (icode, 2, ops);
9796 135551 : temp = ops[0].value;
9797 : }
9798 75916 : else if (targetm.slow_unaligned_access (mode, align))
9799 0 : temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
9800 : 0, unsignedp, target,
9801 : mode, mode, false, alt_rtl);
9802 211467 : return temp;
9803 : }
9804 :
9805 : /* Return true if OP is known to be either LOWER or LOWER + 1, with one
9806 : value a positive power of two. */
9807 :
9808 : static bool
9809 60241 : near_pow2_divisor_range_p (tree op, wide_int &lower)
9810 : {
9811 60241 : if (TREE_CODE (op) != SSA_NAME)
9812 : return false;
9813 :
9814 32034 : int_range_max range;
9815 32034 : range_query *query = get_range_query (cfun);
9816 32034 : if (!query->range_of_expr (range, op, currently_expanding_gimple_stmt)
9817 32034 : || range.num_pairs () != 1)
9818 : return false;
9819 :
9820 30036 : lower = range.lower_bound ();
9821 30036 : wide_int upper = lower + 1;
9822 60072 : return (range.upper_bound () == upper
9823 87 : && wi::gt_p (lower, 0, TYPE_SIGN (TREE_TYPE (op)))
9824 30227 : && (wi::popcount (lower) == 1 || wi::popcount (upper) == 1));
9825 32034 : }
9826 :
9827 : /* Helper function of expand_expr_2, expand a division or modulo.
9828 : op0 and op1 should be already expanded treeop0 and treeop1, using
9829 : expand_operands. */
9830 :
9831 : static rtx
9832 169319 : expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
9833 : tree treeop1, rtx op0, rtx op1, rtx target, int unsignedp)
9834 : {
9835 338638 : bool mod_p = (code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR
9836 169319 : || code == CEIL_MOD_EXPR || code == ROUND_MOD_EXPR);
9837 169319 : bool speed_p = optimize_insn_for_speed_p ();
9838 :
9839 169319 : scalar_int_mode int_mode;
9840 169319 : wide_int lower;
9841 : /* Split x / y when y is one of two neighboring constants and the target can
9842 : select between the constant divisions cheaply. */
9843 169319 : if (code == TRUNC_DIV_EXPR
9844 234666 : && is_a <scalar_int_mode> (mode, &int_mode)
9845 65420 : && speed_p
9846 62850 : && can_conditionally_move_p (int_mode)
9847 229560 : && near_pow2_divisor_range_p (treeop1, lower))
9848 : {
9849 73 : signop sgn = TYPE_SIGN (TREE_TYPE (treeop1));
9850 73 : unsigned int prec = GET_MODE_PRECISION (int_mode);
9851 73 : wide_int upper = lower + 1;
9852 73 : rtx op_lower
9853 73 : = immed_wide_int_const (wide_int::from (lower, prec, sgn), int_mode);
9854 73 : rtx op_upper
9855 73 : = immed_wide_int_const (wide_int::from (upper, prec, sgn), int_mode);
9856 :
9857 73 : do_pending_stack_adjust ();
9858 73 : start_sequence ();
9859 73 : rtx q_lower = expand_divmod (0, TRUNC_DIV_EXPR, mode, op0, op_lower,
9860 : NULL_RTX, unsignedp);
9861 73 : rtx q_upper = expand_divmod (0, TRUNC_DIV_EXPR, mode, op0, op_upper,
9862 : NULL_RTX, unsignedp);
9863 73 : rtx split_ret
9864 73 : = emit_conditional_move (target, { EQ, op1, op_lower, int_mode },
9865 : q_lower, q_upper, int_mode, unsignedp);
9866 73 : rtx_insn *split_insns = end_sequence ();
9867 :
9868 : /* Cost the unsplit form as a single DIV/UDIV. */
9869 73 : rtx div_rtx = gen_rtx_fmt_ee (unsignedp ? UDIV : DIV, int_mode, op0, op1);
9870 73 : unsigned div_cost = set_src_cost (div_rtx, int_mode, speed_p);
9871 73 : if (split_ret && seq_cost (split_insns, speed_p) < div_cost)
9872 : {
9873 73 : emit_insn (split_insns);
9874 73 : return split_ret;
9875 : }
9876 73 : }
9877 :
9878 169246 : if (SCALAR_INT_MODE_P (mode)
9879 169246 : && optimize >= 2
9880 141970 : && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1
9881 212730 : && get_range_pos_neg (treeop1, currently_expanding_gimple_stmt) == 1)
9882 : {
9883 : /* If both arguments are known to be positive when interpreted
9884 : as signed, we can expand it as both signed and unsigned
9885 : division or modulo. Choose the cheaper sequence in that case. */
9886 14005 : do_pending_stack_adjust ();
9887 14005 : start_sequence ();
9888 14005 : rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
9889 14005 : rtx_insn *uns_insns = end_sequence ();
9890 14005 : start_sequence ();
9891 14005 : rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
9892 14005 : rtx_insn *sgn_insns = end_sequence ();
9893 14005 : unsigned uns_cost = seq_cost (uns_insns, speed_p);
9894 14005 : unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
9895 14005 : bool was_tie = false;
9896 :
9897 : /* If costs are the same then use as tie breaker the other other
9898 : factor. */
9899 14005 : if (uns_cost == sgn_cost)
9900 : {
9901 3591 : uns_cost = seq_cost (uns_insns, !speed_p);
9902 3591 : sgn_cost = seq_cost (sgn_insns, !speed_p);
9903 3591 : was_tie = true;
9904 : }
9905 :
9906 14005 : if (dump_file && (dump_flags & TDF_DETAILS))
9907 0 : fprintf (dump_file, ";; positive division:%s unsigned cost: %u; "
9908 : "signed cost: %u\n",
9909 : was_tie ? " (needed tie breaker)" : "", uns_cost, sgn_cost);
9910 :
9911 14005 : if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
9912 : {
9913 11288 : emit_insn (uns_insns);
9914 11288 : return uns_ret;
9915 : }
9916 2717 : emit_insn (sgn_insns);
9917 2717 : return sgn_ret;
9918 : }
9919 155241 : return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
9920 169319 : }
9921 :
9922 : /* Return true if EXP has a range of values [0..1], false
9923 : otherwise. This works for constants and ssa names, calling back into the ranger. */
9924 : static bool
9925 1527538 : expr_has_boolean_range (tree exp, gimple *stmt)
9926 : {
9927 : /* An integral type with a single bit of precision. */
9928 3055063 : if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
9929 1527538 : && TYPE_UNSIGNED (TREE_TYPE (exp))
9930 2539342 : && TYPE_PRECISION (TREE_TYPE (exp)) == 1)
9931 : return true;
9932 :
9933 : /* Signed 1 bit integers are not boolean ranges. */
9934 3055063 : if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
9935 3055063 : || TYPE_PRECISION (TREE_TYPE (exp)) <= 1)
9936 : return false;
9937 :
9938 1527494 : if (TREE_CODE (exp) == SSA_NAME)
9939 906818 : return ssa_name_has_boolean_range (exp, stmt);
9940 620676 : if (TREE_CODE (exp) == INTEGER_CST)
9941 546772 : return wi::leu_p (wi::to_wide (exp), 1);
9942 : return false;
9943 : }
9944 :
9945 : rtx
9946 13661179 : expand_expr_real_2 (const_sepops ops, rtx target, machine_mode tmode,
9947 : enum expand_modifier modifier)
9948 : {
9949 13661179 : rtx op0, op1, op2, temp;
9950 13661179 : rtx_code_label *lab;
9951 13661179 : tree type;
9952 13661179 : int unsignedp;
9953 13661179 : machine_mode mode;
9954 13661179 : scalar_int_mode int_mode;
9955 13661179 : enum tree_code code = ops->code;
9956 13661179 : optab this_optab;
9957 13661179 : rtx subtarget, original_target;
9958 13661179 : int ignore;
9959 13661179 : bool reduce_bit_field;
9960 13661179 : location_t loc = ops->location;
9961 13661179 : tree treeop0, treeop1, treeop2;
9962 : #define REDUCE_BIT_FIELD(expr) (reduce_bit_field \
9963 : ? reduce_to_bit_field_precision ((expr), \
9964 : target, \
9965 : type) \
9966 : : (expr))
9967 :
9968 13661179 : type = ops->type;
9969 13661179 : mode = TYPE_MODE (type);
9970 13661179 : unsignedp = TYPE_UNSIGNED (type);
9971 :
9972 13661179 : treeop0 = ops->op0;
9973 13661179 : treeop1 = ops->op1;
9974 13661179 : treeop2 = ops->op2;
9975 :
9976 : /* We should be called only on simple (binary or unary) expressions,
9977 : exactly those that are valid in gimple expressions that aren't
9978 : GIMPLE_SINGLE_RHS (or invalid). */
9979 13661179 : gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
9980 : || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
9981 : || get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS);
9982 :
9983 27322358 : ignore = (target == const0_rtx
9984 13661179 : || ((CONVERT_EXPR_CODE_P (code)
9985 9822213 : || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
9986 3857062 : && TREE_CODE (type) == VOID_TYPE));
9987 :
9988 : /* We should be called only if we need the result. */
9989 0 : gcc_assert (!ignore);
9990 :
9991 : /* An operation in what may be a bit-field type needs the
9992 : result to be reduced to the precision of the bit-field type,
9993 : which is narrower than that of the type's mode. */
9994 28154810 : reduce_bit_field = (INTEGRAL_TYPE_P (type)
9995 13661179 : && !type_has_mode_precision_p (type));
9996 :
9997 832452 : if (reduce_bit_field
9998 832452 : && (modifier == EXPAND_STACK_PARM
9999 831928 : || (target && GET_MODE (target) != mode)))
10000 513699 : target = 0;
10001 :
10002 : /* Use subtarget as the target for operand 0 of a binary operation. */
10003 13661179 : subtarget = get_subtarget (target);
10004 13661179 : original_target = target;
10005 :
10006 13661179 : switch (code)
10007 : {
10008 3842142 : case NON_LVALUE_EXPR:
10009 3842142 : case PAREN_EXPR:
10010 3842142 : CASE_CONVERT:
10011 3842142 : if (treeop0 == error_mark_node)
10012 0 : return const0_rtx;
10013 :
10014 3842142 : if (TREE_CODE (type) == UNION_TYPE)
10015 : {
10016 0 : tree valtype = TREE_TYPE (treeop0);
10017 :
10018 : /* If both input and output are BLKmode, this conversion isn't doing
10019 : anything except possibly changing memory attribute. */
10020 0 : if (mode == BLKmode && TYPE_MODE (valtype) == BLKmode)
10021 : {
10022 0 : rtx result = expand_expr (treeop0, target, tmode,
10023 : modifier);
10024 :
10025 0 : result = copy_rtx (result);
10026 0 : set_mem_attributes (result, type, 0);
10027 0 : return result;
10028 : }
10029 :
10030 0 : if (target == 0)
10031 : {
10032 0 : if (TYPE_MODE (type) != BLKmode)
10033 0 : target = gen_reg_rtx (TYPE_MODE (type));
10034 : else
10035 0 : target = assign_temp (type, 1, 1);
10036 : }
10037 :
10038 0 : if (MEM_P (target))
10039 : /* Store data into beginning of memory target. */
10040 0 : store_expr (treeop0,
10041 0 : adjust_address (target, TYPE_MODE (valtype), 0),
10042 : modifier == EXPAND_STACK_PARM,
10043 0 : false, TYPE_REVERSE_STORAGE_ORDER (type));
10044 :
10045 : else
10046 : {
10047 0 : gcc_assert (REG_P (target)
10048 : && !TYPE_REVERSE_STORAGE_ORDER (type));
10049 :
10050 : /* Store this field into a union of the proper type. */
10051 0 : poly_uint64 op0_size
10052 0 : = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (treeop0)));
10053 0 : poly_uint64 union_size = GET_MODE_BITSIZE (mode);
10054 0 : store_field (target,
10055 : /* The conversion must be constructed so that
10056 : we know at compile time how many bits
10057 : to preserve. */
10058 0 : ordered_min (op0_size, union_size),
10059 0 : 0, 0, 0, TYPE_MODE (valtype), treeop0, 0,
10060 : false, false);
10061 : }
10062 :
10063 : /* Return the entire union. */
10064 : return target;
10065 : }
10066 :
10067 3842142 : if (mode == TYPE_MODE (TREE_TYPE (treeop0)))
10068 : {
10069 2278586 : op0 = expand_expr (treeop0, target, VOIDmode,
10070 : modifier);
10071 :
10072 2278586 : return REDUCE_BIT_FIELD (op0);
10073 : }
10074 :
10075 1927975 : op0 = expand_expr (treeop0, NULL_RTX, mode,
10076 : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
10077 1563556 : if (GET_MODE (op0) == mode)
10078 : ;
10079 :
10080 : /* If OP0 is a constant, just convert it into the proper mode. */
10081 1520564 : else if (CONSTANT_P (op0))
10082 : {
10083 905 : tree inner_type = TREE_TYPE (treeop0);
10084 905 : machine_mode inner_mode = GET_MODE (op0);
10085 :
10086 905 : if (inner_mode == VOIDmode)
10087 15 : inner_mode = TYPE_MODE (inner_type);
10088 :
10089 905 : if (modifier == EXPAND_INITIALIZER)
10090 0 : op0 = force_lowpart_subreg (mode, op0, inner_mode);
10091 : else
10092 905 : op0 = convert_modes (mode, inner_mode, op0,
10093 905 : TYPE_UNSIGNED (inner_type));
10094 : }
10095 :
10096 1519659 : else if (modifier == EXPAND_INITIALIZER)
10097 24 : op0 = gen_rtx_fmt_e (TYPE_UNSIGNED (TREE_TYPE (treeop0))
10098 : ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
10099 :
10100 1519647 : else if (SCALAR_INT_MODE_P (GET_MODE (op0))
10101 1343952 : && optimize >= 2
10102 787542 : && SCALAR_INT_MODE_P (mode)
10103 787542 : && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
10104 787341 : && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
10105 1574682 : > GET_MODE_SIZE (as_a <scalar_int_mode> (GET_MODE (op0))))
10106 2069509 : && get_range_pos_neg (treeop0,
10107 : currently_expanding_gimple_stmt) == 1)
10108 : {
10109 : /* If argument is known to be positive when interpreted
10110 : as signed, we can expand it as both sign and zero
10111 : extension. Choose the cheaper sequence in that case. */
10112 139732 : bool speed_p = optimize_insn_for_speed_p ();
10113 139732 : rtx uns_ret = NULL_RTX, sgn_ret = NULL_RTX;
10114 139732 : do_pending_stack_adjust ();
10115 139732 : start_sequence ();
10116 139732 : if (target == NULL_RTX)
10117 115383 : uns_ret = convert_to_mode (mode, op0, 1);
10118 : else
10119 24349 : convert_move (target, op0, 1);
10120 139732 : rtx_insn *uns_insns = end_sequence ();
10121 139732 : start_sequence ();
10122 139732 : if (target == NULL_RTX)
10123 115383 : sgn_ret = convert_to_mode (mode, op0, 0);
10124 : else
10125 24349 : convert_move (target, op0, 0);
10126 139732 : rtx_insn *sgn_insns = end_sequence ();
10127 139732 : unsigned uns_cost = seq_cost (uns_insns, speed_p);
10128 139732 : unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
10129 139732 : bool was_tie = false;
10130 :
10131 : /* If costs are the same then use as tie breaker the other other
10132 : factor. */
10133 139732 : if (uns_cost == sgn_cost)
10134 : {
10135 38738 : uns_cost = seq_cost (uns_insns, !speed_p);
10136 38738 : sgn_cost = seq_cost (sgn_insns, !speed_p);
10137 38738 : was_tie = true;
10138 : }
10139 :
10140 139732 : if (dump_file && (dump_flags & TDF_DETAILS))
10141 0 : fprintf (dump_file, ";; positive extension:%s unsigned cost: %u; "
10142 : "signed cost: %u\n",
10143 : was_tie ? " (needed tie breaker)" : "",
10144 : uns_cost, sgn_cost);
10145 139732 : if (uns_cost < sgn_cost
10146 139732 : || (uns_cost == sgn_cost && TYPE_UNSIGNED (TREE_TYPE (treeop0))))
10147 : {
10148 124612 : emit_insn (uns_insns);
10149 124612 : sgn_ret = uns_ret;
10150 : }
10151 : else
10152 15120 : emit_insn (sgn_insns);
10153 139732 : if (target == NULL_RTX)
10154 115383 : op0 = sgn_ret;
10155 : else
10156 24349 : op0 = target;
10157 : }
10158 1379915 : else if (target == 0)
10159 866449 : op0 = convert_to_mode (mode, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10160 : else
10161 : {
10162 513466 : convert_move (target, op0, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10163 513466 : op0 = target;
10164 : }
10165 :
10166 1563556 : return REDUCE_BIT_FIELD (op0);
10167 :
10168 0 : case ADDR_SPACE_CONVERT_EXPR:
10169 0 : {
10170 0 : tree treeop0_type = TREE_TYPE (treeop0);
10171 :
10172 0 : gcc_assert (POINTER_TYPE_P (type));
10173 0 : gcc_assert (POINTER_TYPE_P (treeop0_type));
10174 :
10175 0 : addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
10176 0 : addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
10177 :
10178 : /* Conversions between pointers to the same address space should
10179 : have been implemented via CONVERT_EXPR / NOP_EXPR. */
10180 0 : gcc_assert (as_to != as_from);
10181 :
10182 0 : op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
10183 :
10184 : /* Ask target code to handle conversion between pointers
10185 : to overlapping address spaces. */
10186 0 : if (targetm.addr_space.subset_p (as_to, as_from)
10187 0 : || targetm.addr_space.subset_p (as_from, as_to))
10188 : {
10189 0 : op0 = targetm.addr_space.convert (op0, treeop0_type, type);
10190 : }
10191 : else
10192 : {
10193 : /* For disjoint address spaces, converting anything but a null
10194 : pointer invokes undefined behavior. We truncate or extend the
10195 : value as if we'd converted via integers, which handles 0 as
10196 : required, and all others as the programmer likely expects. */
10197 : #ifndef POINTERS_EXTEND_UNSIGNED
10198 : const int POINTERS_EXTEND_UNSIGNED = 1;
10199 : #endif
10200 0 : op0 = convert_modes (mode, TYPE_MODE (treeop0_type),
10201 : op0, POINTERS_EXTEND_UNSIGNED);
10202 : }
10203 0 : gcc_assert (op0);
10204 : return op0;
10205 : }
10206 :
10207 1374078 : case POINTER_PLUS_EXPR:
10208 : /* Even though the sizetype mode and the pointer's mode can be different
10209 : expand is able to handle this correctly and get the correct result out
10210 : of the PLUS_EXPR code. */
10211 : /* Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR
10212 : if sizetype precision is smaller than pointer precision. */
10213 1374078 : if (TYPE_PRECISION (sizetype) < TYPE_PRECISION (type))
10214 0 : treeop1 = fold_convert_loc (loc, type,
10215 : fold_convert_loc (loc, ssizetype,
10216 : treeop1));
10217 : /* If sizetype precision is larger than pointer precision, truncate the
10218 : offset to have matching modes. */
10219 1374078 : else if (TYPE_PRECISION (sizetype) > TYPE_PRECISION (type))
10220 0 : treeop1 = fold_convert_loc (loc, type, treeop1);
10221 : /* FALLTHRU */
10222 :
10223 5392710 : case PLUS_EXPR:
10224 : /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
10225 : something else, make sure we add the register to the constant and
10226 : then to the other thing. This case can occur during strength
10227 : reduction and doing it this way will produce better code if the
10228 : frame pointer or argument pointer is eliminated.
10229 :
10230 : fold-const.cc will ensure that the constant is always in the inner
10231 : PLUS_EXPR, so the only case we need to do anything about is if
10232 : sp, ap, or fp is our second argument, in which case we must swap
10233 : the innermost first argument and our second argument. */
10234 :
10235 5392710 : if (TREE_CODE (treeop0) == PLUS_EXPR
10236 6948 : && TREE_CODE (TREE_OPERAND (treeop0, 1)) == INTEGER_CST
10237 0 : && VAR_P (treeop1)
10238 5392710 : && (DECL_RTL (treeop1) == frame_pointer_rtx
10239 0 : || DECL_RTL (treeop1) == stack_pointer_rtx
10240 0 : || DECL_RTL (treeop1) == arg_pointer_rtx))
10241 : {
10242 0 : gcc_unreachable ();
10243 : }
10244 :
10245 : /* If the result is to be ptr_mode and we are adding an integer to
10246 : something, we might be forming a constant. So try to use
10247 : plus_constant. If it produces a sum and we can't accept it,
10248 : use force_operand. This allows P = &ARR[const] to generate
10249 : efficient code on machines where a SYMBOL_REF is not a valid
10250 : address.
10251 :
10252 : If this is an EXPAND_SUM call, always return the sum. */
10253 5392710 : if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
10254 5392710 : || (mode == ptr_mode && (unsignedp || ! flag_trapv)))
10255 : {
10256 3520619 : if (modifier == EXPAND_STACK_PARM)
10257 18888 : target = 0;
10258 3520619 : if (TREE_CODE (treeop0) == INTEGER_CST
10259 3521626 : && HWI_COMPUTABLE_MODE_P (mode)
10260 3521630 : && TREE_CONSTANT (treeop1))
10261 : {
10262 4 : rtx constant_part;
10263 4 : HOST_WIDE_INT wc;
10264 4 : machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop1));
10265 :
10266 4 : op1 = expand_expr (treeop1, subtarget, VOIDmode,
10267 : EXPAND_SUM);
10268 : /* Use wi::shwi to ensure that the constant is
10269 : truncated according to the mode of OP1, then sign extended
10270 : to a HOST_WIDE_INT. Using the constant directly can result
10271 : in non-canonical RTL in a 64x32 cross compile. */
10272 4 : wc = TREE_INT_CST_LOW (treeop0);
10273 4 : constant_part =
10274 4 : immed_wide_int_const (wi::shwi (wc, wmode), wmode);
10275 4 : op1 = plus_constant (mode, op1, INTVAL (constant_part));
10276 4 : if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
10277 1 : op1 = force_operand (op1, target);
10278 4 : return REDUCE_BIT_FIELD (op1);
10279 : }
10280 :
10281 3520615 : else if (TREE_CODE (treeop1) == INTEGER_CST
10282 7489975 : && HWI_COMPUTABLE_MODE_P (mode)
10283 5899130 : && TREE_CONSTANT (treeop0))
10284 : {
10285 281246 : rtx constant_part;
10286 281246 : HOST_WIDE_INT wc;
10287 281246 : machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop0));
10288 :
10289 490693 : op0 = expand_expr (treeop0, subtarget, VOIDmode,
10290 : (modifier == EXPAND_INITIALIZER
10291 : ? EXPAND_INITIALIZER : EXPAND_SUM));
10292 281246 : if (! CONSTANT_P (op0))
10293 : {
10294 6 : op1 = expand_expr (treeop1, NULL_RTX,
10295 : VOIDmode, modifier);
10296 : /* Return a PLUS if modifier says it's OK. */
10297 6 : if (modifier == EXPAND_SUM
10298 : || modifier == EXPAND_INITIALIZER)
10299 6 : return simplify_gen_binary (PLUS, mode, op0, op1);
10300 0 : goto binop2;
10301 : }
10302 : /* Use wi::shwi to ensure that the constant is
10303 : truncated according to the mode of OP1, then sign extended
10304 : to a HOST_WIDE_INT. Using the constant directly can result
10305 : in non-canonical RTL in a 64x32 cross compile. */
10306 281240 : wc = TREE_INT_CST_LOW (treeop1);
10307 281240 : constant_part
10308 281240 : = immed_wide_int_const (wi::shwi (wc, wmode), wmode);
10309 281240 : op0 = plus_constant (mode, op0, INTVAL (constant_part));
10310 281240 : if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
10311 208616 : op0 = force_operand (op0, target);
10312 281240 : return REDUCE_BIT_FIELD (op0);
10313 : }
10314 : }
10315 :
10316 : /* Use TER to expand pointer addition of a negated value
10317 : as pointer subtraction. */
10318 9149454 : if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
10319 4018619 : || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
10320 81699 : && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
10321 1092841 : && TREE_CODE (treeop1) == SSA_NAME
10322 6249600 : && TYPE_MODE (TREE_TYPE (treeop0))
10323 569070 : == TYPE_MODE (TREE_TYPE (treeop1)))
10324 : {
10325 569070 : gimple *def = get_def_for_expr (treeop1, NEGATE_EXPR);
10326 569070 : if (def)
10327 : {
10328 2173 : treeop1 = gimple_assign_rhs1 (def);
10329 2173 : code = MINUS_EXPR;
10330 2173 : goto do_minus;
10331 : }
10332 : }
10333 :
10334 : /* No sense saving up arithmetic to be done
10335 : if it's all in the wrong mode to form part of an address.
10336 : And force_operand won't know whether to sign-extend or
10337 : zero-extend. */
10338 5109287 : if (modifier != EXPAND_INITIALIZER
10339 5109287 : && (modifier != EXPAND_SUM || mode != ptr_mode))
10340 : {
10341 4531598 : expand_operands (treeop0, treeop1,
10342 : subtarget, &op0, &op1, modifier);
10343 4531598 : if (op0 == const0_rtx)
10344 8994 : return op1;
10345 4522604 : if (op1 == const0_rtx)
10346 : return op0;
10347 4522353 : goto binop2;
10348 : }
10349 :
10350 577689 : expand_operands (treeop0, treeop1,
10351 : subtarget, &op0, &op1, modifier);
10352 577689 : return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
10353 :
10354 552492 : case MINUS_EXPR:
10355 552492 : case POINTER_DIFF_EXPR:
10356 552492 : do_minus:
10357 : /* For initializers, we are allowed to return a MINUS of two
10358 : symbolic constants. Here we handle all cases when both operands
10359 : are constant. */
10360 : /* Handle difference of two symbolic constants,
10361 : for the sake of an initializer. */
10362 552492 : if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
10363 2679 : && really_constant_p (treeop0)
10364 553004 : && really_constant_p (treeop1))
10365 : {
10366 68 : expand_operands (treeop0, treeop1,
10367 : NULL_RTX, &op0, &op1, modifier);
10368 68 : return simplify_gen_binary (MINUS, mode, op0, op1);
10369 : }
10370 :
10371 : /* No sense saving up arithmetic to be done
10372 : if it's all in the wrong mode to form part of an address.
10373 : And force_operand won't know whether to sign-extend or
10374 : zero-extend. */
10375 552424 : if (modifier != EXPAND_INITIALIZER
10376 552424 : && (modifier != EXPAND_SUM || mode != ptr_mode))
10377 549813 : goto binop;
10378 :
10379 2611 : expand_operands (treeop0, treeop1,
10380 : subtarget, &op0, &op1, modifier);
10381 :
10382 : /* Convert A - const to A + (-const). */
10383 2611 : if (CONST_INT_P (op1))
10384 : {
10385 0 : op1 = negate_rtx (mode, op1);
10386 0 : return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
10387 : }
10388 :
10389 2611 : goto binop2;
10390 :
10391 0 : case WIDEN_MULT_PLUS_EXPR:
10392 0 : case WIDEN_MULT_MINUS_EXPR:
10393 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
10394 0 : op2 = expand_normal (treeop2);
10395 0 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
10396 : target, unsignedp);
10397 0 : return target;
10398 :
10399 24470 : case WIDEN_MULT_EXPR:
10400 : /* If first operand is constant, swap them.
10401 : Thus the following special case checks need only
10402 : check the second operand. */
10403 24470 : if (TREE_CODE (treeop0) == INTEGER_CST)
10404 368 : std::swap (treeop0, treeop1);
10405 :
10406 : /* First, check if we have a multiplication of one signed and one
10407 : unsigned operand. */
10408 24470 : if (TREE_CODE (treeop1) != INTEGER_CST
10409 24470 : && (TYPE_UNSIGNED (TREE_TYPE (treeop0))
10410 18639 : != TYPE_UNSIGNED (TREE_TYPE (treeop1))))
10411 : {
10412 0 : machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));
10413 0 : this_optab = usmul_widen_optab;
10414 0 : if (find_widening_optab_handler (this_optab, mode, innermode)
10415 : != CODE_FOR_nothing)
10416 : {
10417 0 : if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10418 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
10419 : EXPAND_NORMAL);
10420 : else
10421 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
10422 : EXPAND_NORMAL);
10423 : /* op0 and op1 might still be constant, despite the above
10424 : != INTEGER_CST check. Handle it. */
10425 0 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10426 : {
10427 0 : op0 = convert_modes (mode, innermode, op0, true);
10428 0 : op1 = convert_modes (mode, innermode, op1, false);
10429 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
10430 : target, unsignedp));
10431 : }
10432 0 : goto binop3;
10433 : }
10434 : }
10435 : /* Check for a multiplication with matching signedness. */
10436 24470 : else if ((TREE_CODE (treeop1) == INTEGER_CST
10437 5831 : && int_fits_type_p (treeop1, TREE_TYPE (treeop0)))
10438 24474 : || (TYPE_UNSIGNED (TREE_TYPE (treeop1))
10439 18643 : == TYPE_UNSIGNED (TREE_TYPE (treeop0))))
10440 : {
10441 24470 : tree op0type = TREE_TYPE (treeop0);
10442 24470 : machine_mode innermode = TYPE_MODE (op0type);
10443 24470 : bool zextend_p = TYPE_UNSIGNED (op0type);
10444 24470 : optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
10445 2590 : this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
10446 :
10447 24470 : if (TREE_CODE (treeop0) != INTEGER_CST)
10448 : {
10449 24470 : if (find_widening_optab_handler (this_optab, mode, innermode)
10450 : != CODE_FOR_nothing)
10451 : {
10452 24470 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
10453 : EXPAND_NORMAL);
10454 : /* op0 and op1 might still be constant, despite the above
10455 : != INTEGER_CST check. Handle it. */
10456 24470 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10457 : {
10458 0 : widen_mult_const:
10459 0 : op0 = convert_modes (mode, innermode, op0, zextend_p);
10460 0 : op1
10461 0 : = convert_modes (mode, innermode, op1,
10462 0 : TYPE_UNSIGNED (TREE_TYPE (treeop1)));
10463 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
10464 : target,
10465 : unsignedp));
10466 : }
10467 24470 : temp = expand_widening_mult (mode, op0, op1, target,
10468 : unsignedp, this_optab);
10469 24470 : return REDUCE_BIT_FIELD (temp);
10470 : }
10471 0 : if (find_widening_optab_handler (other_optab, mode, innermode)
10472 : != CODE_FOR_nothing
10473 0 : && innermode == word_mode)
10474 : {
10475 0 : rtx htem, hipart;
10476 0 : op0 = expand_normal (treeop0);
10477 0 : op1 = expand_normal (treeop1);
10478 : /* op0 and op1 might be constants, despite the above
10479 : != INTEGER_CST check. Handle it. */
10480 0 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
10481 0 : goto widen_mult_const;
10482 0 : temp = expand_binop (mode, other_optab, op0, op1, target,
10483 : unsignedp, OPTAB_LIB_WIDEN);
10484 0 : hipart = gen_highpart (word_mode, temp);
10485 0 : htem = expand_mult_highpart_adjust (word_mode, hipart,
10486 : op0, op1, hipart,
10487 : zextend_p);
10488 0 : if (htem != hipart)
10489 0 : emit_move_insn (hipart, htem);
10490 0 : return REDUCE_BIT_FIELD (temp);
10491 : }
10492 : }
10493 : }
10494 0 : treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0);
10495 0 : treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1);
10496 0 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10497 0 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
10498 :
10499 1428593 : case MULT_EXPR:
10500 : /* If this is a fixed-point operation, then we cannot use the code
10501 : below because "expand_mult" doesn't support sat/no-sat fixed-point
10502 : multiplications. */
10503 1428593 : if (ALL_FIXED_POINT_MODE_P (mode))
10504 0 : goto binop;
10505 :
10506 : /* If first operand is constant, swap them.
10507 : Thus the following special case checks need only
10508 : check the second operand. */
10509 1428593 : if (TREE_CODE (treeop0) == INTEGER_CST)
10510 686 : std::swap (treeop0, treeop1);
10511 :
10512 : /* Attempt to return something suitable for generating an
10513 : indexed address, for machines that support that. */
10514 :
10515 539051 : if (modifier == EXPAND_SUM && mode == ptr_mode
10516 1967644 : && tree_fits_shwi_p (treeop1))
10517 : {
10518 531305 : tree exp1 = treeop1;
10519 :
10520 531305 : op0 = expand_expr (treeop0, subtarget, VOIDmode,
10521 : EXPAND_SUM);
10522 :
10523 531305 : if (!REG_P (op0))
10524 245019 : op0 = force_operand (op0, NULL_RTX);
10525 531305 : if (!REG_P (op0))
10526 2358 : op0 = copy_to_mode_reg (mode, op0);
10527 :
10528 531305 : op1 = gen_int_mode (tree_to_shwi (exp1),
10529 531305 : TYPE_MODE (TREE_TYPE (exp1)));
10530 531305 : return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, op1));
10531 : }
10532 :
10533 897288 : if (modifier == EXPAND_STACK_PARM)
10534 2941 : target = 0;
10535 :
10536 897288 : if (SCALAR_INT_MODE_P (mode) && optimize >= 2)
10537 : {
10538 541692 : gimple *def_stmt0 = get_def_for_expr (treeop0, TRUNC_DIV_EXPR);
10539 541692 : gimple *def_stmt1 = get_def_for_expr (treeop1, TRUNC_DIV_EXPR);
10540 541692 : if (def_stmt0
10541 541692 : && !operand_equal_p (treeop1, gimple_assign_rhs2 (def_stmt0), 0))
10542 : def_stmt0 = NULL;
10543 541692 : if (def_stmt1
10544 541692 : && !operand_equal_p (treeop0, gimple_assign_rhs2 (def_stmt1), 0))
10545 : def_stmt1 = NULL;
10546 :
10547 541692 : if (def_stmt0 || def_stmt1)
10548 : {
10549 : /* X / Y * Y can be expanded as X - X % Y too.
10550 : Choose the cheaper sequence of those two. */
10551 194 : if (def_stmt0)
10552 194 : treeop0 = gimple_assign_rhs1 (def_stmt0);
10553 : else
10554 : {
10555 0 : treeop1 = treeop0;
10556 0 : treeop0 = gimple_assign_rhs1 (def_stmt1);
10557 : }
10558 194 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
10559 : EXPAND_NORMAL);
10560 194 : bool speed_p = optimize_insn_for_speed_p ();
10561 194 : do_pending_stack_adjust ();
10562 194 : start_sequence ();
10563 194 : rtx divmul_ret
10564 194 : = expand_expr_divmod (TRUNC_DIV_EXPR, mode, treeop0, treeop1,
10565 : op0, op1, NULL_RTX, unsignedp);
10566 194 : divmul_ret = expand_mult (mode, divmul_ret, op1, target,
10567 : unsignedp);
10568 194 : rtx_insn *divmul_insns = end_sequence ();
10569 194 : start_sequence ();
10570 194 : rtx modsub_ret
10571 194 : = expand_expr_divmod (TRUNC_MOD_EXPR, mode, treeop0, treeop1,
10572 : op0, op1, NULL_RTX, unsignedp);
10573 194 : this_optab = optab_for_tree_code (MINUS_EXPR, type,
10574 : optab_default);
10575 194 : modsub_ret = expand_binop (mode, this_optab, op0, modsub_ret,
10576 : target, unsignedp, OPTAB_LIB_WIDEN);
10577 194 : rtx_insn *modsub_insns = end_sequence ();
10578 194 : unsigned divmul_cost = seq_cost (divmul_insns, speed_p);
10579 194 : unsigned modsub_cost = seq_cost (modsub_insns, speed_p);
10580 : /* If costs are the same then use as tie breaker the other other
10581 : factor. */
10582 194 : if (divmul_cost == modsub_cost)
10583 : {
10584 5 : divmul_cost = seq_cost (divmul_insns, !speed_p);
10585 5 : modsub_cost = seq_cost (modsub_insns, !speed_p);
10586 : }
10587 :
10588 194 : if (divmul_cost <= modsub_cost)
10589 : {
10590 121 : emit_insn (divmul_insns);
10591 121 : return REDUCE_BIT_FIELD (divmul_ret);
10592 : }
10593 73 : emit_insn (modsub_insns);
10594 73 : return REDUCE_BIT_FIELD (modsub_ret);
10595 : }
10596 : }
10597 :
10598 897094 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10599 :
10600 : /* Expand X*Y as X&-Y when Y must be zero or one. */
10601 897094 : if (SCALAR_INT_MODE_P (mode))
10602 : {
10603 763769 : bool bit0_p = expr_has_boolean_range (treeop0, currently_expanding_gimple_stmt);
10604 763769 : bool bit1_p = expr_has_boolean_range (treeop1, currently_expanding_gimple_stmt);
10605 :
10606 : /* Expand X*Y as X&Y when both X and Y must be zero or one. */
10607 763769 : if (bit0_p && bit1_p)
10608 0 : return REDUCE_BIT_FIELD (expand_and (mode, op0, op1, target));
10609 :
10610 763769 : if (bit0_p || bit1_p)
10611 : {
10612 3987 : bool speed = optimize_insn_for_speed_p ();
10613 3987 : int cost = add_cost (speed, mode) + neg_cost (speed, mode);
10614 3987 : struct algorithm algorithm;
10615 3987 : enum mult_variant variant;
10616 3987 : if (CONST_INT_P (op1)
10617 3987 : ? !choose_mult_variant (mode, INTVAL (op1),
10618 : &algorithm, &variant, cost)
10619 627 : : cost < mul_cost (speed, mode))
10620 : {
10621 1954 : temp = bit0_p ? expand_and (mode, negate_rtx (mode, op0),
10622 : op1, target)
10623 238 : : expand_and (mode, op0,
10624 : negate_rtx (mode, op1),
10625 : target);
10626 1954 : return REDUCE_BIT_FIELD (temp);
10627 : }
10628 : }
10629 : }
10630 :
10631 895140 : return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
10632 :
10633 168931 : case TRUNC_MOD_EXPR:
10634 168931 : case FLOOR_MOD_EXPR:
10635 168931 : case CEIL_MOD_EXPR:
10636 168931 : case ROUND_MOD_EXPR:
10637 :
10638 168931 : case TRUNC_DIV_EXPR:
10639 168931 : case FLOOR_DIV_EXPR:
10640 168931 : case CEIL_DIV_EXPR:
10641 168931 : case ROUND_DIV_EXPR:
10642 168931 : case EXACT_DIV_EXPR:
10643 : /* If this is a fixed-point operation, then we cannot use the code
10644 : below because "expand_divmod" doesn't support sat/no-sat fixed-point
10645 : divisions. */
10646 168931 : if (ALL_FIXED_POINT_MODE_P (mode))
10647 0 : goto binop;
10648 :
10649 168931 : if (modifier == EXPAND_STACK_PARM)
10650 312 : target = 0;
10651 : /* Possible optimization: compute the dividend with EXPAND_SUM
10652 : then if the divisor is constant can optimize the case
10653 : where some terms of the dividend have coeffs divisible by it. */
10654 168931 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10655 168931 : return expand_expr_divmod (code, mode, treeop0, treeop1, op0, op1,
10656 168931 : target, unsignedp);
10657 :
10658 30946 : case RDIV_EXPR:
10659 30946 : goto binop;
10660 :
10661 3507 : case MULT_HIGHPART_EXPR:
10662 3507 : expand_operands (treeop0, treeop1, subtarget, &op0, &op1, EXPAND_NORMAL);
10663 3507 : temp = expand_mult_highpart (mode, op0, op1, target, unsignedp);
10664 3507 : gcc_assert (temp);
10665 : return temp;
10666 :
10667 0 : case FIXED_CONVERT_EXPR:
10668 0 : op0 = expand_normal (treeop0);
10669 0 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10670 0 : target = gen_reg_rtx (mode);
10671 :
10672 0 : if ((TREE_CODE (TREE_TYPE (treeop0)) == INTEGER_TYPE
10673 0 : && TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10674 0 : || (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type)))
10675 0 : expand_fixed_convert (target, op0, 1, TYPE_SATURATING (type));
10676 : else
10677 0 : expand_fixed_convert (target, op0, 0, TYPE_SATURATING (type));
10678 : return target;
10679 :
10680 48303 : case FIX_TRUNC_EXPR:
10681 48303 : op0 = expand_normal (treeop0);
10682 48303 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10683 3427 : target = gen_reg_rtx (mode);
10684 48303 : expand_fix (target, op0, unsignedp);
10685 48303 : return target;
10686 :
10687 133287 : case FLOAT_EXPR:
10688 133287 : op0 = expand_normal (treeop0);
10689 133287 : if (target == 0 || modifier == EXPAND_STACK_PARM)
10690 62946 : target = gen_reg_rtx (mode);
10691 : /* expand_float can't figure out what to do if FROM has VOIDmode.
10692 : So give it the correct mode. With -O, cse will optimize this. */
10693 133287 : if (GET_MODE (op0) == VOIDmode)
10694 109 : op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (treeop0)),
10695 : op0);
10696 266574 : expand_float (target, op0,
10697 133287 : TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10698 133287 : return target;
10699 :
10700 59231 : case NEGATE_EXPR:
10701 59231 : op0 = expand_expr (treeop0, subtarget,
10702 : VOIDmode, EXPAND_NORMAL);
10703 59231 : if (modifier == EXPAND_STACK_PARM)
10704 241 : target = 0;
10705 59231 : temp = expand_unop (mode,
10706 : optab_for_tree_code (NEGATE_EXPR, type,
10707 : optab_default),
10708 : op0, target, 0);
10709 59231 : gcc_assert (temp);
10710 59231 : return REDUCE_BIT_FIELD (temp);
10711 :
10712 28313 : case ABS_EXPR:
10713 28313 : case ABSU_EXPR:
10714 28313 : op0 = expand_expr (treeop0, subtarget,
10715 : VOIDmode, EXPAND_NORMAL);
10716 28313 : if (modifier == EXPAND_STACK_PARM)
10717 65 : target = 0;
10718 :
10719 : /* ABS_EXPR is not valid for complex arguments. */
10720 28313 : gcc_assert (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
10721 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT);
10722 :
10723 : /* Unsigned abs is simply the operand. Testing here means we don't
10724 : risk generating incorrect code below. */
10725 28313 : if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
10726 : return op0;
10727 :
10728 28313 : return expand_abs (mode, op0, target, unsignedp,
10729 56626 : safe_from_p (target, treeop0, 1));
10730 :
10731 136366 : case MAX_EXPR:
10732 136366 : case MIN_EXPR:
10733 136366 : target = original_target;
10734 136366 : if (target == 0
10735 136366 : || modifier == EXPAND_STACK_PARM
10736 70606 : || (MEM_P (target) && MEM_VOLATILE_P (target))
10737 70606 : || GET_MODE (target) != mode
10738 206972 : || (REG_P (target)
10739 63991 : && REGNO (target) < FIRST_PSEUDO_REGISTER))
10740 65760 : target = gen_reg_rtx (mode);
10741 136366 : expand_operands (treeop0, treeop1,
10742 : target, &op0, &op1, EXPAND_NORMAL);
10743 :
10744 : /* First try to do it with a special MIN or MAX instruction.
10745 : If that does not win, use a conditional jump to select the proper
10746 : value. */
10747 136366 : this_optab = optab_for_tree_code (code, type, optab_default);
10748 136366 : temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
10749 : OPTAB_WIDEN);
10750 136366 : if (temp != 0)
10751 : return temp;
10752 :
10753 122 : if (VECTOR_TYPE_P (type))
10754 0 : gcc_unreachable ();
10755 :
10756 : /* At this point, a MEM target is no longer useful; we will get better
10757 : code without it. */
10758 :
10759 122 : if (! REG_P (target))
10760 1 : target = gen_reg_rtx (mode);
10761 :
10762 : /* If op1 was placed in target, swap op0 and op1. */
10763 122 : if (target != op0 && target == op1)
10764 0 : std::swap (op0, op1);
10765 :
10766 : /* We generate better code and avoid problems with op1 mentioning
10767 : target by forcing op1 into a pseudo if it isn't a constant. */
10768 122 : if (! CONSTANT_P (op1))
10769 42 : op1 = force_reg (mode, op1);
10770 :
10771 122 : {
10772 122 : enum rtx_code comparison_code;
10773 122 : rtx cmpop1 = op1;
10774 :
10775 122 : if (code == MAX_EXPR)
10776 62 : comparison_code = unsignedp ? GEU : GE;
10777 : else
10778 60 : comparison_code = unsignedp ? LEU : LE;
10779 :
10780 : /* Canonicalize to comparisons against 0. */
10781 122 : if (op1 == const1_rtx)
10782 : {
10783 : /* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
10784 : or (a != 0 ? a : 1) for unsigned.
10785 : For MIN we are safe converting (a <= 1 ? a : 1)
10786 : into (a <= 0 ? a : 1) */
10787 0 : cmpop1 = const0_rtx;
10788 0 : if (code == MAX_EXPR)
10789 0 : comparison_code = unsignedp ? NE : GT;
10790 : }
10791 122 : if (op1 == constm1_rtx && !unsignedp)
10792 : {
10793 : /* Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
10794 : and (a <= -1 ? a : -1) into (a < 0 ? a : -1) */
10795 0 : cmpop1 = const0_rtx;
10796 0 : if (code == MIN_EXPR)
10797 0 : comparison_code = LT;
10798 : }
10799 :
10800 : /* Use a conditional move if possible. */
10801 122 : if (can_conditionally_move_p (mode))
10802 : {
10803 75 : rtx insn;
10804 :
10805 75 : start_sequence ();
10806 :
10807 : /* Try to emit the conditional move. */
10808 75 : insn = emit_conditional_move (target,
10809 : { comparison_code,
10810 : op0, cmpop1, mode },
10811 : op0, op1, mode,
10812 : unsignedp);
10813 :
10814 : /* If we could do the conditional move, emit the sequence,
10815 : and return. */
10816 75 : if (insn)
10817 : {
10818 41 : rtx_insn *seq = end_sequence ();
10819 41 : emit_insn (seq);
10820 41 : return target;
10821 : }
10822 :
10823 : /* Otherwise discard the sequence and fall back to code with
10824 : branches. */
10825 34 : end_sequence ();
10826 : }
10827 :
10828 81 : if (target != op0)
10829 52 : emit_move_insn (target, op0);
10830 :
10831 81 : lab = gen_label_rtx ();
10832 81 : do_compare_rtx_and_jump (target, cmpop1, comparison_code,
10833 : unsignedp, mode, NULL_RTX, NULL, lab,
10834 : profile_probability::uninitialized ());
10835 : }
10836 81 : emit_move_insn (target, op1);
10837 81 : emit_label (lab);
10838 81 : return target;
10839 :
10840 62174 : case BIT_NOT_EXPR:
10841 62174 : op0 = expand_expr (treeop0, subtarget,
10842 : VOIDmode, EXPAND_NORMAL);
10843 62174 : if (modifier == EXPAND_STACK_PARM)
10844 88 : target = 0;
10845 : /* In case we have to reduce the result to bitfield precision
10846 : for unsigned bitfield expand this as XOR with a proper constant
10847 : instead. */
10848 62174 : if (reduce_bit_field && TYPE_UNSIGNED (type))
10849 : {
10850 23258 : int_mode = SCALAR_INT_TYPE_MODE (type);
10851 23258 : wide_int mask = wi::mask (TYPE_PRECISION (type),
10852 46516 : false, GET_MODE_PRECISION (int_mode));
10853 :
10854 46516 : temp = expand_binop (int_mode, xor_optab, op0,
10855 46516 : immed_wide_int_const (mask, int_mode),
10856 : target, 1, OPTAB_LIB_WIDEN);
10857 23258 : }
10858 : else
10859 38916 : temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
10860 62174 : gcc_assert (temp);
10861 : return temp;
10862 :
10863 : /* ??? Can optimize bitwise operations with one arg constant.
10864 : Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
10865 : and (a bitwise1 b) bitwise2 b (etc)
10866 : but that is probably not worth while. */
10867 :
10868 618838 : case BIT_AND_EXPR:
10869 618838 : case BIT_IOR_EXPR:
10870 618838 : case BIT_XOR_EXPR:
10871 618838 : goto binop;
10872 :
10873 8560 : case LROTATE_EXPR:
10874 8560 : case RROTATE_EXPR:
10875 8560 : gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
10876 : || type_has_mode_precision_p (type));
10877 : /* fall through */
10878 :
10879 305153 : case LSHIFT_EXPR:
10880 305153 : case RSHIFT_EXPR:
10881 305153 : {
10882 : /* If this is a fixed-point operation, then we cannot use the code
10883 : below because "expand_shift" doesn't support sat/no-sat fixed-point
10884 : shifts. */
10885 305153 : if (ALL_FIXED_POINT_MODE_P (mode))
10886 0 : goto binop;
10887 :
10888 305153 : if (! safe_from_p (subtarget, treeop1, 1))
10889 4976 : subtarget = 0;
10890 305153 : if (modifier == EXPAND_STACK_PARM)
10891 2586 : target = 0;
10892 305153 : op0 = expand_expr (treeop0, subtarget,
10893 : VOIDmode, EXPAND_NORMAL);
10894 :
10895 : /* Left shift optimization when shifting across word_size boundary.
10896 :
10897 : If mode == GET_MODE_WIDER_MODE (word_mode), then normally
10898 : there isn't native instruction to support this wide mode
10899 : left shift. Given below scenario:
10900 :
10901 : Type A = (Type) B << C
10902 :
10903 : |< T >|
10904 : | dest_high | dest_low |
10905 :
10906 : | word_size |
10907 :
10908 : If the shift amount C caused we shift B to across the word
10909 : size boundary, i.e part of B shifted into high half of
10910 : destination register, and part of B remains in the low
10911 : half, then GCC will use the following left shift expand
10912 : logic:
10913 :
10914 : 1. Initialize dest_low to B.
10915 : 2. Initialize every bit of dest_high to the sign bit of B.
10916 : 3. Logic left shift dest_low by C bit to finalize dest_low.
10917 : The value of dest_low before this shift is kept in a temp D.
10918 : 4. Logic left shift dest_high by C.
10919 : 5. Logic right shift D by (word_size - C).
10920 : 6. Or the result of 4 and 5 to finalize dest_high.
10921 :
10922 : While, by checking gimple statements, if operand B is
10923 : coming from signed extension, then we can simplify above
10924 : expand logic into:
10925 :
10926 : 1. dest_high = src_low >> (word_size - C).
10927 : 2. dest_low = src_low << C.
10928 :
10929 : We can use one arithmetic right shift to finish all the
10930 : purpose of steps 2, 4, 5, 6, thus we reduce the steps
10931 : needed from 6 into 2.
10932 :
10933 : The case is similar for zero extension, except that we
10934 : initialize dest_high to zero rather than copies of the sign
10935 : bit from B. Furthermore, we need to use a logical right shift
10936 : in this case.
10937 :
10938 : The choice of sign-extension versus zero-extension is
10939 : determined entirely by whether or not B is signed and is
10940 : independent of the current setting of unsignedp. */
10941 :
10942 305153 : temp = NULL_RTX;
10943 305153 : if (code == LSHIFT_EXPR
10944 305153 : && target
10945 33124 : && REG_P (target)
10946 30163 : && GET_MODE_2XWIDER_MODE (word_mode).exists (&int_mode)
10947 30163 : && mode == int_mode
10948 1505 : && TREE_CONSTANT (treeop1)
10949 305998 : && TREE_CODE (treeop0) == SSA_NAME)
10950 : {
10951 845 : gimple *def = SSA_NAME_DEF_STMT (treeop0);
10952 845 : if (is_gimple_assign (def)
10953 845 : && gimple_assign_rhs_code (def) == NOP_EXPR)
10954 : {
10955 334 : scalar_int_mode rmode = SCALAR_INT_TYPE_MODE
10956 : (TREE_TYPE (gimple_assign_rhs1 (def)));
10957 :
10958 668 : if (GET_MODE_SIZE (rmode) < GET_MODE_SIZE (int_mode)
10959 622 : && TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (word_mode)
10960 476 : && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (rmode))
10961 71 : >= GET_MODE_BITSIZE (word_mode)))
10962 : {
10963 67 : rtx_insn *seq, *seq_old;
10964 67 : poly_uint64 high_off = subreg_highpart_offset (word_mode,
10965 : int_mode);
10966 67 : bool extend_unsigned
10967 67 : = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)));
10968 67 : rtx low = lowpart_subreg (word_mode, op0, int_mode);
10969 67 : rtx dest_low = lowpart_subreg (word_mode, target, int_mode);
10970 67 : rtx dest_high = simplify_gen_subreg (word_mode, target,
10971 : int_mode, high_off);
10972 67 : HOST_WIDE_INT ramount = (BITS_PER_WORD
10973 67 : - TREE_INT_CST_LOW (treeop1));
10974 67 : tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
10975 :
10976 67 : start_sequence ();
10977 : /* dest_high = src_low >> (word_size - C). */
10978 67 : temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
10979 : rshift, dest_high,
10980 : extend_unsigned);
10981 67 : if (temp != dest_high)
10982 0 : emit_move_insn (dest_high, temp);
10983 :
10984 : /* dest_low = src_low << C. */
10985 67 : temp = expand_variable_shift (LSHIFT_EXPR, word_mode, low,
10986 : treeop1, dest_low, unsignedp);
10987 67 : if (temp != dest_low)
10988 2 : emit_move_insn (dest_low, temp);
10989 :
10990 67 : seq = end_sequence ();
10991 67 : temp = target ;
10992 :
10993 67 : if (have_insn_for (ASHIFT, int_mode))
10994 : {
10995 67 : bool speed_p = optimize_insn_for_speed_p ();
10996 67 : start_sequence ();
10997 67 : rtx ret_old = expand_variable_shift (code, int_mode,
10998 : op0, treeop1,
10999 : target,
11000 : unsignedp);
11001 :
11002 67 : seq_old = end_sequence ();
11003 134 : if (seq_cost (seq, speed_p)
11004 67 : >= seq_cost (seq_old, speed_p))
11005 : {
11006 67 : seq = seq_old;
11007 67 : temp = ret_old;
11008 : }
11009 : }
11010 67 : emit_insn (seq);
11011 : }
11012 : }
11013 : }
11014 :
11015 67 : if (temp == NULL_RTX)
11016 305086 : temp = expand_variable_shift (code, mode, op0, treeop1, target,
11017 : unsignedp);
11018 305153 : if (code == LSHIFT_EXPR)
11019 80437 : temp = REDUCE_BIT_FIELD (temp);
11020 : return temp;
11021 : }
11022 :
11023 : /* Could determine the answer when only additive constants differ. Also,
11024 : the addition of one can be handled by changing the condition. */
11025 643567 : case LT_EXPR:
11026 643567 : case LE_EXPR:
11027 643567 : case GT_EXPR:
11028 643567 : case GE_EXPR:
11029 643567 : case EQ_EXPR:
11030 643567 : case NE_EXPR:
11031 643567 : case UNORDERED_EXPR:
11032 643567 : case ORDERED_EXPR:
11033 643567 : case UNLT_EXPR:
11034 643567 : case UNLE_EXPR:
11035 643567 : case UNGT_EXPR:
11036 643567 : case UNGE_EXPR:
11037 643567 : case UNEQ_EXPR:
11038 643567 : case LTGT_EXPR:
11039 643567 : {
11040 1056578 : temp = do_store_flag (ops,
11041 : modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
11042 : tmode != VOIDmode ? tmode : mode);
11043 643567 : if (temp)
11044 : return temp;
11045 :
11046 : /* Use a compare and a jump for BLKmode comparisons, or for function
11047 : type comparisons is have_canonicalize_funcptr_for_compare. */
11048 :
11049 0 : if ((target == 0
11050 0 : || modifier == EXPAND_STACK_PARM
11051 0 : || ! safe_from_p (target, treeop0, 1)
11052 0 : || ! safe_from_p (target, treeop1, 1)
11053 : /* Make sure we don't have a hard reg (such as function's return
11054 : value) live across basic blocks, if not optimizing. */
11055 0 : || (!optimize && REG_P (target)
11056 0 : && REGNO (target) < FIRST_PSEUDO_REGISTER)))
11057 0 : target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
11058 :
11059 0 : emit_move_insn (target, const0_rtx);
11060 :
11061 0 : rtx_code_label *lab1 = gen_label_rtx ();
11062 0 : jumpifnot_1 (code, treeop0, treeop1, lab1,
11063 : profile_probability::uninitialized ());
11064 :
11065 0 : if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
11066 0 : emit_move_insn (target, constm1_rtx);
11067 : else
11068 0 : emit_move_insn (target, const1_rtx);
11069 :
11070 0 : emit_label (lab1);
11071 0 : return target;
11072 : }
11073 55972 : case COMPLEX_EXPR:
11074 : /* Get the rtx code of the operands. */
11075 55972 : op0 = expand_normal (treeop0);
11076 55972 : op1 = expand_normal (treeop1);
11077 :
11078 55972 : if (!target)
11079 3097 : target = gen_reg_rtx (TYPE_MODE (type));
11080 : else
11081 : /* If target overlaps with op1, then either we need to force
11082 : op1 into a pseudo (if target also overlaps with op0),
11083 : or write the complex parts in reverse order. */
11084 52875 : switch (GET_CODE (target))
11085 : {
11086 50121 : case CONCAT:
11087 50121 : if (reg_overlap_mentioned_p (XEXP (target, 0), op1))
11088 : {
11089 0 : if (reg_overlap_mentioned_p (XEXP (target, 1), op0))
11090 : {
11091 0 : complex_expr_force_op1:
11092 1724 : temp = gen_reg_rtx (GET_MODE_INNER (GET_MODE (target)));
11093 862 : emit_move_insn (temp, op1);
11094 862 : op1 = temp;
11095 862 : break;
11096 : }
11097 0 : complex_expr_swap_order:
11098 : /* Move the imaginary (op1) and real (op0) parts to their
11099 : location. */
11100 1 : write_complex_part (target, op1, true, true);
11101 1 : write_complex_part (target, op0, false, false);
11102 :
11103 1 : return target;
11104 : }
11105 : break;
11106 2754 : case MEM:
11107 5508 : temp = adjust_address_nv (target,
11108 : GET_MODE_INNER (GET_MODE (target)), 0);
11109 2754 : if (reg_overlap_mentioned_p (temp, op1))
11110 : {
11111 863 : scalar_mode imode = GET_MODE_INNER (GET_MODE (target));
11112 1726 : temp = adjust_address_nv (target, imode,
11113 : GET_MODE_SIZE (imode));
11114 863 : if (reg_overlap_mentioned_p (temp, op0))
11115 862 : goto complex_expr_force_op1;
11116 1 : goto complex_expr_swap_order;
11117 : }
11118 : break;
11119 0 : default:
11120 0 : if (reg_overlap_mentioned_p (target, op1))
11121 : {
11122 0 : if (reg_overlap_mentioned_p (target, op0))
11123 0 : goto complex_expr_force_op1;
11124 0 : goto complex_expr_swap_order;
11125 : }
11126 : break;
11127 : }
11128 :
11129 : /* Move the real (op0) and imaginary (op1) parts to their location. */
11130 55971 : write_complex_part (target, op0, false, true);
11131 55971 : write_complex_part (target, op1, true, false);
11132 :
11133 55971 : return target;
11134 :
11135 0 : case WIDEN_SUM_EXPR:
11136 0 : {
11137 0 : tree oprnd0 = treeop0;
11138 0 : tree oprnd1 = treeop1;
11139 :
11140 0 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11141 0 : target = expand_widen_pattern_expr (ops, op0, NULL_RTX, op1,
11142 : target, unsignedp);
11143 0 : return target;
11144 : }
11145 :
11146 18278 : case VEC_UNPACK_HI_EXPR:
11147 18278 : case VEC_UNPACK_LO_EXPR:
11148 18278 : case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
11149 18278 : case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
11150 18278 : {
11151 18278 : op0 = expand_normal (treeop0);
11152 18278 : temp = expand_widen_pattern_expr (ops, op0, NULL_RTX, NULL_RTX,
11153 : target, unsignedp);
11154 18278 : gcc_assert (temp);
11155 : return temp;
11156 : }
11157 :
11158 1754 : case VEC_UNPACK_FLOAT_HI_EXPR:
11159 1754 : case VEC_UNPACK_FLOAT_LO_EXPR:
11160 1754 : {
11161 1754 : op0 = expand_normal (treeop0);
11162 : /* The signedness is determined from input operand. */
11163 1754 : temp = expand_widen_pattern_expr
11164 3508 : (ops, op0, NULL_RTX, NULL_RTX,
11165 1754 : target, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
11166 :
11167 1754 : gcc_assert (temp);
11168 : return temp;
11169 : }
11170 :
11171 995 : case VEC_WIDEN_MULT_HI_EXPR:
11172 995 : case VEC_WIDEN_MULT_LO_EXPR:
11173 995 : case VEC_WIDEN_MULT_EVEN_EXPR:
11174 995 : case VEC_WIDEN_MULT_ODD_EXPR:
11175 995 : case VEC_WIDEN_LSHIFT_HI_EXPR:
11176 995 : case VEC_WIDEN_LSHIFT_LO_EXPR:
11177 995 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11178 995 : target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX,
11179 : target, unsignedp);
11180 995 : gcc_assert (target);
11181 : return target;
11182 :
11183 370 : case VEC_PACK_SAT_EXPR:
11184 370 : case VEC_PACK_FIX_TRUNC_EXPR:
11185 370 : mode = TYPE_MODE (TREE_TYPE (treeop0));
11186 370 : subtarget = NULL_RTX;
11187 370 : goto binop;
11188 :
11189 11106 : case VEC_PACK_TRUNC_EXPR:
11190 11106 : if (VECTOR_BOOLEAN_TYPE_P (type)
11191 2478 : && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (treeop0))
11192 2478 : && mode == TYPE_MODE (TREE_TYPE (treeop0))
11193 11810 : && SCALAR_INT_MODE_P (mode))
11194 : {
11195 704 : class expand_operand eops[4];
11196 704 : machine_mode imode = TYPE_MODE (TREE_TYPE (treeop0));
11197 704 : expand_operands (treeop0, treeop1,
11198 : subtarget, &op0, &op1, EXPAND_NORMAL);
11199 704 : this_optab = vec_pack_sbool_trunc_optab;
11200 704 : enum insn_code icode = optab_handler (this_optab, imode);
11201 704 : create_output_operand (&eops[0], target, mode);
11202 704 : create_convert_operand_from (&eops[1], op0, imode, false);
11203 704 : create_convert_operand_from (&eops[2], op1, imode, false);
11204 704 : temp = GEN_INT (TYPE_VECTOR_SUBPARTS (type).to_constant ());
11205 704 : create_input_operand (&eops[3], temp, imode);
11206 704 : expand_insn (icode, 4, eops);
11207 704 : return eops[0].value;
11208 : }
11209 10402 : mode = TYPE_MODE (TREE_TYPE (treeop0));
11210 10402 : subtarget = NULL_RTX;
11211 10402 : goto binop;
11212 :
11213 27 : case VEC_PACK_FLOAT_EXPR:
11214 27 : mode = TYPE_MODE (TREE_TYPE (treeop0));
11215 27 : expand_operands (treeop0, treeop1,
11216 : subtarget, &op0, &op1, EXPAND_NORMAL);
11217 27 : this_optab = optab_for_tree_code (code, TREE_TYPE (treeop0),
11218 : optab_default);
11219 81 : target = expand_binop (mode, this_optab, op0, op1, target,
11220 27 : TYPE_UNSIGNED (TREE_TYPE (treeop0)),
11221 : OPTAB_LIB_WIDEN);
11222 27 : gcc_assert (target);
11223 : return target;
11224 :
11225 75963 : case VEC_PERM_EXPR:
11226 75963 : {
11227 75963 : expand_operands (treeop0, treeop1, target, &op0, &op1, EXPAND_NORMAL);
11228 75963 : vec_perm_builder sel;
11229 75963 : if (TREE_CODE (treeop2) == VECTOR_CST
11230 75963 : && tree_to_vec_perm_builder (&sel, treeop2))
11231 : {
11232 75945 : machine_mode sel_mode = TYPE_MODE (TREE_TYPE (treeop2));
11233 75945 : temp = expand_vec_perm_const (mode, op0, op1, sel,
11234 : sel_mode, target);
11235 : }
11236 : else
11237 : {
11238 18 : op2 = expand_normal (treeop2);
11239 18 : temp = expand_vec_perm_var (mode, op0, op1, op2, target);
11240 : }
11241 75963 : gcc_assert (temp);
11242 75963 : return temp;
11243 75963 : }
11244 :
11245 429 : case DOT_PROD_EXPR:
11246 429 : {
11247 429 : tree oprnd0 = treeop0;
11248 429 : tree oprnd1 = treeop1;
11249 429 : tree oprnd2 = treeop2;
11250 :
11251 429 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11252 429 : op2 = expand_normal (oprnd2);
11253 429 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
11254 : target, unsignedp);
11255 429 : return target;
11256 : }
11257 :
11258 113 : case SAD_EXPR:
11259 113 : {
11260 113 : tree oprnd0 = treeop0;
11261 113 : tree oprnd1 = treeop1;
11262 113 : tree oprnd2 = treeop2;
11263 :
11264 113 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11265 113 : op2 = expand_normal (oprnd2);
11266 113 : target = expand_widen_pattern_expr (ops, op0, op1, op2,
11267 : target, unsignedp);
11268 113 : return target;
11269 : }
11270 :
11271 0 : case REALIGN_LOAD_EXPR:
11272 0 : {
11273 0 : tree oprnd0 = treeop0;
11274 0 : tree oprnd1 = treeop1;
11275 0 : tree oprnd2 = treeop2;
11276 :
11277 0 : this_optab = optab_for_tree_code (code, type, optab_default);
11278 0 : expand_operands (oprnd0, oprnd1, NULL_RTX, &op0, &op1, EXPAND_NORMAL);
11279 0 : op2 = expand_normal (oprnd2);
11280 0 : temp = expand_ternary_op (mode, this_optab, op0, op1, op2,
11281 : target, unsignedp);
11282 0 : gcc_assert (temp);
11283 : return temp;
11284 : }
11285 :
11286 18096 : case COND_EXPR:
11287 18096 : {
11288 : /* A COND_EXPR with its type being VOID_TYPE represents a
11289 : conditional jump and is handled in
11290 : expand_gimple_cond_expr. */
11291 18096 : gcc_assert (!VOID_TYPE_P (type));
11292 :
11293 : /* Note that COND_EXPRs whose type is a structure or union
11294 : are required to be constructed to contain assignments of
11295 : a temporary variable, so that we can evaluate them here
11296 : for side effect only. If type is void, we must do likewise. */
11297 :
11298 18096 : gcc_assert (!TREE_ADDRESSABLE (type)
11299 : && !ignore
11300 : && TREE_TYPE (treeop1) != void_type_node
11301 : && TREE_TYPE (treeop2) != void_type_node);
11302 :
11303 18096 : temp = expand_cond_expr_using_cmove (treeop0, treeop1, treeop2);
11304 18096 : if (temp)
11305 : return temp;
11306 :
11307 : /* If we are not to produce a result, we have no target. Otherwise,
11308 : if a target was specified use it; it will not be used as an
11309 : intermediate target unless it is safe. If no target, use a
11310 : temporary. */
11311 :
11312 3839 : if (modifier != EXPAND_STACK_PARM
11313 3839 : && original_target
11314 2262 : && safe_from_p (original_target, treeop0, 1)
11315 0 : && GET_MODE (original_target) == mode
11316 3839 : && !MEM_P (original_target))
11317 : temp = original_target;
11318 : else
11319 3839 : temp = assign_temp (type, 0, 1);
11320 :
11321 3839 : do_pending_stack_adjust ();
11322 3839 : NO_DEFER_POP;
11323 3839 : rtx_code_label *lab0 = gen_label_rtx ();
11324 3839 : rtx_code_label *lab1 = gen_label_rtx ();
11325 3839 : jumpifnot (treeop0, lab0,
11326 : profile_probability::uninitialized ());
11327 3839 : store_expr (treeop1, temp,
11328 : modifier == EXPAND_STACK_PARM,
11329 : false, false);
11330 :
11331 3839 : emit_jump_insn (targetm.gen_jump (lab1));
11332 3839 : emit_barrier ();
11333 3839 : emit_label (lab0);
11334 3839 : store_expr (treeop2, temp,
11335 : modifier == EXPAND_STACK_PARM,
11336 : false, false);
11337 :
11338 3839 : emit_label (lab1);
11339 3839 : OK_DEFER_POP;
11340 3839 : return temp;
11341 : }
11342 :
11343 0 : case VEC_DUPLICATE_EXPR:
11344 0 : op0 = expand_expr (treeop0, NULL_RTX, VOIDmode, modifier);
11345 0 : target = expand_vector_broadcast (mode, op0);
11346 0 : gcc_assert (target);
11347 : return target;
11348 :
11349 0 : case VEC_SERIES_EXPR:
11350 0 : expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1, modifier);
11351 0 : return expand_vec_series_expr (mode, op0, op1, target);
11352 :
11353 1226 : case BIT_INSERT_EXPR:
11354 1226 : {
11355 1226 : unsigned bitpos = tree_to_uhwi (treeop2);
11356 1226 : unsigned bitsize;
11357 1226 : if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
11358 881 : bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
11359 : else
11360 345 : bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
11361 1226 : op0 = expand_normal (treeop0);
11362 1226 : op1 = expand_normal (treeop1);
11363 1226 : rtx dst = gen_reg_rtx (mode);
11364 1226 : emit_move_insn (dst, op0);
11365 1226 : store_bit_field (dst, bitsize, bitpos, 0, 0,
11366 1226 : TYPE_MODE (TREE_TYPE (treeop1)), op1, false, false);
11367 1226 : return dst;
11368 : }
11369 :
11370 0 : default:
11371 0 : gcc_unreachable ();
11372 : }
11373 :
11374 : /* Here to do an ordinary binary operator. */
11375 1210369 : binop:
11376 1210369 : expand_operands (treeop0, treeop1,
11377 : subtarget, &op0, &op1, EXPAND_NORMAL);
11378 5735333 : binop2:
11379 5735333 : this_optab = optab_for_tree_code (code, type, optab_default);
11380 5735333 : binop3:
11381 5735333 : if (modifier == EXPAND_STACK_PARM)
11382 27181 : target = 0;
11383 5735333 : temp = expand_binop (mode, this_optab, op0, op1, target,
11384 : unsignedp, OPTAB_LIB_WIDEN);
11385 5735333 : gcc_assert (temp);
11386 : /* Bitwise operations do not need bitfield reduction as we expect their
11387 : operands being properly truncated. */
11388 5735333 : if (code == BIT_XOR_EXPR
11389 : || code == BIT_AND_EXPR
11390 5735333 : || code == BIT_IOR_EXPR)
11391 : return temp;
11392 5116495 : return REDUCE_BIT_FIELD (temp);
11393 : }
11394 : #undef REDUCE_BIT_FIELD
11395 :
11396 :
11397 : /* Return TRUE if expression STMT is suitable for replacement.
11398 : Never consider memory loads as replaceable, because those don't ever lead
11399 : into constant expressions. */
11400 :
11401 : static bool
11402 8 : stmt_is_replaceable_p (gimple *stmt)
11403 : {
11404 8 : if (ssa_is_replaceable_p (stmt))
11405 : {
11406 : /* Don't move around loads. */
11407 7 : if (!gimple_assign_single_p (stmt)
11408 7 : || is_gimple_val (gimple_assign_rhs1 (stmt)))
11409 6 : return true;
11410 : }
11411 : return false;
11412 : }
11413 :
11414 : /* A subroutine of expand_expr_real_1. Expand gimple assignment G,
11415 : which is known to set an SSA_NAME result. The other arguments are
11416 : as for expand_expr_real_1. */
11417 :
11418 : rtx
11419 15253371 : expand_expr_real_gassign (gassign *g, rtx target, machine_mode tmode,
11420 : enum expand_modifier modifier, rtx *alt_rtl,
11421 : bool inner_reference_p)
11422 : {
11423 15253371 : separate_ops ops;
11424 15253371 : rtx r;
11425 15253371 : location_t saved_loc = curr_insn_location ();
11426 15253371 : auto loc = gimple_location (g);
11427 15253371 : if (loc != UNKNOWN_LOCATION)
11428 12213334 : set_curr_insn_location (loc);
11429 15253371 : tree lhs = gimple_assign_lhs (g);
11430 15253371 : ops.code = gimple_assign_rhs_code (g);
11431 15253371 : ops.type = TREE_TYPE (lhs);
11432 15253371 : switch (get_gimple_rhs_class (ops.code))
11433 : {
11434 95664 : case GIMPLE_TERNARY_RHS:
11435 191328 : ops.op2 = gimple_assign_rhs3 (g);
11436 : /* Fallthru */
11437 8183807 : case GIMPLE_BINARY_RHS:
11438 8183807 : ops.op1 = gimple_assign_rhs2 (g);
11439 :
11440 : /* Try to expand conditional compare. */
11441 8183807 : if (targetm.have_ccmp ())
11442 : {
11443 164994 : gcc_checking_assert (targetm.gen_ccmp_next != NULL);
11444 164994 : r = expand_ccmp_expr (g, TYPE_MODE (ops.type));
11445 164994 : if (r)
11446 : break;
11447 : }
11448 : /* Fallthru */
11449 11765406 : case GIMPLE_UNARY_RHS:
11450 11765406 : ops.op0 = gimple_assign_rhs1 (g);
11451 11765406 : ops.location = loc;
11452 11765406 : r = expand_expr_real_2 (&ops, target, tmode, modifier);
11453 11765406 : break;
11454 3487945 : case GIMPLE_SINGLE_RHS:
11455 3487945 : {
11456 3487945 : r = expand_expr_real (gimple_assign_rhs1 (g), target,
11457 : tmode, modifier, alt_rtl,
11458 : inner_reference_p);
11459 3487945 : break;
11460 : }
11461 0 : default:
11462 0 : gcc_unreachable ();
11463 : }
11464 15253371 : set_curr_insn_location (saved_loc);
11465 15253371 : if (REG_P (r) && !REG_EXPR (r))
11466 3994104 : set_reg_attrs_for_decl_rtl (lhs, r);
11467 15253371 : return r;
11468 : }
11469 :
11470 : /* A subroutine of expand_expr_real_1. Attempt to VIEW_CONVERT_EXPR
11471 : the complex expression OP0 to the vector mode MODE. Store the
11472 : result at TARGET if possible (if TARGET is nonzero). Returns
11473 : NULL_RTX on failure. */
11474 : static rtx
11475 6662 : try_expand_complex_as_vector (machine_mode mode, rtx op0, rtx target)
11476 : {
11477 6662 : if (COMPLEX_MODE_P (GET_MODE (op0))
11478 1404 : && VECTOR_MODE_P (mode)
11479 58 : && known_eq (GET_MODE_NUNITS (mode), 2)
11480 6720 : && GET_MODE_INNER (mode) == GET_MODE_INNER (GET_MODE (op0)))
11481 : {
11482 29 : enum insn_code icode = convert_optab_handler (vec_init_optab, mode,
11483 29 : GET_MODE_INNER (mode));
11484 29 : if (icode != CODE_FOR_nothing)
11485 : {
11486 29 : if (!target || !REG_P (target))
11487 16 : target = gen_reg_rtx (mode);
11488 29 : rtx rpart = read_complex_part (op0, false);
11489 29 : rtx ipart = read_complex_part (op0, true);
11490 29 : if (!REG_P (rpart) && !CONSTANT_P (rpart))
11491 0 : rpart = force_reg (GET_MODE_INNER (mode), rpart);
11492 29 : if (!REG_P (ipart) && !CONSTANT_P (ipart))
11493 0 : ipart = force_reg (GET_MODE_INNER (mode), ipart);
11494 29 : rtvec vec = rtvec_alloc (2);
11495 29 : RTVEC_ELT (vec, 0) = rpart;
11496 29 : RTVEC_ELT (vec, 1) = ipart;
11497 29 : rtx par = gen_rtx_PARALLEL (mode, vec);
11498 29 : rtx_insn *insn = GEN_FCN (icode) (target, par);
11499 29 : if (insn)
11500 : {
11501 29 : emit_insn (insn);
11502 29 : return target;
11503 : }
11504 : }
11505 : }
11506 : return NULL_RTX;
11507 : }
11508 :
11509 : rtx
11510 159542845 : expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
11511 : enum expand_modifier modifier, rtx *alt_rtl,
11512 : bool inner_reference_p)
11513 : {
11514 159542845 : rtx op0, op1, temp, decl_rtl;
11515 159542845 : tree type;
11516 159542845 : int unsignedp;
11517 159542845 : machine_mode mode, dmode;
11518 159542845 : enum tree_code code = TREE_CODE (exp);
11519 159542845 : rtx subtarget, original_target;
11520 159542845 : int ignore;
11521 159542845 : bool reduce_bit_field;
11522 159542845 : location_t loc = EXPR_LOCATION (exp);
11523 159542845 : struct separate_ops ops;
11524 159542845 : tree treeop0, treeop1, treeop2;
11525 159542845 : tree ssa_name = NULL_TREE;
11526 159542845 : gimple *g;
11527 :
11528 : /* Some ABIs define padding bits in _BitInt uninitialized. Normally, RTL
11529 : expansion sign/zero extends integral types with less than mode precision
11530 : when reading from bit-fields and after arithmetic operations (see
11531 : REDUCE_BIT_FIELD in expand_expr_real_2) and on subsequent loads relies
11532 : on those extensions to have been already performed, but because of the
11533 : above for _BitInt they need to be sign/zero extended when reading from
11534 : locations that could be exposed to ABI boundaries (when loading from
11535 : objects in memory, or function arguments, return value). Because we
11536 : internally extend after arithmetic operations, we can avoid doing that
11537 : when reading from SSA_NAMEs of vars. */
11538 : #define EXTEND_BITINT(expr) \
11539 : ((BITINT_TYPE_P (type) \
11540 : && !bitint_extended \
11541 : && reduce_bit_field \
11542 : && mode != BLKmode \
11543 : && modifier != EXPAND_MEMORY \
11544 : && modifier != EXPAND_WRITE \
11545 : && modifier != EXPAND_INITIALIZER \
11546 : && modifier != EXPAND_CONST_ADDRESS) \
11547 : ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
11548 :
11549 159542845 : type = TREE_TYPE (exp);
11550 159542845 : mode = TYPE_MODE (type);
11551 159542845 : unsignedp = TYPE_UNSIGNED (type);
11552 159542845 : if (BITINT_TYPE_P (type) && bitint_extended == -1)
11553 : {
11554 9099 : struct bitint_info info;
11555 9099 : bool ok = targetm.c.bitint_type_info (TYPE_PRECISION (type), &info);
11556 9099 : gcc_assert (ok);
11557 9099 : bitint_extended = info.extended;
11558 : }
11559 :
11560 159542845 : treeop0 = treeop1 = treeop2 = NULL_TREE;
11561 159542845 : if (!VL_EXP_CLASS_P (exp))
11562 152731085 : switch (TREE_CODE_LENGTH (code))
11563 : {
11564 5602148 : default:
11565 5602148 : case 3: treeop2 = TREE_OPERAND (exp, 2); /* FALLTHRU */
11566 13727147 : case 2: treeop1 = TREE_OPERAND (exp, 1); /* FALLTHRU */
11567 28311036 : case 1: treeop0 = TREE_OPERAND (exp, 0); /* FALLTHRU */
11568 : case 0: break;
11569 : }
11570 159542845 : ops.code = code;
11571 159542845 : ops.type = type;
11572 159542845 : ops.op0 = treeop0;
11573 159542845 : ops.op1 = treeop1;
11574 159542845 : ops.op2 = treeop2;
11575 159542845 : ops.location = loc;
11576 :
11577 319085690 : ignore = (target == const0_rtx
11578 159542845 : || ((CONVERT_EXPR_CODE_P (code)
11579 154432384 : || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
11580 963111 : && TREE_CODE (type) == VOID_TYPE));
11581 :
11582 : /* An operation in what may be a bit-field type needs the
11583 : result to be reduced to the precision of the bit-field type,
11584 : which is narrower than that of the type's mode. */
11585 319085454 : reduce_bit_field = (!ignore
11586 155043364 : && INTEGRAL_TYPE_P (type)
11587 81753483 : && !type_has_mode_precision_p (type));
11588 :
11589 : /* If we are going to ignore this result, we need only do something
11590 : if there is a side-effect somewhere in the expression. If there
11591 : is, short-circuit the most common cases here. Note that we must
11592 : not call expand_expr with anything but const0_rtx in case this
11593 : is an initial expansion of a size that contains a PLACEHOLDER_EXPR. */
11594 :
11595 : if (ignore)
11596 : {
11597 4499481 : if (! TREE_SIDE_EFFECTS (exp))
11598 : return const0_rtx;
11599 :
11600 : /* Ensure we reference a volatile object even if value is ignored, but
11601 : don't do this if all we are doing is taking its address. */
11602 4499245 : if (TREE_THIS_VOLATILE (exp)
11603 0 : && TREE_CODE (exp) != FUNCTION_DECL
11604 0 : && mode != VOIDmode && mode != BLKmode
11605 0 : && modifier != EXPAND_CONST_ADDRESS)
11606 : {
11607 0 : temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
11608 0 : if (MEM_P (temp))
11609 0 : copy_to_reg (temp);
11610 0 : return const0_rtx;
11611 : }
11612 :
11613 4499245 : if (TREE_CODE_CLASS (code) == tcc_unary
11614 : || code == BIT_FIELD_REF
11615 4499245 : || code == COMPONENT_REF
11616 4499245 : || code == INDIRECT_REF)
11617 0 : return expand_expr (treeop0, const0_rtx, VOIDmode,
11618 0 : modifier);
11619 :
11620 4499245 : else if (TREE_CODE_CLASS (code) == tcc_binary
11621 4499245 : || TREE_CODE_CLASS (code) == tcc_comparison
11622 4499245 : || code == ARRAY_REF || code == ARRAY_RANGE_REF)
11623 : {
11624 0 : expand_expr (treeop0, const0_rtx, VOIDmode, modifier);
11625 0 : expand_expr (treeop1, const0_rtx, VOIDmode, modifier);
11626 0 : return const0_rtx;
11627 : }
11628 :
11629 : target = 0;
11630 : }
11631 :
11632 159542609 : if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
11633 39592 : target = 0;
11634 :
11635 : /* Use subtarget as the target for operand 0 of a binary operation. */
11636 159542609 : subtarget = get_subtarget (target);
11637 159542609 : original_target = target;
11638 :
11639 159542609 : switch (code)
11640 : {
11641 10821 : case LABEL_DECL:
11642 10821 : {
11643 10821 : tree function = decl_function_context (exp);
11644 :
11645 10821 : temp = label_rtx (exp);
11646 14765 : temp = gen_rtx_LABEL_REF (Pmode, temp);
11647 :
11648 10821 : if (function != current_function_decl
11649 1270 : && function != 0)
11650 1270 : LABEL_REF_NONLOCAL_P (temp) = 1;
11651 :
11652 10821 : temp = gen_rtx_MEM (FUNCTION_MODE, temp);
11653 10821 : return temp;
11654 : }
11655 :
11656 57665394 : case SSA_NAME:
11657 : /* ??? ivopts calls expander, without any preparation from
11658 : out-of-ssa. So fake instructions as if this was an access to the
11659 : base variable. This unnecessarily allocates a pseudo, see how we can
11660 : reuse it, if partition base vars have it set already. */
11661 57665394 : if (!currently_expanding_to_rtl)
11662 : {
11663 0 : tree var = SSA_NAME_VAR (exp);
11664 0 : if (var && DECL_RTL_SET_P (var))
11665 0 : return DECL_RTL (var);
11666 0 : return gen_raw_REG (TYPE_MODE (TREE_TYPE (exp)),
11667 0 : LAST_VIRTUAL_REGISTER + 1);
11668 : }
11669 :
11670 57665394 : g = get_gimple_for_ssa_name (exp);
11671 : /* For EXPAND_INITIALIZER try harder to get something simpler. */
11672 57665394 : if (g == NULL
11673 57665394 : && modifier == EXPAND_INITIALIZER
11674 26 : && !SSA_NAME_IS_DEFAULT_DEF (exp)
11675 11 : && (optimize || !SSA_NAME_VAR (exp)
11676 1 : || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
11677 10 : && is_gimple_assign (SSA_NAME_DEF_STMT (exp))
11678 57665402 : && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
11679 6 : g = SSA_NAME_DEF_STMT (exp);
11680 57665394 : if (safe_is_a <gassign *> (g))
11681 9206442 : return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode,
11682 9206442 : modifier, alt_rtl, inner_reference_p);
11683 48458952 : else if (safe_is_a <gcall *> (g))
11684 : {
11685 : /* ??? internal call expansion doesn't follow the usual API
11686 : of returning the destination RTX and being passed a desired
11687 : target. */
11688 75022 : if (modifier == EXPAND_WRITE)
11689 37515 : return DECL_RTL (SSA_NAME_VAR (exp));
11690 37507 : rtx dest = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
11691 37507 : tree tmplhs = make_tree (TREE_TYPE (exp), dest);
11692 37507 : tree var_or_id = SSA_NAME_VAR (exp);
11693 : if (!var_or_id)
11694 27458 : var_or_id = SSA_NAME_IDENTIFIER (exp);
11695 37507 : SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, tmplhs);
11696 37507 : expand_internal_call (as_a <gcall *> (g));
11697 37507 : SET_SSA_NAME_VAR_OR_IDENTIFIER (exp, var_or_id);
11698 37507 : return dest;
11699 : }
11700 :
11701 48383930 : ssa_name = exp;
11702 48383930 : decl_rtl = get_rtx_for_ssa_name (ssa_name);
11703 48383930 : exp = SSA_NAME_VAR (ssa_name);
11704 : /* Optimize and avoid to EXTEND_BITINIT doing anything if it is an
11705 : SSA_NAME computed within the current function. In such case the
11706 : value have been already extended before. While if it is a function
11707 : parameter, result or some memory location, we need to be prepared
11708 : for some other compiler leaving the bits uninitialized. */
11709 18903403 : if (!exp || VAR_P (exp))
11710 : reduce_bit_field = false;
11711 48383930 : goto expand_decl_rtl;
11712 :
11713 19871232 : case VAR_DECL:
11714 : /* Allow accel compiler to handle variables that require special
11715 : treatment, e.g. if they have been modified in some way earlier in
11716 : compilation by the adjust_private_decl OpenACC hook. */
11717 19871232 : if (flag_openacc && targetm.goacc.expand_var_decl)
11718 : {
11719 0 : temp = targetm.goacc.expand_var_decl (exp);
11720 0 : if (temp)
11721 : return temp;
11722 : }
11723 : /* Expand const VAR_DECLs with CONSTRUCTOR initializers that
11724 : have scalar integer modes to a reg via store_constructor. */
11725 19871232 : if (TREE_READONLY (exp)
11726 3379287 : && !TREE_SIDE_EFFECTS (exp)
11727 3356879 : && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM)
11728 18634 : && immediate_const_ctor_p (DECL_INITIAL (exp))
11729 163 : && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (exp)))
11730 127 : && crtl->emit.regno_pointer_align_length
11731 19871359 : && !target)
11732 : {
11733 88 : target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
11734 88 : store_constructor (DECL_INITIAL (exp), target, 0,
11735 88 : int_expr_size (DECL_INITIAL (exp)), false);
11736 88 : return target;
11737 : }
11738 : /* ... fall through ... */
11739 :
11740 20416234 : case PARM_DECL:
11741 : /* If a static var's type was incomplete when the decl was written,
11742 : but the type is complete now, lay out the decl now. */
11743 20416234 : if (DECL_SIZE (exp) == 0
11744 45232 : && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
11745 20461354 : && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
11746 45120 : layout_decl (exp, 0);
11747 :
11748 : /* fall through */
11749 :
11750 21885202 : case FUNCTION_DECL:
11751 21885202 : case RESULT_DECL:
11752 21885202 : decl_rtl = DECL_RTL (exp);
11753 70269132 : expand_decl_rtl:
11754 70269132 : gcc_assert (decl_rtl);
11755 :
11756 : /* DECL_MODE might change when TYPE_MODE depends on attribute target
11757 : settings for VECTOR_TYPE_P that might switch for the function. */
11758 70269132 : if (currently_expanding_to_rtl
11759 66586500 : && code == VAR_DECL && MEM_P (decl_rtl)
11760 85109615 : && VECTOR_TYPE_P (type) && exp && DECL_MODE (exp) != mode)
11761 61 : decl_rtl = change_address (decl_rtl, TYPE_MODE (type), 0);
11762 : else
11763 70269071 : decl_rtl = copy_rtx (decl_rtl);
11764 :
11765 : /* Record writes to register variables. */
11766 70269132 : if (modifier == EXPAND_WRITE
11767 22072007 : && REG_P (decl_rtl)
11768 86416188 : && HARD_REGISTER_P (decl_rtl))
11769 2027 : add_to_hard_reg_set (&crtl->asm_clobbers,
11770 2027 : GET_MODE (decl_rtl), REGNO (decl_rtl));
11771 :
11772 : /* Ensure variable marked as used even if it doesn't go through
11773 : a parser. If it hasn't be used yet, write out an external
11774 : definition. */
11775 70269132 : if (exp)
11776 40788605 : TREE_USED (exp) = 1;
11777 :
11778 : /* Show we haven't gotten RTL for this yet. */
11779 111057737 : temp = 0;
11780 :
11781 : /* Variables inherited from containing functions should have
11782 : been lowered by this point. */
11783 40788605 : if (exp)
11784 : {
11785 40788605 : tree context = decl_function_context (exp);
11786 40788605 : gcc_assert (SCOPE_FILE_SCOPE_P (context)
11787 : || context == current_function_decl
11788 : || TREE_STATIC (exp)
11789 : || DECL_EXTERNAL (exp)
11790 : /* ??? C++ creates functions that are not
11791 : TREE_STATIC. */
11792 : || TREE_CODE (exp) == FUNCTION_DECL);
11793 : }
11794 :
11795 : /* This is the case of an array whose size is to be determined
11796 : from its initializer, while the initializer is still being parsed.
11797 : ??? We aren't parsing while expanding anymore. */
11798 :
11799 70269132 : if (MEM_P (decl_rtl) && REG_P (XEXP (decl_rtl, 0)))
11800 394922 : temp = validize_mem (decl_rtl);
11801 :
11802 : /* If DECL_RTL is memory, we are in the normal case and the
11803 : address is not valid, get the address into a register. */
11804 :
11805 69874210 : else if (MEM_P (decl_rtl) && modifier != EXPAND_INITIALIZER)
11806 : {
11807 18934518 : if (alt_rtl)
11808 2032047 : *alt_rtl = decl_rtl;
11809 18934518 : decl_rtl = use_anchored_address (decl_rtl);
11810 18934518 : if (modifier != EXPAND_CONST_ADDRESS
11811 18934518 : && modifier != EXPAND_SUM
11812 31342833 : && !memory_address_addr_space_p (exp ? DECL_MODE (exp)
11813 17568 : : GET_MODE (decl_rtl),
11814 : XEXP (decl_rtl, 0),
11815 12408315 : MEM_ADDR_SPACE (decl_rtl)))
11816 137277 : temp = replace_equiv_address (decl_rtl,
11817 : copy_rtx (XEXP (decl_rtl, 0)));
11818 : }
11819 :
11820 : /* If we got something, return it. But first, set the alignment
11821 : if the address is a register. */
11822 19329440 : if (temp != 0)
11823 : {
11824 532199 : if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0)))
11825 500176 : mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
11826 : }
11827 69736933 : else if (MEM_P (decl_rtl))
11828 : temp = decl_rtl;
11829 :
11830 47924767 : if (temp != 0)
11831 : {
11832 22844551 : if (MEM_P (temp)
11833 : && modifier != EXPAND_WRITE
11834 22844551 : && modifier != EXPAND_MEMORY
11835 : && modifier != EXPAND_INITIALIZER
11836 16858998 : && modifier != EXPAND_CONST_ADDRESS
11837 6985041 : && modifier != EXPAND_SUM
11838 6985041 : && !inner_reference_p
11839 4584586 : && mode != BLKmode
11840 27061412 : && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
11841 20100 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
11842 20100 : MEM_ALIGN (temp), NULL_RTX, NULL);
11843 :
11844 22844551 : return EXTEND_BITINT (temp);
11845 : }
11846 :
11847 47424581 : if (exp)
11848 17961632 : dmode = DECL_MODE (exp);
11849 : else
11850 29462949 : dmode = TYPE_MODE (TREE_TYPE (ssa_name));
11851 :
11852 : /* If the mode of DECL_RTL does not match that of the decl,
11853 : there are two cases: we are dealing with a BLKmode value
11854 : that is returned in a register, or we are dealing with
11855 : a promoted value. In the latter case, return a SUBREG
11856 : of the wanted mode, but mark it so that we know that it
11857 : was already extended. */
11858 47424581 : if (REG_P (decl_rtl)
11859 46887045 : && dmode != BLKmode
11860 46887045 : && GET_MODE (decl_rtl) != dmode)
11861 : {
11862 82 : machine_mode pmode;
11863 :
11864 : /* Get the signedness to be used for this variable. Ensure we get
11865 : the same mode we got when the variable was declared. */
11866 82 : if (code != SSA_NAME)
11867 0 : pmode = promote_decl_mode (exp, &unsignedp);
11868 82 : else if ((g = SSA_NAME_DEF_STMT (ssa_name))
11869 82 : && gimple_code (g) == GIMPLE_CALL
11870 84 : && !gimple_call_internal_p (g))
11871 2 : pmode = promote_function_mode (type, mode, &unsignedp,
11872 2 : gimple_call_fntype (g),
11873 : 2);
11874 : else
11875 80 : pmode = promote_ssa_mode (ssa_name, &unsignedp);
11876 82 : gcc_assert (GET_MODE (decl_rtl) == pmode);
11877 :
11878 : /* Some ABIs require scalar floating point modes to be passed
11879 : in a wider scalar integer mode. We need to explicitly
11880 : truncate to an integer mode of the correct precision before
11881 : using a SUBREG to reinterpret as a floating point value. */
11882 82 : if (SCALAR_FLOAT_MODE_P (mode)
11883 0 : && SCALAR_INT_MODE_P (pmode)
11884 82 : && known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (pmode)))
11885 0 : return convert_wider_int_to_float (mode, pmode, decl_rtl);
11886 :
11887 82 : temp = gen_lowpart_SUBREG (mode, decl_rtl);
11888 82 : SUBREG_PROMOTED_VAR_P (temp) = 1;
11889 82 : SUBREG_PROMOTED_SET (temp, unsignedp);
11890 82 : return EXTEND_BITINT (temp);
11891 : }
11892 :
11893 47424499 : return EXTEND_BITINT (decl_rtl);
11894 :
11895 43035787 : case INTEGER_CST:
11896 43035787 : {
11897 43035787 : if (BITINT_TYPE_P (type))
11898 : {
11899 11849 : unsigned int prec = TYPE_PRECISION (type);
11900 11849 : struct bitint_info info;
11901 11849 : bool ok = targetm.c.bitint_type_info (prec, &info);
11902 11849 : gcc_assert (ok);
11903 11849 : scalar_int_mode limb_mode
11904 11849 : = as_a <scalar_int_mode> (info.limb_mode);
11905 11849 : unsigned int limb_prec = GET_MODE_PRECISION (limb_mode);
11906 19467 : if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE)
11907 : {
11908 : /* Emit large/huge _BitInt INTEGER_CSTs into memory. */
11909 5159 : exp = tree_output_constant_def (exp);
11910 5159 : return expand_expr (exp, target, VOIDmode, modifier);
11911 : }
11912 : }
11913 :
11914 : /* Given that TYPE_PRECISION (type) is not always equal to
11915 : GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
11916 : the former to the latter according to the signedness of the
11917 : type. */
11918 43030628 : scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (type);
11919 43030628 : temp = immed_wide_int_const
11920 43030628 : (wi::to_wide (exp, GET_MODE_PRECISION (int_mode)), int_mode);
11921 43030628 : return temp;
11922 : }
11923 :
11924 573338 : case VECTOR_CST:
11925 573338 : {
11926 573338 : tree tmp = NULL_TREE;
11927 573338 : if (VECTOR_MODE_P (mode))
11928 570469 : return const_vector_from_tree (exp);
11929 2869 : scalar_int_mode int_mode;
11930 2869 : if (is_int_mode (mode, &int_mode))
11931 : {
11932 926 : tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1);
11933 926 : if (type_for_mode)
11934 926 : tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
11935 : type_for_mode, exp);
11936 : }
11937 926 : if (!tmp)
11938 : {
11939 1943 : vec<constructor_elt, va_gc> *v;
11940 : /* Constructors need to be fixed-length. FIXME. */
11941 1943 : unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
11942 1943 : vec_alloc (v, nunits);
11943 31617 : for (unsigned int i = 0; i < nunits; ++i)
11944 27731 : CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, VECTOR_CST_ELT (exp, i));
11945 1943 : tmp = build_constructor (type, v);
11946 : }
11947 2869 : return expand_expr (tmp, ignore ? const0_rtx : target,
11948 2869 : tmode, modifier);
11949 : }
11950 :
11951 136 : case CONST_DECL:
11952 136 : if (modifier == EXPAND_WRITE)
11953 : {
11954 : /* Writing into CONST_DECL is always invalid, but handle it
11955 : gracefully. */
11956 2 : addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
11957 2 : scalar_int_mode address_mode = targetm.addr_space.address_mode (as);
11958 2 : op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
11959 : EXPAND_NORMAL, as);
11960 2 : op0 = memory_address_addr_space (mode, op0, as);
11961 2 : temp = gen_rtx_MEM (mode, op0);
11962 2 : set_mem_addr_space (temp, as);
11963 2 : return temp;
11964 : }
11965 134 : return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
11966 :
11967 866367 : case REAL_CST:
11968 : /* If optimized, generate immediate CONST_DOUBLE
11969 : which will be turned into memory by reload if necessary.
11970 :
11971 : We used to force a register so that loop.c could see it. But
11972 : this does not allow gen_* patterns to perform optimizations with
11973 : the constants. It also produces two insns in cases like "x = 1.0;".
11974 : On most machines, floating-point constants are not permitted in
11975 : many insns, so we'd end up copying it to a register in any case.
11976 :
11977 : Now, we do the copying in expand_binop, if appropriate. */
11978 866367 : return const_double_from_real_value (TREE_REAL_CST (exp),
11979 1732734 : TYPE_MODE (TREE_TYPE (exp)));
11980 :
11981 0 : case FIXED_CST:
11982 0 : return CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (exp),
11983 : TYPE_MODE (TREE_TYPE (exp)));
11984 :
11985 18396 : case COMPLEX_CST:
11986 : /* Handle evaluating a complex constant in a CONCAT target. */
11987 18396 : if (original_target && GET_CODE (original_target) == CONCAT)
11988 : {
11989 219 : rtx rtarg, itarg;
11990 :
11991 219 : mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
11992 219 : rtarg = XEXP (original_target, 0);
11993 219 : itarg = XEXP (original_target, 1);
11994 :
11995 : /* Move the real and imaginary parts separately. */
11996 219 : op0 = expand_expr (TREE_REALPART (exp), rtarg, mode, EXPAND_NORMAL);
11997 219 : op1 = expand_expr (TREE_IMAGPART (exp), itarg, mode, EXPAND_NORMAL);
11998 :
11999 219 : if (op0 != rtarg)
12000 219 : emit_move_insn (rtarg, op0);
12001 219 : if (op1 != itarg)
12002 219 : emit_move_insn (itarg, op1);
12003 :
12004 : return original_target;
12005 : }
12006 :
12007 : /* fall through */
12008 :
12009 202884 : case STRING_CST:
12010 202884 : temp = expand_expr_constant (exp, 1, modifier);
12011 :
12012 : /* temp contains a constant address.
12013 : On RISC machines where a constant address isn't valid,
12014 : make some insns to get that address into a register. */
12015 202884 : if (modifier != EXPAND_CONST_ADDRESS
12016 : && modifier != EXPAND_INITIALIZER
12017 202884 : && modifier != EXPAND_SUM
12018 221441 : && ! memory_address_addr_space_p (mode, XEXP (temp, 0),
12019 18557 : MEM_ADDR_SPACE (temp)))
12020 12 : return replace_equiv_address (temp,
12021 12 : copy_rtx (XEXP (temp, 0)));
12022 : return temp;
12023 :
12024 0 : case POLY_INT_CST:
12025 0 : return immed_wide_int_const (poly_int_cst_value (exp), mode);
12026 :
12027 1640 : case SAVE_EXPR:
12028 1640 : {
12029 1640 : tree val = treeop0;
12030 1640 : rtx ret = expand_expr_real_1 (val, target, tmode, modifier, alt_rtl,
12031 : inner_reference_p);
12032 :
12033 1640 : if (!SAVE_EXPR_RESOLVED_P (exp))
12034 : {
12035 : /* We can indeed still hit this case, typically via builtin
12036 : expanders calling save_expr immediately before expanding
12037 : something. Assume this means that we only have to deal
12038 : with non-BLKmode values. */
12039 1593 : gcc_assert (GET_MODE (ret) != BLKmode);
12040 :
12041 1593 : val = build_decl (curr_insn_location (),
12042 1593 : VAR_DECL, NULL, TREE_TYPE (exp));
12043 1593 : DECL_ARTIFICIAL (val) = 1;
12044 1593 : DECL_IGNORED_P (val) = 1;
12045 1593 : treeop0 = val;
12046 1593 : TREE_OPERAND (exp, 0) = treeop0;
12047 1593 : SAVE_EXPR_RESOLVED_P (exp) = 1;
12048 :
12049 1593 : if (!CONSTANT_P (ret))
12050 1593 : ret = copy_to_reg (ret);
12051 1593 : SET_DECL_RTL (val, ret);
12052 : }
12053 :
12054 : return ret;
12055 : }
12056 :
12057 :
12058 179805 : case CONSTRUCTOR:
12059 : /* If we don't need the result, just ensure we evaluate any
12060 : subexpressions. */
12061 179805 : if (ignore)
12062 : {
12063 : unsigned HOST_WIDE_INT idx;
12064 : tree value;
12065 :
12066 0 : FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
12067 0 : expand_expr (value, const0_rtx, VOIDmode, EXPAND_NORMAL);
12068 :
12069 0 : return const0_rtx;
12070 : }
12071 :
12072 179805 : return expand_constructor (exp, target, modifier, false);
12073 :
12074 858516 : case TARGET_MEM_REF:
12075 858516 : {
12076 858516 : addr_space_t as
12077 858516 : = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
12078 858516 : unsigned int align;
12079 :
12080 858516 : op0 = addr_for_mem_ref (exp, as, true);
12081 858516 : op0 = memory_address_addr_space (mode, op0, as);
12082 858516 : temp = gen_rtx_MEM (mode, op0);
12083 858516 : set_mem_attributes (temp, exp, 0);
12084 858516 : set_mem_addr_space (temp, as);
12085 858516 : align = get_object_alignment (exp);
12086 858516 : if (modifier != EXPAND_WRITE
12087 858516 : && modifier != EXPAND_MEMORY
12088 591739 : && mode != BLKmode
12089 1444331 : && align < GET_MODE_ALIGNMENT (mode))
12090 53356 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
12091 : align, NULL_RTX, NULL);
12092 858516 : return EXTEND_BITINT (temp);
12093 : }
12094 :
12095 6815306 : case MEM_REF:
12096 6815306 : {
12097 6815306 : const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
12098 6815306 : addr_space_t as
12099 6815306 : = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
12100 6815306 : machine_mode address_mode;
12101 6815306 : tree base = TREE_OPERAND (exp, 0);
12102 6815306 : gimple *def_stmt;
12103 6815306 : unsigned align;
12104 : /* Handle expansion of non-aliased memory with non-BLKmode. That
12105 : might end up in a register. */
12106 6815306 : if (mem_ref_refers_to_non_mem_p (exp))
12107 : {
12108 80912 : poly_int64 offset = mem_ref_offset (exp).force_shwi ();
12109 80912 : base = TREE_OPERAND (base, 0);
12110 80912 : poly_uint64 type_size;
12111 80912 : if (known_eq (offset, 0)
12112 46438 : && !reverse
12113 46438 : && poly_int_tree_p (TYPE_SIZE (type), &type_size)
12114 173788 : && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
12115 19273 : return expand_expr (build1 (VIEW_CONVERT_EXPR, type, base),
12116 19273 : target, tmode, modifier);
12117 61639 : unsigned align;
12118 61639 : if (TYPE_MODE (type) == BLKmode || maybe_lt (offset, 0))
12119 : {
12120 218 : temp = assign_stack_temp (DECL_MODE (base),
12121 436 : GET_MODE_SIZE (DECL_MODE (base)));
12122 218 : store_expr (base, temp, 0, false, false);
12123 218 : temp = adjust_address (temp, TYPE_MODE (type), offset);
12124 218 : if (TYPE_MODE (type) == BLKmode)
12125 197 : set_mem_size (temp, int_size_in_bytes (type));
12126 : /* When the original ref was misaligned so will be the
12127 : access to the stack temporary. Not all targets handle
12128 : this correctly, some will ICE in sanity checking.
12129 : Handle this by doing bitfield extraction when necessary. */
12130 42 : else if ((align = get_object_alignment (exp))
12131 21 : < GET_MODE_ALIGNMENT (TYPE_MODE (type)))
12132 3 : temp
12133 3 : = expand_misaligned_mem_ref (temp, TYPE_MODE (type),
12134 : unsignedp, align,
12135 : modifier == EXPAND_STACK_PARM
12136 : ? NULL_RTX : target, NULL);
12137 : return temp;
12138 : }
12139 : /* When the access is fully outside of the underlying object
12140 : expand the offset as zero. This avoids out-of-bound
12141 : BIT_FIELD_REFs and generates smaller code for these cases
12142 : with UB. */
12143 61421 : type_size = tree_to_poly_uint64 (TYPE_SIZE_UNIT (type));
12144 122842 : if (!ranges_maybe_overlap_p (offset, type_size, 0,
12145 122842 : GET_MODE_SIZE (DECL_MODE (base))))
12146 37 : offset = 0;
12147 61421 : exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
12148 61421 : bitsize_int (offset * BITS_PER_UNIT));
12149 61421 : REF_REVERSE_STORAGE_ORDER (exp) = reverse;
12150 61421 : return expand_expr (exp, target, tmode, modifier);
12151 : }
12152 6734394 : address_mode = targetm.addr_space.address_mode (as);
12153 6734394 : if ((def_stmt = get_def_for_expr (base, BIT_AND_EXPR)))
12154 : {
12155 44 : tree mask = gimple_assign_rhs2 (def_stmt);
12156 44 : base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
12157 : gimple_assign_rhs1 (def_stmt), mask);
12158 44 : TREE_OPERAND (exp, 0) = base;
12159 : }
12160 6734394 : align = get_object_alignment (exp);
12161 6734394 : op0 = expand_expr (base, NULL_RTX, VOIDmode, EXPAND_SUM);
12162 6734394 : op0 = memory_address_addr_space (mode, op0, as);
12163 6734394 : if (!integer_zerop (TREE_OPERAND (exp, 1)))
12164 : {
12165 2047204 : rtx off = immed_wide_int_const (mem_ref_offset (exp), address_mode);
12166 2047204 : op0 = simplify_gen_binary (PLUS, address_mode, op0, off);
12167 2047204 : op0 = memory_address_addr_space (mode, op0, as);
12168 : }
12169 6734394 : temp = gen_rtx_MEM (mode, op0);
12170 6734394 : set_mem_attributes (temp, exp, 0);
12171 6734394 : set_mem_addr_space (temp, as);
12172 6734394 : if (TREE_THIS_VOLATILE (exp))
12173 12395 : MEM_VOLATILE_P (temp) = 1;
12174 6734394 : if (modifier == EXPAND_WRITE || modifier == EXPAND_MEMORY)
12175 : return temp;
12176 3994508 : if (!inner_reference_p
12177 2061617 : && mode != BLKmode
12178 5994652 : && align < GET_MODE_ALIGNMENT (mode))
12179 143348 : temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align,
12180 : modifier == EXPAND_STACK_PARM
12181 : ? NULL_RTX : target, alt_rtl);
12182 3994508 : if (reverse)
12183 16 : temp = flip_storage_order (mode, temp);
12184 3994508 : return EXTEND_BITINT (temp);
12185 : }
12186 :
12187 629540 : case ARRAY_REF:
12188 :
12189 629540 : {
12190 629540 : tree array = treeop0;
12191 629540 : tree index = treeop1;
12192 629540 : tree init;
12193 :
12194 : /* Fold an expression like: "foo"[2].
12195 : This is not done in fold so it won't happen inside &.
12196 : Don't fold if this is for wide characters since it's too
12197 : difficult to do correctly and this is a very rare case. */
12198 :
12199 629540 : if (modifier != EXPAND_CONST_ADDRESS
12200 629540 : && modifier != EXPAND_INITIALIZER
12201 629540 : && modifier != EXPAND_MEMORY)
12202 : {
12203 629435 : tree t = fold_read_from_constant_string (exp);
12204 :
12205 629435 : if (t)
12206 0 : return expand_expr (t, target, tmode, modifier);
12207 : }
12208 :
12209 : /* If this is a constant index into a constant array,
12210 : just get the value from the array. Handle both the cases when
12211 : we have an explicit constructor and when our operand is a variable
12212 : that was declared const. */
12213 :
12214 629540 : if (modifier != EXPAND_CONST_ADDRESS
12215 : && modifier != EXPAND_INITIALIZER
12216 : && modifier != EXPAND_MEMORY
12217 629435 : && TREE_CODE (array) == CONSTRUCTOR
12218 0 : && ! TREE_SIDE_EFFECTS (array)
12219 629540 : && TREE_CODE (index) == INTEGER_CST)
12220 : {
12221 : unsigned HOST_WIDE_INT ix;
12222 : tree field, value;
12223 :
12224 0 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (array), ix,
12225 : field, value)
12226 0 : if (tree_int_cst_equal (field, index))
12227 : {
12228 0 : if (!TREE_SIDE_EFFECTS (value)
12229 0 : && TREE_CODE (value) != RAW_DATA_CST)
12230 0 : return expand_expr (fold (value), target, tmode, modifier);
12231 : break;
12232 : }
12233 : }
12234 :
12235 629540 : else if (optimize >= 1
12236 : && modifier != EXPAND_CONST_ADDRESS
12237 359260 : && modifier != EXPAND_INITIALIZER
12238 359260 : && modifier != EXPAND_MEMORY
12239 359159 : && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
12240 9062 : && TREE_CODE (index) == INTEGER_CST
12241 2027 : && (VAR_P (array) || TREE_CODE (array) == CONST_DECL)
12242 629689 : && (init = ctor_for_folding (array)) != error_mark_node)
12243 : {
12244 108 : if (init == NULL_TREE)
12245 : {
12246 5 : tree value = build_zero_cst (type);
12247 5 : if (TREE_CODE (value) == CONSTRUCTOR)
12248 : {
12249 : /* If VALUE is a CONSTRUCTOR, this optimization is only
12250 : useful if this doesn't store the CONSTRUCTOR into
12251 : memory. If it does, it is more efficient to just
12252 : load the data from the array directly. */
12253 5 : rtx ret = expand_constructor (value, target,
12254 : modifier, true);
12255 5 : if (ret == NULL_RTX)
12256 : value = NULL_TREE;
12257 : }
12258 :
12259 : if (value)
12260 0 : return expand_expr (value, target, tmode, modifier);
12261 : }
12262 103 : else if (TREE_CODE (init) == CONSTRUCTOR)
12263 : {
12264 : unsigned HOST_WIDE_INT ix;
12265 : tree field, value;
12266 :
12267 168 : FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
12268 : field, value)
12269 166 : if (tree_int_cst_equal (field, index))
12270 : {
12271 100 : if (TREE_SIDE_EFFECTS (value)
12272 100 : || TREE_CODE (value) == RAW_DATA_CST)
12273 : break;
12274 :
12275 100 : if (TREE_CODE (value) == CONSTRUCTOR)
12276 : {
12277 : /* If VALUE is a CONSTRUCTOR, this
12278 : optimization is only useful if
12279 : this doesn't store the CONSTRUCTOR
12280 : into memory. If it does, it is more
12281 : efficient to just load the data from
12282 : the array directly. */
12283 95 : rtx ret = expand_constructor (value, target,
12284 : modifier, true);
12285 95 : if (ret == NULL_RTX)
12286 : break;
12287 : }
12288 :
12289 62 : return expand_expr (fold (value), target, tmode,
12290 62 : modifier);
12291 : }
12292 : }
12293 1 : else if (TREE_CODE (init) == STRING_CST)
12294 : {
12295 1 : tree low_bound = array_ref_low_bound (exp);
12296 1 : tree index1 = fold_convert_loc (loc, sizetype, treeop1);
12297 :
12298 : /* Optimize the special case of a zero lower bound.
12299 :
12300 : We convert the lower bound to sizetype to avoid problems
12301 : with constant folding. E.g. suppose the lower bound is
12302 : 1 and its mode is QI. Without the conversion
12303 : (ARRAY + (INDEX - (unsigned char)1))
12304 : becomes
12305 : (ARRAY + (-(unsigned char)1) + INDEX)
12306 : which becomes
12307 : (ARRAY + 255 + INDEX). Oops! */
12308 1 : if (!integer_zerop (low_bound))
12309 0 : index1 = size_diffop_loc (loc, index1,
12310 : fold_convert_loc (loc, sizetype,
12311 : low_bound));
12312 :
12313 1 : if (tree_fits_uhwi_p (index1)
12314 2 : && compare_tree_int (index1, TREE_STRING_LENGTH (init)) < 0)
12315 : {
12316 0 : tree char_type = TREE_TYPE (TREE_TYPE (init));
12317 0 : scalar_int_mode char_mode;
12318 :
12319 629478 : if (is_int_mode (TYPE_MODE (char_type), &char_mode)
12320 0 : && GET_MODE_SIZE (char_mode) == 1)
12321 0 : return gen_int_mode (TREE_STRING_POINTER (init)
12322 0 : [TREE_INT_CST_LOW (index1)],
12323 : char_mode);
12324 : }
12325 : }
12326 : }
12327 : }
12328 629478 : goto normal_inner_ref;
12329 :
12330 3760178 : case COMPONENT_REF:
12331 3760178 : gcc_assert (TREE_CODE (treeop0) != CONSTRUCTOR);
12332 : /* Fall through. */
12333 4658106 : case BIT_FIELD_REF:
12334 4658106 : case ARRAY_RANGE_REF:
12335 3760178 : normal_inner_ref:
12336 4658106 : {
12337 4658106 : machine_mode mode1, mode2;
12338 4658106 : poly_int64 bitsize, bitpos, bytepos;
12339 4658106 : tree offset;
12340 4658106 : int reversep, volatilep = 0;
12341 4658106 : tree tem
12342 4658106 : = get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode1,
12343 : &unsignedp, &reversep, &volatilep);
12344 4658106 : rtx orig_op0, memloc;
12345 4658106 : bool clear_mem_expr = false;
12346 4658106 : bool must_force_mem;
12347 :
12348 : /* If we got back the original object, something is wrong. Perhaps
12349 : we are evaluating an expression too early. In any event, don't
12350 : infinitely recurse. */
12351 4658106 : gcc_assert (tem != exp);
12352 :
12353 : /* Make sure bitpos is not negative, this can wreak havoc later. */
12354 4658106 : if (maybe_lt (bitpos, 0))
12355 : {
12356 249 : gcc_checking_assert (offset == NULL_TREE);
12357 249 : offset = size_int (bits_to_bytes_round_down (bitpos));
12358 249 : bitpos = num_trailing_bits (bitpos);
12359 : }
12360 :
12361 : /* If we have either an offset, a BLKmode result, or a reference
12362 : outside the underlying object, we must force it to memory.
12363 : Such a case can occur in Ada if we have unchecked conversion
12364 : of an expression from a scalar type to an aggregate type or
12365 : for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
12366 : passed a partially uninitialized object or a view-conversion
12367 : to a larger size. */
12368 9316212 : must_force_mem = offset != NULL_TREE
12369 4377998 : || mode1 == BLKmode
12370 8963905 : || (mode == BLKmode
12371 0 : && !int_mode_for_size (bitsize, 1).exists ());
12372 :
12373 527249 : const enum expand_modifier tem_modifier
12374 : = must_force_mem
12375 : ? EXPAND_MEMORY
12376 4305799 : : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier;
12377 :
12378 : /* If TEM's type is a union of variable size, pass TARGET to the inner
12379 : computation, since it will need a temporary and TARGET is known
12380 : to have to do. This occurs in unchecked conversion in Ada. */
12381 4658106 : const rtx tem_target
12382 4658106 : = TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
12383 36707 : && COMPLETE_TYPE_P (TREE_TYPE (tem))
12384 36702 : && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) != INTEGER_CST
12385 0 : && modifier != EXPAND_STACK_PARM
12386 4658106 : ? target
12387 : : NULL_RTX;
12388 :
12389 9316212 : orig_op0 = op0
12390 4658106 : = expand_expr_real (tem, tem_target, VOIDmode, tem_modifier, NULL,
12391 : true);
12392 :
12393 : /* If the field has a mode, we want to access it in the
12394 : field's mode, not the computed mode.
12395 : If a MEM has VOIDmode (external with incomplete type),
12396 : use BLKmode for it instead. */
12397 4658106 : if (MEM_P (op0))
12398 : {
12399 4309177 : if (mode1 != VOIDmode)
12400 4151621 : op0 = adjust_address (op0, mode1, 0);
12401 157556 : else if (GET_MODE (op0) == VOIDmode)
12402 0 : op0 = adjust_address (op0, BLKmode, 0);
12403 : }
12404 :
12405 4658106 : mode2
12406 4658106 : = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
12407 :
12408 : /* See above for the rationale. */
12409 9316212 : if (maybe_gt (bitpos + bitsize, GET_MODE_BITSIZE (mode2)))
12410 2938033 : must_force_mem = true;
12411 :
12412 : /* Handle CONCAT first. */
12413 4658106 : if (GET_CODE (op0) == CONCAT && !must_force_mem)
12414 : {
12415 114 : if (known_eq (bitpos, 0)
12416 206 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
12417 98 : && COMPLEX_MODE_P (mode1)
12418 93 : && COMPLEX_MODE_P (GET_MODE (op0))
12419 393 : && (GET_MODE_PRECISION (GET_MODE_INNER (mode1))
12420 186 : == GET_MODE_PRECISION (GET_MODE_INNER (GET_MODE (op0)))))
12421 : {
12422 93 : if (reversep)
12423 0 : op0 = flip_storage_order (GET_MODE (op0), op0);
12424 93 : if (mode1 != GET_MODE (op0))
12425 : {
12426 : rtx parts[2];
12427 0 : for (int i = 0; i < 2; i++)
12428 : {
12429 0 : rtx op = read_complex_part (op0, i != 0);
12430 0 : if (GET_CODE (op) == SUBREG)
12431 0 : op = force_reg (GET_MODE (op), op);
12432 0 : temp = gen_lowpart_common (GET_MODE_INNER (mode1), op);
12433 0 : if (temp)
12434 : op = temp;
12435 : else
12436 : {
12437 0 : if (!REG_P (op) && !MEM_P (op))
12438 0 : op = force_reg (GET_MODE (op), op);
12439 0 : op = gen_lowpart (GET_MODE_INNER (mode1), op);
12440 : }
12441 0 : parts[i] = op;
12442 : }
12443 0 : op0 = gen_rtx_CONCAT (mode1, parts[0], parts[1]);
12444 : }
12445 : return op0;
12446 : }
12447 21 : if (known_eq (bitpos, 0)
12448 20 : && known_eq (bitsize,
12449 : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
12450 23 : && maybe_ne (bitsize, 0))
12451 : {
12452 : op0 = XEXP (op0, 0);
12453 : mode2 = GET_MODE (op0);
12454 : }
12455 38 : else if (known_eq (bitpos,
12456 : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
12457 4 : && known_eq (bitsize,
12458 : GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1))))
12459 0 : && maybe_ne (bitpos, 0)
12460 19 : && maybe_ne (bitsize, 0))
12461 : {
12462 0 : op0 = XEXP (op0, 1);
12463 0 : bitpos = 0;
12464 0 : mode2 = GET_MODE (op0);
12465 : }
12466 : else
12467 : /* Otherwise force into memory. */
12468 : must_force_mem = true;
12469 : }
12470 :
12471 : /* If this is a constant, put it in a register if it is a legitimate
12472 : constant and we don't need a memory reference. */
12473 4658013 : if (CONSTANT_P (op0)
12474 33 : && mode2 != BLKmode
12475 33 : && targetm.legitimate_constant_p (mode2, op0)
12476 4658034 : && !must_force_mem)
12477 21 : op0 = force_reg (mode2, op0);
12478 :
12479 : /* Otherwise, if this is a constant, try to force it to the constant
12480 : pool. Note that back-ends, e.g. MIPS, may refuse to do so if it
12481 : is a legitimate constant. */
12482 4657992 : else if (CONSTANT_P (op0) && (memloc = force_const_mem (mode2, op0)))
12483 12 : op0 = validize_mem (memloc);
12484 :
12485 : /* Otherwise, if this is a constant or the object is not in memory
12486 : and need be, put it there. */
12487 4657980 : else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
12488 : {
12489 1095 : machine_mode tem_mode = TYPE_MODE (TREE_TYPE (tem));
12490 1095 : poly_int64 size;
12491 1095 : if (!poly_int_tree_p (TYPE_SIZE_UNIT (TREE_TYPE (tem)), &size))
12492 0 : size = max_int_size_in_bytes (TREE_TYPE (tem));
12493 1095 : unsigned int align = TREE_CODE (tem) == SSA_NAME
12494 1095 : ? TYPE_ALIGN (TREE_TYPE (tem))
12495 1095 : : get_object_alignment (tem);
12496 1095 : if (STRICT_ALIGNMENT)
12497 : {
12498 : /* For STRICT_ALIGNMENT targets, when we force the operand to
12499 : memory, we may need to increase the alignment to meet the
12500 : expectation in later RTL lowering passes. The increased
12501 : alignment is capped by MAX_SUPPORTED_STACK_ALIGNMENT. */
12502 : if (tem_mode != BLKmode)
12503 : align = MAX (align, GET_MODE_ALIGNMENT (tem_mode));
12504 : else
12505 : align = MAX (align, TYPE_ALIGN (TREE_TYPE (tem)));
12506 : align = MIN (align, (unsigned) MAX_SUPPORTED_STACK_ALIGNMENT);
12507 : }
12508 1095 : memloc = assign_stack_local (tem_mode, size, align);
12509 1095 : emit_move_insn (memloc, op0);
12510 1095 : op0 = memloc;
12511 1095 : clear_mem_expr = true;
12512 : }
12513 :
12514 4658013 : if (offset)
12515 : {
12516 280108 : machine_mode address_mode;
12517 280108 : rtx offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode,
12518 : EXPAND_SUM);
12519 :
12520 280108 : gcc_assert (MEM_P (op0));
12521 :
12522 280108 : address_mode = get_address_mode (op0);
12523 280108 : if (GET_MODE (offset_rtx) != address_mode)
12524 : {
12525 : /* We cannot be sure that the RTL in offset_rtx is valid outside
12526 : of a memory address context, so force it into a register
12527 : before attempting to convert it to the desired mode. */
12528 422 : offset_rtx = force_operand (offset_rtx, NULL_RTX);
12529 422 : offset_rtx = convert_to_mode (address_mode, offset_rtx, 0);
12530 : }
12531 :
12532 : /* See the comment in expand_assignment for the rationale. */
12533 280108 : if (mode1 != VOIDmode
12534 279892 : && maybe_ne (bitpos, 0)
12535 74596 : && maybe_gt (bitsize, 0)
12536 354165 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
12537 354165 : && multiple_p (bitpos, bitsize)
12538 148114 : && multiple_p (bitsize, GET_MODE_ALIGNMENT (mode1))
12539 354165 : && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1))
12540 : {
12541 73699 : op0 = adjust_address (op0, mode1, bytepos);
12542 73699 : bitpos = 0;
12543 : }
12544 :
12545 280108 : op0 = offset_address (op0, offset_rtx,
12546 : highest_pow2_factor (offset));
12547 : }
12548 :
12549 : /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
12550 : record its alignment as BIGGEST_ALIGNMENT. */
12551 4658013 : if (MEM_P (op0)
12552 4310284 : && known_eq (bitpos, 0)
12553 1457328 : && offset != 0
12554 4937074 : && is_aligning_offset (offset, tem))
12555 0 : set_mem_align (op0, BIGGEST_ALIGNMENT);
12556 :
12557 : /* Don't forget about volatility even if this is a bitfield. */
12558 4658013 : if (MEM_P (op0) && volatilep && ! MEM_VOLATILE_P (op0))
12559 : {
12560 528 : if (op0 == orig_op0)
12561 158 : op0 = copy_rtx (op0);
12562 :
12563 528 : MEM_VOLATILE_P (op0) = 1;
12564 : }
12565 :
12566 4658013 : if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL)
12567 : {
12568 6 : if (op0 == orig_op0)
12569 0 : op0 = copy_rtx (op0);
12570 :
12571 6 : set_mem_align (op0, BITS_PER_UNIT);
12572 : }
12573 :
12574 : /* In cases where an aligned union has an unaligned object
12575 : as a field, we might be extracting a BLKmode value from
12576 : an integer-mode (e.g., SImode) object. Handle this case
12577 : by doing the extract into an object as wide as the field
12578 : (which we know to be the width of a basic mode), then
12579 : storing into memory, and changing the mode to BLKmode. */
12580 4658013 : if (mode1 == VOIDmode
12581 4426727 : || REG_P (op0) || GET_CODE (op0) == SUBREG
12582 4152694 : || (mode1 != BLKmode && ! direct_load[(int) mode1]
12583 27185 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
12584 23074 : && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
12585 : && modifier != EXPAND_CONST_ADDRESS
12586 15389 : && modifier != EXPAND_INITIALIZER
12587 15389 : && modifier != EXPAND_MEMORY)
12588 : /* If the bitfield is volatile and the bitsize
12589 : is narrower than the access size of the bitfield,
12590 : we need to extract bitfields from the access. */
12591 4137305 : || (volatilep && TREE_CODE (exp) == COMPONENT_REF
12592 1503 : && DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))
12593 10 : && mode1 != BLKmode
12594 20 : && maybe_lt (bitsize, GET_MODE_SIZE (mode1) * BITS_PER_UNIT))
12595 : /* If the field isn't aligned enough to fetch as a memref,
12596 : fetch it as a bit field. */
12597 4137296 : || (mode1 != BLKmode
12598 4064233 : && (((MEM_P (op0)
12599 4064233 : ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
12600 7983983 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode1))
12601 0 : : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
12602 0 : || !multiple_p (bitpos, GET_MODE_ALIGNMENT (mode)))
12603 75519 : && modifier != EXPAND_MEMORY
12604 75519 : && ((modifier == EXPAND_CONST_ADDRESS
12605 75519 : || modifier == EXPAND_INITIALIZER)
12606 75519 : ? STRICT_ALIGNMENT
12607 75519 : : targetm.slow_unaligned_access (mode1,
12608 75519 : MEM_ALIGN (op0))))
12609 4064233 : || !multiple_p (bitpos, BITS_PER_UNIT)))
12610 : /* If the type and the field are a constant size and the
12611 : size of the type isn't the same size as the bitfield,
12612 : we must use bitfield operations. */
12613 12859542 : || (known_size_p (bitsize)
12614 4137296 : && TYPE_SIZE (TREE_TYPE (exp))
12615 4137296 : && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
12616 4658013 : && maybe_ne (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
12617 : bitsize)))
12618 : {
12619 520747 : machine_mode ext_mode = mode;
12620 :
12621 520747 : if (ext_mode == BLKmode
12622 520747 : && ! (target != 0 && MEM_P (op0)
12623 22 : && MEM_P (target)
12624 22 : && multiple_p (bitpos, BITS_PER_UNIT)))
12625 4 : ext_mode = int_mode_for_size (bitsize, 1).else_blk ();
12626 :
12627 520747 : if (ext_mode == BLKmode)
12628 : {
12629 26 : if (target == 0)
12630 4 : target = assign_temp (type, 1, 1);
12631 :
12632 : /* ??? Unlike the similar test a few lines below, this one is
12633 : very likely obsolete. */
12634 26 : if (known_eq (bitsize, 0))
12635 : return target;
12636 :
12637 : /* In this case, BITPOS must start at a byte boundary and
12638 : TARGET, if specified, must be a MEM. */
12639 26 : gcc_assert (MEM_P (op0)
12640 : && (!target || MEM_P (target)));
12641 :
12642 26 : bytepos = exact_div (bitpos, BITS_PER_UNIT);
12643 26 : poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
12644 52 : emit_block_move (target,
12645 : adjust_address (op0, VOIDmode, bytepos),
12646 26 : gen_int_mode (bytesize, Pmode),
12647 : (modifier == EXPAND_STACK_PARM
12648 : ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
12649 :
12650 26 : return target;
12651 : }
12652 :
12653 : /* If we have nothing to extract, the result will be 0 for targets
12654 : with SHIFT_COUNT_TRUNCATED == 0 and garbage otherwise. Always
12655 : return 0 for the sake of consistency, as reading a zero-sized
12656 : bitfield is valid in Ada and the value is fully specified. */
12657 520721 : if (known_eq (bitsize, 0))
12658 0 : return const0_rtx;
12659 :
12660 520721 : op0 = validize_mem (op0);
12661 :
12662 520721 : if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
12663 49656 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12664 :
12665 : /* If the result has aggregate type and the extraction is done in
12666 : an integral mode, then the field may be not aligned on a byte
12667 : boundary; in this case, if it has reverse storage order, it
12668 : needs to be extracted as a scalar field with reverse storage
12669 : order and put back into memory order afterwards. */
12670 520721 : if (AGGREGATE_TYPE_P (type)
12671 5170 : && GET_MODE_CLASS (ext_mode) == MODE_INT)
12672 5088 : reversep = TYPE_REVERSE_STORAGE_ORDER (type);
12673 :
12674 520721 : gcc_checking_assert (known_ge (bitpos, 0));
12675 1054107 : op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
12676 : (modifier == EXPAND_STACK_PARM
12677 : ? NULL_RTX : target),
12678 : ext_mode, ext_mode, reversep, alt_rtl);
12679 :
12680 : /* If the result has aggregate type and the mode of OP0 is an
12681 : integral mode then, if BITSIZE is narrower than this mode
12682 : and this is for big-endian data, we must put the field
12683 : into the high-order bits. And we must also put it back
12684 : into memory order if it has been previously reversed. */
12685 520721 : scalar_int_mode op0_mode;
12686 520721 : if (AGGREGATE_TYPE_P (type)
12687 520721 : && is_int_mode (GET_MODE (op0), &op0_mode))
12688 : {
12689 5088 : HOST_WIDE_INT size = GET_MODE_BITSIZE (op0_mode);
12690 :
12691 5088 : gcc_checking_assert (known_le (bitsize, size));
12692 5088 : if (maybe_lt (bitsize, size)
12693 5088 : && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
12694 0 : op0 = expand_shift (LSHIFT_EXPR, op0_mode, op0,
12695 : size - bitsize, op0, 1);
12696 :
12697 5088 : if (reversep)
12698 0 : op0 = flip_storage_order (op0_mode, op0);
12699 : }
12700 :
12701 : /* If the result type is BLKmode, store the data into a temporary
12702 : of the appropriate type, but with the mode corresponding to the
12703 : mode for the data we have (op0's mode). */
12704 520721 : if (mode == BLKmode)
12705 : {
12706 0 : rtx new_rtx
12707 0 : = assign_stack_temp_for_type (ext_mode,
12708 0 : GET_MODE_BITSIZE (ext_mode),
12709 : type);
12710 0 : emit_move_insn (new_rtx, op0);
12711 0 : op0 = copy_rtx (new_rtx);
12712 0 : PUT_MODE (op0, BLKmode);
12713 : }
12714 :
12715 : return op0;
12716 : }
12717 :
12718 : /* If the result is BLKmode, use that to access the object
12719 : now as well. */
12720 4137266 : if (mode == BLKmode)
12721 73037 : mode1 = BLKmode;
12722 :
12723 : /* Get a reference to just this component. */
12724 4137266 : bytepos = bits_to_bytes_round_down (bitpos);
12725 4137266 : if (modifier == EXPAND_CONST_ADDRESS
12726 4137266 : || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
12727 165478 : op0 = adjust_address_nv (op0, mode1, bytepos);
12728 : else
12729 3971788 : op0 = adjust_address (op0, mode1, bytepos);
12730 :
12731 4137266 : if (op0 == orig_op0)
12732 127348 : op0 = copy_rtx (op0);
12733 :
12734 : /* Don't set memory attributes if the base expression is
12735 : SSA_NAME that got expanded as a MEM or a CONSTANT. In that case,
12736 : we should just honor its original memory attributes. */
12737 4137266 : if (!(TREE_CODE (tem) == SSA_NAME
12738 9501 : && (MEM_P (orig_op0) || CONSTANT_P (orig_op0))))
12739 4127765 : set_mem_attributes (op0, exp, 0);
12740 :
12741 4137266 : if (REG_P (XEXP (op0, 0)))
12742 667811 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12743 :
12744 : /* If op0 is a temporary because the original expressions was forced
12745 : to memory, clear MEM_EXPR so that the original expression cannot
12746 : be marked as addressable through MEM_EXPR of the temporary. */
12747 4137266 : if (clear_mem_expr)
12748 1061 : set_mem_expr (op0, NULL_TREE);
12749 :
12750 4137266 : MEM_VOLATILE_P (op0) |= volatilep;
12751 :
12752 4137266 : if (reversep
12753 : && modifier != EXPAND_MEMORY
12754 497 : && modifier != EXPAND_WRITE)
12755 497 : op0 = flip_storage_order (mode1, op0);
12756 :
12757 4137266 : op0 = EXTEND_BITINT (op0);
12758 :
12759 4137266 : if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
12760 : || modifier == EXPAND_CONST_ADDRESS
12761 0 : || modifier == EXPAND_INITIALIZER)
12762 : return op0;
12763 :
12764 0 : if (target == 0)
12765 0 : target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
12766 :
12767 0 : convert_move (target, op0, unsignedp);
12768 0 : return target;
12769 : }
12770 :
12771 85301 : case OBJ_TYPE_REF:
12772 85301 : return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, tmode, modifier);
12773 :
12774 6811532 : case CALL_EXPR:
12775 : /* All valid uses of __builtin_va_arg_pack () are removed during
12776 : inlining. */
12777 6811532 : if (CALL_EXPR_VA_ARG_PACK (exp))
12778 6 : error ("invalid use of %<__builtin_va_arg_pack ()%>");
12779 6811532 : {
12780 6811532 : tree fndecl = get_callee_fndecl (exp), attr;
12781 :
12782 6811532 : if (fndecl
12783 : /* Don't diagnose the error attribute in thunks, those are
12784 : artificially created. */
12785 6624628 : && !CALL_FROM_THUNK_P (exp)
12786 13432574 : && (attr = lookup_attribute ("error",
12787 6621042 : DECL_ATTRIBUTES (fndecl))) != NULL)
12788 : {
12789 5 : const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
12790 10 : error ("call to %qs declared with attribute error: %s",
12791 : identifier_to_locale (ident),
12792 5 : TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
12793 : }
12794 6811532 : if (fndecl
12795 : /* Don't diagnose the warning attribute in thunks, those are
12796 : artificially created. */
12797 6624628 : && !CALL_FROM_THUNK_P (exp)
12798 13432574 : && (attr = lookup_attribute ("warning",
12799 6621042 : DECL_ATTRIBUTES (fndecl))) != NULL)
12800 : {
12801 21 : const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
12802 42 : warning_at (EXPR_LOCATION (exp),
12803 21 : OPT_Wattribute_warning,
12804 : "call to %qs declared with attribute warning: %s",
12805 : identifier_to_locale (ident),
12806 21 : TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
12807 : }
12808 :
12809 : /* Check for a built-in function. */
12810 6811532 : if (fndecl && fndecl_built_in_p (fndecl))
12811 : {
12812 2016791 : gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
12813 2016791 : return expand_builtin (exp, target, subtarget, tmode, ignore);
12814 : }
12815 : }
12816 4794741 : temp = expand_call (exp, target, ignore);
12817 4794739 : return EXTEND_BITINT (temp);
12818 :
12819 351968 : case VIEW_CONVERT_EXPR:
12820 351968 : op0 = NULL_RTX;
12821 :
12822 : /* If we are converting to BLKmode, try to avoid an intermediate
12823 : temporary by fetching an inner memory reference. */
12824 351968 : if (mode == BLKmode
12825 74118 : && poly_int_tree_p (TYPE_SIZE (type))
12826 74118 : && TYPE_MODE (TREE_TYPE (treeop0)) != BLKmode
12827 351968 : && handled_component_p (treeop0))
12828 : {
12829 0 : machine_mode mode1;
12830 0 : poly_int64 bitsize, bitpos, bytepos;
12831 0 : tree offset;
12832 0 : int reversep, volatilep = 0;
12833 0 : tree tem
12834 0 : = get_inner_reference (treeop0, &bitsize, &bitpos, &offset, &mode1,
12835 : &unsignedp, &reversep, &volatilep);
12836 :
12837 : /* ??? We should work harder and deal with non-zero offsets. */
12838 0 : if (!offset
12839 0 : && multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
12840 0 : && !reversep
12841 0 : && known_size_p (bitsize)
12842 0 : && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
12843 : {
12844 : /* See the normal_inner_ref case for the rationale. */
12845 0 : rtx orig_op0
12846 0 : = expand_expr_real (tem,
12847 0 : (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
12848 0 : && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
12849 : != INTEGER_CST)
12850 0 : && modifier != EXPAND_STACK_PARM
12851 : ? target : NULL_RTX),
12852 : VOIDmode,
12853 : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
12854 : NULL, true);
12855 :
12856 0 : if (MEM_P (orig_op0))
12857 : {
12858 0 : op0 = orig_op0;
12859 :
12860 : /* Get a reference to just this component. */
12861 0 : if (modifier == EXPAND_CONST_ADDRESS
12862 : || modifier == EXPAND_SUM
12863 0 : || modifier == EXPAND_INITIALIZER)
12864 0 : op0 = adjust_address_nv (op0, mode, bytepos);
12865 : else
12866 0 : op0 = adjust_address (op0, mode, bytepos);
12867 :
12868 0 : if (op0 == orig_op0)
12869 0 : op0 = copy_rtx (op0);
12870 :
12871 0 : set_mem_attributes (op0, treeop0, 0);
12872 0 : if (REG_P (XEXP (op0, 0)))
12873 0 : mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
12874 :
12875 0 : MEM_VOLATILE_P (op0) |= volatilep;
12876 : }
12877 : }
12878 : }
12879 :
12880 0 : if (!op0)
12881 426097 : op0 = expand_expr_real (treeop0, NULL_RTX, VOIDmode, modifier,
12882 : NULL, inner_reference_p || mode == BLKmode);
12883 :
12884 : /* If the input and output modes are both the same, we are done. */
12885 351968 : if (mode == GET_MODE (op0))
12886 : ;
12887 : /* Similarly if the output mode is BLKmode and input is a MEM,
12888 : adjust_address done below is all we need. */
12889 152430 : else if (mode == BLKmode && MEM_P (op0))
12890 : ;
12891 : /* If neither mode is BLKmode, and both modes are the same size
12892 : then we can use gen_lowpart. */
12893 : else if (mode != BLKmode
12894 152396 : && GET_MODE (op0) != BLKmode
12895 151069 : && known_eq (GET_MODE_PRECISION (mode),
12896 : GET_MODE_PRECISION (GET_MODE (op0)))
12897 147170 : && !COMPLEX_MODE_P (GET_MODE (op0)))
12898 : {
12899 145766 : if (GET_CODE (op0) == SUBREG)
12900 108 : op0 = force_reg (GET_MODE (op0), op0);
12901 145766 : temp = gen_lowpart_common (mode, op0);
12902 145766 : if (temp)
12903 : op0 = temp;
12904 : else
12905 : {
12906 27999 : if (!REG_P (op0) && !MEM_P (op0))
12907 18 : op0 = force_reg (GET_MODE (op0), op0);
12908 27999 : op0 = gen_lowpart (mode, op0);
12909 : }
12910 : }
12911 : /* If both types are integral, convert from one mode to the other. */
12912 6662 : else if (INTEGRAL_TYPE_P (type)
12913 3130 : && INTEGRAL_TYPE_P (TREE_TYPE (treeop0))
12914 0 : && mode != BLKmode
12915 6662 : && GET_MODE (op0) != BLKmode)
12916 0 : op0 = convert_modes (mode, GET_MODE (op0), op0,
12917 0 : TYPE_UNSIGNED (TREE_TYPE (treeop0)));
12918 : /* If the output type is a bit-field type, do an extraction. */
12919 6662 : else if (reduce_bit_field
12920 2 : && mode != BLKmode
12921 2 : && (MEM_P (op0) || !COMPLEX_MODE_P (GET_MODE (op0))))
12922 0 : return extract_bit_field (op0, TYPE_PRECISION (type), 0,
12923 0 : TYPE_UNSIGNED (type), NULL_RTX,
12924 : mode, mode, false, NULL);
12925 : /* If source is a complex number and destination is a
12926 : two-component vector with same inner type, try to use
12927 : vector initialization. */
12928 6662 : else if ((temp = try_expand_complex_as_vector (mode, op0, target))
12929 : != NULL_RTX)
12930 : return temp;
12931 : /* As a last resort, spill op0 to memory, and reload it in a
12932 : different mode. */
12933 6633 : else if (!MEM_P (op0))
12934 : {
12935 : /* If the operand is not a MEM, force it into memory. Since we
12936 : are going to be changing the mode of the MEM, don't call
12937 : force_const_mem for constants because we don't allow pool
12938 : constants to change mode. */
12939 5296 : tree inner_type = TREE_TYPE (treeop0);
12940 :
12941 5296 : gcc_assert (!TREE_ADDRESSABLE (exp));
12942 :
12943 5296 : if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
12944 5292 : target
12945 : = assign_stack_temp_for_type
12946 5292 : (TYPE_MODE (inner_type),
12947 10584 : GET_MODE_SIZE (TYPE_MODE (inner_type)), inner_type);
12948 :
12949 5296 : emit_move_insn (target, op0);
12950 5296 : op0 = target;
12951 :
12952 5296 : if (reduce_bit_field && mode != BLKmode)
12953 2 : return extract_bit_field (op0, TYPE_PRECISION (type), 0,
12954 2 : TYPE_UNSIGNED (type), NULL_RTX,
12955 : mode, mode, false, NULL);
12956 : }
12957 :
12958 : /* If OP0 is (now) a MEM, we need to deal with alignment issues. If the
12959 : output type is such that the operand is known to be aligned, indicate
12960 : that it is. Otherwise, we need only be concerned about alignment for
12961 : non-BLKmode results. */
12962 351937 : if (MEM_P (op0))
12963 : {
12964 128590 : enum insn_code icode;
12965 :
12966 128590 : if (modifier != EXPAND_WRITE
12967 128590 : && modifier != EXPAND_MEMORY
12968 128590 : && !inner_reference_p
12969 128589 : && mode != BLKmode
12970 183061 : && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
12971 : {
12972 : /* If the target does have special handling for unaligned
12973 : loads of mode then use them. */
12974 15841 : if ((icode = optab_handler (movmisalign_optab, mode))
12975 : != CODE_FOR_nothing)
12976 : {
12977 1906 : rtx reg;
12978 :
12979 1906 : op0 = adjust_address (op0, mode, 0);
12980 : /* We've already validated the memory, and we're creating a
12981 : new pseudo destination. The predicates really can't
12982 : fail. */
12983 1906 : reg = gen_reg_rtx (mode);
12984 :
12985 : /* Nor can the insn generator. */
12986 1906 : rtx_insn *insn = GEN_FCN (icode) (reg, op0);
12987 1906 : emit_insn (insn);
12988 1906 : return reg;
12989 : }
12990 : else if (STRICT_ALIGNMENT)
12991 : {
12992 : poly_uint64 mode_size = GET_MODE_SIZE (mode);
12993 : poly_uint64 temp_size = mode_size;
12994 : if (GET_MODE (op0) != BLKmode)
12995 : temp_size = upper_bound (temp_size,
12996 : GET_MODE_SIZE (GET_MODE (op0)));
12997 : rtx new_rtx
12998 : = assign_stack_temp_for_type (mode, temp_size, type);
12999 : rtx new_with_op0_mode
13000 : = adjust_address (new_rtx, GET_MODE (op0), 0);
13001 :
13002 : gcc_assert (!TREE_ADDRESSABLE (exp));
13003 :
13004 : if (GET_MODE (op0) == BLKmode)
13005 : {
13006 : rtx size_rtx = gen_int_mode (mode_size, Pmode);
13007 : emit_block_move (new_with_op0_mode, op0, size_rtx,
13008 : (modifier == EXPAND_STACK_PARM
13009 : ? BLOCK_OP_CALL_PARM
13010 : : BLOCK_OP_NORMAL));
13011 : }
13012 : else
13013 : emit_move_insn (new_with_op0_mode, op0);
13014 :
13015 : op0 = new_rtx;
13016 : }
13017 : }
13018 :
13019 126684 : op0 = adjust_address (op0, mode, 0);
13020 : }
13021 :
13022 : return op0;
13023 :
13024 63798 : case MODIFY_EXPR:
13025 63798 : {
13026 63798 : tree lhs = treeop0;
13027 63798 : tree rhs = treeop1;
13028 63798 : gcc_assert (ignore);
13029 :
13030 : /* Check for |= or &= of a bitfield of size one into another bitfield
13031 : of size 1. In this case, (unless we need the result of the
13032 : assignment) we can do this more efficiently with a
13033 : test followed by an assignment, if necessary.
13034 :
13035 : ??? At this point, we can't get a BIT_FIELD_REF here. But if
13036 : things change so we do, this code should be enhanced to
13037 : support it. */
13038 63798 : if (TREE_CODE (lhs) == COMPONENT_REF
13039 60546 : && (TREE_CODE (rhs) == BIT_IOR_EXPR
13040 60546 : || TREE_CODE (rhs) == BIT_AND_EXPR)
13041 0 : && TREE_OPERAND (rhs, 0) == lhs
13042 0 : && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
13043 0 : && integer_onep (DECL_SIZE (TREE_OPERAND (lhs, 1)))
13044 63798 : && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
13045 : {
13046 0 : rtx_code_label *label = gen_label_rtx ();
13047 0 : int value = TREE_CODE (rhs) == BIT_IOR_EXPR;
13048 0 : profile_probability prob = profile_probability::uninitialized ();
13049 0 : if (value)
13050 0 : jumpifnot (TREE_OPERAND (rhs, 1), label, prob);
13051 : else
13052 0 : jumpif (TREE_OPERAND (rhs, 1), label, prob);
13053 0 : expand_assignment (lhs, build_int_cst (TREE_TYPE (rhs), value),
13054 : false);
13055 0 : do_pending_stack_adjust ();
13056 0 : emit_label (label);
13057 0 : return const0_rtx;
13058 : }
13059 :
13060 63798 : expand_assignment (lhs, rhs, false);
13061 63798 : return const0_rtx;
13062 : }
13063 :
13064 13248182 : case ADDR_EXPR:
13065 13248182 : return expand_expr_addr_expr (exp, target, tmode, modifier);
13066 :
13067 173202 : case REALPART_EXPR:
13068 173202 : op0 = expand_normal (treeop0);
13069 173202 : return read_complex_part (op0, false);
13070 :
13071 197034 : case IMAGPART_EXPR:
13072 197034 : op0 = expand_normal (treeop0);
13073 197034 : return read_complex_part (op0, true);
13074 :
13075 0 : case RETURN_EXPR:
13076 0 : case LABEL_EXPR:
13077 0 : case GOTO_EXPR:
13078 0 : case SWITCH_EXPR:
13079 0 : case ASM_EXPR:
13080 : /* Expanded in cfgexpand.cc. */
13081 0 : gcc_unreachable ();
13082 :
13083 0 : case TRY_CATCH_EXPR:
13084 0 : case CATCH_EXPR:
13085 0 : case EH_FILTER_EXPR:
13086 0 : case TRY_FINALLY_EXPR:
13087 0 : case EH_ELSE_EXPR:
13088 : /* Lowered by tree-eh.cc. */
13089 0 : gcc_unreachable ();
13090 :
13091 0 : case WITH_CLEANUP_EXPR:
13092 0 : case CLEANUP_POINT_EXPR:
13093 0 : case TARGET_EXPR:
13094 0 : case CASE_LABEL_EXPR:
13095 0 : case VA_ARG_EXPR:
13096 0 : case BIND_EXPR:
13097 0 : case INIT_EXPR:
13098 0 : case CONJ_EXPR:
13099 0 : case COMPOUND_EXPR:
13100 0 : case PREINCREMENT_EXPR:
13101 0 : case PREDECREMENT_EXPR:
13102 0 : case POSTINCREMENT_EXPR:
13103 0 : case POSTDECREMENT_EXPR:
13104 0 : case LOOP_EXPR:
13105 0 : case EXIT_EXPR:
13106 0 : case COMPOUND_LITERAL_EXPR:
13107 : /* Lowered by gimplify.cc. */
13108 0 : gcc_unreachable ();
13109 :
13110 0 : case FDESC_EXPR:
13111 : /* Function descriptors are not valid except for as
13112 : initialization constants, and should not be expanded. */
13113 0 : gcc_unreachable ();
13114 :
13115 258 : case WITH_SIZE_EXPR:
13116 : /* WITH_SIZE_EXPR expands to its first argument. The caller should
13117 : have pulled out the size to use in whatever context it needed. */
13118 258 : return expand_expr_real (treeop0, original_target, tmode,
13119 258 : modifier, alt_rtl, inner_reference_p);
13120 :
13121 1857663 : default:
13122 1857663 : return expand_expr_real_2 (&ops, target, tmode, modifier);
13123 : }
13124 : }
13125 : #undef EXTEND_BITINT
13126 :
13127 : /* Subroutine of above: reduce EXP to the precision of TYPE (in the
13128 : signedness of TYPE), possibly returning the result in TARGET.
13129 : TYPE is known to be a partial integer type. */
13130 : static rtx
13131 89668 : reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
13132 : {
13133 89668 : scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
13134 89668 : HOST_WIDE_INT prec = TYPE_PRECISION (type);
13135 89668 : gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
13136 : && (!target || GET_MODE (target) == mode));
13137 :
13138 : /* For constant values, reduce using wide_int_to_tree. */
13139 89668 : if (poly_int_rtx_p (exp))
13140 : {
13141 0 : auto value = wi::to_poly_wide (exp, mode);
13142 0 : tree t = wide_int_to_tree (type, value);
13143 0 : return expand_expr (t, target, VOIDmode, EXPAND_NORMAL);
13144 : }
13145 89668 : else if (TYPE_UNSIGNED (type))
13146 : {
13147 70557 : rtx mask = immed_wide_int_const
13148 70557 : (wi::mask (prec, false, GET_MODE_PRECISION (mode)), mode);
13149 70557 : return expand_and (mode, exp, mask, target);
13150 : }
13151 : else
13152 : {
13153 19111 : int count = GET_MODE_PRECISION (mode) - prec;
13154 19111 : exp = expand_shift (LSHIFT_EXPR, mode, exp, count, target, 0);
13155 19111 : return expand_shift (RSHIFT_EXPR, mode, exp, count, target, 0);
13156 : }
13157 : }
13158 :
13159 : /* Subroutine of above: returns true if OFFSET corresponds to an offset that
13160 : when applied to the address of EXP produces an address known to be
13161 : aligned more than BIGGEST_ALIGNMENT. */
13162 :
13163 : static bool
13164 279061 : is_aligning_offset (const_tree offset, const_tree exp)
13165 : {
13166 : /* Strip off any conversions. */
13167 296862 : while (CONVERT_EXPR_P (offset))
13168 17801 : offset = TREE_OPERAND (offset, 0);
13169 :
13170 : /* We must now have a BIT_AND_EXPR with a constant that is one less than
13171 : power of 2 and which is larger than BIGGEST_ALIGNMENT. */
13172 279061 : if (TREE_CODE (offset) != BIT_AND_EXPR
13173 0 : || !tree_fits_uhwi_p (TREE_OPERAND (offset, 1))
13174 0 : || compare_tree_int (TREE_OPERAND (offset, 1),
13175 0 : BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
13176 279061 : || !pow2p_hwi (tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1))
13177 : return false;
13178 :
13179 : /* Look at the first operand of BIT_AND_EXPR and strip any conversion.
13180 : It must be NEGATE_EXPR. Then strip any more conversions. */
13181 0 : offset = TREE_OPERAND (offset, 0);
13182 0 : while (CONVERT_EXPR_P (offset))
13183 0 : offset = TREE_OPERAND (offset, 0);
13184 :
13185 0 : if (TREE_CODE (offset) != NEGATE_EXPR)
13186 : return false;
13187 :
13188 0 : offset = TREE_OPERAND (offset, 0);
13189 0 : while (CONVERT_EXPR_P (offset))
13190 0 : offset = TREE_OPERAND (offset, 0);
13191 :
13192 : /* This must now be the address of EXP. */
13193 0 : return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
13194 : }
13195 :
13196 : /* Return a STRING_CST corresponding to ARG's constant initializer either
13197 : if it's a string constant, or, when VALREP is set, any other constant,
13198 : or null otherwise.
13199 : On success, set *PTR_OFFSET to the (possibly non-constant) byte offset
13200 : within the byte string that ARG is references. If nonnull set *MEM_SIZE
13201 : to the size of the byte string. If nonnull, set *DECL to the constant
13202 : declaration ARG refers to. */
13203 :
13204 : static tree
13205 15891601 : constant_byte_string (tree arg, tree *ptr_offset, tree *mem_size, tree *decl,
13206 : bool valrep = false)
13207 : {
13208 15891601 : tree dummy = NULL_TREE;
13209 15891601 : if (!mem_size)
13210 11128 : mem_size = &dummy;
13211 :
13212 : /* Store the type of the original expression before conversions
13213 : via NOP_EXPR or POINTER_PLUS_EXPR to other types have been
13214 : removed. */
13215 15891601 : tree argtype = TREE_TYPE (arg);
13216 :
13217 15891601 : tree array;
13218 15891601 : STRIP_NOPS (arg);
13219 :
13220 : /* Non-constant index into the character array in an ARRAY_REF
13221 : expression or null. */
13222 15891601 : tree varidx = NULL_TREE;
13223 :
13224 15891601 : poly_int64 base_off = 0;
13225 :
13226 15891601 : if (TREE_CODE (arg) == ADDR_EXPR)
13227 : {
13228 6457190 : arg = TREE_OPERAND (arg, 0);
13229 6457190 : tree ref = arg;
13230 6457190 : if (TREE_CODE (arg) == ARRAY_REF)
13231 : {
13232 569809 : tree idx = TREE_OPERAND (arg, 1);
13233 569809 : if (TREE_CODE (idx) != INTEGER_CST)
13234 : {
13235 : /* From a pointer (but not array) argument extract the variable
13236 : index to prevent get_addr_base_and_unit_offset() from failing
13237 : due to it. Use it later to compute the non-constant offset
13238 : into the string and return it to the caller. */
13239 167954 : varidx = idx;
13240 167954 : ref = TREE_OPERAND (arg, 0);
13241 :
13242 167954 : if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
13243 : return NULL_TREE;
13244 :
13245 28905 : if (!integer_zerop (array_ref_low_bound (arg)))
13246 : return NULL_TREE;
13247 :
13248 28157 : if (!integer_onep (array_ref_element_size (arg)))
13249 : return NULL_TREE;
13250 : }
13251 : }
13252 6316250 : array = get_addr_base_and_unit_offset (ref, &base_off);
13253 6316250 : if (!array
13254 6268543 : || (TREE_CODE (array) != VAR_DECL
13255 6268543 : && TREE_CODE (array) != CONST_DECL
13256 3931516 : && TREE_CODE (array) != STRING_CST))
13257 : return NULL_TREE;
13258 : }
13259 9434411 : else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR)
13260 : {
13261 27056 : tree arg0 = TREE_OPERAND (arg, 0);
13262 27056 : tree arg1 = TREE_OPERAND (arg, 1);
13263 :
13264 27056 : tree offset;
13265 27056 : tree str = string_constant (arg0, &offset, mem_size, decl);
13266 27056 : if (!str)
13267 : {
13268 17550 : str = string_constant (arg1, &offset, mem_size, decl);
13269 17550 : arg1 = arg0;
13270 : }
13271 :
13272 17550 : if (str)
13273 : {
13274 : /* Avoid pointers to arrays (see bug 86622). */
13275 9506 : if (POINTER_TYPE_P (TREE_TYPE (arg))
13276 9506 : && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
13277 1890 : && !(decl && !*decl)
13278 12026 : && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
13279 1260 : && tree_fits_uhwi_p (*mem_size)
13280 1260 : && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
13281 : return NULL_TREE;
13282 :
13283 7616 : tree type = TREE_TYPE (offset);
13284 7616 : arg1 = fold_convert (type, arg1);
13285 7616 : *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, arg1);
13286 7616 : return str;
13287 : }
13288 : return NULL_TREE;
13289 : }
13290 9407355 : else if (TREE_CODE (arg) == SSA_NAME)
13291 : {
13292 3919717 : gimple *stmt = SSA_NAME_DEF_STMT (arg);
13293 3919717 : if (!is_gimple_assign (stmt))
13294 : return NULL_TREE;
13295 :
13296 1054324 : tree rhs1 = gimple_assign_rhs1 (stmt);
13297 1054324 : tree_code code = gimple_assign_rhs_code (stmt);
13298 1054324 : if (code == ADDR_EXPR)
13299 236249 : return string_constant (rhs1, ptr_offset, mem_size, decl);
13300 818075 : else if (code != POINTER_PLUS_EXPR)
13301 : return NULL_TREE;
13302 :
13303 194198 : tree offset;
13304 194198 : if (tree str = string_constant (rhs1, &offset, mem_size, decl))
13305 : {
13306 : /* Avoid pointers to arrays (see bug 86622). */
13307 23635 : if (POINTER_TYPE_P (TREE_TYPE (rhs1))
13308 23635 : && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
13309 19700 : && !(decl && !*decl)
13310 39883 : && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
13311 8124 : && tree_fits_uhwi_p (*mem_size)
13312 8124 : && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
13313 : return NULL_TREE;
13314 :
13315 7237 : tree rhs2 = gimple_assign_rhs2 (stmt);
13316 7237 : tree type = TREE_TYPE (offset);
13317 7237 : rhs2 = fold_convert (type, rhs2);
13318 7237 : *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
13319 7237 : return str;
13320 : }
13321 : return NULL_TREE;
13322 : }
13323 5487638 : else if (DECL_P (arg))
13324 : array = arg;
13325 : else
13326 : return NULL_TREE;
13327 :
13328 8866510 : tree offset = wide_int_to_tree (sizetype, base_off);
13329 8866510 : if (varidx)
13330 : {
13331 2850 : if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
13332 : return NULL_TREE;
13333 :
13334 2139 : gcc_assert (TREE_CODE (arg) == ARRAY_REF);
13335 2139 : tree chartype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg, 0)));
13336 2139 : if (TREE_CODE (chartype) != INTEGER_TYPE)
13337 : return NULL;
13338 :
13339 1983 : offset = fold_convert (sizetype, varidx);
13340 : }
13341 :
13342 8865643 : if (TREE_CODE (array) == STRING_CST)
13343 : {
13344 3537136 : *ptr_offset = fold_convert (sizetype, offset);
13345 3537136 : *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
13346 3537136 : if (decl)
13347 760349 : *decl = NULL_TREE;
13348 3537136 : gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
13349 : >= TREE_STRING_LENGTH (array));
13350 : return array;
13351 : }
13352 :
13353 5328507 : tree init = ctor_for_folding (array);
13354 5328507 : if (!init || init == error_mark_node)
13355 : return NULL_TREE;
13356 :
13357 163244 : if (valrep)
13358 : {
13359 58506 : HOST_WIDE_INT cstoff;
13360 58506 : if (!base_off.is_constant (&cstoff))
13361 : return NULL_TREE;
13362 :
13363 : /* Check that the host and target are sane. */
13364 58506 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
13365 : return NULL_TREE;
13366 :
13367 58506 : HOST_WIDE_INT typesz = int_size_in_bytes (TREE_TYPE (init));
13368 58506 : if (typesz <= 0 || (int) typesz != typesz)
13369 : return NULL_TREE;
13370 :
13371 58353 : HOST_WIDE_INT size = typesz;
13372 58353 : if (VAR_P (array)
13373 58341 : && DECL_SIZE_UNIT (array)
13374 116694 : && tree_fits_shwi_p (DECL_SIZE_UNIT (array)))
13375 : {
13376 58341 : size = tree_to_shwi (DECL_SIZE_UNIT (array));
13377 58341 : gcc_checking_assert (size >= typesz);
13378 : }
13379 :
13380 : /* If value representation was requested convert the initializer
13381 : for the whole array or object into a string of bytes forming
13382 : its value representation and return it. */
13383 58353 : unsigned char *bytes = XNEWVEC (unsigned char, size);
13384 58353 : int r = native_encode_initializer (init, bytes, size);
13385 58353 : if (r < typesz)
13386 : {
13387 60 : XDELETEVEC (bytes);
13388 60 : return NULL_TREE;
13389 : }
13390 :
13391 58293 : if (r < size)
13392 0 : memset (bytes + r, '\0', size - r);
13393 :
13394 58293 : const char *p = reinterpret_cast<const char *>(bytes);
13395 58293 : init = build_string_literal (size, p, char_type_node);
13396 58293 : init = TREE_OPERAND (init, 0);
13397 58293 : init = TREE_OPERAND (init, 0);
13398 58293 : XDELETE (bytes);
13399 :
13400 58293 : *mem_size = size_int (TREE_STRING_LENGTH (init));
13401 58293 : *ptr_offset = wide_int_to_tree (ssizetype, base_off);
13402 :
13403 58293 : if (decl)
13404 0 : *decl = array;
13405 :
13406 : return init;
13407 : }
13408 :
13409 104738 : if (TREE_CODE (init) == CONSTRUCTOR)
13410 : {
13411 : /* Convert the 64-bit constant offset to a wider type to avoid
13412 : overflow and use it to obtain the initializer for the subobject
13413 : it points into. */
13414 83997 : offset_int wioff;
13415 83997 : if (!base_off.is_constant (&wioff))
13416 155 : return NULL_TREE;
13417 :
13418 83997 : wioff *= BITS_PER_UNIT;
13419 83997 : if (!wi::fits_uhwi_p (wioff))
13420 : return NULL_TREE;
13421 :
13422 83889 : base_off = wioff.to_uhwi ();
13423 83889 : unsigned HOST_WIDE_INT fieldoff = 0;
13424 83889 : init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array,
13425 : &fieldoff);
13426 83889 : if (!init || init == error_mark_node)
13427 : return NULL_TREE;
13428 :
13429 83842 : HOST_WIDE_INT cstoff;
13430 83842 : if (!base_off.is_constant (&cstoff))
13431 : return NULL_TREE;
13432 :
13433 83842 : cstoff = (cstoff - fieldoff) / BITS_PER_UNIT;
13434 83842 : tree off = build_int_cst (sizetype, cstoff);
13435 83842 : if (varidx)
13436 1122 : offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, off);
13437 : else
13438 : offset = off;
13439 : }
13440 :
13441 104583 : *ptr_offset = offset;
13442 :
13443 104583 : tree inittype = TREE_TYPE (init);
13444 :
13445 104583 : if (TREE_CODE (init) == INTEGER_CST
13446 104583 : && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE
13447 1116 : || TYPE_MAIN_VARIANT (inittype) == char_type_node))
13448 : {
13449 : /* Check that the host and target are sane. */
13450 903 : if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
13451 : return NULL_TREE;
13452 :
13453 : /* For a reference to (address of) a single constant character,
13454 : store the native representation of the character in CHARBUF.
13455 : If the reference is to an element of an array or a member
13456 : of a struct, only consider narrow characters until ctors
13457 : for wide character arrays are transformed to STRING_CSTs
13458 : like those for narrow arrays. */
13459 903 : unsigned char charbuf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
13460 903 : int len = native_encode_expr (init, charbuf, sizeof charbuf, 0);
13461 903 : if (len > 0)
13462 : {
13463 : /* Construct a string literal with elements of INITTYPE and
13464 : the representation above. Then strip
13465 : the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */
13466 903 : init = build_string_literal (len, (char *)charbuf, inittype);
13467 903 : init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
13468 : }
13469 : }
13470 :
13471 104583 : tree initsize = TYPE_SIZE_UNIT (inittype);
13472 :
13473 104583 : if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))
13474 : {
13475 : /* Fold an empty/zero constructor for an implicitly initialized
13476 : object or subobject into the empty string. */
13477 :
13478 : /* Determine the character type from that of the original
13479 : expression. */
13480 9337 : tree chartype = argtype;
13481 9337 : if (POINTER_TYPE_P (chartype))
13482 9330 : chartype = TREE_TYPE (chartype);
13483 14958 : while (TREE_CODE (chartype) == ARRAY_TYPE)
13484 5621 : chartype = TREE_TYPE (chartype);
13485 :
13486 9337 : if (INTEGRAL_TYPE_P (chartype)
13487 9337 : && TYPE_PRECISION (chartype) == TYPE_PRECISION (char_type_node))
13488 : {
13489 : /* Convert a char array to an empty STRING_CST having an array
13490 : of the expected type and size. */
13491 9133 : if (!initsize)
13492 3090 : initsize = integer_zero_node;
13493 6043 : else if (!tree_fits_uhwi_p (initsize))
13494 : return NULL_TREE;
13495 :
13496 9127 : unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
13497 9127 : if (size > (unsigned HOST_WIDE_INT) INT_MAX)
13498 : return NULL_TREE;
13499 :
13500 9127 : init = build_string_literal (size, NULL, chartype, size);
13501 9127 : init = TREE_OPERAND (init, 0);
13502 9127 : init = TREE_OPERAND (init, 0);
13503 :
13504 9127 : *ptr_offset = integer_zero_node;
13505 : }
13506 : }
13507 :
13508 104577 : if (decl)
13509 54389 : *decl = array;
13510 :
13511 104577 : if (TREE_CODE (init) != STRING_CST)
13512 : return NULL_TREE;
13513 :
13514 72333 : *mem_size = initsize;
13515 :
13516 72333 : gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
13517 :
13518 : return init;
13519 : }
13520 :
13521 : /* Return STRING_CST if an ARG corresponds to a string constant or zero
13522 : if it doesn't. If we return nonzero, set *PTR_OFFSET to the (possibly
13523 : non-constant) offset in bytes within the string that ARG is accessing.
13524 : If MEM_SIZE is non-zero the storage size of the memory is returned.
13525 : If DECL is non-zero the constant declaration is returned if available. */
13526 :
13527 : tree
13528 11209923 : string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
13529 : {
13530 11209923 : return constant_byte_string (arg, ptr_offset, mem_size, decl, false);
13531 : }
13532 :
13533 : /* Similar to string_constant, return a STRING_CST corresponding
13534 : to the value representation of the first argument if it's
13535 : a constant. */
13536 :
13537 : tree
13538 4681678 : byte_representation (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
13539 : {
13540 4681678 : return constant_byte_string (arg, ptr_offset, mem_size, decl, true);
13541 : }
13542 :
13543 : /* Optimize x % C1 == C2 for signed modulo if C1 is a power of two and C2
13544 : is non-zero and C3 ((1<<(prec-1)) | (C1 - 1)):
13545 : for C2 > 0 to x & C3 == C2
13546 : for C2 < 0 to x & C3 == (C2 & C3). */
13547 : enum tree_code
13548 35 : maybe_optimize_pow2p_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
13549 : {
13550 35 : gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
13551 35 : tree treeop0 = gimple_assign_rhs1 (stmt);
13552 35 : tree treeop1 = gimple_assign_rhs2 (stmt);
13553 35 : tree type = TREE_TYPE (*arg0);
13554 35 : scalar_int_mode mode;
13555 35 : if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
13556 : return code;
13557 70 : if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
13558 35 : || TYPE_PRECISION (type) <= 1
13559 35 : || TYPE_UNSIGNED (type)
13560 : /* Signed x % c == 0 should have been optimized into unsigned modulo
13561 : earlier. */
13562 35 : || integer_zerop (*arg1)
13563 : /* If c is known to be non-negative, modulo will be expanded as unsigned
13564 : modulo. */
13565 70 : || get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) == 1)
13566 : return code;
13567 :
13568 : /* x % c == d where d < 0 && d <= -c should be always false. */
13569 35 : if (tree_int_cst_sgn (*arg1) == -1
13570 51 : && -wi::to_widest (treeop1) >= wi::to_widest (*arg1))
13571 : return code;
13572 :
13573 35 : int prec = TYPE_PRECISION (type);
13574 35 : wide_int w = wi::to_wide (treeop1) - 1;
13575 35 : w |= wi::shifted_mask (0, prec - 1, true, prec);
13576 35 : tree c3 = wide_int_to_tree (type, w);
13577 35 : tree c4 = *arg1;
13578 35 : if (tree_int_cst_sgn (*arg1) == -1)
13579 16 : c4 = wide_int_to_tree (type, w & wi::to_wide (*arg1));
13580 :
13581 35 : rtx op0 = expand_normal (treeop0);
13582 35 : treeop0 = make_tree (TREE_TYPE (treeop0), op0);
13583 :
13584 35 : bool speed_p = optimize_insn_for_speed_p ();
13585 :
13586 35 : do_pending_stack_adjust ();
13587 :
13588 35 : location_t loc = gimple_location (stmt);
13589 35 : struct separate_ops ops;
13590 35 : ops.code = TRUNC_MOD_EXPR;
13591 35 : ops.location = loc;
13592 35 : ops.type = TREE_TYPE (treeop0);
13593 35 : ops.op0 = treeop0;
13594 35 : ops.op1 = treeop1;
13595 35 : ops.op2 = NULL_TREE;
13596 35 : start_sequence ();
13597 35 : rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13598 : EXPAND_NORMAL);
13599 35 : rtx_insn *moinsns = end_sequence ();
13600 :
13601 35 : unsigned mocost = seq_cost (moinsns, speed_p);
13602 35 : mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
13603 35 : mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
13604 :
13605 35 : ops.code = BIT_AND_EXPR;
13606 35 : ops.location = loc;
13607 35 : ops.type = TREE_TYPE (treeop0);
13608 35 : ops.op0 = treeop0;
13609 35 : ops.op1 = c3;
13610 35 : ops.op2 = NULL_TREE;
13611 35 : start_sequence ();
13612 35 : rtx mur = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13613 : EXPAND_NORMAL);
13614 35 : rtx_insn *muinsns = end_sequence ();
13615 :
13616 35 : unsigned mucost = seq_cost (muinsns, speed_p);
13617 35 : mucost += rtx_cost (mur, mode, EQ, 0, speed_p);
13618 35 : mucost += rtx_cost (expand_normal (c4), mode, EQ, 1, speed_p);
13619 :
13620 35 : if (mocost <= mucost)
13621 : {
13622 0 : emit_insn (moinsns);
13623 0 : *arg0 = make_tree (TREE_TYPE (*arg0), mor);
13624 0 : return code;
13625 : }
13626 :
13627 35 : emit_insn (muinsns);
13628 35 : *arg0 = make_tree (TREE_TYPE (*arg0), mur);
13629 35 : *arg1 = c4;
13630 35 : return code;
13631 35 : }
13632 :
13633 : /* Attempt to optimize unsigned (X % C1) == C2 (or (X % C1) != C2).
13634 : If C1 is odd to:
13635 : (X - C2) * C3 <= C4 (or >), where
13636 : C3 is modular multiplicative inverse of C1 and 1<<prec and
13637 : C4 is ((1<<prec) - 1) / C1 or ((1<<prec) - 1) / C1 - 1 (the latter
13638 : if C2 > ((1<<prec) - 1) % C1).
13639 : If C1 is even, S = ctz (C1) and C2 is 0, use
13640 : ((X * C3) r>> S) <= C4, where C3 is modular multiplicative
13641 : inverse of C1>>S and 1<<prec and C4 is (((1<<prec) - 1) / (C1>>S)) >> S.
13642 :
13643 : For signed (X % C1) == 0 if C1 is odd to (all operations in it
13644 : unsigned):
13645 : (X * C3) + C4 <= 2 * C4, where
13646 : C3 is modular multiplicative inverse of (unsigned) C1 and 1<<prec and
13647 : C4 is ((1<<(prec - 1) - 1) / C1).
13648 : If C1 is even, S = ctz(C1), use
13649 : ((X * C3) + C4) r>> S <= (C4 >> (S - 1))
13650 : where C3 is modular multiplicative inverse of (unsigned)(C1>>S) and 1<<prec
13651 : and C4 is ((1<<(prec - 1) - 1) / (C1>>S)) & (-1<<S).
13652 :
13653 : See the Hacker's Delight book, section 10-17. */
13654 : enum tree_code
13655 3373210 : maybe_optimize_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
13656 : {
13657 3373210 : gcc_checking_assert (code == EQ_EXPR || code == NE_EXPR);
13658 3373210 : gcc_checking_assert (TREE_CODE (*arg1) == INTEGER_CST);
13659 :
13660 3373210 : if (optimize < 2)
13661 : return code;
13662 :
13663 2555114 : gimple *stmt = get_def_for_expr (*arg0, TRUNC_MOD_EXPR);
13664 2555114 : if (stmt == NULL)
13665 : return code;
13666 :
13667 2111 : tree treeop0 = gimple_assign_rhs1 (stmt);
13668 2111 : tree treeop1 = gimple_assign_rhs2 (stmt);
13669 2111 : if (TREE_CODE (treeop0) != SSA_NAME
13670 2009 : || TREE_CODE (treeop1) != INTEGER_CST
13671 : /* Don't optimize the undefined behavior case x % 0;
13672 : x % 1 should have been optimized into zero, punt if
13673 : it makes it here for whatever reason;
13674 : x % -c should have been optimized into x % c. */
13675 1651 : || compare_tree_int (treeop1, 2) <= 0
13676 : /* Likewise x % c == d where d >= c should be always false. */
13677 3686 : || tree_int_cst_le (treeop1, *arg1))
13678 : return code;
13679 :
13680 : /* Unsigned x % pow2 is handled right already, for signed
13681 : modulo handle it in maybe_optimize_pow2p_mod_cmp. */
13682 1575 : if (integer_pow2p (treeop1))
13683 35 : return maybe_optimize_pow2p_mod_cmp (code, arg0, arg1);
13684 :
13685 1540 : tree type = TREE_TYPE (*arg0);
13686 1540 : scalar_int_mode mode;
13687 1540 : if (!is_a <scalar_int_mode> (TYPE_MODE (type), &mode))
13688 : return code;
13689 3080 : if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
13690 1540 : || TYPE_PRECISION (type) <= 1)
13691 : return code;
13692 :
13693 1540 : signop sgn = UNSIGNED;
13694 : /* If both operands are known to have the sign bit clear, handle
13695 : even the signed modulo case as unsigned. treeop1 is always
13696 : positive >= 2, checked above. */
13697 1540 : if (!TYPE_UNSIGNED (type)
13698 1540 : && get_range_pos_neg (treeop0, currently_expanding_gimple_stmt) != 1)
13699 : sgn = SIGNED;
13700 :
13701 1540 : if (!TYPE_UNSIGNED (type))
13702 : {
13703 1312 : if (tree_int_cst_sgn (*arg1) == -1)
13704 : return code;
13705 1305 : type = unsigned_type_for (type);
13706 1305 : if (!type || TYPE_MODE (type) != TYPE_MODE (TREE_TYPE (*arg0)))
13707 : return code;
13708 : }
13709 :
13710 1533 : int prec = TYPE_PRECISION (type);
13711 1533 : wide_int w = wi::to_wide (treeop1);
13712 1533 : int shift = wi::ctz (w);
13713 : /* Unsigned (X % C1) == C2 is equivalent to (X - C2) % C1 == 0 if
13714 : C2 <= -1U % C1, because for any Z >= 0U - C2 in that case (Z % C1) != 0.
13715 : If C1 is odd, we can handle all cases by subtracting
13716 : C4 below. We could handle even the even C1 and C2 > -1U % C1 cases
13717 : e.g. by testing for overflow on the subtraction, punt on that for now
13718 : though. */
13719 1533 : if ((sgn == SIGNED || shift) && !integer_zerop (*arg1))
13720 : {
13721 189 : if (sgn == SIGNED)
13722 174 : return code;
13723 26 : wide_int x = wi::umod_trunc (wi::mask (prec, false, prec), w);
13724 26 : if (wi::gtu_p (wi::to_wide (*arg1), x))
13725 11 : return code;
13726 26 : }
13727 :
13728 1359 : imm_use_iterator imm_iter;
13729 1359 : use_operand_p use_p;
13730 6878 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, treeop0)
13731 : {
13732 5529 : gimple *use_stmt = USE_STMT (use_p);
13733 : /* Punt if treeop0 is used in the same bb in a division
13734 : or another modulo with the same divisor. We should expect
13735 : the division and modulo combined together. */
13736 10961 : if (use_stmt == stmt
13737 5529 : || gimple_bb (use_stmt) != gimple_bb (stmt))
13738 5432 : continue;
13739 97 : if (!is_gimple_assign (use_stmt)
13740 97 : || (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR
13741 81 : && gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR))
13742 72 : continue;
13743 25 : if (gimple_assign_rhs1 (use_stmt) != treeop0
13744 25 : || !operand_equal_p (gimple_assign_rhs2 (use_stmt), treeop1, 0))
13745 15 : continue;
13746 10 : return code;
13747 10 : }
13748 :
13749 1349 : w = wi::lrshift (w, shift);
13750 1349 : wide_int a = wide_int::from (w, prec + 1, UNSIGNED);
13751 1349 : wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
13752 1349 : wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
13753 1349 : tree c3 = wide_int_to_tree (type, m);
13754 1349 : tree c5 = NULL_TREE;
13755 1349 : wide_int d, e;
13756 1349 : if (sgn == UNSIGNED)
13757 : {
13758 1008 : d = wi::divmod_trunc (wi::mask (prec, false, prec), w, UNSIGNED, &e);
13759 : /* Use <= floor ((1<<prec) - 1) / C1 only if C2 <= ((1<<prec) - 1) % C1,
13760 : otherwise use < or subtract one from C4. E.g. for
13761 : x % 3U == 0 we transform this into x * 0xaaaaaaab <= 0x55555555, but
13762 : x % 3U == 1 already needs to be
13763 : (x - 1) * 0xaaaaaaabU <= 0x55555554. */
13764 1008 : if (!shift && wi::gtu_p (wi::to_wide (*arg1), e))
13765 15 : d -= 1;
13766 1008 : if (shift)
13767 442 : d = wi::lrshift (d, shift);
13768 : }
13769 : else
13770 : {
13771 341 : e = wi::udiv_trunc (wi::mask (prec - 1, false, prec), w);
13772 341 : if (!shift)
13773 142 : d = wi::lshift (e, 1);
13774 : else
13775 : {
13776 199 : e = wi::bit_and (e, wi::mask (shift, true, prec));
13777 199 : d = wi::lrshift (e, shift - 1);
13778 : }
13779 341 : c5 = wide_int_to_tree (type, e);
13780 : }
13781 1349 : tree c4 = wide_int_to_tree (type, d);
13782 :
13783 1349 : rtx op0 = expand_normal (treeop0);
13784 1349 : treeop0 = make_tree (TREE_TYPE (treeop0), op0);
13785 :
13786 1349 : bool speed_p = optimize_insn_for_speed_p ();
13787 :
13788 1349 : do_pending_stack_adjust ();
13789 :
13790 1349 : location_t loc = gimple_location (stmt);
13791 1349 : struct separate_ops ops;
13792 1349 : ops.code = TRUNC_MOD_EXPR;
13793 1349 : ops.location = loc;
13794 1349 : ops.type = TREE_TYPE (treeop0);
13795 1349 : ops.op0 = treeop0;
13796 1349 : ops.op1 = treeop1;
13797 1349 : ops.op2 = NULL_TREE;
13798 1349 : start_sequence ();
13799 1349 : rtx mor = expand_expr_real_2 (&ops, NULL_RTX, TYPE_MODE (ops.type),
13800 : EXPAND_NORMAL);
13801 1349 : rtx_insn *moinsns = end_sequence ();
13802 :
13803 1349 : unsigned mocost = seq_cost (moinsns, speed_p);
13804 1349 : mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
13805 1349 : mocost += rtx_cost (expand_normal (*arg1), mode, EQ, 1, speed_p);
13806 :
13807 1349 : tree t = fold_convert_loc (loc, type, treeop0);
13808 1349 : if (!integer_zerop (*arg1))
13809 36 : t = fold_build2_loc (loc, MINUS_EXPR, type, t, fold_convert (type, *arg1));
13810 1349 : t = fold_build2_loc (loc, MULT_EXPR, type, t, c3);
13811 1349 : if (sgn == SIGNED)
13812 341 : t = fold_build2_loc (loc, PLUS_EXPR, type, t, c5);
13813 1349 : if (shift)
13814 : {
13815 641 : tree s = build_int_cst (NULL_TREE, shift);
13816 641 : t = fold_build2_loc (loc, RROTATE_EXPR, type, t, s);
13817 : }
13818 :
13819 1349 : start_sequence ();
13820 1349 : rtx mur = expand_normal (t);
13821 1349 : rtx_insn *muinsns = end_sequence ();
13822 :
13823 1349 : unsigned mucost = seq_cost (muinsns, speed_p);
13824 1349 : mucost += rtx_cost (mur, mode, LE, 0, speed_p);
13825 1349 : mucost += rtx_cost (expand_normal (c4), mode, LE, 1, speed_p);
13826 :
13827 1349 : if (mocost <= mucost)
13828 : {
13829 217 : emit_insn (moinsns);
13830 217 : *arg0 = make_tree (TREE_TYPE (*arg0), mor);
13831 217 : return code;
13832 : }
13833 :
13834 1132 : emit_insn (muinsns);
13835 1132 : *arg0 = make_tree (type, mur);
13836 1132 : *arg1 = c4;
13837 1132 : return code == EQ_EXPR ? LE_EXPR : GT_EXPR;
13838 2882 : }
13839 :
13840 : /* Optimize x - y < 0 into x < 0 if x - y has undefined overflow. */
13841 :
13842 : void
13843 241576 : maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
13844 : {
13845 241576 : gcc_checking_assert (code == GT_EXPR || code == GE_EXPR
13846 : || code == LT_EXPR || code == LE_EXPR);
13847 241576 : gcc_checking_assert (integer_zerop (*arg1));
13848 :
13849 241576 : if (!optimize)
13850 : return;
13851 :
13852 207797 : gimple *stmt = get_def_for_expr (*arg0, MINUS_EXPR);
13853 207797 : if (stmt == NULL)
13854 : return;
13855 :
13856 1371 : tree treeop0 = gimple_assign_rhs1 (stmt);
13857 1371 : tree treeop1 = gimple_assign_rhs2 (stmt);
13858 1371 : if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (treeop0)))
13859 : return;
13860 :
13861 1274 : *arg0 = treeop0;
13862 1274 : *arg1 = treeop1;
13863 : }
13864 :
13865 :
13866 : /* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
13867 : a single bit equality/inequality test, returns where the result is located. */
13868 :
13869 : static rtx
13870 9846 : expand_single_bit_test (location_t loc, enum tree_code code,
13871 : tree inner, int bitnum,
13872 : tree result_type, rtx target,
13873 : machine_mode mode)
13874 : {
13875 9846 : gcc_assert (code == NE_EXPR || code == EQ_EXPR);
13876 :
13877 9846 : tree type = TREE_TYPE (inner);
13878 9846 : scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
13879 9846 : int ops_unsigned;
13880 9846 : tree signed_type, unsigned_type, intermediate_type;
13881 9846 : gimple *inner_def;
13882 :
13883 : /* First, see if we can fold the single bit test into a sign-bit
13884 : test. */
13885 9846 : if (bitnum == TYPE_PRECISION (type) - 1
13886 9846 : && type_has_mode_precision_p (type))
13887 : {
13888 241 : tree stype = signed_type_for (type);
13889 444 : tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
13890 : result_type,
13891 : fold_convert_loc (loc, stype, inner),
13892 : build_int_cst (stype, 0));
13893 241 : return expand_expr (tmp, target, VOIDmode, EXPAND_NORMAL);
13894 : }
13895 :
13896 : /* Otherwise we have (A & C) != 0 where C is a single bit,
13897 : convert that into ((A >> C2) & 1). Where C2 = log2(C).
13898 : Similarly for (A & C) == 0. */
13899 :
13900 : /* If INNER is a right shift of a constant and it plus BITNUM does
13901 : not overflow, adjust BITNUM and INNER. */
13902 9605 : if ((inner_def = get_def_for_expr (inner, RSHIFT_EXPR))
13903 61 : && TREE_CODE (gimple_assign_rhs2 (inner_def)) == INTEGER_CST
13904 16 : && bitnum < TYPE_PRECISION (type)
13905 9621 : && wi::ltu_p (wi::to_wide (gimple_assign_rhs2 (inner_def)),
13906 9605 : TYPE_PRECISION (type) - bitnum))
13907 : {
13908 16 : bitnum += tree_to_uhwi (gimple_assign_rhs2 (inner_def));
13909 16 : inner = gimple_assign_rhs1 (inner_def);
13910 : }
13911 :
13912 : /* If we are going to be able to omit the AND below, we must do our
13913 : operations as unsigned. If we must use the AND, we have a choice.
13914 : Normally unsigned is faster, but for some machines signed is. */
13915 9605 : ops_unsigned = (load_extend_op (operand_mode) == SIGN_EXTEND
13916 : && !flag_syntax_only) ? 0 : 1;
13917 :
13918 9605 : signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
13919 9605 : unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
13920 9605 : intermediate_type = ops_unsigned ? unsigned_type : signed_type;
13921 9605 : inner = fold_convert_loc (loc, intermediate_type, inner);
13922 :
13923 9605 : rtx inner0 = expand_expr (inner, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13924 :
13925 9605 : if (CONST_SCALAR_INT_P (inner0))
13926 : {
13927 0 : wide_int t = rtx_mode_t (inner0, operand_mode);
13928 0 : bool setp = (wi::lrshift (t, bitnum) & 1) != 0;
13929 0 : return (setp ^ (code == EQ_EXPR)) ? const1_rtx : const0_rtx;
13930 0 : }
13931 9605 : int bitpos = bitnum;
13932 :
13933 9605 : if (BYTES_BIG_ENDIAN)
13934 : bitpos = GET_MODE_BITSIZE (operand_mode) - 1 - bitpos;
13935 :
13936 9605 : inner0 = extract_bit_field (inner0, 1, bitpos, 1, target,
13937 : operand_mode, mode, 0, NULL);
13938 :
13939 9605 : if (code == EQ_EXPR)
13940 2694 : inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
13941 : NULL_RTX, 1, OPTAB_LIB_WIDEN);
13942 9605 : if (GET_MODE (inner0) != mode)
13943 : {
13944 0 : rtx t = gen_reg_rtx (mode);
13945 0 : convert_move (t, inner0, 0);
13946 0 : return t;
13947 : }
13948 : return inner0;
13949 : }
13950 :
13951 : /* Generate code to calculate OPS, and exploded expression
13952 : using a store-flag instruction and return an rtx for the result.
13953 : OPS reflects a comparison.
13954 :
13955 : If TARGET is nonzero, store the result there if convenient.
13956 :
13957 : Return zero if there is no suitable set-flag instruction
13958 : available on this machine.
13959 :
13960 : Once expand_expr has been called on the arguments of the comparison,
13961 : we are committed to doing the store flag, since it is not safe to
13962 : re-evaluate the expression. We emit the store-flag insn by calling
13963 : emit_store_flag, but only expand the arguments if we have a reason
13964 : to believe that emit_store_flag will be successful. If we think that
13965 : it will, but it isn't, we have to simulate the store-flag with a
13966 : set/jump/set sequence. */
13967 :
13968 : static rtx
13969 643674 : do_store_flag (const_sepops ops, rtx target, machine_mode mode)
13970 : {
13971 643674 : enum rtx_code code;
13972 643674 : tree arg0, arg1, type;
13973 643674 : machine_mode operand_mode;
13974 643674 : int unsignedp;
13975 643674 : rtx op0, op1;
13976 643674 : rtx subtarget = target;
13977 643674 : location_t loc = ops->location;
13978 643674 : unsigned HOST_WIDE_INT nunits;
13979 :
13980 643674 : arg0 = ops->op0;
13981 643674 : arg1 = ops->op1;
13982 :
13983 : /* Don't crash if the comparison was erroneous. */
13984 643674 : if (arg0 == error_mark_node || arg1 == error_mark_node)
13985 0 : return const0_rtx;
13986 :
13987 643674 : type = TREE_TYPE (arg0);
13988 643674 : operand_mode = TYPE_MODE (type);
13989 643674 : unsignedp = TYPE_UNSIGNED (type);
13990 :
13991 : /* We won't bother with BLKmode store-flag operations because it would mean
13992 : passing a lot of information to emit_store_flag. */
13993 643674 : if (operand_mode == BLKmode)
13994 : return 0;
13995 :
13996 : /* We won't bother with store-flag operations involving function pointers
13997 : when function pointers must be canonicalized before comparisons. */
13998 643674 : if (targetm.have_canonicalize_funcptr_for_compare ()
13999 643674 : && ((POINTER_TYPE_P (TREE_TYPE (arg0))
14000 0 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
14001 0 : || (POINTER_TYPE_P (TREE_TYPE (arg1))
14002 0 : && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
14003 : return 0;
14004 :
14005 643674 : STRIP_NOPS (arg0);
14006 643674 : STRIP_NOPS (arg1);
14007 :
14008 : /* For vector typed comparisons emit code to generate the desired
14009 : all-ones or all-zeros mask. */
14010 643674 : if (VECTOR_TYPE_P (ops->type))
14011 : {
14012 26175 : tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
14013 26175 : if (VECTOR_BOOLEAN_TYPE_P (ops->type)
14014 52350 : && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
14015 26175 : return expand_vec_cmp_expr (ops->type, ifexp, target);
14016 : else
14017 0 : gcc_unreachable ();
14018 : }
14019 :
14020 : /* Optimize (x % C1) == C2 or (x % C1) != C2 if it is beneficial
14021 : into (x - C2) * C3 < C4. */
14022 617499 : if ((ops->code == EQ_EXPR || ops->code == NE_EXPR)
14023 415109 : && TREE_CODE (arg0) == SSA_NAME
14024 414534 : && TREE_CODE (arg1) == INTEGER_CST)
14025 : {
14026 248635 : enum tree_code new_code = maybe_optimize_mod_cmp (ops->code,
14027 : &arg0, &arg1);
14028 248635 : if (new_code != ops->code)
14029 : {
14030 107 : struct separate_ops nops = *ops;
14031 107 : nops.code = new_code;
14032 107 : nops.op0 = arg0;
14033 107 : nops.op1 = arg1;
14034 107 : nops.type = TREE_TYPE (arg0);
14035 107 : return do_store_flag (&nops, target, mode);
14036 : }
14037 : }
14038 :
14039 : /* Optimize (x - y) < 0 into x < y if x - y has undefined overflow. */
14040 617392 : if (!unsignedp
14041 442905 : && (ops->code == LT_EXPR || ops->code == LE_EXPR
14042 442905 : || ops->code == GT_EXPR || ops->code == GE_EXPR)
14043 127846 : && integer_zerop (arg1)
14044 655994 : && TREE_CODE (arg0) == SSA_NAME)
14045 38598 : maybe_optimize_sub_cmp_0 (ops->code, &arg0, &arg1);
14046 :
14047 : /* Get the rtx comparison code to use. We know that EXP is a comparison
14048 : operation of some type. Some comparisons against 1 and -1 can be
14049 : converted to comparisons with zero. Do so here so that the tests
14050 : below will be aware that we have a comparison with zero. These
14051 : tests will not catch constants in the first operand, but constants
14052 : are rarely passed as the first operand. */
14053 :
14054 617392 : switch (ops->code)
14055 : {
14056 : case EQ_EXPR:
14057 : code = EQ;
14058 : break;
14059 235582 : case NE_EXPR:
14060 235582 : code = NE;
14061 235582 : break;
14062 42307 : case LT_EXPR:
14063 42307 : if (integer_onep (arg1))
14064 0 : arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
14065 : else
14066 42307 : code = unsignedp ? LTU : LT;
14067 : break;
14068 33570 : case LE_EXPR:
14069 33570 : if (! unsignedp && integer_all_onesp (arg1))
14070 0 : arg1 = integer_zero_node, code = LT;
14071 : else
14072 33570 : code = unsignedp ? LEU : LE;
14073 : break;
14074 54257 : case GT_EXPR:
14075 54257 : if (! unsignedp && integer_all_onesp (arg1))
14076 0 : arg1 = integer_zero_node, code = GE;
14077 : else
14078 54257 : code = unsignedp ? GTU : GT;
14079 : break;
14080 47684 : case GE_EXPR:
14081 47684 : if (integer_onep (arg1))
14082 0 : arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
14083 : else
14084 47684 : code = unsignedp ? GEU : GE;
14085 : break;
14086 :
14087 1030 : case UNORDERED_EXPR:
14088 1030 : code = UNORDERED;
14089 1030 : break;
14090 720 : case ORDERED_EXPR:
14091 720 : code = ORDERED;
14092 720 : break;
14093 535 : case UNLT_EXPR:
14094 535 : code = UNLT;
14095 535 : break;
14096 11128 : case UNLE_EXPR:
14097 11128 : code = UNLE;
14098 11128 : break;
14099 1002 : case UNGT_EXPR:
14100 1002 : code = UNGT;
14101 1002 : break;
14102 9936 : case UNGE_EXPR:
14103 9936 : code = UNGE;
14104 9936 : break;
14105 135 : case UNEQ_EXPR:
14106 135 : code = UNEQ;
14107 135 : break;
14108 86 : case LTGT_EXPR:
14109 86 : code = LTGT;
14110 86 : break;
14111 :
14112 0 : default:
14113 0 : gcc_unreachable ();
14114 : }
14115 :
14116 : /* Put a constant second. */
14117 617392 : if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST
14118 615422 : || TREE_CODE (arg0) == FIXED_CST)
14119 : {
14120 1970 : std::swap (arg0, arg1);
14121 1970 : code = swap_condition (code);
14122 : }
14123 :
14124 : /* If this is an equality or inequality test of a single bit, we can
14125 : do this by shifting the bit being tested to the low-order bit and
14126 : masking the result with the constant 1. If the condition was EQ,
14127 : we xor it with 1. This does not require an scc insn and is faster
14128 : than an scc insn even if we have it. */
14129 :
14130 617392 : if ((code == NE || code == EQ)
14131 415002 : && (integer_zerop (arg1)
14132 259923 : || integer_pow2p (arg1))
14133 : /* vector types are not handled here. */
14134 188424 : && TREE_CODE (TREE_TYPE (arg1)) != VECTOR_TYPE
14135 805776 : && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type)))
14136 : {
14137 188384 : tree narg0 = arg0;
14138 188384 : wide_int nz = tree_nonzero_bits (narg0);
14139 188384 : gimple *srcstmt = get_def_for_expr (narg0, BIT_AND_EXPR);
14140 : /* If the defining statement was (x & POW2), then use that instead of
14141 : the non-zero bits. */
14142 188384 : if (srcstmt && integer_pow2p (gimple_assign_rhs2 (srcstmt)))
14143 : {
14144 5479 : nz = wi::to_wide (gimple_assign_rhs2 (srcstmt));
14145 5479 : narg0 = gimple_assign_rhs1 (srcstmt);
14146 : }
14147 :
14148 188384 : if (wi::popcount (nz) == 1
14149 188384 : && (integer_zerop (arg1)
14150 188384 : || wi::to_wide (arg1) == nz))
14151 : {
14152 9846 : int bitnum = wi::exact_log2 (nz);
14153 9846 : enum tree_code tcode = EQ_EXPR;
14154 9846 : if ((code == NE) ^ !integer_zerop (arg1))
14155 7114 : tcode = NE_EXPR;
14156 :
14157 9846 : type = lang_hooks.types.type_for_mode (mode, unsignedp);
14158 9846 : return expand_single_bit_test (loc, tcode,
14159 : narg0,
14160 : bitnum, type, target, mode);
14161 : }
14162 188384 : }
14163 :
14164 :
14165 607546 : if (! get_subtarget (target)
14166 607546 : || GET_MODE (subtarget) != operand_mode)
14167 : subtarget = 0;
14168 :
14169 607546 : expand_operands (arg0, arg1, subtarget, &op0, &op1, EXPAND_NORMAL);
14170 :
14171 : /* For boolean vectors with less than mode precision
14172 : make sure to fill padding with consistent values. */
14173 40 : if (VECTOR_BOOLEAN_TYPE_P (type)
14174 27 : && SCALAR_INT_MODE_P (operand_mode)
14175 607546 : && TYPE_VECTOR_SUBPARTS (type).is_constant (&nunits)
14176 607546 : && maybe_ne (GET_MODE_PRECISION (operand_mode), nunits))
14177 : {
14178 0 : gcc_assert (code == EQ || code == NE);
14179 0 : op0 = expand_binop (mode, and_optab, op0,
14180 0 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
14181 : NULL_RTX, true, OPTAB_WIDEN);
14182 0 : op1 = expand_binop (mode, and_optab, op1,
14183 : GEN_INT ((HOST_WIDE_INT_1U << nunits) - 1),
14184 : NULL_RTX, true, OPTAB_WIDEN);
14185 : }
14186 :
14187 607546 : if (target == 0)
14188 415319 : target = gen_reg_rtx (mode);
14189 :
14190 : /* Try a cstore if possible. */
14191 607546 : return emit_store_flag_force (target, code, op0, op1,
14192 : operand_mode, unsignedp,
14193 607546 : (TYPE_PRECISION (ops->type) == 1
14194 1214420 : && !TYPE_UNSIGNED (ops->type)) ? -1 : 1);
14195 : }
14196 :
14197 : /* Attempt to generate a casesi instruction. Returns true if successful,
14198 : false otherwise (i.e. if there is no casesi instruction).
14199 :
14200 : DEFAULT_PROBABILITY is the probability of jumping to the default
14201 : label. */
14202 : bool
14203 7077 : try_casesi (tree index_type, tree index_expr, tree minval, tree range,
14204 : rtx table_label, rtx default_label, rtx fallback_label,
14205 : profile_probability default_probability)
14206 : {
14207 7077 : class expand_operand ops[5];
14208 7077 : scalar_int_mode index_mode = SImode;
14209 7077 : rtx op1, op2, index;
14210 :
14211 7077 : if (! targetm.have_casesi ())
14212 : return false;
14213 :
14214 : /* The index must be some form of integer. Convert it to SImode. */
14215 0 : scalar_int_mode omode = SCALAR_INT_TYPE_MODE (index_type);
14216 0 : if (GET_MODE_BITSIZE (omode) > GET_MODE_BITSIZE (index_mode))
14217 : {
14218 0 : rtx rangertx = expand_normal (range);
14219 :
14220 : /* We must handle the endpoints in the original mode. */
14221 0 : index_expr = build2 (MINUS_EXPR, index_type,
14222 : index_expr, minval);
14223 0 : minval = integer_zero_node;
14224 0 : index = expand_normal (index_expr);
14225 0 : if (default_label)
14226 0 : emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
14227 : omode, 1, default_label,
14228 : default_probability);
14229 : /* Now we can safely truncate. */
14230 0 : index = convert_to_mode (index_mode, index, 0);
14231 : }
14232 : else
14233 : {
14234 0 : if (omode != index_mode)
14235 : {
14236 0 : index_type = lang_hooks.types.type_for_mode (index_mode, 0);
14237 0 : index_expr = fold_convert (index_type, index_expr);
14238 : }
14239 :
14240 0 : index = expand_normal (index_expr);
14241 : }
14242 :
14243 0 : do_pending_stack_adjust ();
14244 :
14245 0 : op1 = expand_normal (minval);
14246 0 : op2 = expand_normal (range);
14247 :
14248 0 : create_input_operand (&ops[0], index, index_mode);
14249 0 : create_convert_operand_from_type (&ops[1], op1, TREE_TYPE (minval));
14250 0 : create_convert_operand_from_type (&ops[2], op2, TREE_TYPE (range));
14251 0 : create_fixed_operand (&ops[3], table_label);
14252 0 : create_fixed_operand (&ops[4], (default_label
14253 : ? default_label
14254 : : fallback_label));
14255 0 : expand_jump_insn (targetm.code_for_casesi, 5, ops);
14256 0 : return true;
14257 : }
14258 :
14259 : /* Attempt to generate a tablejump instruction; same concept. */
14260 : /* Subroutine of the next function.
14261 :
14262 : INDEX is the value being switched on, with the lowest value
14263 : in the table already subtracted.
14264 : MODE is its expected mode (needed if INDEX is constant).
14265 : RANGE is the length of the jump table.
14266 : TABLE_LABEL is a CODE_LABEL rtx for the table itself.
14267 :
14268 : DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
14269 : index value is out of range.
14270 : DEFAULT_PROBABILITY is the probability of jumping to
14271 : the default label. */
14272 :
14273 : static void
14274 7077 : do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label,
14275 : rtx default_label, profile_probability default_probability)
14276 : {
14277 7077 : rtx temp, vector;
14278 :
14279 7077 : if (INTVAL (range) > cfun->cfg->max_jumptable_ents)
14280 5990 : cfun->cfg->max_jumptable_ents = INTVAL (range);
14281 :
14282 : /* Do an unsigned comparison (in the proper mode) between the index
14283 : expression and the value which represents the length of the range.
14284 : Since we just finished subtracting the lower bound of the range
14285 : from the index expression, this comparison allows us to simultaneously
14286 : check that the original index expression value is both greater than
14287 : or equal to the minimum value of the range and less than or equal to
14288 : the maximum value of the range. */
14289 :
14290 7077 : if (default_label)
14291 7031 : emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
14292 : default_label, default_probability);
14293 :
14294 : /* If index is in range, it must fit in Pmode.
14295 : Convert to Pmode so we can index with it. */
14296 8144 : if (mode != Pmode)
14297 : {
14298 6074 : unsigned int width;
14299 :
14300 : /* We know the value of INDEX is between 0 and RANGE. If we have a
14301 : sign-extended subreg, and RANGE does not have the sign bit set, then
14302 : we have a value that is valid for both sign and zero extension. In
14303 : this case, we get better code if we sign extend. */
14304 6074 : if (GET_CODE (index) == SUBREG
14305 9 : && SUBREG_PROMOTED_VAR_P (index)
14306 0 : && SUBREG_PROMOTED_SIGNED_P (index)
14307 0 : && ((width = GET_MODE_PRECISION (as_a <scalar_int_mode> (mode)))
14308 : <= HOST_BITS_PER_WIDE_INT)
14309 6074 : && ! (UINTVAL (range) & (HOST_WIDE_INT_1U << (width - 1))))
14310 0 : index = convert_to_mode (Pmode, index, 0);
14311 : else
14312 6074 : index = convert_to_mode (Pmode, index, 1);
14313 : }
14314 :
14315 : /* Don't let a MEM slip through, because then INDEX that comes
14316 : out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
14317 : and break_out_memory_refs will go to work on it and mess it up. */
14318 : #ifdef PIC_CASE_VECTOR_ADDRESS
14319 : if (flag_pic && !REG_P (index))
14320 : index = copy_to_mode_reg (Pmode, index);
14321 : #endif
14322 :
14323 : /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
14324 : GET_MODE_SIZE, because this indicates how large insns are. The other
14325 : uses should all be Pmode, because they are addresses. This code
14326 : could fail if addresses and insns are not the same size. */
14327 8144 : index = simplify_gen_binary (MULT, Pmode, index,
14328 14154 : gen_int_mode (GET_MODE_SIZE (CASE_VECTOR_MODE),
14329 7077 : Pmode));
14330 8144 : index = simplify_gen_binary (PLUS, Pmode, index,
14331 7077 : gen_rtx_LABEL_REF (Pmode, table_label));
14332 :
14333 : #ifdef PIC_CASE_VECTOR_ADDRESS
14334 : if (flag_pic)
14335 : index = PIC_CASE_VECTOR_ADDRESS (index);
14336 : else
14337 : #endif
14338 8756 : index = memory_address (CASE_VECTOR_MODE, index);
14339 8756 : temp = gen_reg_rtx (CASE_VECTOR_MODE);
14340 8756 : vector = gen_const_mem (CASE_VECTOR_MODE, index);
14341 7077 : convert_move (temp, vector, 0);
14342 :
14343 7077 : emit_jump_insn (targetm.gen_tablejump (temp, table_label));
14344 :
14345 : /* If we are generating PIC code or if the table is PC-relative, the
14346 : table and JUMP_INSN must be adjacent, so don't output a BARRIER. */
14347 7077 : if (! CASE_VECTOR_PC_RELATIVE && ! flag_pic)
14348 5900 : emit_barrier ();
14349 7077 : }
14350 :
14351 : bool
14352 7077 : try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
14353 : rtx table_label, rtx default_label,
14354 : profile_probability default_probability)
14355 : {
14356 7077 : rtx index;
14357 :
14358 7077 : if (! targetm.have_tablejump ())
14359 : return false;
14360 :
14361 7077 : index_expr = fold_build2 (MINUS_EXPR, index_type,
14362 : fold_convert (index_type, index_expr),
14363 : fold_convert (index_type, minval));
14364 7077 : index = expand_normal (index_expr);
14365 7077 : do_pending_stack_adjust ();
14366 :
14367 7077 : do_tablejump (index, TYPE_MODE (index_type),
14368 7077 : convert_modes (TYPE_MODE (index_type),
14369 7077 : TYPE_MODE (TREE_TYPE (range)),
14370 : expand_normal (range),
14371 7077 : TYPE_UNSIGNED (TREE_TYPE (range))),
14372 : table_label, default_label, default_probability);
14373 7077 : return true;
14374 : }
14375 :
14376 : /* Return a CONST_VECTOR rtx representing vector mask for
14377 : a VECTOR_CST of booleans. */
14378 : static rtx
14379 684 : const_vector_mask_from_tree (tree exp)
14380 : {
14381 684 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
14382 684 : machine_mode inner = GET_MODE_INNER (mode);
14383 :
14384 684 : rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
14385 684 : VECTOR_CST_NELTS_PER_PATTERN (exp));
14386 684 : unsigned int count = builder.encoded_nelts ();
14387 3680 : for (unsigned int i = 0; i < count; ++i)
14388 : {
14389 2996 : tree elt = VECTOR_CST_ELT (exp, i);
14390 2996 : gcc_assert (TREE_CODE (elt) == INTEGER_CST);
14391 2996 : if (integer_zerop (elt))
14392 1177 : builder.quick_push (CONST0_RTX (inner));
14393 1819 : else if (integer_onep (elt)
14394 1819 : || integer_minus_onep (elt))
14395 1819 : builder.quick_push (CONSTM1_RTX (inner));
14396 : else
14397 0 : gcc_unreachable ();
14398 : }
14399 684 : return builder.build ();
14400 684 : }
14401 :
14402 : /* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
14403 : static rtx
14404 570469 : const_vector_from_tree (tree exp)
14405 : {
14406 570469 : machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
14407 :
14408 570469 : if (initializer_zerop (exp))
14409 170103 : return CONST0_RTX (mode);
14410 :
14411 400366 : if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
14412 684 : return const_vector_mask_from_tree (exp);
14413 :
14414 399682 : machine_mode inner = GET_MODE_INNER (mode);
14415 :
14416 399682 : rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
14417 399682 : VECTOR_CST_NELTS_PER_PATTERN (exp));
14418 399682 : unsigned int count = builder.encoded_nelts ();
14419 1288674 : for (unsigned int i = 0; i < count; ++i)
14420 : {
14421 888992 : tree elt = VECTOR_CST_ELT (exp, i);
14422 888992 : if (TREE_CODE (elt) == REAL_CST)
14423 135726 : builder.quick_push (const_double_from_real_value (TREE_REAL_CST (elt),
14424 : inner));
14425 753266 : else if (TREE_CODE (elt) == FIXED_CST)
14426 0 : builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt),
14427 : inner));
14428 : else
14429 753266 : builder.quick_push (immed_wide_int_const (wi::to_poly_wide (elt),
14430 : inner));
14431 : }
14432 399682 : return builder.build ();
14433 399682 : }
14434 :
14435 : /* Build a decl for a personality function given a language prefix. */
14436 :
14437 : tree
14438 33085 : build_personality_function (const char *lang)
14439 : {
14440 33085 : const char *unwind_and_version;
14441 33085 : tree decl, type;
14442 33085 : char *name;
14443 :
14444 33085 : switch (targetm_common.except_unwind_info (&global_options))
14445 : {
14446 : case UI_NONE:
14447 : return NULL;
14448 : case UI_SJLJ:
14449 : unwind_and_version = "_sj0";
14450 : break;
14451 33085 : case UI_DWARF2:
14452 33085 : case UI_TARGET:
14453 33085 : unwind_and_version = "_v0";
14454 33085 : break;
14455 0 : case UI_SEH:
14456 0 : unwind_and_version = "_seh0";
14457 0 : break;
14458 0 : default:
14459 0 : gcc_unreachable ();
14460 : }
14461 :
14462 33085 : name = ACONCAT (("__", lang, "_personality", unwind_and_version, NULL));
14463 :
14464 33085 : type = build_function_type_list (unsigned_type_node,
14465 : integer_type_node, integer_type_node,
14466 : long_long_unsigned_type_node,
14467 : ptr_type_node, ptr_type_node, NULL_TREE);
14468 33085 : decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
14469 : get_identifier (name), type);
14470 33085 : DECL_ARTIFICIAL (decl) = 1;
14471 33085 : DECL_EXTERNAL (decl) = 1;
14472 33085 : TREE_PUBLIC (decl) = 1;
14473 :
14474 : /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
14475 : are the flags assigned by targetm.encode_section_info. */
14476 33085 : SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
14477 :
14478 33085 : return decl;
14479 : }
14480 :
14481 : /* Extracts the personality function of DECL and returns the corresponding
14482 : libfunc. */
14483 :
14484 : rtx
14485 1665407 : get_personality_function (tree decl)
14486 : {
14487 1665407 : tree personality = DECL_FUNCTION_PERSONALITY (decl);
14488 1665407 : enum eh_personality_kind pk;
14489 :
14490 1665407 : pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
14491 1665407 : if (pk == eh_personality_none)
14492 : return NULL;
14493 :
14494 158181 : if (!personality
14495 158181 : && pk == eh_personality_any)
14496 72334 : personality = lang_hooks.eh_personality ();
14497 :
14498 158181 : if (pk == eh_personality_lang)
14499 85847 : gcc_assert (personality != NULL_TREE);
14500 :
14501 158181 : return XEXP (DECL_RTL (personality), 0);
14502 : }
14503 :
14504 : /* Returns a tree for the size of EXP in bytes. */
14505 :
14506 : static tree
14507 14947391 : tree_expr_size (const_tree exp)
14508 : {
14509 14947391 : if (DECL_P (exp)
14510 14947391 : && DECL_SIZE_UNIT (exp) != 0)
14511 1953581 : return DECL_SIZE_UNIT (exp);
14512 : else
14513 12993810 : return size_in_bytes (TREE_TYPE (exp));
14514 : }
14515 :
14516 : /* Return an rtx for the size in bytes of the value of EXP. */
14517 :
14518 : rtx
14519 14754876 : expr_size (tree exp)
14520 : {
14521 14754876 : tree size;
14522 :
14523 14754876 : if (TREE_CODE (exp) == WITH_SIZE_EXPR)
14524 773 : size = TREE_OPERAND (exp, 1);
14525 : else
14526 : {
14527 14754103 : size = tree_expr_size (exp);
14528 14754103 : gcc_assert (size);
14529 14754103 : gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp));
14530 : }
14531 :
14532 14754876 : return expand_expr (size, NULL_RTX, TYPE_MODE (sizetype), EXPAND_NORMAL);
14533 : }
14534 :
14535 : /* Return a wide integer for the size in bytes of the value of EXP, or -1
14536 : if the size can vary or is larger than an integer. */
14537 :
14538 : HOST_WIDE_INT
14539 193288 : int_expr_size (const_tree exp)
14540 : {
14541 193288 : tree size;
14542 :
14543 193288 : if (TREE_CODE (exp) == WITH_SIZE_EXPR)
14544 0 : size = TREE_OPERAND (exp, 1);
14545 : else
14546 : {
14547 193288 : size = tree_expr_size (exp);
14548 193288 : gcc_assert (size);
14549 : }
14550 :
14551 193288 : if (size == 0 || !tree_fits_shwi_p (size))
14552 : return -1;
14553 :
14554 193288 : return tree_to_shwi (size);
14555 : }
14556 :
14557 : /* Return the quotient of polynomial long division of x^2N by POLYNOMIAL
14558 : in GF (2^N).
14559 : Author: Richard Sandiford <richard.sandiford@arm.com> */
14560 :
14561 : unsigned HOST_WIDE_INT
14562 0 : gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial,
14563 : unsigned short n)
14564 : {
14565 : /* The result has degree N, so needs N + 1 bits. */
14566 0 : gcc_assert (n < 64);
14567 :
14568 : /* Perform a division step for the x^2N coefficient. At this point the
14569 : quotient and remainder have N implicit trailing zeros. */
14570 : unsigned HOST_WIDE_INT quotient = 1;
14571 : unsigned HOST_WIDE_INT remainder = polynomial;
14572 :
14573 : /* Process the coefficients for x^(2N-1) down to x^N, with each step
14574 : reducing the number of implicit trailing zeros by one. */
14575 0 : for (unsigned int i = 0; i < n; ++i)
14576 : {
14577 0 : bool coeff = remainder & (HOST_WIDE_INT_1U << (n - 1));
14578 0 : quotient = (quotient << 1) | coeff;
14579 0 : remainder = (remainder << 1) ^ (coeff ? polynomial : 0);
14580 : }
14581 0 : return quotient;
14582 : }
14583 :
14584 : /* Calculate CRC for the initial CRC and given POLYNOMIAL.
14585 : CRC_BITS is CRC size. */
14586 :
14587 : static unsigned HOST_WIDE_INT
14588 34560 : calculate_crc (unsigned HOST_WIDE_INT crc,
14589 : unsigned HOST_WIDE_INT polynomial,
14590 : unsigned short crc_bits)
14591 : {
14592 34560 : unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
14593 34560 : crc = crc << (crc_bits - 8);
14594 311040 : for (short i = 8; i > 0; --i)
14595 : {
14596 276480 : if (crc & msb)
14597 138240 : crc = (crc << 1) ^ polynomial;
14598 : else
14599 138240 : crc <<= 1;
14600 : }
14601 : /* Zero out bits in crc beyond the specified number of crc_bits. */
14602 34560 : if (crc_bits < sizeof (crc) * CHAR_BIT)
14603 31488 : crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
14604 34560 : return crc;
14605 : }
14606 :
14607 : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
14608 : POLYNOM is the polynomial used to calculate the CRC table's elements.
14609 : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14610 :
14611 : static rtx
14612 135 : assemble_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14613 : {
14614 135 : unsigned table_el_n = 0x100;
14615 135 : tree ar = build_array_type (make_unsigned_type (crc_bits),
14616 135 : build_index_type (size_int (table_el_n - 1)));
14617 :
14618 : /* Initialize the table. */
14619 135 : vec<tree, va_gc> *initial_values;
14620 135 : vec_alloc (initial_values, table_el_n);
14621 34830 : for (size_t i = 0; i < table_el_n; ++i)
14622 : {
14623 34560 : unsigned HOST_WIDE_INT crc = calculate_crc (i, polynom, crc_bits);
14624 34560 : tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
14625 34560 : vec_safe_push (initial_values, element);
14626 : }
14627 135 : tree ctor = build_constructor_from_vec (ar, initial_values);
14628 135 : rtx mem = output_constant_def (ctor, 1);
14629 135 : gcc_assert (MEM_P (mem));
14630 135 : if (dump_file && (dump_flags & TDF_DETAILS))
14631 : {
14632 16 : fprintf (dump_file,
14633 : ";; emitting crc table crc_%u_polynomial_"
14634 : HOST_WIDE_INT_PRINT_HEX " ",
14635 : crc_bits, polynom);
14636 16 : print_rtl_single (dump_file, XEXP (mem, 0));
14637 16 : fprintf (dump_file, "\n");
14638 : }
14639 :
14640 135 : return XEXP (mem, 0);
14641 : }
14642 :
14643 : /* Generate CRC lookup table by calculating CRC for all possible
14644 : 8-bit data values. The table is stored with a specific name in the read-only
14645 : static data section.
14646 : POLYNOM is the polynomial used to calculate the CRC table's elements.
14647 : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14648 :
14649 : static rtx
14650 135 : generate_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14651 : {
14652 135 : gcc_assert (crc_bits <= 64);
14653 :
14654 135 : return assemble_crc_table (polynom, crc_bits);
14655 : }
14656 :
14657 : /* Calculate CRC for the initial CRC and given POLYNOMIAL.
14658 : CRC_BITS is CRC size. */
14659 :
14660 : static unsigned HOST_WIDE_INT
14661 35328 : calculate_reversed_crc (unsigned HOST_WIDE_INT crc,
14662 : unsigned HOST_WIDE_INT polynomial,
14663 : unsigned short crc_bits)
14664 : {
14665 35328 : unsigned HOST_WIDE_INT rev_polynom = reflect_hwi (polynomial, crc_bits);
14666 353280 : for (int j = 0; j < 8; j++)
14667 : {
14668 282624 : if (crc & 1)
14669 141312 : crc = (crc >> 1) ^ rev_polynom;
14670 : else
14671 141312 : crc >>= 1;
14672 : }
14673 : /* Zero out bits in crc beyond the specified number of crc_bits. */
14674 35328 : if (crc_bits < sizeof (crc) * CHAR_BIT)
14675 29952 : crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
14676 35328 : return crc;
14677 : }
14678 :
14679 : /* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
14680 : POLYNOM is the polynomial used to calculate the CRC table's elements.
14681 : CRC_BITS is the size of CRC, may be 8, 16, ... . */
14682 :
14683 : static rtx
14684 138 : assemble_reversed_crc_table (unsigned HOST_WIDE_INT polynom, unsigned short crc_bits)
14685 : {
14686 138 : unsigned table_el_n = 0x100;
14687 138 : tree ar = build_array_type (make_unsigned_type (crc_bits),
14688 138 : build_index_type (size_int (table_el_n - 1)));
14689 :
14690 : /* Initialize the table. */
14691 138 : vec<tree, va_gc> *initial_values;
14692 138 : vec_alloc (initial_values, table_el_n);
14693 35604 : for (size_t i = 0; i < table_el_n; ++i)
14694 : {
14695 35328 : unsigned HOST_WIDE_INT crc = calculate_reversed_crc (i, polynom, crc_bits);
14696 35328 : tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
14697 35328 : vec_safe_push (initial_values, element);
14698 : }
14699 138 : tree ctor = build_constructor_from_vec (ar, initial_values);
14700 138 : rtx mem = output_constant_def (ctor, 1);
14701 138 : gcc_assert (MEM_P (mem));
14702 138 : if (dump_file && (dump_flags & TDF_DETAILS))
14703 : {
14704 16 : fprintf (dump_file,
14705 : ";; emitting reversed crc table crc_%u_polynomial_"
14706 : HOST_WIDE_INT_PRINT_HEX " ",
14707 : crc_bits, polynom);
14708 16 : print_rtl_single (dump_file, XEXP (mem, 0));
14709 16 : fprintf (dump_file, "\n");
14710 : }
14711 :
14712 138 : return XEXP (mem, 0);
14713 : }
14714 :
14715 : /* Generate reversed CRC table for the given POLYNOM and CRC_BITS. */
14716 :
14717 : static rtx
14718 138 : generate_reversed_crc_table (unsigned HOST_WIDE_INT polynom,
14719 : unsigned short crc_bits)
14720 : {
14721 138 : gcc_assert (crc_bits <= 64);
14722 :
14723 138 : return assemble_reversed_crc_table (polynom, crc_bits);
14724 : }
14725 :
14726 : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
14727 : POLYNOMIAL (without leading 1).
14728 :
14729 : First, using POLYNOMIAL's value generates CRC table of 256 elements,
14730 : then generates the assembly for the following code,
14731 : where crc_bit_size and data_bit_size may be 8, 16, 32, 64, depending on CRC:
14732 :
14733 : for (int i = 0; i < data_bit_size / 8; i++)
14734 : crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
14735 : ^ (data >> (data_bit_size - (i + 1) * 8)
14736 : & 0xFF))];
14737 :
14738 : So to take values from the table, we need 8-bit data.
14739 : If input data size is not 8, then first we extract upper 8 bits,
14740 : then the other 8 bits, and so on. */
14741 :
14742 : static void
14743 135 : calculate_table_based_CRC (rtx *crc, const rtx &input_data,
14744 : const rtx &polynomial,
14745 : machine_mode data_mode)
14746 : {
14747 135 : machine_mode mode = GET_MODE (*crc);
14748 135 : unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
14749 135 : unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
14750 135 : rtx tab = generate_crc_table (UINTVAL (polynomial), crc_bit_size);
14751 :
14752 529 : for (unsigned short i = 0; i < data_size; i++)
14753 : {
14754 : /* crc >> (crc_bit_size - 8). */
14755 259 : *crc = force_reg (mode, *crc);
14756 259 : rtx op1 = expand_shift (RSHIFT_EXPR, mode, *crc, crc_bit_size - 8,
14757 : NULL_RTX, 1);
14758 :
14759 : /* data >> (8 * (GET_MODE_SIZE (data_mode).to_constant () - i - 1)). */
14760 259 : unsigned range_8 = 8 * (data_size - i - 1);
14761 : /* CRC's mode is always at least as wide as INPUT_DATA. Convert
14762 : INPUT_DATA into CRC's mode. */
14763 259 : rtx data = gen_reg_rtx (mode);
14764 259 : convert_move (data, input_data, 1);
14765 259 : data = expand_shift (RSHIFT_EXPR, mode, data, range_8, NULL_RTX, 1);
14766 :
14767 : /* data >> (8 * (GET_MODE_SIZE (mode)
14768 : .to_constant () - i - 1)) & 0xFF. */
14769 259 : rtx data_final = expand_and (mode, data,
14770 : gen_int_mode (255, mode), NULL_RTX);
14771 :
14772 : /* (crc >> (crc_bit_size - 8)) ^ data_8bit. */
14773 259 : rtx in = expand_binop (mode, xor_optab, op1, data_final,
14774 : NULL_RTX, 1, OPTAB_WIDEN);
14775 :
14776 : /* ((crc >> (crc_bit_size - 8)) ^ data_8bit) & 0xFF. */
14777 259 : rtx index = expand_and (mode, in, gen_int_mode (255, mode),
14778 : NULL_RTX);
14779 518 : int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
14780 259 : index = expand_shift (LSHIFT_EXPR, mode, index,
14781 259 : log_crc_size, NULL_RTX, 0);
14782 :
14783 264 : rtx addr = gen_reg_rtx (Pmode);
14784 259 : convert_move (addr, index, 1);
14785 264 : addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
14786 : 0, OPTAB_DIRECT);
14787 :
14788 : /* crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit] */
14789 259 : rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
14790 :
14791 : /* (crc << 8) if CRC is larger than 8, otherwise crc = 0. */
14792 259 : rtx high = NULL_RTX;
14793 259 : if (crc_bit_size != 8)
14794 229 : high = expand_shift (LSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 0);
14795 : else
14796 30 : high = gen_int_mode (0, mode);
14797 :
14798 : /* crc = (crc << 8)
14799 : ^ crc_table[(crc >> (crc_bit_size - 8)) ^ data_8bit]; */
14800 259 : *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
14801 : OPTAB_WIDEN);
14802 : }
14803 135 : }
14804 :
14805 : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA
14806 : and the POLYNOMIAL (without leading 1).
14807 :
14808 : This function generates code for reversed (bit-reflected) CRC calculation
14809 : using a pre-computed lookup table. Unlike the standard CRC calculation,
14810 : this processes data from LSB to MSB, eliminating the need for explicit
14811 : bit reflection before and after the CRC computation. */
14812 :
14813 : static void
14814 138 : calculate_table_based_reversed_CRC (rtx *crc, const rtx &input_data,
14815 : const rtx &polynomial,
14816 : machine_mode data_mode)
14817 : {
14818 138 : machine_mode mode = GET_MODE (*crc);
14819 138 : unsigned short crc_bit_size = GET_MODE_BITSIZE (mode).to_constant ();
14820 138 : unsigned short data_size = GET_MODE_SIZE (data_mode).to_constant ();
14821 138 : rtx tab = generate_reversed_crc_table (UINTVAL (polynomial), crc_bit_size);
14822 :
14823 : /* CRC's mode is always at least as wide as INPUT_DATA. Convert
14824 : INPUT_DATA into CRC's mode once outside the loop since INPUT_DATA
14825 : is loop-invariant. */
14826 138 : rtx data_in_crc_mode = gen_reg_rtx (mode);
14827 138 : convert_move (data_in_crc_mode, input_data, 1);
14828 :
14829 502 : for (unsigned short i = 0; i < data_size; i++)
14830 : {
14831 226 : *crc = force_reg (mode, *crc);
14832 :
14833 : /* data >> (8 * i). */
14834 226 : unsigned range_8 = 8 * i;
14835 226 : rtx data = expand_shift (RSHIFT_EXPR, mode, data_in_crc_mode,
14836 226 : range_8, NULL_RTX, 1);
14837 :
14838 : /* crc ^ (data >> (8 * i)). */
14839 226 : rtx in = expand_binop (mode, xor_optab, *crc, data,
14840 : NULL_RTX, 1, OPTAB_WIDEN);
14841 :
14842 : /* (crc ^ data) & 0xFF. */
14843 226 : rtx index = expand_and (mode, in, gen_int_mode (255, mode),
14844 : NULL_RTX);
14845 452 : int log_crc_size = exact_log2 (GET_MODE_SIZE (mode).to_constant ());
14846 226 : index = expand_shift (LSHIFT_EXPR, mode, index,
14847 226 : log_crc_size, NULL_RTX, 0);
14848 :
14849 239 : rtx addr = gen_reg_rtx (Pmode);
14850 226 : convert_move (addr, index, 1);
14851 239 : addr = expand_binop (Pmode, add_optab, addr, tab, NULL_RTX,
14852 : 0, OPTAB_DIRECT);
14853 :
14854 : /* crc_table[(crc ^ data) & 0xFF]. */
14855 226 : rtx tab_el = validize_mem (gen_rtx_MEM (mode, addr));
14856 :
14857 : /* (crc >> 8) if CRC is larger than 8, otherwise 0. */
14858 226 : rtx high = NULL_RTX;
14859 226 : if (crc_bit_size != 8)
14860 217 : high = expand_shift (RSHIFT_EXPR, mode, *crc, 8, NULL_RTX, 1);
14861 : else
14862 9 : high = gen_int_mode (0, mode);
14863 :
14864 : /* crc = (crc >> 8) ^ crc_table[(crc ^ data) & 0xFF]. */
14865 226 : *crc = expand_binop (mode, xor_optab, tab_el, high, NULL_RTX, 1,
14866 : OPTAB_WIDEN);
14867 : }
14868 138 : }
14869 :
14870 : /* Generate table-based CRC code for the given CRC, INPUT_DATA and the
14871 : POLYNOMIAL (without leading 1).
14872 :
14873 : CRC is OP1, data is OP2 and the polynomial is OP3.
14874 : This must generate a CRC table and an assembly for the following code,
14875 : where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
14876 : uint_crc_bit_size_t
14877 : crc_crc_bit_size (uint_crc_bit_size_t crc_init,
14878 : uint_data_bit_size_t data, size_t size)
14879 : {
14880 : uint_crc_bit_size_t crc = crc_init;
14881 : for (int i = 0; i < data_bit_size / 8; i++)
14882 : crc = (crc << 8) ^ crc_table[(crc >> (crc_bit_size - 8))
14883 : ^ (data >> (data_bit_size - (i + 1) * 8)
14884 : & 0xFF))];
14885 : return crc;
14886 : } */
14887 :
14888 : void
14889 135 : expand_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
14890 : machine_mode data_mode)
14891 : {
14892 135 : gcc_assert (!CONST_INT_P (op0));
14893 135 : gcc_assert (CONST_INT_P (op3));
14894 135 : machine_mode crc_mode = GET_MODE (op0);
14895 135 : rtx crc = gen_reg_rtx (crc_mode);
14896 135 : convert_move (crc, op1, 0);
14897 135 : calculate_table_based_CRC (&crc, op2, op3, data_mode);
14898 135 : convert_move (op0, crc, 0);
14899 135 : }
14900 :
14901 : /* Generate the common operation for reflecting values:
14902 : *OP = (*OP & AND1_VALUE) << SHIFT_VAL | (*OP & AND2_VALUE) >> SHIFT_VAL; */
14903 :
14904 : void
14905 0 : gen_common_operation_to_reflect (rtx *op,
14906 : unsigned HOST_WIDE_INT and1_value,
14907 : unsigned HOST_WIDE_INT and2_value,
14908 : unsigned shift_val)
14909 : {
14910 0 : rtx op1 = expand_and (GET_MODE (*op), *op,
14911 0 : gen_int_mode (and1_value, GET_MODE (*op)), NULL_RTX);
14912 0 : op1 = expand_shift (LSHIFT_EXPR, GET_MODE (*op), op1, shift_val, op1, 0);
14913 0 : rtx op2 = expand_and (GET_MODE (*op), *op,
14914 0 : gen_int_mode (and2_value, GET_MODE (*op)), NULL_RTX);
14915 0 : op2 = expand_shift (RSHIFT_EXPR, GET_MODE (*op), op2, shift_val, op2, 1);
14916 0 : *op = expand_binop (GET_MODE (*op), ior_optab, op1,
14917 : op2, *op, 0, OPTAB_LIB_WIDEN);
14918 0 : }
14919 :
14920 : /* Reflect 64-bit value for the 64-bit target. */
14921 :
14922 : void
14923 0 : reflect_64_bit_value (rtx *op)
14924 : {
14925 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00000000FFFFFFFF),
14926 : HOST_WIDE_INT_C (0xFFFFFFFF00000000), 32);
14927 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF0000FFFF),
14928 : HOST_WIDE_INT_C (0xFFFF0000FFFF0000), 16);
14929 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF00FF00FF),
14930 : HOST_WIDE_INT_C (0xFF00FF00FF00FF00), 8);
14931 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F0F0F0F0F),
14932 : HOST_WIDE_INT_C (0xF0F0F0F0F0F0F0F0), 4);
14933 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333333333333333),
14934 : HOST_WIDE_INT_C (0xCCCCCCCCCCCCCCCC), 2);
14935 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555555555555555),
14936 : HOST_WIDE_INT_C (0xAAAAAAAAAAAAAAAA), 1);
14937 0 : }
14938 :
14939 : /* Reflect 32-bit value for the 32-bit target. */
14940 :
14941 : void
14942 0 : reflect_32_bit_value (rtx *op)
14943 : {
14944 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0000FFFF),
14945 : HOST_WIDE_INT_C (0xFFFF0000), 16);
14946 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF00FF),
14947 : HOST_WIDE_INT_C (0xFF00FF00), 8);
14948 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F0F0F),
14949 : HOST_WIDE_INT_C (0xF0F0F0F0), 4);
14950 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33333333),
14951 : HOST_WIDE_INT_C (0xCCCCCCCC), 2);
14952 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55555555),
14953 : HOST_WIDE_INT_C (0xAAAAAAAA), 1);
14954 0 : }
14955 :
14956 : /* Reflect 16-bit value for the 16-bit target. */
14957 :
14958 : void
14959 0 : reflect_16_bit_value (rtx *op)
14960 : {
14961 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x00FF),
14962 : HOST_WIDE_INT_C (0xFF00), 8);
14963 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F0F),
14964 : HOST_WIDE_INT_C (0xF0F0), 4);
14965 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x3333),
14966 : HOST_WIDE_INT_C (0xCCCC), 2);
14967 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x5555),
14968 : HOST_WIDE_INT_C (0xAAAA), 1);
14969 0 : }
14970 :
14971 : /* Reflect 8-bit value for the 8-bit target. */
14972 :
14973 : void
14974 0 : reflect_8_bit_value (rtx *op)
14975 : {
14976 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x0F),
14977 : HOST_WIDE_INT_C (0xF0), 4);
14978 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x33),
14979 : HOST_WIDE_INT_C (0xCC), 2);
14980 0 : gen_common_operation_to_reflect (op, HOST_WIDE_INT_C (0x55),
14981 : HOST_WIDE_INT_C (0xAA), 1);
14982 0 : }
14983 :
14984 : /* Generate instruction sequence which reflects the value of the OP
14985 : using shift, and, or operations. OP's mode may be less than word_mode. */
14986 :
14987 : void
14988 0 : generate_reflecting_code_standard (rtx *op)
14989 : {
14990 0 : gcc_assert (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () >= 8
14991 : && GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () <= 64);
14992 :
14993 0 : if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 64)
14994 0 : reflect_64_bit_value (op);
14995 0 : else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 32)
14996 0 : reflect_32_bit_value (op);
14997 0 : else if (GET_MODE_BITSIZE (GET_MODE (*op)).to_constant () == 16)
14998 0 : reflect_16_bit_value (op);
14999 : else
15000 0 : reflect_8_bit_value (op);
15001 0 : }
15002 :
15003 : /* Generate table-based reversed CRC code for the given CRC, INPUT_DATA and
15004 : the POLYNOMIAL (without leading 1).
15005 :
15006 : CRC is OP1, data is OP2 and the polynomial is OP3.
15007 : This generates a reversed CRC table and assembly for the following code,
15008 : where crc_bit_size and data_bit_size may be 8, 16, 32, 64:
15009 : uint_crc_bit_size_t
15010 : crc_crc_bit_size (uint_crc_bit_size_t crc_init,
15011 : uint_data_bit_size_t data)
15012 : {
15013 : uint_crc_bit_size_t crc = crc_init;
15014 : for (int i = 0; i < data_bit_size / 8; i++)
15015 : crc = (crc >> 8) ^ crc_table[(crc ^ (data >> (i * 8))) & 0xFF];
15016 : return crc;
15017 : }
15018 :
15019 : This approach uses a pre-computed reversed polynomial table, eliminating
15020 : the need for explicit bit reflection before and after the CRC computation. */
15021 :
15022 : void
15023 138 : expand_reversed_crc_table_based (rtx op0, rtx op1, rtx op2, rtx op3,
15024 : machine_mode data_mode)
15025 : {
15026 138 : gcc_assert (!CONST_INT_P (op0));
15027 138 : gcc_assert (CONST_INT_P (op3));
15028 138 : machine_mode crc_mode = GET_MODE (op0);
15029 138 : rtx crc = gen_reg_rtx (crc_mode);
15030 138 : convert_move (crc, op1, 0);
15031 138 : calculate_table_based_reversed_CRC (&crc, op2, op3, data_mode);
15032 138 : convert_move (op0, crc, 0);
15033 138 : }
|