1/* Convert tree expression to rtl instructions, for GNU compiler.
2 Copyright (C) 1988-2023 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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
69
70/* If this is nonzero, we do not bother generating VOLATILE
71 around volatile memory references, and we are willing to
72 output indirect addresses. If cse is to follow, we reject
73 indirect addresses so a useful potential cse is generated;
74 if it is used only once, instruction combination will produce
75 the same indirect address eventually. */
76int cse_not_expected;
77
78static bool block_move_libcall_safe_for_call_parm (void);
79static bool emit_block_move_via_pattern (rtx, rtx, rtx, unsigned, unsigned,
80 HOST_WIDE_INT, unsigned HOST_WIDE_INT,
81 unsigned HOST_WIDE_INT,
82 unsigned HOST_WIDE_INT, bool);
83static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned);
84static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
85static rtx_insn *compress_float_constant (rtx, rtx);
86static rtx get_subtarget (rtx);
87static rtx store_field (rtx, poly_int64, poly_int64, poly_uint64, poly_uint64,
88 machine_mode, tree, alias_set_type, bool, bool);
89
90static unsigned HOST_WIDE_INT highest_pow2_factor_for_target (const_tree, const_tree);
91
92static bool is_aligning_offset (const_tree, const_tree);
93static rtx reduce_to_bit_field_precision (rtx, rtx, tree);
94static rtx do_store_flag (sepops, rtx, machine_mode);
95#ifdef PUSH_ROUNDING
96static void emit_single_push_insn (machine_mode, rtx, tree);
97#endif
98static void do_tablejump (rtx, machine_mode, rtx, rtx, rtx,
99 profile_probability);
100static rtx const_vector_from_tree (tree);
101static tree tree_expr_size (const_tree);
102static void convert_mode_scalar (rtx, rtx, int);
103
104
105/* This is run to set up which modes can be used
106 directly in memory and to initialize the block move optab. It is run
107 at the beginning of compilation and when the target is reinitialized. */
108
109void
110init_expr_target (void)
111{
112 rtx pat;
113 int num_clobbers;
114 rtx mem, mem1;
115 rtx reg;
116
117 /* Try indexing by frame ptr and try by stack ptr.
118 It is known that on the Convex the stack ptr isn't a valid index.
119 With luck, one or the other is valid on any machine. */
120 mem = gen_rtx_MEM (word_mode, stack_pointer_rtx);
121 mem1 = gen_rtx_MEM (word_mode, frame_pointer_rtx);
122
123 /* A scratch register we can modify in-place below to avoid
124 useless RTL allocations. */
125 reg = gen_rtx_REG (word_mode, LAST_VIRTUAL_REGISTER + 1);
126
127 rtx_insn *insn = as_a<rtx_insn *> (p: rtx_alloc (INSN));
128 pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
129 PATTERN (insn) = pat;
130
131 for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
132 mode = (machine_mode) ((int) mode + 1))
133 {
134 int regno;
135
136 direct_load[(int) mode] = direct_store[(int) mode] = 0;
137 PUT_MODE (x: mem, mode);
138 PUT_MODE (x: mem1, mode);
139
140 /* See if there is some register that can be used in this mode and
141 directly loaded or stored from memory. */
142
143 if (mode != VOIDmode && mode != BLKmode)
144 for (regno = 0; regno < FIRST_PSEUDO_REGISTER
145 && (direct_load[(int) mode] == 0 || direct_store[(int) mode] == 0);
146 regno++)
147 {
148 if (!targetm.hard_regno_mode_ok (regno, mode))
149 continue;
150
151 set_mode_and_regno (reg, mode, regno);
152
153 SET_SRC (pat) = mem;
154 SET_DEST (pat) = reg;
155 if (recog (pat, insn, &num_clobbers) >= 0)
156 direct_load[(int) mode] = 1;
157
158 SET_SRC (pat) = mem1;
159 SET_DEST (pat) = reg;
160 if (recog (pat, insn, &num_clobbers) >= 0)
161 direct_load[(int) mode] = 1;
162
163 SET_SRC (pat) = reg;
164 SET_DEST (pat) = mem;
165 if (recog (pat, insn, &num_clobbers) >= 0)
166 direct_store[(int) mode] = 1;
167
168 SET_SRC (pat) = reg;
169 SET_DEST (pat) = mem1;
170 if (recog (pat, insn, &num_clobbers) >= 0)
171 direct_store[(int) mode] = 1;
172 }
173 }
174
175 mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
176
177 opt_scalar_float_mode mode_iter;
178 FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
179 {
180 scalar_float_mode mode = mode_iter.require ();
181 scalar_float_mode srcmode;
182 FOR_EACH_MODE_UNTIL (srcmode, mode)
183 {
184 enum insn_code ic;
185
186 ic = can_extend_p (mode, srcmode, 0);
187 if (ic == CODE_FOR_nothing)
188 continue;
189
190 PUT_MODE (x: mem, mode: srcmode);
191
192 if (insn_operand_matches (icode: ic, opno: 1, operand: mem))
193 float_extend_from_mem[mode][srcmode] = true;
194 }
195 }
196}
197
198/* This is run at the start of compiling a function. */
199
200void
201init_expr (void)
202{
203 memset (s: &crtl->expr, c: 0, n: sizeof (crtl->expr));
204}
205
206/* Copy data from FROM to TO, where the machine modes are not the same.
207 Both modes may be integer, or both may be floating, or both may be
208 fixed-point.
209 UNSIGNEDP should be nonzero if FROM is an unsigned type.
210 This causes zero-extension instead of sign-extension. */
211
212void
213convert_move (rtx to, rtx from, int unsignedp)
214{
215 machine_mode to_mode = GET_MODE (to);
216 machine_mode from_mode = GET_MODE (from);
217
218 gcc_assert (to_mode != BLKmode);
219 gcc_assert (from_mode != BLKmode);
220
221 /* If the source and destination are already the same, then there's
222 nothing to do. */
223 if (to == from)
224 return;
225
226 /* If FROM is a SUBREG that indicates that we have already done at least
227 the required extension, strip it. We don't handle such SUBREGs as
228 TO here. */
229
230 scalar_int_mode to_int_mode;
231 if (GET_CODE (from) == SUBREG
232 && SUBREG_PROMOTED_VAR_P (from)
233 && is_a <scalar_int_mode> (m: to_mode, result: &to_int_mode)
234 && (GET_MODE_PRECISION (mode: subreg_promoted_mode (x: from))
235 >= GET_MODE_PRECISION (mode: to_int_mode))
236 && SUBREG_CHECK_PROMOTED_SIGN (from, unsignedp))
237 {
238 scalar_int_mode int_orig_mode;
239 scalar_int_mode int_inner_mode;
240 machine_mode orig_mode = GET_MODE (from);
241
242 from = gen_lowpart (to_int_mode, SUBREG_REG (from));
243 from_mode = to_int_mode;
244
245 /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
246 the original mode, but narrower than the inner mode. */
247 if (GET_CODE (from) == SUBREG
248 && is_a <scalar_int_mode> (m: orig_mode, result: &int_orig_mode)
249 && GET_MODE_PRECISION (mode: to_int_mode)
250 > GET_MODE_PRECISION (mode: int_orig_mode)
251 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (from)),
252 result: &int_inner_mode)
253 && GET_MODE_PRECISION (mode: int_inner_mode)
254 > GET_MODE_PRECISION (mode: to_int_mode))
255 {
256 SUBREG_PROMOTED_VAR_P (from) = 1;
257 SUBREG_PROMOTED_SET (from, unsignedp);
258 }
259 }
260
261 gcc_assert (GET_CODE (to) != SUBREG || !SUBREG_PROMOTED_VAR_P (to));
262
263 if (to_mode == from_mode
264 || (from_mode == VOIDmode && CONSTANT_P (from)))
265 {
266 emit_move_insn (to, from);
267 return;
268 }
269
270 if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
271 {
272 if (GET_MODE_UNIT_PRECISION (to_mode)
273 > GET_MODE_UNIT_PRECISION (from_mode))
274 {
275 optab op = unsignedp ? zext_optab : sext_optab;
276 insn_code icode = convert_optab_handler (op, to_mode, from_mode);
277 if (icode != CODE_FOR_nothing)
278 {
279 emit_unop_insn (icode, to, from,
280 unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
281 return;
282 }
283 }
284
285 if (GET_MODE_UNIT_PRECISION (to_mode)
286 < GET_MODE_UNIT_PRECISION (from_mode))
287 {
288 insn_code icode = convert_optab_handler (op: trunc_optab,
289 to_mode, from_mode);
290 if (icode != CODE_FOR_nothing)
291 {
292 emit_unop_insn (icode, to, from, TRUNCATE);
293 return;
294 }
295 }
296
297 gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
298 GET_MODE_BITSIZE (to_mode)));
299
300 if (VECTOR_MODE_P (to_mode))
301 from = simplify_gen_subreg (outermode: to_mode, op: from, GET_MODE (from), byte: 0);
302 else
303 to = simplify_gen_subreg (outermode: from_mode, op: to, GET_MODE (to), byte: 0);
304
305 emit_move_insn (to, from);
306 return;
307 }
308
309 if (GET_CODE (to) == CONCAT && GET_CODE (from) == CONCAT)
310 {
311 convert_move (XEXP (to, 0), XEXP (from, 0), unsignedp);
312 convert_move (XEXP (to, 1), XEXP (from, 1), unsignedp);
313 return;
314 }
315
316 convert_mode_scalar (to, from, unsignedp);
317}
318
319/* Like convert_move, but deals only with scalar modes. */
320
321static void
322convert_mode_scalar (rtx to, rtx from, int unsignedp)
323{
324 /* Both modes should be scalar types. */
325 scalar_mode from_mode = as_a <scalar_mode> (GET_MODE (from));
326 scalar_mode to_mode = as_a <scalar_mode> (GET_MODE (to));
327 bool to_real = SCALAR_FLOAT_MODE_P (to_mode);
328 bool from_real = SCALAR_FLOAT_MODE_P (from_mode);
329 enum insn_code code;
330 rtx libcall;
331
332 gcc_assert (to_real == from_real);
333
334 /* rtx code for making an equivalent value. */
335 enum rtx_code equiv_code = (unsignedp < 0 ? UNKNOWN
336 : (unsignedp ? ZERO_EXTEND : SIGN_EXTEND));
337
338 if (to_real)
339 {
340 rtx value;
341 rtx_insn *insns;
342 convert_optab tab;
343
344 gcc_assert ((GET_MODE_PRECISION (from_mode)
345 != GET_MODE_PRECISION (to_mode))
346 || (DECIMAL_FLOAT_MODE_P (from_mode)
347 != DECIMAL_FLOAT_MODE_P (to_mode))
348 || (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
349 && REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
350 || (REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
351 && REAL_MODE_FORMAT (from_mode) == &ieee_half_format));
352
353 if (GET_MODE_PRECISION (mode: from_mode) == GET_MODE_PRECISION (mode: to_mode))
354 /* Conversion between decimal float and binary float, same size. */
355 tab = DECIMAL_FLOAT_MODE_P (from_mode) ? trunc_optab : sext_optab;
356 else if (GET_MODE_PRECISION (mode: from_mode) < GET_MODE_PRECISION (mode: to_mode))
357 tab = sext_optab;
358 else
359 tab = trunc_optab;
360
361 /* Try converting directly if the insn is supported. */
362
363 code = convert_optab_handler (op: tab, to_mode, from_mode);
364 if (code != CODE_FOR_nothing)
365 {
366 emit_unop_insn (code, to, from,
367 tab == sext_optab ? FLOAT_EXTEND : FLOAT_TRUNCATE);
368 return;
369 }
370
371#ifdef HAVE_SFmode
372 if (REAL_MODE_FORMAT (from_mode) == &arm_bfloat_half_format
373 && REAL_MODE_FORMAT (SFmode) == &ieee_single_format)
374 {
375 if (GET_MODE_PRECISION (mode: to_mode) > GET_MODE_PRECISION (SFmode))
376 {
377 /* To cut down on libgcc size, implement
378 BFmode -> {DF,XF,TF}mode conversions by
379 BFmode -> SFmode -> {DF,XF,TF}mode conversions. */
380 rtx temp = gen_reg_rtx (SFmode);
381 convert_mode_scalar (to: temp, from, unsignedp);
382 convert_mode_scalar (to, from: temp, unsignedp);
383 return;
384 }
385 if (REAL_MODE_FORMAT (to_mode) == &ieee_half_format)
386 {
387 /* Similarly, implement BFmode -> HFmode as
388 BFmode -> SFmode -> HFmode conversion where SFmode
389 has superset of BFmode values. We don't need
390 to handle sNaNs by raising exception and turning
391 into into qNaN though, as that can be done in the
392 SFmode -> HFmode conversion too. */
393 rtx temp = gen_reg_rtx (SFmode);
394 int save_flag_finite_math_only = flag_finite_math_only;
395 flag_finite_math_only = true;
396 convert_mode_scalar (to: temp, from, unsignedp);
397 flag_finite_math_only = save_flag_finite_math_only;
398 convert_mode_scalar (to, from: temp, unsignedp);
399 return;
400 }
401 if (to_mode == SFmode
402 && !HONOR_NANS (from_mode)
403 && !HONOR_NANS (to_mode)
404 && optimize_insn_for_speed_p ())
405 {
406 /* If we don't expect sNaNs, for BFmode -> SFmode we can just
407 shift the bits up. */
408 machine_mode fromi_mode, toi_mode;
409 if (int_mode_for_size (size: GET_MODE_BITSIZE (mode: from_mode),
410 limit: 0).exists (mode: &fromi_mode)
411 && int_mode_for_size (size: GET_MODE_BITSIZE (mode: to_mode),
412 limit: 0).exists (mode: &toi_mode))
413 {
414 start_sequence ();
415 rtx fromi = lowpart_subreg (outermode: fromi_mode, op: from, innermode: from_mode);
416 rtx tof = NULL_RTX;
417 if (fromi)
418 {
419 rtx toi;
420 if (GET_MODE (fromi) == VOIDmode)
421 toi = simplify_unary_operation (code: ZERO_EXTEND, mode: toi_mode,
422 op: fromi, op_mode: fromi_mode);
423 else
424 {
425 toi = gen_reg_rtx (toi_mode);
426 convert_mode_scalar (to: toi, from: fromi, unsignedp: 1);
427 }
428 toi
429 = maybe_expand_shift (LSHIFT_EXPR, toi_mode, toi,
430 GET_MODE_PRECISION (mode: to_mode)
431 - GET_MODE_PRECISION (mode: from_mode),
432 NULL_RTX, 1);
433 if (toi)
434 {
435 tof = lowpart_subreg (outermode: to_mode, op: toi, innermode: toi_mode);
436 if (tof)
437 emit_move_insn (to, tof);
438 }
439 }
440 insns = get_insns ();
441 end_sequence ();
442 if (tof)
443 {
444 emit_insn (insns);
445 return;
446 }
447 }
448 }
449 }
450 if (REAL_MODE_FORMAT (from_mode) == &ieee_single_format
451 && REAL_MODE_FORMAT (to_mode) == &arm_bfloat_half_format
452 && !HONOR_NANS (from_mode)
453 && !HONOR_NANS (to_mode)
454 && !flag_rounding_math
455 && optimize_insn_for_speed_p ())
456 {
457 /* If we don't expect qNaNs nor sNaNs and can assume rounding
458 to nearest, we can expand the conversion inline as
459 (fromi + 0x7fff + ((fromi >> 16) & 1)) >> 16. */
460 machine_mode fromi_mode, toi_mode;
461 if (int_mode_for_size (size: GET_MODE_BITSIZE (mode: from_mode),
462 limit: 0).exists (mode: &fromi_mode)
463 && int_mode_for_size (size: GET_MODE_BITSIZE (mode: to_mode),
464 limit: 0).exists (mode: &toi_mode))
465 {
466 start_sequence ();
467 rtx fromi = lowpart_subreg (outermode: fromi_mode, op: from, innermode: from_mode);
468 rtx tof = NULL_RTX;
469 do
470 {
471 if (!fromi)
472 break;
473 int shift = (GET_MODE_PRECISION (mode: from_mode)
474 - GET_MODE_PRECISION (mode: to_mode));
475 rtx temp1
476 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode, fromi,
477 shift, NULL_RTX, 1);
478 if (!temp1)
479 break;
480 rtx temp2
481 = expand_binop (fromi_mode, and_optab, temp1, const1_rtx,
482 NULL_RTX, 1, OPTAB_DIRECT);
483 if (!temp2)
484 break;
485 rtx temp3
486 = expand_binop (fromi_mode, add_optab, fromi,
487 gen_int_mode ((HOST_WIDE_INT_1U
488 << (shift - 1)) - 1,
489 fromi_mode), NULL_RTX,
490 1, OPTAB_DIRECT);
491 if (!temp3)
492 break;
493 rtx temp4
494 = expand_binop (fromi_mode, add_optab, temp3, temp2,
495 NULL_RTX, 1, OPTAB_DIRECT);
496 if (!temp4)
497 break;
498 rtx temp5 = maybe_expand_shift (RSHIFT_EXPR, fromi_mode,
499 temp4, shift, NULL_RTX, 1);
500 if (!temp5)
501 break;
502 rtx temp6 = lowpart_subreg (outermode: toi_mode, op: temp5, innermode: fromi_mode);
503 if (!temp6)
504 break;
505 tof = lowpart_subreg (outermode: to_mode, op: force_reg (toi_mode, temp6),
506 innermode: toi_mode);
507 if (tof)
508 emit_move_insn (to, tof);
509 }
510 while (0);
511 insns = get_insns ();
512 end_sequence ();
513 if (tof)
514 {
515 emit_insn (insns);
516 return;
517 }
518 }
519 }
520#endif
521
522 /* Otherwise use a libcall. */
523 libcall = convert_optab_libfunc (tab, to_mode, from_mode);
524
525 /* Is this conversion implemented yet? */
526 gcc_assert (libcall);
527
528 start_sequence ();
529 value = emit_library_call_value (fun: libcall, NULL_RTX, fn_type: LCT_CONST, outmode: to_mode,
530 arg1: from, arg1_mode: from_mode);
531 insns = get_insns ();
532 end_sequence ();
533 emit_libcall_block (insns, to, value,
534 tab == trunc_optab ? gen_rtx_FLOAT_TRUNCATE (to_mode,
535 from)
536 : gen_rtx_FLOAT_EXTEND (to_mode, from));
537 return;
538 }
539
540 /* Handle pointer conversion. */ /* SPEE 900220. */
541 /* If the target has a converter from FROM_MODE to TO_MODE, use it. */
542 {
543 convert_optab ctab;
544
545 if (GET_MODE_PRECISION (mode: from_mode) > GET_MODE_PRECISION (mode: to_mode))
546 ctab = trunc_optab;
547 else if (unsignedp)
548 ctab = zext_optab;
549 else
550 ctab = sext_optab;
551
552 if (convert_optab_handler (op: ctab, to_mode, from_mode)
553 != CODE_FOR_nothing)
554 {
555 emit_unop_insn (convert_optab_handler (op: ctab, to_mode, from_mode),
556 to, from, UNKNOWN);
557 return;
558 }
559 }
560
561 /* Targets are expected to provide conversion insns between PxImode and
562 xImode for all MODE_PARTIAL_INT modes they use, but no others. */
563 if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT)
564 {
565 scalar_int_mode full_mode
566 = smallest_int_mode_for_size (size: GET_MODE_BITSIZE (mode: to_mode));
567
568 gcc_assert (convert_optab_handler (trunc_optab, to_mode, full_mode)
569 != CODE_FOR_nothing);
570
571 if (full_mode != from_mode)
572 from = convert_to_mode (full_mode, from, unsignedp);
573 emit_unop_insn (convert_optab_handler (op: trunc_optab, to_mode, from_mode: full_mode),
574 to, from, UNKNOWN);
575 return;
576 }
577 if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT)
578 {
579 rtx new_from;
580 scalar_int_mode full_mode
581 = smallest_int_mode_for_size (size: GET_MODE_BITSIZE (mode: from_mode));
582 convert_optab ctab = unsignedp ? zext_optab : sext_optab;
583 enum insn_code icode;
584
585 icode = convert_optab_handler (op: ctab, to_mode: full_mode, from_mode);
586 gcc_assert (icode != CODE_FOR_nothing);
587
588 if (to_mode == full_mode)
589 {
590 emit_unop_insn (icode, to, from, UNKNOWN);
591 return;
592 }
593
594 new_from = gen_reg_rtx (full_mode);
595 emit_unop_insn (icode, new_from, from, UNKNOWN);
596
597 /* else proceed to integer conversions below. */
598 from_mode = full_mode;
599 from = new_from;
600 }
601
602 /* Make sure both are fixed-point modes or both are not. */
603 gcc_assert (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode) ==
604 ALL_SCALAR_FIXED_POINT_MODE_P (to_mode));
605 if (ALL_SCALAR_FIXED_POINT_MODE_P (from_mode))
606 {
607 /* If we widen from_mode to to_mode and they are in the same class,
608 we won't saturate the result.
609 Otherwise, always saturate the result to play safe. */
610 if (GET_MODE_CLASS (from_mode) == GET_MODE_CLASS (to_mode)
611 && GET_MODE_SIZE (mode: from_mode) < GET_MODE_SIZE (mode: to_mode))
612 expand_fixed_convert (to, from, 0, 0);
613 else
614 expand_fixed_convert (to, from, 0, 1);
615 return;
616 }
617
618 /* Now both modes are integers. */
619
620 /* Handle expanding beyond a word. */
621 if (GET_MODE_PRECISION (mode: from_mode) < GET_MODE_PRECISION (mode: to_mode)
622 && GET_MODE_PRECISION (mode: to_mode) > BITS_PER_WORD)
623 {
624 rtx_insn *insns;
625 rtx lowpart;
626 rtx fill_value;
627 rtx lowfrom;
628 int i;
629 scalar_mode lowpart_mode;
630 int nwords = CEIL (GET_MODE_SIZE (to_mode), UNITS_PER_WORD);
631
632 /* Try converting directly if the insn is supported. */
633 if ((code = can_extend_p (to_mode, from_mode, unsignedp))
634 != CODE_FOR_nothing)
635 {
636 /* If FROM is a SUBREG, put it into a register. Do this
637 so that we always generate the same set of insns for
638 better cse'ing; if an intermediate assignment occurred,
639 we won't be doing the operation directly on the SUBREG. */
640 if (optimize > 0 && GET_CODE (from) == SUBREG)
641 from = force_reg (from_mode, from);
642 emit_unop_insn (code, to, from, equiv_code);
643 return;
644 }
645 /* Next, try converting via full word. */
646 else if (GET_MODE_PRECISION (mode: from_mode) < BITS_PER_WORD
647 && ((code = can_extend_p (to_mode, word_mode, unsignedp))
648 != CODE_FOR_nothing))
649 {
650 rtx word_to = gen_reg_rtx (word_mode);
651 if (REG_P (to))
652 {
653 if (reg_overlap_mentioned_p (to, from))
654 from = force_reg (from_mode, from);
655 emit_clobber (to);
656 }
657 convert_move (to: word_to, from, unsignedp);
658 emit_unop_insn (code, to, word_to, equiv_code);
659 return;
660 }
661
662 /* No special multiword conversion insn; do it by hand. */
663 start_sequence ();
664
665 /* Since we will turn this into a no conflict block, we must ensure
666 the source does not overlap the target so force it into an isolated
667 register when maybe so. Likewise for any MEM input, since the
668 conversion sequence might require several references to it and we
669 must ensure we're getting the same value every time. */
670
671 if (MEM_P (from) || reg_overlap_mentioned_p (to, from))
672 from = force_reg (from_mode, from);
673
674 /* Get a copy of FROM widened to a word, if necessary. */
675 if (GET_MODE_PRECISION (mode: from_mode) < BITS_PER_WORD)
676 lowpart_mode = word_mode;
677 else
678 lowpart_mode = from_mode;
679
680 lowfrom = convert_to_mode (lowpart_mode, from, unsignedp);
681
682 lowpart = gen_lowpart (lowpart_mode, to);
683 emit_move_insn (lowpart, lowfrom);
684
685 /* Compute the value to put in each remaining word. */
686 if (unsignedp)
687 fill_value = const0_rtx;
688 else
689 fill_value = emit_store_flag_force (gen_reg_rtx (word_mode),
690 LT, lowfrom, const0_rtx,
691 lowpart_mode, 0, -1);
692
693 /* Fill the remaining words. */
694 for (i = GET_MODE_SIZE (mode: lowpart_mode) / UNITS_PER_WORD; i < nwords; i++)
695 {
696 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
697 rtx subword = operand_subword (to, index, 1, to_mode);
698
699 gcc_assert (subword);
700
701 if (fill_value != subword)
702 emit_move_insn (subword, fill_value);
703 }
704
705 insns = get_insns ();
706 end_sequence ();
707
708 emit_insn (insns);
709 return;
710 }
711
712 /* Truncating multi-word to a word or less. */
713 if (GET_MODE_PRECISION (mode: from_mode) > BITS_PER_WORD
714 && GET_MODE_PRECISION (mode: to_mode) <= BITS_PER_WORD)
715 {
716 if (!((MEM_P (from)
717 && ! MEM_VOLATILE_P (from)
718 && direct_load[(int) to_mode]
719 && ! mode_dependent_address_p (XEXP (from, 0),
720 MEM_ADDR_SPACE (from)))
721 || REG_P (from)
722 || GET_CODE (from) == SUBREG))
723 from = force_reg (from_mode, from);
724 convert_move (to, gen_lowpart (word_mode, from), unsignedp: 0);
725 return;
726 }
727
728 /* Now follow all the conversions between integers
729 no more than a word long. */
730
731 /* For truncation, usually we can just refer to FROM in a narrower mode. */
732 if (GET_MODE_BITSIZE (mode: to_mode) < GET_MODE_BITSIZE (mode: from_mode)
733 && TRULY_NOOP_TRUNCATION_MODES_P (to_mode, from_mode))
734 {
735 if (!((MEM_P (from)
736 && ! MEM_VOLATILE_P (from)
737 && direct_load[(int) to_mode]
738 && ! mode_dependent_address_p (XEXP (from, 0),
739 MEM_ADDR_SPACE (from)))
740 || REG_P (from)
741 || GET_CODE (from) == SUBREG))
742 from = force_reg (from_mode, from);
743 if (REG_P (from) && REGNO (from) < FIRST_PSEUDO_REGISTER
744 && !targetm.hard_regno_mode_ok (REGNO (from), to_mode))
745 from = copy_to_reg (from);
746 emit_move_insn (to, gen_lowpart (to_mode, from));
747 return;
748 }
749
750 /* Handle extension. */
751 if (GET_MODE_PRECISION (mode: to_mode) > GET_MODE_PRECISION (mode: from_mode))
752 {
753 /* Convert directly if that works. */
754 if ((code = can_extend_p (to_mode, from_mode, unsignedp))
755 != CODE_FOR_nothing)
756 {
757 emit_unop_insn (code, to, from, equiv_code);
758 return;
759 }
760 else
761 {
762 rtx tmp;
763 int shift_amount;
764
765 /* Search for a mode to convert via. */
766 opt_scalar_mode intermediate_iter;
767 FOR_EACH_MODE_FROM (intermediate_iter, from_mode)
768 {
769 scalar_mode intermediate = intermediate_iter.require ();
770 if (((can_extend_p (to_mode, intermediate, unsignedp)
771 != CODE_FOR_nothing)
772 || (GET_MODE_SIZE (mode: to_mode) < GET_MODE_SIZE (mode: intermediate)
773 && TRULY_NOOP_TRUNCATION_MODES_P (to_mode,
774 intermediate)))
775 && (can_extend_p (intermediate, from_mode, unsignedp)
776 != CODE_FOR_nothing))
777 {
778 convert_move (to, from: convert_to_mode (intermediate, from,
779 unsignedp), unsignedp);
780 return;
781 }
782 }
783
784 /* No suitable intermediate mode.
785 Generate what we need with shifts. */
786 shift_amount = (GET_MODE_PRECISION (mode: to_mode)
787 - GET_MODE_PRECISION (mode: from_mode));
788 from = gen_lowpart (to_mode, force_reg (from_mode, from));
789 tmp = expand_shift (LSHIFT_EXPR, to_mode, from, shift_amount,
790 to, unsignedp);
791 tmp = expand_shift (RSHIFT_EXPR, to_mode, tmp, shift_amount,
792 to, unsignedp);
793 if (tmp != to)
794 emit_move_insn (to, tmp);
795 return;
796 }
797 }
798
799 /* Support special truncate insns for certain modes. */
800 if (convert_optab_handler (op: trunc_optab, to_mode,
801 from_mode) != CODE_FOR_nothing)
802 {
803 emit_unop_insn (convert_optab_handler (op: trunc_optab, to_mode, from_mode),
804 to, from, UNKNOWN);
805 return;
806 }
807
808 /* Handle truncation of volatile memrefs, and so on;
809 the things that couldn't be truncated directly,
810 and for which there was no special instruction.
811
812 ??? Code above formerly short-circuited this, for most integer
813 mode pairs, with a force_reg in from_mode followed by a recursive
814 call to this routine. Appears always to have been wrong. */
815 if (GET_MODE_PRECISION (mode: to_mode) < GET_MODE_PRECISION (mode: from_mode))
816 {
817 rtx temp = force_reg (to_mode, gen_lowpart (to_mode, from));
818 emit_move_insn (to, temp);
819 return;
820 }
821
822 /* Mode combination is not recognized. */
823 gcc_unreachable ();
824}
825
826/* Return an rtx for a value that would result
827 from converting X to mode MODE.
828 Both X and MODE may be floating, or both integer.
829 UNSIGNEDP is nonzero if X is an unsigned value.
830 This can be done by referring to a part of X in place
831 or by copying to a new temporary with conversion. */
832
833rtx
834convert_to_mode (machine_mode mode, rtx x, int unsignedp)
835{
836 return convert_modes (mode, VOIDmode, x, unsignedp);
837}
838
839/* Return an rtx for a value that would result
840 from converting X from mode OLDMODE to mode MODE.
841 Both modes may be floating, or both integer.
842 UNSIGNEDP is nonzero if X is an unsigned value.
843
844 This can be done by referring to a part of X in place
845 or by copying to a new temporary with conversion.
846
847 You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode. */
848
849rtx
850convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
851{
852 rtx temp;
853 scalar_int_mode int_mode;
854
855 /* If FROM is a SUBREG that indicates that we have already done at least
856 the required extension, strip it. */
857
858 if (GET_CODE (x) == SUBREG
859 && SUBREG_PROMOTED_VAR_P (x)
860 && is_a <scalar_int_mode> (m: mode, result: &int_mode)
861 && (GET_MODE_PRECISION (mode: subreg_promoted_mode (x))
862 >= GET_MODE_PRECISION (mode: int_mode))
863 && SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
864 {
865 scalar_int_mode int_orig_mode;
866 scalar_int_mode int_inner_mode;
867 machine_mode orig_mode = GET_MODE (x);
868 x = gen_lowpart (int_mode, SUBREG_REG (x));
869
870 /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
871 the original mode, but narrower than the inner mode. */
872 if (GET_CODE (x) == SUBREG
873 && is_a <scalar_int_mode> (m: orig_mode, result: &int_orig_mode)
874 && GET_MODE_PRECISION (mode: int_mode)
875 > GET_MODE_PRECISION (mode: int_orig_mode)
876 && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)),
877 result: &int_inner_mode)
878 && GET_MODE_PRECISION (mode: int_inner_mode)
879 > GET_MODE_PRECISION (mode: int_mode))
880 {
881 SUBREG_PROMOTED_VAR_P (x) = 1;
882 SUBREG_PROMOTED_SET (x, unsignedp);
883 }
884 }
885
886 if (GET_MODE (x) != VOIDmode)
887 oldmode = GET_MODE (x);
888
889 if (mode == oldmode)
890 return x;
891
892 if (CONST_SCALAR_INT_P (x)
893 && is_a <scalar_int_mode> (m: mode, result: &int_mode))
894 {
895 /* If the caller did not tell us the old mode, then there is not
896 much to do with respect to canonicalization. We have to
897 assume that all the bits are significant. */
898 if (!is_a <scalar_int_mode> (m: oldmode))
899 oldmode = MAX_MODE_INT;
900 wide_int w = wide_int::from (x: rtx_mode_t (x, oldmode),
901 precision: GET_MODE_PRECISION (mode: int_mode),
902 sgn: unsignedp ? UNSIGNED : SIGNED);
903 return immed_wide_int_const (w, int_mode);
904 }
905
906 /* We can do this with a gen_lowpart if both desired and current modes
907 are integer, and this is either a constant integer, a register, or a
908 non-volatile MEM. */
909 scalar_int_mode int_oldmode;
910 if (is_int_mode (mode, int_mode: &int_mode)
911 && is_int_mode (mode: oldmode, int_mode: &int_oldmode)
912 && GET_MODE_PRECISION (mode: int_mode) <= GET_MODE_PRECISION (mode: int_oldmode)
913 && ((MEM_P (x) && !MEM_VOLATILE_P (x) && direct_load[(int) int_mode])
914 || CONST_POLY_INT_P (x)
915 || (REG_P (x)
916 && (!HARD_REGISTER_P (x)
917 || targetm.hard_regno_mode_ok (REGNO (x), int_mode))
918 && TRULY_NOOP_TRUNCATION_MODES_P (int_mode, GET_MODE (x)))))
919 return gen_lowpart (int_mode, x);
920
921 /* Converting from integer constant into mode is always equivalent to an
922 subreg operation. */
923 if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode)
924 {
925 gcc_assert (known_eq (GET_MODE_BITSIZE (mode),
926 GET_MODE_BITSIZE (oldmode)));
927 return simplify_gen_subreg (outermode: mode, op: x, innermode: oldmode, byte: 0);
928 }
929
930 temp = gen_reg_rtx (mode);
931 convert_move (to: temp, from: x, unsignedp);
932 return temp;
933}
934
935/* Variant of convert_modes for ABI parameter passing/return.
936 Return an rtx for a value that would result from converting X from
937 a floating point mode FMODE to wider integer mode MODE. */
938
939rtx
940convert_float_to_wider_int (machine_mode mode, machine_mode fmode, rtx x)
941{
942 gcc_assert (SCALAR_INT_MODE_P (mode) && SCALAR_FLOAT_MODE_P (fmode));
943 scalar_int_mode tmp_mode = int_mode_for_mode (fmode).require ();
944 rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
945 return convert_modes (mode, oldmode: tmp_mode, x: tmp, unsignedp: 1);
946}
947
948/* Variant of convert_modes for ABI parameter passing/return.
949 Return an rtx for a value that would result from converting X from
950 an integer mode IMODE to a narrower floating point mode MODE. */
951
952rtx
953convert_wider_int_to_float (machine_mode mode, machine_mode imode, rtx x)
954{
955 gcc_assert (SCALAR_FLOAT_MODE_P (mode) && SCALAR_INT_MODE_P (imode));
956 scalar_int_mode tmp_mode = int_mode_for_mode (mode).require ();
957 rtx tmp = force_reg (tmp_mode, gen_lowpart (tmp_mode, x));
958 return gen_lowpart_SUBREG (mode, tmp);
959}
960
961/* Return the largest alignment we can use for doing a move (or store)
962 of MAX_PIECES. ALIGN is the largest alignment we could use. */
963
964static unsigned int
965alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
966{
967 scalar_int_mode tmode
968 = int_mode_for_size (size: max_pieces * BITS_PER_UNIT, limit: 0).require ();
969
970 if (align >= GET_MODE_ALIGNMENT (tmode))
971 align = GET_MODE_ALIGNMENT (tmode);
972 else
973 {
974 scalar_int_mode xmode = NARROWEST_INT_MODE;
975 opt_scalar_int_mode mode_iter;
976 FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
977 {
978 tmode = mode_iter.require ();
979 if (GET_MODE_SIZE (mode: tmode) > max_pieces
980 || targetm.slow_unaligned_access (tmode, align))
981 break;
982 xmode = tmode;
983 }
984
985 align = MAX (align, GET_MODE_ALIGNMENT (xmode));
986 }
987
988 return align;
989}
990
991/* Return true if we know how to implement OP using vectors of bytes. */
992static bool
993can_use_qi_vectors (by_pieces_operation op)
994{
995 return (op == COMPARE_BY_PIECES
996 || op == SET_BY_PIECES
997 || op == CLEAR_BY_PIECES);
998}
999
1000/* Return true if optabs exists for the mode and certain by pieces
1001 operations. */
1002static bool
1003by_pieces_mode_supported_p (fixed_size_mode mode, by_pieces_operation op)
1004{
1005 if (optab_handler (op: mov_optab, mode) == CODE_FOR_nothing)
1006 return false;
1007
1008 if ((op == SET_BY_PIECES || op == CLEAR_BY_PIECES)
1009 && VECTOR_MODE_P (mode)
1010 && optab_handler (op: vec_duplicate_optab, mode) == CODE_FOR_nothing)
1011 return false;
1012
1013 if (op == COMPARE_BY_PIECES
1014 && !can_compare_p (EQ, mode, ccp_jump))
1015 return false;
1016
1017 return true;
1018}
1019
1020/* Return the widest mode that can be used to perform part of an
1021 operation OP on SIZE bytes. Try to use QI vector modes where
1022 possible. */
1023static fixed_size_mode
1024widest_fixed_size_mode_for_size (unsigned int size, by_pieces_operation op)
1025{
1026 fixed_size_mode result = NARROWEST_INT_MODE;
1027
1028 gcc_checking_assert (size > 1);
1029
1030 /* Use QI vector only if size is wider than a WORD. */
1031 if (can_use_qi_vectors (op) && size > UNITS_PER_WORD)
1032 {
1033 machine_mode mode;
1034 fixed_size_mode candidate;
1035 FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1036 if (is_a<fixed_size_mode> (m: mode, result: &candidate)
1037 && GET_MODE_INNER (candidate) == QImode)
1038 {
1039 if (GET_MODE_SIZE (mode: candidate) >= size)
1040 break;
1041 if (by_pieces_mode_supported_p (mode: candidate, op))
1042 result = candidate;
1043 }
1044
1045 if (result != NARROWEST_INT_MODE)
1046 return result;
1047 }
1048
1049 opt_scalar_int_mode tmode;
1050 scalar_int_mode mode;
1051 FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
1052 {
1053 mode = tmode.require ();
1054 if (GET_MODE_SIZE (mode) < size
1055 && by_pieces_mode_supported_p (mode, op))
1056 result = mode;
1057 }
1058
1059 return result;
1060}
1061
1062/* Determine whether an operation OP on LEN bytes with alignment ALIGN can
1063 and should be performed piecewise. */
1064
1065static bool
1066can_do_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align,
1067 enum by_pieces_operation op)
1068{
1069 return targetm.use_by_pieces_infrastructure_p (len, align, op,
1070 optimize_insn_for_speed_p ());
1071}
1072
1073/* Determine whether the LEN bytes can be moved by using several move
1074 instructions. Return nonzero if a call to move_by_pieces should
1075 succeed. */
1076
1077bool
1078can_move_by_pieces (unsigned HOST_WIDE_INT len, unsigned int align)
1079{
1080 return can_do_by_pieces (len, align, op: MOVE_BY_PIECES);
1081}
1082
1083/* Return number of insns required to perform operation OP by pieces
1084 for L bytes. ALIGN (in bits) is maximum alignment we can assume. */
1085
1086unsigned HOST_WIDE_INT
1087by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
1088 unsigned int max_size, by_pieces_operation op)
1089{
1090 unsigned HOST_WIDE_INT n_insns = 0;
1091 fixed_size_mode mode;
1092
1093 if (targetm.overlap_op_by_pieces_p () && op != COMPARE_BY_PIECES)
1094 {
1095 /* NB: Round up L and ALIGN to the widest integer mode for
1096 MAX_SIZE. */
1097 mode = widest_fixed_size_mode_for_size (size: max_size, op);
1098 if (optab_handler (op: mov_optab, mode) != CODE_FOR_nothing)
1099 {
1100 unsigned HOST_WIDE_INT up = ROUND_UP (l, GET_MODE_SIZE (mode));
1101 if (up > l)
1102 l = up;
1103 align = GET_MODE_ALIGNMENT (mode);
1104 }
1105 }
1106
1107 align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1108
1109 while (max_size > 1 && l > 0)
1110 {
1111 mode = widest_fixed_size_mode_for_size (size: max_size, op);
1112 enum insn_code icode;
1113
1114 unsigned int modesize = GET_MODE_SIZE (mode);
1115
1116 icode = optab_handler (op: mov_optab, mode);
1117 if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
1118 {
1119 unsigned HOST_WIDE_INT n_pieces = l / modesize;
1120 l %= modesize;
1121 switch (op)
1122 {
1123 default:
1124 n_insns += n_pieces;
1125 break;
1126
1127 case COMPARE_BY_PIECES:
1128 int batch = targetm.compare_by_pieces_branch_ratio (mode);
1129 int batch_ops = 4 * batch - 1;
1130 unsigned HOST_WIDE_INT full = n_pieces / batch;
1131 n_insns += full * batch_ops;
1132 if (n_pieces % batch != 0)
1133 n_insns++;
1134 break;
1135
1136 }
1137 }
1138 max_size = modesize;
1139 }
1140
1141 gcc_assert (!l);
1142 return n_insns;
1143}
1144
1145/* Used when performing piecewise block operations, holds information
1146 about one of the memory objects involved. The member functions
1147 can be used to generate code for loading from the object and
1148 updating the address when iterating. */
1149
1150class pieces_addr
1151{
1152 /* The object being referenced, a MEM. Can be NULL_RTX to indicate
1153 stack pushes. */
1154 rtx m_obj;
1155 /* The address of the object. Can differ from that seen in the
1156 MEM rtx if we copied the address to a register. */
1157 rtx m_addr;
1158 /* Nonzero if the address on the object has an autoincrement already,
1159 signifies whether that was an increment or decrement. */
1160 signed char m_addr_inc;
1161 /* Nonzero if we intend to use autoinc without the address already
1162 having autoinc form. We will insert add insns around each memory
1163 reference, expecting later passes to form autoinc addressing modes.
1164 The only supported options are predecrement and postincrement. */
1165 signed char m_explicit_inc;
1166 /* True if we have either of the two possible cases of using
1167 autoincrement. */
1168 bool m_auto;
1169 /* True if this is an address to be used for load operations rather
1170 than stores. */
1171 bool m_is_load;
1172
1173 /* Optionally, a function to obtain constants for any given offset into
1174 the objects, and data associated with it. */
1175 by_pieces_constfn m_constfn;
1176 void *m_cfndata;
1177public:
1178 pieces_addr (rtx, bool, by_pieces_constfn, void *);
1179 rtx adjust (fixed_size_mode, HOST_WIDE_INT, by_pieces_prev * = nullptr);
1180 void increment_address (HOST_WIDE_INT);
1181 void maybe_predec (HOST_WIDE_INT);
1182 void maybe_postinc (HOST_WIDE_INT);
1183 void decide_autoinc (machine_mode, bool, HOST_WIDE_INT);
1184 int get_addr_inc ()
1185 {
1186 return m_addr_inc;
1187 }
1188};
1189
1190/* Initialize a pieces_addr structure from an object OBJ. IS_LOAD is
1191 true if the operation to be performed on this object is a load
1192 rather than a store. For stores, OBJ can be NULL, in which case we
1193 assume the operation is a stack push. For loads, the optional
1194 CONSTFN and its associated CFNDATA can be used in place of the
1195 memory load. */
1196
1197pieces_addr::pieces_addr (rtx obj, bool is_load, by_pieces_constfn constfn,
1198 void *cfndata)
1199 : m_obj (obj), m_is_load (is_load), m_constfn (constfn), m_cfndata (cfndata)
1200{
1201 m_addr_inc = 0;
1202 m_auto = false;
1203 if (obj)
1204 {
1205 rtx addr = XEXP (obj, 0);
1206 rtx_code code = GET_CODE (addr);
1207 m_addr = addr;
1208 bool dec = code == PRE_DEC || code == POST_DEC;
1209 bool inc = code == PRE_INC || code == POST_INC;
1210 m_auto = inc || dec;
1211 if (m_auto)
1212 m_addr_inc = dec ? -1 : 1;
1213
1214 /* While we have always looked for these codes here, the code
1215 implementing the memory operation has never handled them.
1216 Support could be added later if necessary or beneficial. */
1217 gcc_assert (code != PRE_INC && code != POST_DEC);
1218 }
1219 else
1220 {
1221 m_addr = NULL_RTX;
1222 if (!is_load)
1223 {
1224 m_auto = true;
1225 if (STACK_GROWS_DOWNWARD)
1226 m_addr_inc = -1;
1227 else
1228 m_addr_inc = 1;
1229 }
1230 else
1231 gcc_assert (constfn != NULL);
1232 }
1233 m_explicit_inc = 0;
1234 if (constfn)
1235 gcc_assert (is_load);
1236}
1237
1238/* Decide whether to use autoinc for an address involved in a memory op.
1239 MODE is the mode of the accesses, REVERSE is true if we've decided to
1240 perform the operation starting from the end, and LEN is the length of
1241 the operation. Don't override an earlier decision to set m_auto. */
1242
1243void
1244pieces_addr::decide_autoinc (machine_mode ARG_UNUSED (mode), bool reverse,
1245 HOST_WIDE_INT len)
1246{
1247 if (m_auto || m_obj == NULL_RTX)
1248 return;
1249
1250 bool use_predec = (m_is_load
1251 ? USE_LOAD_PRE_DECREMENT (mode)
1252 : USE_STORE_PRE_DECREMENT (mode));
1253 bool use_postinc = (m_is_load
1254 ? USE_LOAD_POST_INCREMENT (mode)
1255 : USE_STORE_POST_INCREMENT (mode));
1256 machine_mode addr_mode = get_address_mode (mem: m_obj);
1257
1258 if (use_predec && reverse)
1259 {
1260 m_addr = copy_to_mode_reg (addr_mode,
1261 plus_constant (addr_mode,
1262 m_addr, len));
1263 m_auto = true;
1264 m_explicit_inc = -1;
1265 }
1266 else if (use_postinc && !reverse)
1267 {
1268 m_addr = copy_to_mode_reg (addr_mode, m_addr);
1269 m_auto = true;
1270 m_explicit_inc = 1;
1271 }
1272 else if (CONSTANT_P (m_addr))
1273 m_addr = copy_to_mode_reg (addr_mode, m_addr);
1274}
1275
1276/* Adjust the address to refer to the data at OFFSET in MODE. If we
1277 are using autoincrement for this address, we don't add the offset,
1278 but we still modify the MEM's properties. */
1279
1280rtx
1281pieces_addr::adjust (fixed_size_mode mode, HOST_WIDE_INT offset,
1282 by_pieces_prev *prev)
1283{
1284 if (m_constfn)
1285 /* Pass the previous data to m_constfn. */
1286 return m_constfn (m_cfndata, prev, offset, mode);
1287 if (m_obj == NULL_RTX)
1288 return NULL_RTX;
1289 if (m_auto)
1290 return adjust_automodify_address (m_obj, mode, m_addr, offset);
1291 else
1292 return adjust_address (m_obj, mode, offset);
1293}
1294
1295/* Emit an add instruction to increment the address by SIZE. */
1296
1297void
1298pieces_addr::increment_address (HOST_WIDE_INT size)
1299{
1300 rtx amount = gen_int_mode (size, GET_MODE (m_addr));
1301 emit_insn (gen_add2_insn (m_addr, amount));
1302}
1303
1304/* If we are supposed to decrement the address after each access, emit code
1305 to do so now. Increment by SIZE (which has should have the correct sign
1306 already). */
1307
1308void
1309pieces_addr::maybe_predec (HOST_WIDE_INT size)
1310{
1311 if (m_explicit_inc >= 0)
1312 return;
1313 gcc_assert (HAVE_PRE_DECREMENT);
1314 increment_address (size);
1315}
1316
1317/* If we are supposed to decrement the address after each access, emit code
1318 to do so now. Increment by SIZE. */
1319
1320void
1321pieces_addr::maybe_postinc (HOST_WIDE_INT size)
1322{
1323 if (m_explicit_inc <= 0)
1324 return;
1325 gcc_assert (HAVE_POST_INCREMENT);
1326 increment_address (size);
1327}
1328
1329/* This structure is used by do_op_by_pieces to describe the operation
1330 to be performed. */
1331
1332class op_by_pieces_d
1333{
1334 private:
1335 fixed_size_mode get_usable_mode (fixed_size_mode, unsigned int);
1336 fixed_size_mode smallest_fixed_size_mode_for_size (unsigned int);
1337
1338 protected:
1339 pieces_addr m_to, m_from;
1340 /* Make m_len read-only so that smallest_fixed_size_mode_for_size can
1341 use it to check the valid mode size. */
1342 const unsigned HOST_WIDE_INT m_len;
1343 HOST_WIDE_INT m_offset;
1344 unsigned int m_align;
1345 unsigned int m_max_size;
1346 bool m_reverse;
1347 /* True if this is a stack push. */
1348 bool m_push;
1349 /* True if targetm.overlap_op_by_pieces_p () returns true. */
1350 bool m_overlap_op_by_pieces;
1351 /* The type of operation that we're performing. */
1352 by_pieces_operation m_op;
1353
1354 /* Virtual functions, overriden by derived classes for the specific
1355 operation. */
1356 virtual void generate (rtx, rtx, machine_mode) = 0;
1357 virtual bool prepare_mode (machine_mode, unsigned int) = 0;
1358 virtual void finish_mode (machine_mode)
1359 {
1360 }
1361
1362 public:
1363 op_by_pieces_d (unsigned int, rtx, bool, rtx, bool, by_pieces_constfn,
1364 void *, unsigned HOST_WIDE_INT, unsigned int, bool,
1365 by_pieces_operation);
1366 void run ();
1367};
1368
1369/* The constructor for an op_by_pieces_d structure. We require two
1370 objects named TO and FROM, which are identified as loads or stores
1371 by TO_LOAD and FROM_LOAD. If FROM is a load, the optional FROM_CFN
1372 and its associated FROM_CFN_DATA can be used to replace loads with
1373 constant values. MAX_PIECES describes the maximum number of bytes
1374 at a time which can be moved efficiently. LEN describes the length
1375 of the operation. */
1376
1377op_by_pieces_d::op_by_pieces_d (unsigned int max_pieces, rtx to,
1378 bool to_load, rtx from, bool from_load,
1379 by_pieces_constfn from_cfn,
1380 void *from_cfn_data,
1381 unsigned HOST_WIDE_INT len,
1382 unsigned int align, bool push,
1383 by_pieces_operation op)
1384 : m_to (to, to_load, NULL, NULL),
1385 m_from (from, from_load, from_cfn, from_cfn_data),
1386 m_len (len), m_max_size (max_pieces + 1),
1387 m_push (push), m_op (op)
1388{
1389 int toi = m_to.get_addr_inc ();
1390 int fromi = m_from.get_addr_inc ();
1391 if (toi >= 0 && fromi >= 0)
1392 m_reverse = false;
1393 else if (toi <= 0 && fromi <= 0)
1394 m_reverse = true;
1395 else
1396 gcc_unreachable ();
1397
1398 m_offset = m_reverse ? len : 0;
1399 align = MIN (to ? MEM_ALIGN (to) : align,
1400 from ? MEM_ALIGN (from) : align);
1401
1402 /* If copying requires more than two move insns,
1403 copy addresses to registers (to make displacements shorter)
1404 and use post-increment if available. */
1405 if (by_pieces_ninsns (l: len, align, max_size: m_max_size, op: MOVE_BY_PIECES) > 2)
1406 {
1407 /* Find the mode of the largest comparison. */
1408 fixed_size_mode mode
1409 = widest_fixed_size_mode_for_size (size: m_max_size, op: m_op);
1410
1411 m_from.decide_autoinc (mode, reverse: m_reverse, len);
1412 m_to.decide_autoinc (mode, reverse: m_reverse, len);
1413 }
1414
1415 align = alignment_for_piecewise_move (MOVE_MAX_PIECES, align);
1416 m_align = align;
1417
1418 m_overlap_op_by_pieces = targetm.overlap_op_by_pieces_p ();
1419}
1420
1421/* This function returns the largest usable integer mode for LEN bytes
1422 whose size is no bigger than size of MODE. */
1423
1424fixed_size_mode
1425op_by_pieces_d::get_usable_mode (fixed_size_mode mode, unsigned int len)
1426{
1427 unsigned int size;
1428 do
1429 {
1430 size = GET_MODE_SIZE (mode);
1431 if (len >= size && prepare_mode (mode, m_align))
1432 break;
1433 /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1434 mode = widest_fixed_size_mode_for_size (size, op: m_op);
1435 }
1436 while (1);
1437 return mode;
1438}
1439
1440/* Return the smallest integer or QI vector mode that is not narrower
1441 than SIZE bytes. */
1442
1443fixed_size_mode
1444op_by_pieces_d::smallest_fixed_size_mode_for_size (unsigned int size)
1445{
1446 /* Use QI vector only for > size of WORD. */
1447 if (can_use_qi_vectors (op: m_op) && size > UNITS_PER_WORD)
1448 {
1449 machine_mode mode;
1450 fixed_size_mode candidate;
1451 FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
1452 if (is_a<fixed_size_mode> (m: mode, result: &candidate)
1453 && GET_MODE_INNER (candidate) == QImode)
1454 {
1455 /* Don't return a mode wider than M_LEN. */
1456 if (GET_MODE_SIZE (mode: candidate) > m_len)
1457 break;
1458
1459 if (GET_MODE_SIZE (mode: candidate) >= size
1460 && by_pieces_mode_supported_p (mode: candidate, op: m_op))
1461 return candidate;
1462 }
1463 }
1464
1465 return smallest_int_mode_for_size (size: size * BITS_PER_UNIT);
1466}
1467
1468/* This function contains the main loop used for expanding a block
1469 operation. First move what we can in the largest integer mode,
1470 then go to successively smaller modes. For every access, call
1471 GENFUN with the two operands and the EXTRA_DATA. */
1472
1473void
1474op_by_pieces_d::run ()
1475{
1476 if (m_len == 0)
1477 return;
1478
1479 unsigned HOST_WIDE_INT length = m_len;
1480
1481 /* widest_fixed_size_mode_for_size checks M_MAX_SIZE > 1. */
1482 fixed_size_mode mode
1483 = widest_fixed_size_mode_for_size (size: m_max_size, op: m_op);
1484 mode = get_usable_mode (mode, len: length);
1485
1486 by_pieces_prev to_prev = { .data: nullptr, .mode: mode };
1487 by_pieces_prev from_prev = { .data: nullptr, .mode: mode };
1488
1489 do
1490 {
1491 unsigned int size = GET_MODE_SIZE (mode);
1492 rtx to1 = NULL_RTX, from1;
1493
1494 while (length >= size)
1495 {
1496 if (m_reverse)
1497 m_offset -= size;
1498
1499 to1 = m_to.adjust (mode, offset: m_offset, prev: &to_prev);
1500 to_prev.data = to1;
1501 to_prev.mode = mode;
1502 from1 = m_from.adjust (mode, offset: m_offset, prev: &from_prev);
1503 from_prev.data = from1;
1504 from_prev.mode = mode;
1505
1506 m_to.maybe_predec (size: -(HOST_WIDE_INT)size);
1507 m_from.maybe_predec (size: -(HOST_WIDE_INT)size);
1508
1509 generate (to1, from1, mode);
1510
1511 m_to.maybe_postinc (size);
1512 m_from.maybe_postinc (size);
1513
1514 if (!m_reverse)
1515 m_offset += size;
1516
1517 length -= size;
1518 }
1519
1520 finish_mode (mode);
1521
1522 if (length == 0)
1523 return;
1524
1525 if (!m_push && m_overlap_op_by_pieces)
1526 {
1527 /* NB: Generate overlapping operations if it is not a stack
1528 push since stack push must not overlap. Get the smallest
1529 fixed size mode for M_LEN bytes. */
1530 mode = smallest_fixed_size_mode_for_size (size: length);
1531 mode = get_usable_mode (mode, len: GET_MODE_SIZE (mode));
1532 int gap = GET_MODE_SIZE (mode) - length;
1533 if (gap > 0)
1534 {
1535 /* If size of MODE > M_LEN, generate the last operation
1536 in MODE for the remaining bytes with ovelapping memory
1537 from the previois operation. */
1538 if (m_reverse)
1539 m_offset += gap;
1540 else
1541 m_offset -= gap;
1542 length += gap;
1543 }
1544 }
1545 else
1546 {
1547 /* widest_fixed_size_mode_for_size checks SIZE > 1. */
1548 mode = widest_fixed_size_mode_for_size (size, op: m_op);
1549 mode = get_usable_mode (mode, len: length);
1550 }
1551 }
1552 while (1);
1553}
1554
1555/* Derived class from op_by_pieces_d, providing support for block move
1556 operations. */
1557
1558#ifdef PUSH_ROUNDING
1559#define PUSHG_P(to) ((to) == nullptr)
1560#else
1561#define PUSHG_P(to) false
1562#endif
1563
1564class move_by_pieces_d : public op_by_pieces_d
1565{
1566 insn_gen_fn m_gen_fun;
1567 void generate (rtx, rtx, machine_mode) final override;
1568 bool prepare_mode (machine_mode, unsigned int) final override;
1569
1570 public:
1571 move_by_pieces_d (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1572 unsigned int align)
1573 : op_by_pieces_d (MOVE_MAX_PIECES, to, false, from, true, NULL,
1574 NULL, len, align, PUSHG_P (to), MOVE_BY_PIECES)
1575 {
1576 }
1577 rtx finish_retmode (memop_ret);
1578};
1579
1580/* Return true if MODE can be used for a set of copies, given an
1581 alignment ALIGN. Prepare whatever data is necessary for later
1582 calls to generate. */
1583
1584bool
1585move_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1586{
1587 insn_code icode = optab_handler (op: mov_optab, mode);
1588 m_gen_fun = GEN_FCN (icode);
1589 return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1590}
1591
1592/* A callback used when iterating for a compare_by_pieces_operation.
1593 OP0 and OP1 are the values that have been loaded and should be
1594 compared in MODE. If OP0 is NULL, this means we should generate a
1595 push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1596 gen function that should be used to generate the mode. */
1597
1598void
1599move_by_pieces_d::generate (rtx op0, rtx op1,
1600 machine_mode mode ATTRIBUTE_UNUSED)
1601{
1602#ifdef PUSH_ROUNDING
1603 if (op0 == NULL_RTX)
1604 {
1605 emit_single_push_insn (mode, op1, NULL);
1606 return;
1607 }
1608#endif
1609 emit_insn (m_gen_fun (op0, op1));
1610}
1611
1612/* Perform the final adjustment at the end of a string to obtain the
1613 correct return value for the block operation.
1614 Return value is based on RETMODE argument. */
1615
1616rtx
1617move_by_pieces_d::finish_retmode (memop_ret retmode)
1618{
1619 gcc_assert (!m_reverse);
1620 if (retmode == RETURN_END_MINUS_ONE)
1621 {
1622 m_to.maybe_postinc (size: -1);
1623 --m_offset;
1624 }
1625 return m_to.adjust (QImode, offset: m_offset);
1626}
1627
1628/* Generate several move instructions to copy LEN bytes from block FROM to
1629 block TO. (These are MEM rtx's with BLKmode).
1630
1631 If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1632 used to push FROM to the stack.
1633
1634 ALIGN is maximum stack alignment we can assume.
1635
1636 Return value is based on RETMODE argument. */
1637
1638rtx
1639move_by_pieces (rtx to, rtx from, unsigned HOST_WIDE_INT len,
1640 unsigned int align, memop_ret retmode)
1641{
1642#ifndef PUSH_ROUNDING
1643 if (to == NULL)
1644 gcc_unreachable ();
1645#endif
1646
1647 move_by_pieces_d data (to, from, len, align);
1648
1649 data.run ();
1650
1651 if (retmode != RETURN_BEGIN)
1652 return data.finish_retmode (retmode);
1653 else
1654 return to;
1655}
1656
1657/* Derived class from op_by_pieces_d, providing support for block move
1658 operations. */
1659
1660class store_by_pieces_d : public op_by_pieces_d
1661{
1662 insn_gen_fn m_gen_fun;
1663
1664 void generate (rtx, rtx, machine_mode) final override;
1665 bool prepare_mode (machine_mode, unsigned int) final override;
1666
1667 public:
1668 store_by_pieces_d (rtx to, by_pieces_constfn cfn, void *cfn_data,
1669 unsigned HOST_WIDE_INT len, unsigned int align,
1670 by_pieces_operation op)
1671 : op_by_pieces_d (STORE_MAX_PIECES, to, false, NULL_RTX, true, cfn,
1672 cfn_data, len, align, false, op)
1673 {
1674 }
1675 rtx finish_retmode (memop_ret);
1676};
1677
1678/* Return true if MODE can be used for a set of stores, given an
1679 alignment ALIGN. Prepare whatever data is necessary for later
1680 calls to generate. */
1681
1682bool
1683store_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1684{
1685 insn_code icode = optab_handler (op: mov_optab, mode);
1686 m_gen_fun = GEN_FCN (icode);
1687 return icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode);
1688}
1689
1690/* A callback used when iterating for a store_by_pieces_operation.
1691 OP0 and OP1 are the values that have been loaded and should be
1692 compared in MODE. If OP0 is NULL, this means we should generate a
1693 push; otherwise EXTRA_DATA holds a pointer to a pointer to the insn
1694 gen function that should be used to generate the mode. */
1695
1696void
1697store_by_pieces_d::generate (rtx op0, rtx op1, machine_mode)
1698{
1699 emit_insn (m_gen_fun (op0, op1));
1700}
1701
1702/* Perform the final adjustment at the end of a string to obtain the
1703 correct return value for the block operation.
1704 Return value is based on RETMODE argument. */
1705
1706rtx
1707store_by_pieces_d::finish_retmode (memop_ret retmode)
1708{
1709 gcc_assert (!m_reverse);
1710 if (retmode == RETURN_END_MINUS_ONE)
1711 {
1712 m_to.maybe_postinc (size: -1);
1713 --m_offset;
1714 }
1715 return m_to.adjust (QImode, offset: m_offset);
1716}
1717
1718/* Determine whether the LEN bytes generated by CONSTFUN can be
1719 stored to memory using several move instructions. CONSTFUNDATA is
1720 a pointer which will be passed as argument in every CONSTFUN call.
1721 ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1722 a memset operation and false if it's a copy of a constant string.
1723 Return true if a call to store_by_pieces should succeed. */
1724
1725bool
1726can_store_by_pieces (unsigned HOST_WIDE_INT len,
1727 by_pieces_constfn constfun,
1728 void *constfundata, unsigned int align, bool memsetp)
1729{
1730 unsigned HOST_WIDE_INT l;
1731 unsigned int max_size;
1732 HOST_WIDE_INT offset = 0;
1733 enum insn_code icode;
1734 int reverse;
1735 /* cst is set but not used if LEGITIMATE_CONSTANT doesn't use it. */
1736 rtx cst ATTRIBUTE_UNUSED;
1737
1738 if (len == 0)
1739 return true;
1740
1741 if (!targetm.use_by_pieces_infrastructure_p (len, align,
1742 memsetp
1743 ? SET_BY_PIECES
1744 : STORE_BY_PIECES,
1745 optimize_insn_for_speed_p ()))
1746 return false;
1747
1748 align = alignment_for_piecewise_move (STORE_MAX_PIECES, align);
1749
1750 /* We would first store what we can in the largest integer mode, then go to
1751 successively smaller modes. */
1752
1753 for (reverse = 0;
1754 reverse <= (HAVE_PRE_DECREMENT || HAVE_POST_DECREMENT);
1755 reverse++)
1756 {
1757 l = len;
1758 max_size = STORE_MAX_PIECES + 1;
1759 while (max_size > 1 && l > 0)
1760 {
1761 auto op = memsetp ? SET_BY_PIECES : STORE_BY_PIECES;
1762 auto mode = widest_fixed_size_mode_for_size (size: max_size, op);
1763
1764 icode = optab_handler (op: mov_optab, mode);
1765 if (icode != CODE_FOR_nothing
1766 && align >= GET_MODE_ALIGNMENT (mode))
1767 {
1768 unsigned int size = GET_MODE_SIZE (mode);
1769
1770 while (l >= size)
1771 {
1772 if (reverse)
1773 offset -= size;
1774
1775 cst = (*constfun) (constfundata, nullptr, offset, mode);
1776 /* All CONST_VECTORs can be loaded for memset since
1777 vec_duplicate_optab is a precondition to pick a
1778 vector mode for the memset expander. */
1779 if (!((memsetp && VECTOR_MODE_P (mode))
1780 || targetm.legitimate_constant_p (mode, cst)))
1781 return false;
1782
1783 if (!reverse)
1784 offset += size;
1785
1786 l -= size;
1787 }
1788 }
1789
1790 max_size = GET_MODE_SIZE (mode);
1791 }
1792
1793 /* The code above should have handled everything. */
1794 gcc_assert (!l);
1795 }
1796
1797 return true;
1798}
1799
1800/* Generate several move instructions to store LEN bytes generated by
1801 CONSTFUN to block TO. (A MEM rtx with BLKmode). CONSTFUNDATA is a
1802 pointer which will be passed as argument in every CONSTFUN call.
1803 ALIGN is maximum alignment we can assume. MEMSETP is true if this is
1804 a memset operation and false if it's a copy of a constant string.
1805 Return value is based on RETMODE argument. */
1806
1807rtx
1808store_by_pieces (rtx to, unsigned HOST_WIDE_INT len,
1809 by_pieces_constfn constfun,
1810 void *constfundata, unsigned int align, bool memsetp,
1811 memop_ret retmode)
1812{
1813 if (len == 0)
1814 {
1815 gcc_assert (retmode != RETURN_END_MINUS_ONE);
1816 return to;
1817 }
1818
1819 gcc_assert (targetm.use_by_pieces_infrastructure_p
1820 (len, align,
1821 memsetp ? SET_BY_PIECES : STORE_BY_PIECES,
1822 optimize_insn_for_speed_p ()));
1823
1824 store_by_pieces_d data (to, constfun, constfundata, len, align,
1825 memsetp ? SET_BY_PIECES : STORE_BY_PIECES);
1826 data.run ();
1827
1828 if (retmode != RETURN_BEGIN)
1829 return data.finish_retmode (retmode);
1830 else
1831 return to;
1832}
1833
1834/* Generate several move instructions to clear LEN bytes of block TO. (A MEM
1835 rtx with BLKmode). ALIGN is maximum alignment we can assume. */
1836
1837static void
1838clear_by_pieces (rtx to, unsigned HOST_WIDE_INT len, unsigned int align)
1839{
1840 if (len == 0)
1841 return;
1842
1843 /* Use builtin_memset_read_str to support vector mode broadcast. */
1844 char c = 0;
1845 store_by_pieces_d data (to, builtin_memset_read_str, &c, len, align,
1846 CLEAR_BY_PIECES);
1847 data.run ();
1848}
1849
1850/* Context used by compare_by_pieces_genfn. It stores the fail label
1851 to jump to in case of miscomparison, and for branch ratios greater than 1,
1852 it stores an accumulator and the current and maximum counts before
1853 emitting another branch. */
1854
1855class compare_by_pieces_d : public op_by_pieces_d
1856{
1857 rtx_code_label *m_fail_label;
1858 rtx m_accumulator;
1859 int m_count, m_batch;
1860
1861 void generate (rtx, rtx, machine_mode) final override;
1862 bool prepare_mode (machine_mode, unsigned int) final override;
1863 void finish_mode (machine_mode) final override;
1864
1865 public:
1866 compare_by_pieces_d (rtx op0, rtx op1, by_pieces_constfn op1_cfn,
1867 void *op1_cfn_data, HOST_WIDE_INT len, int align,
1868 rtx_code_label *fail_label)
1869 : op_by_pieces_d (COMPARE_MAX_PIECES, op0, true, op1, true, op1_cfn,
1870 op1_cfn_data, len, align, false, COMPARE_BY_PIECES)
1871 {
1872 m_fail_label = fail_label;
1873 }
1874};
1875
1876/* A callback used when iterating for a compare_by_pieces_operation.
1877 OP0 and OP1 are the values that have been loaded and should be
1878 compared in MODE. DATA holds a pointer to the compare_by_pieces_data
1879 context structure. */
1880
1881void
1882compare_by_pieces_d::generate (rtx op0, rtx op1, machine_mode mode)
1883{
1884 if (m_batch > 1)
1885 {
1886 rtx temp = expand_binop (mode, sub_optab, op0, op1, NULL_RTX,
1887 true, OPTAB_LIB_WIDEN);
1888 if (m_count != 0)
1889 temp = expand_binop (mode, ior_optab, m_accumulator, temp, temp,
1890 true, OPTAB_LIB_WIDEN);
1891 m_accumulator = temp;
1892
1893 if (++m_count < m_batch)
1894 return;
1895
1896 m_count = 0;
1897 op0 = m_accumulator;
1898 op1 = const0_rtx;
1899 m_accumulator = NULL_RTX;
1900 }
1901 do_compare_rtx_and_jump (op0, op1, NE, true, mode, NULL_RTX, NULL,
1902 m_fail_label, profile_probability::uninitialized ());
1903}
1904
1905/* Return true if MODE can be used for a set of moves and comparisons,
1906 given an alignment ALIGN. Prepare whatever data is necessary for
1907 later calls to generate. */
1908
1909bool
1910compare_by_pieces_d::prepare_mode (machine_mode mode, unsigned int align)
1911{
1912 insn_code icode = optab_handler (op: mov_optab, mode);
1913 if (icode == CODE_FOR_nothing
1914 || align < GET_MODE_ALIGNMENT (mode)
1915 || !can_compare_p (EQ, mode, ccp_jump))
1916 return false;
1917 m_batch = targetm.compare_by_pieces_branch_ratio (mode);
1918 if (m_batch < 0)
1919 return false;
1920 m_accumulator = NULL_RTX;
1921 m_count = 0;
1922 return true;
1923}
1924
1925/* Called after expanding a series of comparisons in MODE. If we have
1926 accumulated results for which we haven't emitted a branch yet, do
1927 so now. */
1928
1929void
1930compare_by_pieces_d::finish_mode (machine_mode mode)
1931{
1932 if (m_accumulator != NULL_RTX)
1933 do_compare_rtx_and_jump (m_accumulator, const0_rtx, NE, true, mode,
1934 NULL_RTX, NULL, m_fail_label,
1935 profile_probability::uninitialized ());
1936}
1937
1938/* Generate several move instructions to compare LEN bytes from blocks
1939 ARG0 and ARG1. (These are MEM rtx's with BLKmode).
1940
1941 If PUSH_ROUNDING is defined and TO is NULL, emit_single_push_insn is
1942 used to push FROM to the stack.
1943
1944 ALIGN is maximum stack alignment we can assume.
1945
1946 Optionally, the caller can pass a constfn and associated data in A1_CFN
1947 and A1_CFN_DATA. describing that the second operand being compared is a
1948 known constant and how to obtain its data. */
1949
1950static rtx
1951compare_by_pieces (rtx arg0, rtx arg1, unsigned HOST_WIDE_INT len,
1952 rtx target, unsigned int align,
1953 by_pieces_constfn a1_cfn, void *a1_cfn_data)
1954{
1955 rtx_code_label *fail_label = gen_label_rtx ();
1956 rtx_code_label *end_label = gen_label_rtx ();
1957
1958 if (target == NULL_RTX
1959 || !REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
1960 target = gen_reg_rtx (TYPE_MODE (integer_type_node));
1961
1962 compare_by_pieces_d data (arg0, arg1, a1_cfn, a1_cfn_data, len, align,
1963 fail_label);
1964
1965 data.run ();
1966
1967 emit_move_insn (target, const0_rtx);
1968 emit_jump (end_label);
1969 emit_barrier ();
1970 emit_label (fail_label);
1971 emit_move_insn (target, const1_rtx);
1972 emit_label (end_label);
1973
1974 return target;
1975}
1976
1977/* Emit code to move a block Y to a block X. This may be done with
1978 string-move instructions, with multiple scalar move instructions,
1979 or with a library call.
1980
1981 Both X and Y must be MEM rtx's (perhaps inside VOLATILE) with mode BLKmode.
1982 SIZE is an rtx that says how long they are.
1983 ALIGN is the maximum alignment we can assume they have.
1984 METHOD describes what kind of copy this is, and what mechanisms may be used.
1985 MIN_SIZE is the minimal size of block to move
1986 MAX_SIZE is the maximal size of block to move, if it cannot be represented
1987 in unsigned HOST_WIDE_INT, than it is mask of all ones.
1988
1989 Return the address of the new block, if memcpy is called and returns it,
1990 0 otherwise. */
1991
1992rtx
1993emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
1994 unsigned int expected_align, HOST_WIDE_INT expected_size,
1995 unsigned HOST_WIDE_INT min_size,
1996 unsigned HOST_WIDE_INT max_size,
1997 unsigned HOST_WIDE_INT probable_max_size,
1998 bool bail_out_libcall, bool *is_move_done,
1999 bool might_overlap)
2000{
2001 int may_use_call;
2002 rtx retval = 0;
2003 unsigned int align;
2004
2005 if (is_move_done)
2006 *is_move_done = true;
2007
2008 gcc_assert (size);
2009 if (CONST_INT_P (size) && INTVAL (size) == 0)
2010 return 0;
2011
2012 switch (method)
2013 {
2014 case BLOCK_OP_NORMAL:
2015 case BLOCK_OP_TAILCALL:
2016 may_use_call = 1;
2017 break;
2018
2019 case BLOCK_OP_CALL_PARM:
2020 may_use_call = block_move_libcall_safe_for_call_parm ();
2021
2022 /* Make inhibit_defer_pop nonzero around the library call
2023 to force it to pop the arguments right away. */
2024 NO_DEFER_POP;
2025 break;
2026
2027 case BLOCK_OP_NO_LIBCALL:
2028 may_use_call = 0;
2029 break;
2030
2031 case BLOCK_OP_NO_LIBCALL_RET:
2032 may_use_call = -1;
2033 break;
2034
2035 default:
2036 gcc_unreachable ();
2037 }
2038
2039 gcc_assert (MEM_P (x) && MEM_P (y));
2040 align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2041 gcc_assert (align >= BITS_PER_UNIT);
2042
2043 /* Make sure we've got BLKmode addresses; store_one_arg can decide that
2044 block copy is more efficient for other large modes, e.g. DCmode. */
2045 x = adjust_address (x, BLKmode, 0);
2046 y = adjust_address (y, BLKmode, 0);
2047
2048 /* If source and destination are the same, no need to copy anything. */
2049 if (rtx_equal_p (x, y)
2050 && !MEM_VOLATILE_P (x)
2051 && !MEM_VOLATILE_P (y))
2052 return 0;
2053
2054 /* Set MEM_SIZE as appropriate for this block copy. The main place this
2055 can be incorrect is coming from __builtin_memcpy. */
2056 poly_int64 const_size;
2057 if (poly_int_rtx_p (x: size, res: &const_size))
2058 {
2059 x = shallow_copy_rtx (x);
2060 y = shallow_copy_rtx (y);
2061 set_mem_size (x, const_size);
2062 set_mem_size (y, const_size);
2063 }
2064
2065 bool pieces_ok = CONST_INT_P (size)
2066 && can_move_by_pieces (INTVAL (size), align);
2067 bool pattern_ok = false;
2068
2069 if (!pieces_ok || might_overlap)
2070 {
2071 pattern_ok
2072 = emit_block_move_via_pattern (x, y, size, align,
2073 expected_align, expected_size,
2074 min_size, max_size, probable_max_size,
2075 might_overlap);
2076 if (!pattern_ok && might_overlap)
2077 {
2078 /* Do not try any of the other methods below as they are not safe
2079 for overlapping moves. */
2080 *is_move_done = false;
2081 return retval;
2082 }
2083 }
2084
2085 if (pattern_ok)
2086 ;
2087 else if (pieces_ok)
2088 move_by_pieces (to: x, from: y, INTVAL (size), align, retmode: RETURN_BEGIN);
2089 else if (may_use_call && !might_overlap
2090 && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2091 && ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (y)))
2092 {
2093 if (bail_out_libcall)
2094 {
2095 if (is_move_done)
2096 *is_move_done = false;
2097 return retval;
2098 }
2099
2100 if (may_use_call < 0)
2101 return pc_rtx;
2102
2103 retval = emit_block_copy_via_libcall (dst: x, src: y, size,
2104 tailcall: method == BLOCK_OP_TAILCALL);
2105 }
2106 else if (might_overlap)
2107 *is_move_done = false;
2108 else
2109 emit_block_move_via_loop (x, y, size, align);
2110
2111 if (method == BLOCK_OP_CALL_PARM)
2112 OK_DEFER_POP;
2113
2114 return retval;
2115}
2116
2117rtx
2118emit_block_move (rtx x, rtx y, rtx size, enum block_op_methods method)
2119{
2120 unsigned HOST_WIDE_INT max, min = 0;
2121 if (GET_CODE (size) == CONST_INT)
2122 min = max = UINTVAL (size);
2123 else
2124 max = GET_MODE_MASK (GET_MODE (size));
2125 return emit_block_move_hints (x, y, size, method, expected_align: 0, expected_size: -1,
2126 min_size: min, max_size: max, probable_max_size: max);
2127}
2128
2129/* A subroutine of emit_block_move. Returns true if calling the
2130 block move libcall will not clobber any parameters which may have
2131 already been placed on the stack. */
2132
2133static bool
2134block_move_libcall_safe_for_call_parm (void)
2135{
2136 tree fn;
2137
2138 /* If arguments are pushed on the stack, then they're safe. */
2139 if (targetm.calls.push_argument (0))
2140 return true;
2141
2142 /* If registers go on the stack anyway, any argument is sure to clobber
2143 an outgoing argument. */
2144#if defined (REG_PARM_STACK_SPACE)
2145 fn = builtin_decl_implicit (fncode: BUILT_IN_MEMCPY);
2146 /* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't
2147 depend on its argument. */
2148 (void) fn;
2149 if (OUTGOING_REG_PARM_STACK_SPACE ((!fn ? NULL_TREE : TREE_TYPE (fn)))
2150 && REG_PARM_STACK_SPACE (fn) != 0)
2151 return false;
2152#endif
2153
2154 /* If any argument goes in memory, then it might clobber an outgoing
2155 argument. */
2156 {
2157 CUMULATIVE_ARGS args_so_far_v;
2158 cumulative_args_t args_so_far;
2159 tree arg;
2160
2161 fn = builtin_decl_implicit (fncode: BUILT_IN_MEMCPY);
2162 INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3);
2163 args_so_far = pack_cumulative_args (arg: &args_so_far_v);
2164
2165 arg = TYPE_ARG_TYPES (TREE_TYPE (fn));
2166 for ( ; arg != void_list_node ; arg = TREE_CHAIN (arg))
2167 {
2168 machine_mode mode = TYPE_MODE (TREE_VALUE (arg));
2169 function_arg_info arg_info (mode, /*named=*/true);
2170 rtx tmp = targetm.calls.function_arg (args_so_far, arg_info);
2171 if (!tmp || !REG_P (tmp))
2172 return false;
2173 if (targetm.calls.arg_partial_bytes (args_so_far, arg_info))
2174 return false;
2175 targetm.calls.function_arg_advance (args_so_far, arg_info);
2176 }
2177 }
2178 return true;
2179}
2180
2181/* A subroutine of emit_block_move. Expand a cpymem or movmem pattern;
2182 return true if successful.
2183
2184 X is the destination of the copy or move.
2185 Y is the source of the copy or move.
2186 SIZE is the size of the block to be moved.
2187
2188 MIGHT_OVERLAP indicates this originated with expansion of a
2189 builtin_memmove() and the source and destination blocks may
2190 overlap.
2191 */
2192
2193static bool
2194emit_block_move_via_pattern (rtx x, rtx y, rtx size, unsigned int align,
2195 unsigned int expected_align,
2196 HOST_WIDE_INT expected_size,
2197 unsigned HOST_WIDE_INT min_size,
2198 unsigned HOST_WIDE_INT max_size,
2199 unsigned HOST_WIDE_INT probable_max_size,
2200 bool might_overlap)
2201{
2202 if (expected_align < align)
2203 expected_align = align;
2204 if (expected_size != -1)
2205 {
2206 if ((unsigned HOST_WIDE_INT)expected_size > probable_max_size)
2207 expected_size = probable_max_size;
2208 if ((unsigned HOST_WIDE_INT)expected_size < min_size)
2209 expected_size = min_size;
2210 }
2211
2212 /* Since this is a move insn, we don't care about volatility. */
2213 temporary_volatile_ok v (true);
2214
2215 /* Try the most limited insn first, because there's no point
2216 including more than one in the machine description unless
2217 the more limited one has some advantage. */
2218
2219 opt_scalar_int_mode mode_iter;
2220 FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
2221 {
2222 scalar_int_mode mode = mode_iter.require ();
2223 enum insn_code code;
2224 if (might_overlap)
2225 code = direct_optab_handler (op: movmem_optab, mode);
2226 else
2227 code = direct_optab_handler (op: cpymem_optab, mode);
2228
2229 if (code != CODE_FOR_nothing
2230 /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
2231 here because if SIZE is less than the mode mask, as it is
2232 returned by the macro, it will definitely be less than the
2233 actual mode mask. Since SIZE is within the Pmode address
2234 space, we limit MODE to Pmode. */
2235 && ((CONST_INT_P (size)
2236 && ((unsigned HOST_WIDE_INT) INTVAL (size)
2237 <= (GET_MODE_MASK (mode) >> 1)))
2238 || max_size <= (GET_MODE_MASK (mode) >> 1)
2239 || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
2240 {
2241 class expand_operand ops[9];
2242 unsigned int nops;
2243
2244 /* ??? When called via emit_block_move_for_call, it'd be
2245 nice if there were some way to inform the backend, so
2246 that it doesn't fail the expansion because it thinks
2247 emitting the libcall would be more efficient. */
2248 nops = insn_data[(int) code].n_generator_args;
2249 gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
2250
2251 create_fixed_operand (op: &ops[0], x);
2252 create_fixed_operand (op: &ops[1], x: y);
2253 /* The check above guarantees that this size conversion is valid. */
2254 create_convert_operand_to (op: &ops[2], value: size, mode, unsigned_p: true);
2255 create_integer_operand (&ops[3], align / BITS_PER_UNIT);
2256 if (nops >= 6)
2257 {
2258 create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
2259 create_integer_operand (&ops[5], expected_size);
2260 }
2261 if (nops >= 8)
2262 {
2263 create_integer_operand (&ops[6], min_size);
2264 /* If we cannot represent the maximal size,
2265 make parameter NULL. */
2266 if ((HOST_WIDE_INT) max_size != -1)
2267 create_integer_operand (&ops[7], max_size);
2268 else
2269 create_fixed_operand (op: &ops[7], NULL);
2270 }
2271 if (nops == 9)
2272 {
2273 /* If we cannot represent the maximal size,
2274 make parameter NULL. */
2275 if ((HOST_WIDE_INT) probable_max_size != -1)
2276 create_integer_operand (&ops[8], probable_max_size);
2277 else
2278 create_fixed_operand (op: &ops[8], NULL);
2279 }
2280 if (maybe_expand_insn (icode: code, nops, ops))
2281 return true;
2282 }
2283 }
2284
2285 return false;
2286}
2287
2288/* A subroutine of emit_block_move. Copy the data via an explicit
2289 loop. This is used only when libcalls are forbidden. */
2290/* ??? It'd be nice to copy in hunks larger than QImode. */
2291
2292static void
2293emit_block_move_via_loop (rtx x, rtx y, rtx size,
2294 unsigned int align ATTRIBUTE_UNUSED)
2295{
2296 rtx_code_label *cmp_label, *top_label;
2297 rtx iter, x_addr, y_addr, tmp;
2298 machine_mode x_addr_mode = get_address_mode (mem: x);
2299 machine_mode y_addr_mode = get_address_mode (mem: y);
2300 machine_mode iter_mode;
2301
2302 iter_mode = GET_MODE (size);
2303 if (iter_mode == VOIDmode)
2304 iter_mode = word_mode;
2305
2306 top_label = gen_label_rtx ();
2307 cmp_label = gen_label_rtx ();
2308 iter = gen_reg_rtx (iter_mode);
2309
2310 emit_move_insn (iter, const0_rtx);
2311
2312 x_addr = force_operand (XEXP (x, 0), NULL_RTX);
2313 y_addr = force_operand (XEXP (y, 0), NULL_RTX);
2314 do_pending_stack_adjust ();
2315
2316 emit_jump (cmp_label);
2317 emit_label (top_label);
2318
2319 tmp = convert_modes (mode: x_addr_mode, oldmode: iter_mode, x: iter, unsignedp: true);
2320 x_addr = simplify_gen_binary (code: PLUS, mode: x_addr_mode, op0: x_addr, op1: tmp);
2321
2322 if (x_addr_mode != y_addr_mode)
2323 tmp = convert_modes (mode: y_addr_mode, oldmode: iter_mode, x: iter, unsignedp: true);
2324 y_addr = simplify_gen_binary (code: PLUS, mode: y_addr_mode, op0: y_addr, op1: tmp);
2325
2326 x = change_address (x, QImode, x_addr);
2327 y = change_address (y, QImode, y_addr);
2328
2329 emit_move_insn (x, y);
2330
2331 tmp = expand_simple_binop (iter_mode, PLUS, iter, const1_rtx, iter,
2332 true, OPTAB_LIB_WIDEN);
2333 if (tmp != iter)
2334 emit_move_insn (iter, tmp);
2335
2336 emit_label (cmp_label);
2337
2338 emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
2339 true, top_label,
2340 prob: profile_probability::guessed_always ()
2341 .apply_scale (num: 9, den: 10));
2342}
2343
2344/* Expand a call to memcpy or memmove or memcmp, and return the result.
2345 TAILCALL is true if this is a tail call. */
2346
2347rtx
2348emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src,
2349 rtx size, bool tailcall)
2350{
2351 rtx dst_addr, src_addr;
2352 tree call_expr, dst_tree, src_tree, size_tree;
2353 machine_mode size_mode;
2354
2355 /* Since dst and src are passed to a libcall, mark the corresponding
2356 tree EXPR as addressable. */
2357 tree dst_expr = MEM_EXPR (dst);
2358 tree src_expr = MEM_EXPR (src);
2359 if (dst_expr)
2360 mark_addressable (dst_expr);
2361 if (src_expr)
2362 mark_addressable (src_expr);
2363
2364 dst_addr = copy_addr_to_reg (XEXP (dst, 0));
2365 dst_addr = convert_memory_address (ptr_mode, dst_addr);
2366 dst_tree = make_tree (ptr_type_node, dst_addr);
2367
2368 src_addr = copy_addr_to_reg (XEXP (src, 0));
2369 src_addr = convert_memory_address (ptr_mode, src_addr);
2370 src_tree = make_tree (ptr_type_node, src_addr);
2371
2372 size_mode = TYPE_MODE (sizetype);
2373 size = convert_to_mode (mode: size_mode, x: size, unsignedp: 1);
2374 size = copy_to_mode_reg (size_mode, size);
2375 size_tree = make_tree (sizetype, size);
2376
2377 /* It is incorrect to use the libcall calling conventions for calls to
2378 memcpy/memmove/memcmp because they can be provided by the user. */
2379 tree fn = builtin_decl_implicit (fncode);
2380 call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
2381 CALL_EXPR_TAILCALL (call_expr) = tailcall;
2382
2383 return expand_call (call_expr, NULL_RTX, false);
2384}
2385
2386/* Try to expand cmpstrn or cmpmem operation ICODE with the given operands.
2387 ARG3_TYPE is the type of ARG3_RTX. Return the result rtx on success,
2388 otherwise return null. */
2389
2390rtx
2391expand_cmpstrn_or_cmpmem (insn_code icode, rtx target, rtx arg1_rtx,
2392 rtx arg2_rtx, tree arg3_type, rtx arg3_rtx,
2393 HOST_WIDE_INT align)
2394{
2395 machine_mode insn_mode = insn_data[icode].operand[0].mode;
2396
2397 if (target && (!REG_P (target) || HARD_REGISTER_P (target)))
2398 target = NULL_RTX;
2399
2400 class expand_operand ops[5];
2401 create_output_operand (op: &ops[0], x: target, mode: insn_mode);
2402 create_fixed_operand (op: &ops[1], x: arg1_rtx);
2403 create_fixed_operand (op: &ops[2], x: arg2_rtx);
2404 create_convert_operand_from (op: &ops[3], value: arg3_rtx, TYPE_MODE (arg3_type),
2405 TYPE_UNSIGNED (arg3_type));
2406 create_integer_operand (&ops[4], align);
2407 if (maybe_expand_insn (icode, nops: 5, ops))
2408 return ops[0].value;
2409 return NULL_RTX;
2410}
2411
2412/* Expand a block compare between X and Y with length LEN using the
2413 cmpmem optab, placing the result in TARGET. LEN_TYPE is the type
2414 of the expression that was used to calculate the length. ALIGN
2415 gives the known minimum common alignment. */
2416
2417static rtx
2418emit_block_cmp_via_cmpmem (rtx x, rtx y, rtx len, tree len_type, rtx target,
2419 unsigned align)
2420{
2421 /* Note: The cmpstrnsi pattern, if it exists, is not suitable for
2422 implementing memcmp because it will stop if it encounters two
2423 zero bytes. */
2424 insn_code icode = direct_optab_handler (op: cmpmem_optab, SImode);
2425
2426 if (icode == CODE_FOR_nothing)
2427 return NULL_RTX;
2428
2429 return expand_cmpstrn_or_cmpmem (icode, target, arg1_rtx: x, arg2_rtx: y, arg3_type: len_type, arg3_rtx: len, align);
2430}
2431
2432/* Emit code to compare a block Y to a block X. This may be done with
2433 string-compare instructions, with multiple scalar instructions,
2434 or with a library call.
2435
2436 Both X and Y must be MEM rtx's. LEN is an rtx that says how long
2437 they are. LEN_TYPE is the type of the expression that was used to
2438 calculate it.
2439
2440 If EQUALITY_ONLY is true, it means we don't have to return the tri-state
2441 value of a normal memcmp call, instead we can just compare for equality.
2442 If FORCE_LIBCALL is true, we should emit a call to memcmp rather than
2443 returning NULL_RTX.
2444
2445 Optionally, the caller can pass a constfn and associated data in Y_CFN
2446 and Y_CFN_DATA. describing that the second operand being compared is a
2447 known constant and how to obtain its data.
2448 Return the result of the comparison, or NULL_RTX if we failed to
2449 perform the operation. */
2450
2451rtx
2452emit_block_cmp_hints (rtx x, rtx y, rtx len, tree len_type, rtx target,
2453 bool equality_only, by_pieces_constfn y_cfn,
2454 void *y_cfndata)
2455{
2456 rtx result = 0;
2457
2458 if (CONST_INT_P (len) && INTVAL (len) == 0)
2459 return const0_rtx;
2460
2461 gcc_assert (MEM_P (x) && MEM_P (y));
2462 unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y));
2463 gcc_assert (align >= BITS_PER_UNIT);
2464
2465 x = adjust_address (x, BLKmode, 0);
2466 y = adjust_address (y, BLKmode, 0);
2467
2468 if (equality_only
2469 && CONST_INT_P (len)
2470 && can_do_by_pieces (INTVAL (len), align, op: COMPARE_BY_PIECES))
2471 result = compare_by_pieces (arg0: x, arg1: y, INTVAL (len), target, align,
2472 a1_cfn: y_cfn, a1_cfn_data: y_cfndata);
2473 else
2474 result = emit_block_cmp_via_cmpmem (x, y, len, len_type, target, align);
2475
2476 return result;
2477}
2478
2479/* Copy all or part of a value X into registers starting at REGNO.
2480 The number of registers to be filled is NREGS. */
2481
2482void
2483move_block_to_reg (int regno, rtx x, int nregs, machine_mode mode)
2484{
2485 if (nregs == 0)
2486 return;
2487
2488 if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
2489 x = validize_mem (force_const_mem (mode, x));
2490
2491 /* See if the machine can do this with a load multiple insn. */
2492 if (targetm.have_load_multiple ())
2493 {
2494 rtx_insn *last = get_last_insn ();
2495 rtx first = gen_rtx_REG (word_mode, regno);
2496 if (rtx_insn *pat = targetm.gen_load_multiple (first, x,
2497 GEN_INT (nregs)))
2498 {
2499 emit_insn (pat);
2500 return;
2501 }
2502 else
2503 delete_insns_since (last);
2504 }
2505
2506 for (int i = 0; i < nregs; i++)
2507 emit_move_insn (gen_rtx_REG (word_mode, regno + i),
2508 operand_subword_force (x, i, mode));
2509}
2510
2511/* Copy all or part of a BLKmode value X out of registers starting at REGNO.
2512 The number of registers to be filled is NREGS. */
2513
2514void
2515move_block_from_reg (int regno, rtx x, int nregs)
2516{
2517 if (nregs == 0)
2518 return;
2519
2520 /* See if the machine can do this with a store multiple insn. */
2521 if (targetm.have_store_multiple ())
2522 {
2523 rtx_insn *last = get_last_insn ();
2524 rtx first = gen_rtx_REG (word_mode, regno);
2525 if (rtx_insn *pat = targetm.gen_store_multiple (x, first,
2526 GEN_INT (nregs)))
2527 {
2528 emit_insn (pat);
2529 return;
2530 }
2531 else
2532 delete_insns_since (last);
2533 }
2534
2535 for (int i = 0; i < nregs; i++)
2536 {
2537 rtx tem = operand_subword (x, i, 1, BLKmode);
2538
2539 gcc_assert (tem);
2540
2541 emit_move_insn (tem, gen_rtx_REG (word_mode, regno + i));
2542 }
2543}
2544
2545/* Generate a PARALLEL rtx for a new non-consecutive group of registers from
2546 ORIG, where ORIG is a non-consecutive group of registers represented by
2547 a PARALLEL. The clone is identical to the original except in that the
2548 original set of registers is replaced by a new set of pseudo registers.
2549 The new set has the same modes as the original set. */
2550
2551rtx
2552gen_group_rtx (rtx orig)
2553{
2554 int i, length;
2555 rtx *tmps;
2556
2557 gcc_assert (GET_CODE (orig) == PARALLEL);
2558
2559 length = XVECLEN (orig, 0);
2560 tmps = XALLOCAVEC (rtx, length);
2561
2562 /* Skip a NULL entry in first slot. */
2563 i = XEXP (XVECEXP (orig, 0, 0), 0) ? 0 : 1;
2564
2565 if (i)
2566 tmps[0] = 0;
2567
2568 for (; i < length; i++)
2569 {
2570 machine_mode mode = GET_MODE (XEXP (XVECEXP (orig, 0, i), 0));
2571 rtx offset = XEXP (XVECEXP (orig, 0, i), 1);
2572
2573 tmps[i] = gen_rtx_EXPR_LIST (VOIDmode, gen_reg_rtx (mode), offset);
2574 }
2575
2576 return gen_rtx_PARALLEL (GET_MODE (orig), gen_rtvec_v (length, tmps));
2577}
2578
2579/* A subroutine of emit_group_load. Arguments as for emit_group_load,
2580 except that values are placed in TMPS[i], and must later be moved
2581 into corresponding XEXP (XVECEXP (DST, 0, i), 0) element. */
2582
2583static void
2584emit_group_load_1 (rtx *tmps, rtx dst, rtx orig_src, tree type,
2585 poly_int64 ssize)
2586{
2587 rtx src;
2588 int start, i;
2589 machine_mode m = GET_MODE (orig_src);
2590
2591 gcc_assert (GET_CODE (dst) == PARALLEL);
2592
2593 if (m != VOIDmode
2594 && !SCALAR_INT_MODE_P (m)
2595 && !MEM_P (orig_src)
2596 && GET_CODE (orig_src) != CONCAT)
2597 {
2598 scalar_int_mode imode;
2599 if (int_mode_for_mode (GET_MODE (orig_src)).exists (mode: &imode))
2600 {
2601 src = gen_reg_rtx (imode);
2602 emit_move_insn (gen_lowpart (GET_MODE (orig_src), src), orig_src);
2603 }
2604 else
2605 {
2606 src = assign_stack_temp (GET_MODE (orig_src), ssize);
2607 emit_move_insn (src, orig_src);
2608 }
2609 emit_group_load_1 (tmps, dst, orig_src: src, type, ssize);
2610 return;
2611 }
2612
2613 /* Check for a NULL entry, used to indicate that the parameter goes
2614 both on the stack and in registers. */
2615 if (XEXP (XVECEXP (dst, 0, 0), 0))
2616 start = 0;
2617 else
2618 start = 1;
2619
2620 /* Process the pieces. */
2621 for (i = start; i < XVECLEN (dst, 0); i++)
2622 {
2623 machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
2624 poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (dst, 0, i), 1));
2625 poly_int64 bytelen = GET_MODE_SIZE (mode);
2626 poly_int64 shift = 0;
2627
2628 /* Handle trailing fragments that run over the size of the struct.
2629 It's the target's responsibility to make sure that the fragment
2630 cannot be strictly smaller in some cases and strictly larger
2631 in others. */
2632 gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
2633 if (known_size_p (a: ssize) && maybe_gt (bytepos + bytelen, ssize))
2634 {
2635 /* Arrange to shift the fragment to where it belongs.
2636 extract_bit_field loads to the lsb of the reg. */
2637 if (
2638#ifdef BLOCK_REG_PADDING
2639 BLOCK_REG_PADDING (GET_MODE (orig_src), type, i == start)
2640 == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
2641#else
2642 BYTES_BIG_ENDIAN
2643#endif
2644 )
2645 shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
2646 bytelen = ssize - bytepos;
2647 gcc_assert (maybe_gt (bytelen, 0));
2648 }
2649
2650 /* If we won't be loading directly from memory, protect the real source
2651 from strange tricks we might play; but make sure that the source can
2652 be loaded directly into the destination. */
2653 src = orig_src;
2654 if (!MEM_P (orig_src)
2655 && (!REG_P (orig_src) || HARD_REGISTER_P (orig_src))
2656 && !CONSTANT_P (orig_src))
2657 {
2658 gcc_assert (GET_MODE (orig_src) != VOIDmode);
2659 src = force_reg (GET_MODE (orig_src), orig_src);
2660 }
2661
2662 /* Optimize the access just a bit. */
2663 if (MEM_P (src)
2664 && (! targetm.slow_unaligned_access (mode, MEM_ALIGN (src))
2665 || MEM_ALIGN (src) >= GET_MODE_ALIGNMENT (mode))
2666 && multiple_p (a: bytepos * BITS_PER_UNIT, GET_MODE_ALIGNMENT (mode))
2667 && known_eq (bytelen, GET_MODE_SIZE (mode)))
2668 {
2669 tmps[i] = gen_reg_rtx (mode);
2670 emit_move_insn (tmps[i], adjust_address (src, mode, bytepos));
2671 }
2672 else if (COMPLEX_MODE_P (mode)
2673 && GET_MODE (src) == mode
2674 && known_eq (bytelen, GET_MODE_SIZE (mode)))
2675 /* Let emit_move_complex do the bulk of the work. */
2676 tmps[i] = src;
2677 else if (GET_CODE (src) == CONCAT)
2678 {
2679 poly_int64 slen = GET_MODE_SIZE (GET_MODE (src));
2680 poly_int64 slen0 = GET_MODE_SIZE (GET_MODE (XEXP (src, 0)));
2681 unsigned int elt;
2682 poly_int64 subpos;
2683
2684 if (can_div_trunc_p (a: bytepos, b: slen0, quotient: &elt, remainder: &subpos)
2685 && known_le (subpos + bytelen, slen0))
2686 {
2687 /* The following assumes that the concatenated objects all
2688 have the same size. In this case, a simple calculation
2689 can be used to determine the object and the bit field
2690 to be extracted. */
2691 tmps[i] = XEXP (src, elt);
2692 if (maybe_ne (a: subpos, b: 0)
2693 || maybe_ne (a: subpos + bytelen, b: slen0)
2694 || (!CONSTANT_P (tmps[i])
2695 && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)))
2696 tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT,
2697 subpos * BITS_PER_UNIT,
2698 1, NULL_RTX, mode, mode, false,
2699 NULL);
2700 }
2701 else
2702 {
2703 rtx mem;
2704
2705 gcc_assert (known_eq (bytepos, 0));
2706 mem = assign_stack_temp (GET_MODE (src), slen);
2707 emit_move_insn (mem, src);
2708 tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT,
2709 0, 1, NULL_RTX, mode, mode, false,
2710 NULL);
2711 }
2712 }
2713 else if (CONSTANT_P (src) && GET_MODE (dst) != BLKmode
2714 && XVECLEN (dst, 0) > 1)
2715 tmps[i] = simplify_gen_subreg (outermode: mode, op: src, GET_MODE (dst), byte: bytepos);
2716 else if (CONSTANT_P (src))
2717 {
2718 if (known_eq (bytelen, ssize))
2719 tmps[i] = src;
2720 else
2721 {
2722 rtx first, second;
2723
2724 /* TODO: const_wide_int can have sizes other than this... */
2725 gcc_assert (known_eq (2 * bytelen, ssize));
2726 split_double (src, &first, &second);
2727 if (i)
2728 tmps[i] = second;
2729 else
2730 tmps[i] = first;
2731 }
2732 }
2733 else if (REG_P (src) && GET_MODE (src) == mode)
2734 tmps[i] = src;
2735 else
2736 tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
2737 bytepos * BITS_PER_UNIT, 1, NULL_RTX,
2738 mode, mode, false, NULL);
2739
2740 if (maybe_ne (a: shift, b: 0))
2741 tmps[i] = expand_shift (LSHIFT_EXPR, mode, tmps[i],
2742 shift, tmps[i], 0);
2743 }
2744}
2745
2746/* Emit code to move a block SRC of type TYPE to a block DST,
2747 where DST is non-consecutive registers represented by a PARALLEL.
2748 SSIZE represents the total size of block ORIG_SRC in bytes, or -1
2749 if not known. */
2750
2751void
2752emit_group_load (rtx dst, rtx src, tree type, poly_int64 ssize)
2753{
2754 rtx *tmps;
2755 int i;
2756
2757 tmps = XALLOCAVEC (rtx, XVECLEN (dst, 0));
2758 emit_group_load_1 (tmps, dst, orig_src: src, type, ssize);
2759
2760 /* Copy the extracted pieces into the proper (probable) hard regs. */
2761 for (i = 0; i < XVECLEN (dst, 0); i++)
2762 {
2763 rtx d = XEXP (XVECEXP (dst, 0, i), 0);
2764 if (d == NULL)
2765 continue;
2766 emit_move_insn (d, tmps[i]);
2767 }
2768}
2769
2770/* Similar, but load SRC into new pseudos in a format that looks like
2771 PARALLEL. This can later be fed to emit_group_move to get things
2772 in the right place. */
2773
2774rtx
2775emit_group_load_into_temps (rtx parallel, rtx src, tree type, poly_int64 ssize)
2776{
2777 rtvec vec;
2778 int i;
2779
2780 vec = rtvec_alloc (XVECLEN (parallel, 0));
2781 emit_group_load_1 (tmps: &RTVEC_ELT (vec, 0), dst: parallel, orig_src: src, type, ssize);
2782
2783 /* Convert the vector to look just like the original PARALLEL, except
2784 with the computed values. */
2785 for (i = 0; i < XVECLEN (parallel, 0); i++)
2786 {
2787 rtx e = XVECEXP (parallel, 0, i);
2788 rtx d = XEXP (e, 0);
2789
2790 if (d)
2791 {
2792 d = force_reg (GET_MODE (d), RTVEC_ELT (vec, i));
2793 e = alloc_EXPR_LIST (REG_NOTE_KIND (e), d, XEXP (e, 1));
2794 }
2795 RTVEC_ELT (vec, i) = e;
2796 }
2797
2798 return gen_rtx_PARALLEL (GET_MODE (parallel), vec);
2799}
2800
2801/* Emit code to move a block SRC to block DST, where SRC and DST are
2802 non-consecutive groups of registers, each represented by a PARALLEL. */
2803
2804void
2805emit_group_move (rtx dst, rtx src)
2806{
2807 int i;
2808
2809 gcc_assert (GET_CODE (src) == PARALLEL
2810 && GET_CODE (dst) == PARALLEL
2811 && XVECLEN (src, 0) == XVECLEN (dst, 0));
2812
2813 /* Skip first entry if NULL. */
2814 for (i = XEXP (XVECEXP (src, 0, 0), 0) ? 0 : 1; i < XVECLEN (src, 0); i++)
2815 emit_move_insn (XEXP (XVECEXP (dst, 0, i), 0),
2816 XEXP (XVECEXP (src, 0, i), 0));
2817}
2818
2819/* Move a group of registers represented by a PARALLEL into pseudos. */
2820
2821rtx
2822emit_group_move_into_temps (rtx src)
2823{
2824 rtvec vec = rtvec_alloc (XVECLEN (src, 0));
2825 int i;
2826
2827 for (i = 0; i < XVECLEN (src, 0); i++)
2828 {
2829 rtx e = XVECEXP (src, 0, i);
2830 rtx d = XEXP (e, 0);
2831
2832 if (d)
2833 e = alloc_EXPR_LIST (REG_NOTE_KIND (e), copy_to_reg (d), XEXP (e, 1));
2834 RTVEC_ELT (vec, i) = e;
2835 }
2836
2837 return gen_rtx_PARALLEL (GET_MODE (src), vec);
2838}
2839
2840/* Emit code to move a block SRC to a block ORIG_DST of type TYPE,
2841 where SRC is non-consecutive registers represented by a PARALLEL.
2842 SSIZE represents the total size of block ORIG_DST, or -1 if not
2843 known. */
2844
2845void
2846emit_group_store (rtx orig_dst, rtx src, tree type ATTRIBUTE_UNUSED,
2847 poly_int64 ssize)
2848{
2849 rtx *tmps, dst;
2850 int start, finish, i;
2851 machine_mode m = GET_MODE (orig_dst);
2852
2853 gcc_assert (GET_CODE (src) == PARALLEL);
2854
2855 if (!SCALAR_INT_MODE_P (m)
2856 && !MEM_P (orig_dst) && GET_CODE (orig_dst) != CONCAT)
2857 {
2858 scalar_int_mode imode;
2859 if (int_mode_for_mode (GET_MODE (orig_dst)).exists (mode: &imode))
2860 {
2861 dst = gen_reg_rtx (imode);
2862 emit_group_store (orig_dst: dst, src, type, ssize);
2863 dst = gen_lowpart (GET_MODE (orig_dst), dst);
2864 }
2865 else
2866 {
2867 dst = assign_stack_temp (GET_MODE (orig_dst), ssize);
2868 emit_group_store (orig_dst: dst, src, type, ssize);
2869 }
2870 emit_move_insn (orig_dst, dst);
2871 return;
2872 }
2873
2874 /* Check for a NULL entry, used to indicate that the parameter goes
2875 both on the stack and in registers. */
2876 if (XEXP (XVECEXP (src, 0, 0), 0))
2877 start = 0;
2878 else
2879 start = 1;
2880 finish = XVECLEN (src, 0);
2881
2882 tmps = XALLOCAVEC (rtx, finish);
2883
2884 /* Copy the (probable) hard regs into pseudos. */
2885 for (i = start; i < finish; i++)
2886 {
2887 rtx reg = XEXP (XVECEXP (src, 0, i), 0);
2888 if (!REG_P (reg) || REGNO (reg) < FIRST_PSEUDO_REGISTER)
2889 {
2890 tmps[i] = gen_reg_rtx (GET_MODE (reg));
2891 emit_move_insn (tmps[i], reg);
2892 }
2893 else
2894 tmps[i] = reg;
2895 }
2896
2897 /* If we won't be storing directly into memory, protect the real destination
2898 from strange tricks we might play. */
2899 dst = orig_dst;
2900 if (GET_CODE (dst) == PARALLEL)
2901 {
2902 rtx temp;
2903
2904 /* We can get a PARALLEL dst if there is a conditional expression in
2905 a return statement. In that case, the dst and src are the same,
2906 so no action is necessary. */
2907 if (rtx_equal_p (dst, src))
2908 return;
2909
2910 /* It is unclear if we can ever reach here, but we may as well handle
2911 it. Allocate a temporary, and split this into a store/load to/from
2912 the temporary. */
2913 temp = assign_stack_temp (GET_MODE (dst), ssize);
2914 emit_group_store (orig_dst: temp, src, type, ssize);
2915 emit_group_load (dst, src: temp, type, ssize);
2916 return;
2917 }
2918 else if (!MEM_P (dst) && GET_CODE (dst) != CONCAT)
2919 {
2920 machine_mode outer = GET_MODE (dst);
2921 machine_mode inner;
2922 poly_int64 bytepos;
2923 bool done = false;
2924 rtx temp;
2925
2926 if (!REG_P (dst) || REGNO (dst) < FIRST_PSEUDO_REGISTER)
2927 dst = gen_reg_rtx (outer);
2928
2929 /* Make life a bit easier for combine: if the first element of the
2930 vector is the low part of the destination mode, use a paradoxical
2931 subreg to initialize the destination. */
2932 if (start < finish)
2933 {
2934 inner = GET_MODE (tmps[start]);
2935 bytepos = subreg_lowpart_offset (outermode: inner, innermode: outer);
2936 if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, start), 1)),
2937 bytepos))
2938 {
2939 temp = simplify_gen_subreg (outermode: outer, op: tmps[start], innermode: inner, byte: 0);
2940 if (temp)
2941 {
2942 emit_move_insn (dst, temp);
2943 done = true;
2944 start++;
2945 }
2946 }
2947 }
2948
2949 /* If the first element wasn't the low part, try the last. */
2950 if (!done
2951 && start < finish - 1)
2952 {
2953 inner = GET_MODE (tmps[finish - 1]);
2954 bytepos = subreg_lowpart_offset (outermode: inner, innermode: outer);
2955 if (known_eq (rtx_to_poly_int64 (XEXP (XVECEXP (src, 0,
2956 finish - 1), 1)),
2957 bytepos))
2958 {
2959 temp = simplify_gen_subreg (outermode: outer, op: tmps[finish - 1], innermode: inner, byte: 0);
2960 if (temp)
2961 {
2962 emit_move_insn (dst, temp);
2963 done = true;
2964 finish--;
2965 }
2966 }
2967 }
2968
2969 /* Otherwise, simply initialize the result to zero. */
2970 if (!done)
2971 emit_move_insn (dst, CONST0_RTX (outer));
2972 }
2973
2974 /* Process the pieces. */
2975 for (i = start; i < finish; i++)
2976 {
2977 poly_int64 bytepos = rtx_to_poly_int64 (XEXP (XVECEXP (src, 0, i), 1));
2978 machine_mode mode = GET_MODE (tmps[i]);
2979 poly_int64 bytelen = GET_MODE_SIZE (mode);
2980 poly_uint64 adj_bytelen;
2981 rtx dest = dst;
2982
2983 /* Handle trailing fragments that run over the size of the struct.
2984 It's the target's responsibility to make sure that the fragment
2985 cannot be strictly smaller in some cases and strictly larger
2986 in others. */
2987 gcc_checking_assert (ordered_p (bytepos + bytelen, ssize));
2988 if (known_size_p (a: ssize) && maybe_gt (bytepos + bytelen, ssize))
2989 adj_bytelen = ssize - bytepos;
2990 else
2991 adj_bytelen = bytelen;
2992
2993 /* Deal with destination CONCATs by either storing into one of the parts
2994 or doing a copy after storing into a register or stack temporary. */
2995 if (GET_CODE (dst) == CONCAT)
2996 {
2997 if (known_le (bytepos + adj_bytelen,
2998 GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
2999 dest = XEXP (dst, 0);
3000
3001 else if (known_ge (bytepos, GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)))))
3002 {
3003 bytepos -= GET_MODE_SIZE (GET_MODE (XEXP (dst, 0)));
3004 dest = XEXP (dst, 1);
3005 }
3006
3007 else
3008 {
3009 machine_mode dest_mode = GET_MODE (dest);
3010 machine_mode tmp_mode = GET_MODE (tmps[i]);
3011 scalar_int_mode dest_imode;
3012
3013 gcc_assert (known_eq (bytepos, 0) && XVECLEN (src, 0));
3014
3015 /* If the source is a single scalar integer register, and the
3016 destination has a complex mode for which a same-sized integer
3017 mode exists, then we can take the left-justified part of the
3018 source in the complex mode. */
3019 if (finish == start + 1
3020 && REG_P (tmps[i])
3021 && SCALAR_INT_MODE_P (tmp_mode)
3022 && COMPLEX_MODE_P (dest_mode)
3023 && int_mode_for_mode (dest_mode).exists (mode: &dest_imode))
3024 {
3025 const scalar_int_mode tmp_imode
3026 = as_a <scalar_int_mode> (m: tmp_mode);
3027
3028 if (GET_MODE_BITSIZE (mode: dest_imode)
3029 < GET_MODE_BITSIZE (mode: tmp_imode))
3030 {
3031 dest = gen_reg_rtx (dest_imode);
3032 if (BYTES_BIG_ENDIAN)
3033 tmps[i] = expand_shift (RSHIFT_EXPR, tmp_mode, tmps[i],
3034 GET_MODE_BITSIZE (mode: tmp_imode)
3035 - GET_MODE_BITSIZE (mode: dest_imode),
3036 NULL_RTX, 1);
3037 emit_move_insn (dest, gen_lowpart (dest_imode, tmps[i]));
3038 dst = gen_lowpart (dest_mode, dest);
3039 }
3040 else
3041 dst = gen_lowpart (dest_mode, tmps[i]);
3042 }
3043
3044 /* Otherwise spill the source onto the stack using the more
3045 aligned of the two modes. */
3046 else if (GET_MODE_ALIGNMENT (dest_mode)
3047 >= GET_MODE_ALIGNMENT (tmp_mode))
3048 {
3049 dest = assign_stack_temp (dest_mode,
3050 GET_MODE_SIZE (mode: dest_mode));
3051 emit_move_insn (adjust_address (dest, tmp_mode, bytepos),
3052 tmps[i]);
3053 dst = dest;
3054 }
3055
3056 else
3057 {
3058 dest = assign_stack_temp (tmp_mode,
3059 GET_MODE_SIZE (mode: tmp_mode));
3060 emit_move_insn (dest, tmps[i]);
3061 dst = adjust_address (dest, dest_mode, bytepos);
3062 }
3063
3064 break;
3065 }
3066 }
3067
3068 /* Handle trailing fragments that run over the size of the struct. */
3069 if (known_size_p (a: ssize) && maybe_gt (bytepos + bytelen, ssize))
3070 {
3071 /* store_bit_field always takes its value from the lsb.
3072 Move the fragment to the lsb if it's not already there. */
3073 if (
3074#ifdef BLOCK_REG_PADDING
3075 BLOCK_REG_PADDING (GET_MODE (orig_dst), type, i == start)
3076 == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)
3077#else
3078 BYTES_BIG_ENDIAN
3079#endif
3080 )
3081 {
3082 poly_int64 shift = (bytelen - (ssize - bytepos)) * BITS_PER_UNIT;
3083 tmps[i] = expand_shift (RSHIFT_EXPR, mode, tmps[i],
3084 shift, tmps[i], 0);
3085 }
3086
3087 /* Make sure not to write past the end of the struct. */
3088 store_bit_field (dest,
3089 adj_bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3090 bytepos * BITS_PER_UNIT, ssize * BITS_PER_UNIT - 1,
3091 VOIDmode, tmps[i], false, false);
3092 }
3093
3094 /* Optimize the access just a bit. */
3095 else if (MEM_P (dest)
3096 && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (dest))
3097 || MEM_ALIGN (dest) >= GET_MODE_ALIGNMENT (mode))
3098 && multiple_p (a: bytepos * BITS_PER_UNIT,
3099 GET_MODE_ALIGNMENT (mode))
3100 && known_eq (bytelen, GET_MODE_SIZE (mode)))
3101 emit_move_insn (adjust_address (dest, mode, bytepos), tmps[i]);
3102
3103 else
3104 store_bit_field (dest, bytelen * BITS_PER_UNIT, bytepos * BITS_PER_UNIT,
3105 0, 0, mode, tmps[i], false, false);
3106 }
3107
3108 /* Copy from the pseudo into the (probable) hard reg. */
3109 if (orig_dst != dst)
3110 emit_move_insn (orig_dst, dst);
3111}
3112
3113/* Return a form of X that does not use a PARALLEL. TYPE is the type
3114 of the value stored in X. */
3115
3116rtx
3117maybe_emit_group_store (rtx x, tree type)
3118{
3119 machine_mode mode = TYPE_MODE (type);
3120 gcc_checking_assert (GET_MODE (x) == VOIDmode || GET_MODE (x) == mode);
3121 if (GET_CODE (x) == PARALLEL)
3122 {
3123 rtx result = gen_reg_rtx (mode);
3124 emit_group_store (orig_dst: result, src: x, type, ssize: int_size_in_bytes (type));
3125 return result;
3126 }
3127 return x;
3128}
3129
3130/* Copy a BLKmode object of TYPE out of a register SRCREG into TARGET.
3131
3132 This is used on targets that return BLKmode values in registers. */
3133
3134static void
3135copy_blkmode_from_reg (rtx target, rtx srcreg, tree type)
3136{
3137 unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
3138 rtx src = NULL, dst = NULL;
3139 unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
3140 unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0;
3141 /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3142 fixed_size_mode mode = as_a <fixed_size_mode> (GET_MODE (srcreg));
3143 fixed_size_mode tmode = as_a <fixed_size_mode> (GET_MODE (target));
3144 fixed_size_mode copy_mode;
3145
3146 /* BLKmode registers created in the back-end shouldn't have survived. */
3147 gcc_assert (mode != BLKmode);
3148
3149 /* If the structure doesn't take up a whole number of words, see whether
3150 SRCREG is padded on the left or on the right. If it's on the left,
3151 set PADDING_CORRECTION to the number of bits to skip.
3152
3153 In most ABIs, the structure will be returned at the least end of
3154 the register, which translates to right padding on little-endian
3155 targets and left padding on big-endian targets. The opposite
3156 holds if the structure is returned at the most significant
3157 end of the register. */
3158 if (bytes % UNITS_PER_WORD != 0
3159 && (targetm.calls.return_in_msb (type)
3160 ? !BYTES_BIG_ENDIAN
3161 : BYTES_BIG_ENDIAN))
3162 padding_correction
3163 = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD) * BITS_PER_UNIT));
3164
3165 /* We can use a single move if we have an exact mode for the size. */
3166 else if (MEM_P (target)
3167 && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (target))
3168 || MEM_ALIGN (target) >= GET_MODE_ALIGNMENT (mode))
3169 && bytes == GET_MODE_SIZE (mode))
3170 {
3171 emit_move_insn (adjust_address (target, mode, 0), srcreg);
3172 return;
3173 }
3174
3175 /* And if we additionally have the same mode for a register. */
3176 else if (REG_P (target)
3177 && GET_MODE (target) == mode
3178 && bytes == GET_MODE_SIZE (mode))
3179 {
3180 emit_move_insn (target, srcreg);
3181 return;
3182 }
3183
3184 /* This code assumes srcreg is at least a full word. If it isn't, copy it
3185 into a new pseudo which is a full word. */
3186 if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
3187 {
3188 srcreg = convert_to_mode (mode: word_mode, x: srcreg, TYPE_UNSIGNED (type));
3189 mode = word_mode;
3190 }
3191
3192 /* Copy the structure BITSIZE bits at a time. If the target lives in
3193 memory, take care of not reading/writing past its end by selecting
3194 a copy mode suited to BITSIZE. This should always be possible given
3195 how it is computed.
3196
3197 If the target lives in register, make sure not to select a copy mode
3198 larger than the mode of the register.
3199
3200 We could probably emit more efficient code for machines which do not use
3201 strict alignment, but it doesn't seem worth the effort at the current
3202 time. */
3203
3204 copy_mode = word_mode;
3205 if (MEM_P (target))
3206 {
3207 opt_scalar_int_mode mem_mode = int_mode_for_size (size: bitsize, limit: 1);
3208 if (mem_mode.exists ())
3209 copy_mode = mem_mode.require ();
3210 }
3211 else if (REG_P (target) && GET_MODE_BITSIZE (mode: tmode) < BITS_PER_WORD)
3212 copy_mode = tmode;
3213
3214 for (bitpos = 0, xbitpos = padding_correction;
3215 bitpos < bytes * BITS_PER_UNIT;
3216 bitpos += bitsize, xbitpos += bitsize)
3217 {
3218 /* We need a new source operand each time xbitpos is on a
3219 word boundary and when xbitpos == padding_correction
3220 (the first time through). */
3221 if (xbitpos % BITS_PER_WORD == 0 || xbitpos == padding_correction)
3222 src = operand_subword_force (srcreg, xbitpos / BITS_PER_WORD, mode);
3223
3224 /* We need a new destination operand each time bitpos is on
3225 a word boundary. */
3226 if (REG_P (target) && GET_MODE_BITSIZE (mode: tmode) < BITS_PER_WORD)
3227 dst = target;
3228 else if (bitpos % BITS_PER_WORD == 0)
3229 dst = operand_subword (target, bitpos / BITS_PER_WORD, 1, tmode);
3230
3231 /* Use xbitpos for the source extraction (right justified) and
3232 bitpos for the destination store (left justified). */
3233 store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, 0, 0, copy_mode,
3234 extract_bit_field (src, bitsize,
3235 xbitpos % BITS_PER_WORD, 1,
3236 NULL_RTX, copy_mode, copy_mode,
3237 false, NULL),
3238 false, false);
3239 }
3240}
3241
3242/* Copy BLKmode value SRC into a register of mode MODE_IN. Return the
3243 register if it contains any data, otherwise return null.
3244
3245 This is used on targets that return BLKmode values in registers. */
3246
3247rtx
3248copy_blkmode_to_reg (machine_mode mode_in, tree src)
3249{
3250 int i, n_regs;
3251 unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
3252 unsigned int bitsize;
3253 rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
3254 /* No current ABI uses variable-sized modes to pass a BLKmnode type. */
3255 fixed_size_mode mode = as_a <fixed_size_mode> (m: mode_in);
3256 fixed_size_mode dst_mode;
3257 scalar_int_mode min_mode;
3258
3259 gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
3260
3261 x = expand_normal (exp: src);
3262
3263 bytes = arg_int_size_in_bytes (TREE_TYPE (src));
3264 if (bytes == 0)
3265 return NULL_RTX;
3266
3267 /* If the structure doesn't take up a whole number of words, see
3268 whether the register value should be padded on the left or on
3269 the right. Set PADDING_CORRECTION to the number of padding
3270 bits needed on the left side.
3271
3272 In most ABIs, the structure will be returned at the least end of
3273 the register, which translates to right padding on little-endian
3274 targets and left padding on big-endian targets. The opposite
3275 holds if the structure is returned at the most significant
3276 end of the register. */
3277 if (bytes % UNITS_PER_WORD != 0
3278 && (targetm.calls.return_in_msb (TREE_TYPE (src))
3279 ? !BYTES_BIG_ENDIAN
3280 : BYTES_BIG_ENDIAN))
3281 padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
3282 * BITS_PER_UNIT));
3283
3284 n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
3285 dst_words = XALLOCAVEC (rtx, n_regs);
3286 bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
3287 min_mode = smallest_int_mode_for_size (size: bitsize);
3288
3289 /* Copy the structure BITSIZE bits at a time. */
3290 for (bitpos = 0, xbitpos = padding_correction;
3291 bitpos < bytes * BITS_PER_UNIT;
3292 bitpos += bitsize, xbitpos += bitsize)
3293 {
3294 /* We need a new destination pseudo each time xbitpos is
3295 on a word boundary and when xbitpos == padding_correction
3296 (the first time through). */
3297 if (xbitpos % BITS_PER_WORD == 0
3298 || xbitpos == padding_correction)
3299 {
3300 /* Generate an appropriate register. */
3301 dst_word = gen_reg_rtx (word_mode);
3302 dst_words[xbitpos / BITS_PER_WORD] = dst_word;
3303
3304 /* Clear the destination before we move anything into it. */
3305 emit_move_insn (dst_word, CONST0_RTX (word_mode));
3306 }
3307
3308 /* Find the largest integer mode that can be used to copy all or as
3309 many bits as possible of the structure if the target supports larger
3310 copies. There are too many corner cases here w.r.t to alignments on
3311 the read/writes. So if there is any padding just use single byte
3312 operations. */
3313 opt_scalar_int_mode mode_iter;
3314 if (padding_correction == 0 && !STRICT_ALIGNMENT)
3315 {
3316 FOR_EACH_MODE_FROM (mode_iter, min_mode)
3317 {
3318 unsigned int msize = GET_MODE_BITSIZE (mode: mode_iter.require ());
3319 if (msize <= ((bytes * BITS_PER_UNIT) - bitpos)
3320 && msize <= BITS_PER_WORD)
3321 bitsize = msize;
3322 else
3323 break;
3324 }
3325 }
3326
3327 /* We need a new source operand each time bitpos is on a word
3328 boundary. */
3329 if (bitpos % BITS_PER_WORD == 0)
3330 src_word = operand_subword_force (x, bitpos / BITS_PER_WORD, BLKmode);
3331
3332 /* Use bitpos for the source extraction (left justified) and
3333 xbitpos for the destination store (right justified). */
3334 store_bit_field (dst_word, bitsize, xbitpos % BITS_PER_WORD,
3335 0, 0, word_mode,
3336 extract_bit_field (src_word, bitsize,
3337 bitpos % BITS_PER_WORD, 1,
3338 NULL_RTX, word_mode, word_mode,
3339 false, NULL),
3340 false, false);
3341 }
3342
3343 if (mode == BLKmode)
3344 {
3345 /* Find the smallest integer mode large enough to hold the
3346 entire structure. */
3347 opt_scalar_int_mode mode_iter;
3348 FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
3349 if (GET_MODE_SIZE (mode: mode_iter.require ()) >= bytes)
3350 break;
3351
3352 /* A suitable mode should have been found. */
3353 mode = mode_iter.require ();
3354 }
3355
3356 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (mode: word_mode))
3357 dst_mode = word_mode;
3358 else
3359 dst_mode = mode;
3360 dst = gen_reg_rtx (dst_mode);
3361
3362 for (i = 0; i < n_regs; i++)
3363 emit_move_insn (operand_subword (dst, i, 0, dst_mode), dst_words[i]);
3364
3365 if (mode != dst_mode)
3366 dst = gen_lowpart (mode, dst);
3367
3368 return dst;
3369}
3370
3371/* Add a USE expression for REG to the (possibly empty) list pointed
3372 to by CALL_FUSAGE. REG must denote a hard register. */
3373
3374void
3375use_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3376{
3377 gcc_assert (REG_P (reg));
3378
3379 if (!HARD_REGISTER_P (reg))
3380 return;
3381
3382 *call_fusage
3383 = gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
3384}
3385
3386/* Add a CLOBBER expression for REG to the (possibly empty) list pointed
3387 to by CALL_FUSAGE. REG must denote a hard register. */
3388
3389void
3390clobber_reg_mode (rtx *call_fusage, rtx reg, machine_mode mode)
3391{
3392 gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
3393
3394 *call_fusage
3395 = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
3396}
3397
3398/* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
3399 starting at REGNO. All of these registers must be hard registers. */
3400
3401void
3402use_regs (rtx *call_fusage, int regno, int nregs)
3403{
3404 int i;
3405
3406 gcc_assert (regno + nregs <= FIRST_PSEUDO_REGISTER);
3407
3408 for (i = 0; i < nregs; i++)
3409 use_reg (fusage: call_fusage, reg: regno_reg_rtx[regno + i]);
3410}
3411
3412/* Add USE expressions to *CALL_FUSAGE for each REG contained in the
3413 PARALLEL REGS. This is for calls that pass values in multiple
3414 non-contiguous locations. The Irix 6 ABI has examples of this. */
3415
3416void
3417use_group_regs (rtx *call_fusage, rtx regs)
3418{
3419 int i;
3420
3421 for (i = 0; i < XVECLEN (regs, 0); i++)
3422 {
3423 rtx reg = XEXP (XVECEXP (regs, 0, i), 0);
3424
3425 /* A NULL entry means the parameter goes both on the stack and in
3426 registers. This can also be a MEM for targets that pass values
3427 partially on the stack and partially in registers. */
3428 if (reg != 0 && REG_P (reg))
3429 use_reg (fusage: call_fusage, reg);
3430 }
3431}
3432
3433/* Return the defining gimple statement for SSA_NAME NAME if it is an
3434 assigment and the code of the expresion on the RHS is CODE. Return
3435 NULL otherwise. */
3436
3437static gimple *
3438get_def_for_expr (tree name, enum tree_code code)
3439{
3440 gimple *def_stmt;
3441
3442 if (TREE_CODE (name) != SSA_NAME)
3443 return NULL;
3444
3445 def_stmt = get_gimple_for_ssa_name (exp: name);
3446 if (!def_stmt
3447 || gimple_assign_rhs_code (gs: def_stmt) != code)
3448 return NULL;
3449
3450 return def_stmt;
3451}
3452
3453/* Return the defining gimple statement for SSA_NAME NAME if it is an
3454 assigment and the class of the expresion on the RHS is CLASS. Return
3455 NULL otherwise. */
3456
3457static gimple *
3458get_def_for_expr_class (tree name, enum tree_code_class tclass)
3459{
3460 gimple *def_stmt;
3461
3462 if (TREE_CODE (name) != SSA_NAME)
3463 return NULL;
3464
3465 def_stmt = get_gimple_for_ssa_name (exp: name);
3466 if (!def_stmt
3467 || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass)
3468 return NULL;
3469
3470 return def_stmt;
3471}
3472
3473/* Write zeros through the storage of OBJECT. If OBJECT has BLKmode, SIZE is
3474 its length in bytes. */
3475
3476rtx
3477clear_storage_hints (rtx object, rtx size, enum block_op_methods method,
3478 unsigned int expected_align, HOST_WIDE_INT expected_size,
3479 unsigned HOST_WIDE_INT min_size,
3480 unsigned HOST_WIDE_INT max_size,
3481 unsigned HOST_WIDE_INT probable_max_size,
3482 unsigned ctz_size)
3483{
3484 machine_mode mode = GET_MODE (object);
3485 unsigned int align;
3486
3487 gcc_assert (method == BLOCK_OP_NORMAL || method == BLOCK_OP_TAILCALL);
3488
3489 /* If OBJECT is not BLKmode and SIZE is the same size as its mode,
3490 just move a zero. Otherwise, do this a piece at a time. */
3491 poly_int64 size_val;
3492 if (mode != BLKmode
3493 && poly_int_rtx_p (x: size, res: &size_val)
3494 && known_eq (size_val, GET_MODE_SIZE (mode)))
3495 {
3496 rtx zero = CONST0_RTX (mode);
3497 if (zero != NULL)
3498 {
3499 emit_move_insn (object, zero);
3500 return NULL;
3501 }
3502
3503 if (COMPLEX_MODE_P (mode))
3504 {
3505 zero = CONST0_RTX (GET_MODE_INNER (mode));
3506 if (zero != NULL)
3507 {
3508 write_complex_part (object, zero, 0, true);
3509 write_complex_part (object, zero, 1, false);
3510 return NULL;
3511 }
3512 }
3513 }
3514
3515 if (size == const0_rtx)
3516 return NULL;
3517
3518 align = MEM_ALIGN (object);
3519
3520 if (CONST_INT_P (size)
3521 && targetm.use_by_pieces_infrastructure_p (INTVAL (size), align,
3522 CLEAR_BY_PIECES,
3523 optimize_insn_for_speed_p ()))
3524 clear_by_pieces (to: object, INTVAL (size), align);
3525 else if (set_storage_via_setmem (object, size, const0_rtx, align,
3526 expected_align, expected_size,
3527 min_size, max_size, probable_max_size))
3528 ;
3529 else if (try_store_by_multiple_pieces (to: object, len: size, ctz_len: ctz_size,
3530 min_len: min_size, max_len: max_size,
3531 NULL_RTX, valc: 0, align))
3532 ;
3533 else if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (object)))
3534 return set_storage_via_libcall (object, size, const0_rtx,
3535 method == BLOCK_OP_TAILCALL);
3536 else
3537 gcc_unreachable ();
3538
3539 return NULL;
3540}
3541
3542rtx
3543clear_storage (rtx object, rtx size, enum block_op_methods method)
3544{
3545 unsigned HOST_WIDE_INT max, min = 0;
3546 if (GET_CODE (size) == CONST_INT)
3547 min = max = UINTVAL (size);
3548 else
3549 max = GET_MODE_MASK (GET_MODE (size));
3550 return clear_storage_hints (object, size, method, expected_align: 0, expected_size: -1, min_size: min, max_size: max, probable_max_size: max, ctz_size: 0);
3551}
3552
3553
3554/* A subroutine of clear_storage. Expand a call to memset.
3555 Return the return value of memset, 0 otherwise. */
3556
3557rtx
3558set_storage_via_libcall (rtx object, rtx size, rtx val, bool tailcall)
3559{
3560 tree call_expr, fn, object_tree, size_tree, val_tree;
3561 machine_mode size_mode;
3562
3563 object = copy_addr_to_reg (XEXP (object, 0));
3564 object_tree = make_tree (ptr_type_node, object);
3565
3566 if (!CONST_INT_P (val))
3567 val = convert_to_mode (TYPE_MODE (integer_type_node), x: val, unsignedp: 1);
3568 val_tree = make_tree (integer_type_node, val);
3569
3570 size_mode = TYPE_MODE (sizetype);
3571 size = convert_to_mode (mode: size_mode, x: size, unsignedp: 1);
3572 size = copy_to_mode_reg (size_mode, size);
3573 size_tree = make_tree (sizetype, size);
3574
3575 /* It is incorrect to use the libcall calling conventions for calls to
3576 memset because it can be provided by the user. */
3577 fn = builtin_decl_implicit (fncode: BUILT_IN_MEMSET);
3578 call_expr = build_call_expr (fn, 3, object_tree, val_tree, size_tree);
3579 CALL_EXPR_TAILCALL (call_expr) = tailcall;
3580
3581 return expand_call (call_expr, NULL_RTX, false);
3582}
3583
3584/* Expand a setmem pattern; return true if successful. */
3585
3586bool
3587set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
3588 unsigned int expected_align, HOST_WIDE_INT expected_size,
3589 unsigned HOST_WIDE_INT min_size,
3590 unsigned HOST_WIDE_INT max_size,
3591 unsigned HOST_WIDE_INT probable_max_size)
3592{
3593 /* Try the most limited insn first, because there's no point
3594 including more than one in the machine description unless
3595 the more limited one has some advantage. */
3596
3597 if (expected_align < align)
3598 expected_align = align;
3599 if (expected_size != -1)
3600 {
3601 if ((unsigned HOST_WIDE_INT)expected_size > max_size)
3602 expected_size = max_size;
3603 if ((unsigned HOST_WIDE_INT)expected_size < min_size)
3604 expected_size = min_size;
3605 }
3606
3607 opt_scalar_int_mode mode_iter;
3608 FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
3609 {
3610 scalar_int_mode mode = mode_iter.require ();
3611 enum insn_code code = direct_optab_handler (op: setmem_optab, mode);
3612
3613 if (code != CODE_FOR_nothing
3614 /* We don't need MODE to be narrower than BITS_PER_HOST_WIDE_INT
3615 here because if SIZE is less than the mode mask, as it is
3616 returned by the macro, it will definitely be less than the
3617 actual mode mask. Since SIZE is within the Pmode address
3618 space, we limit MODE to Pmode. */
3619 && ((CONST_INT_P (size)
3620 && ((unsigned HOST_WIDE_INT) INTVAL (size)
3621 <= (GET_MODE_MASK (mode) >> 1)))
3622 || max_size <= (GET_MODE_MASK (mode) >> 1)
3623 || GET_MODE_BITSIZE (mode) >= GET_MODE_BITSIZE (Pmode)))
3624 {
3625 class expand_operand ops[9];
3626 unsigned int nops;
3627
3628 nops = insn_data[(int) code].n_generator_args;
3629 gcc_assert (nops == 4 || nops == 6 || nops == 8 || nops == 9);
3630
3631 create_fixed_operand (op: &ops[0], x: object);
3632 /* The check above guarantees that this size conversion is valid. */
3633 create_convert_operand_to (op: &ops[1], value: size, mode, unsigned_p: true);
3634 create_convert_operand_from (op: &ops[2], value: val, mode: byte_mode, unsigned_p: true);
3635 create_integer_operand (&ops[3], align / BITS_PER_UNIT);
3636 if (nops >= 6)
3637 {
3638 create_integer_operand (&ops[4], expected_align / BITS_PER_UNIT);
3639 create_integer_operand (&ops[5], expected_size);
3640 }
3641 if (nops >= 8)
3642 {
3643 create_integer_operand (&ops[6], min_size);
3644 /* If we cannot represent the maximal size,
3645 make parameter NULL. */
3646 if ((HOST_WIDE_INT) max_size != -1)
3647 create_integer_operand (&ops[7], max_size);
3648 else
3649 create_fixed_operand (op: &ops[7], NULL);
3650 }
3651 if (nops == 9)
3652 {
3653 /* If we cannot represent the maximal size,
3654 make parameter NULL. */
3655 if ((HOST_WIDE_INT) probable_max_size != -1)
3656 create_integer_operand (&ops[8], probable_max_size);
3657 else
3658 create_fixed_operand (op: &ops[8], NULL);
3659 }
3660 if (maybe_expand_insn (icode: code, nops, ops))
3661 return true;
3662 }
3663 }
3664
3665 return false;
3666}
3667
3668
3669/* Write to one of the components of the complex value CPLX. Write VAL to
3670 the real part if IMAG_P is false, and the imaginary part if its true.
3671 If UNDEFINED_P then the value in CPLX is currently undefined. */
3672
3673void
3674write_complex_part (rtx cplx, rtx val, bool imag_p, bool undefined_p)
3675{
3676 machine_mode cmode;
3677 scalar_mode imode;
3678 unsigned ibitsize;
3679
3680 if (GET_CODE (cplx) == CONCAT)
3681 {
3682 emit_move_insn (XEXP (cplx, imag_p), val);
3683 return;
3684 }
3685
3686 cmode = GET_MODE (cplx);
3687 imode = GET_MODE_INNER (cmode);
3688 ibitsize = GET_MODE_BITSIZE (mode: imode);
3689
3690 /* For MEMs simplify_gen_subreg may generate an invalid new address
3691 because, e.g., the original address is considered mode-dependent
3692 by the target, which restricts simplify_subreg from invoking
3693 adjust_address_nv. Instead of preparing fallback support for an
3694 invalid address, we call adjust_address_nv directly. */
3695 if (MEM_P (cplx))
3696 {
3697 emit_move_insn (adjust_address_nv (cplx, imode,
3698 imag_p ? GET_MODE_SIZE (imode) : 0),
3699 val);
3700 return;
3701 }
3702
3703 /* If the sub-object is at least word sized, then we know that subregging
3704 will work. This special case is important, since store_bit_field
3705 wants to operate on integer modes, and there's rarely an OImode to
3706 correspond to TCmode. */
3707 if (ibitsize >= BITS_PER_WORD
3708 /* For hard regs we have exact predicates. Assume we can split
3709 the original object if it spans an even number of hard regs.
3710 This special case is important for SCmode on 64-bit platforms
3711 where the natural size of floating-point regs is 32-bit. */
3712 || (REG_P (cplx)
3713 && REGNO (cplx) < FIRST_PSEUDO_REGISTER
3714 && REG_NREGS (cplx) % 2 == 0))
3715 {
3716 rtx part = simplify_gen_subreg (outermode: imode, op: cplx, innermode: cmode,
3717 byte: imag_p ? GET_MODE_SIZE (mode: imode) : 0);
3718 if (part)
3719 {
3720 emit_move_insn (part, val);
3721 return;
3722 }
3723 else
3724 /* simplify_gen_subreg may fail for sub-word MEMs. */
3725 gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
3726 }
3727
3728 store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val,
3729 false, undefined_p);
3730}
3731
3732/* Extract one of the components of the complex value CPLX. Extract the
3733 real part if IMAG_P is false, and the imaginary part if it's true. */
3734
3735rtx
3736read_complex_part (rtx cplx, bool imag_p)
3737{
3738 machine_mode cmode;
3739 scalar_mode imode;
3740 unsigned ibitsize;
3741
3742 if (GET_CODE (cplx) == CONCAT)
3743 return XEXP (cplx, imag_p);
3744
3745 cmode = GET_MODE (cplx);
3746 imode = GET_MODE_INNER (cmode);
3747 ibitsize = GET_MODE_BITSIZE (mode: imode);
3748
3749 /* Special case reads from complex constants that got spilled to memory. */
3750 if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF)
3751 {
3752 tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0));
3753 if (decl && TREE_CODE (decl) == COMPLEX_CST)
3754 {
3755 tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl);
3756 if (CONSTANT_CLASS_P (part))
3757 return expand_expr (exp: part, NULL_RTX, mode: imode, modifier: EXPAND_NORMAL);
3758 }
3759 }
3760
3761 /* For MEMs simplify_gen_subreg may generate an invalid new address
3762 because, e.g., the original address is considered mode-dependent
3763 by the target, which restricts simplify_subreg from invoking
3764 adjust_address_nv. Instead of preparing fallback support for an
3765 invalid address, we call adjust_address_nv directly. */
3766 if (MEM_P (cplx))
3767 return adjust_address_nv (cplx, imode,
3768 imag_p ? GET_MODE_SIZE (imode) : 0);
3769
3770 /* If the sub-object is at least word sized, then we know that subregging
3771 will work. This special case is important, since extract_bit_field
3772 wants to operate on integer modes, and there's rarely an OImode to
3773 correspond to TCmode. */
3774 if (ibitsize >= BITS_PER_WORD
3775 /* For hard regs we have exact predicates. Assume we can split
3776 the original object if it spans an even number of hard regs.
3777 This special case is important for SCmode on 64-bit platforms
3778 where the natural size of floating-point regs is 32-bit. */
3779 || (REG_P (cplx)
3780 && REGNO (cplx) < FIRST_PSEUDO_REGISTER
3781 && REG_NREGS (cplx) % 2 == 0))
3782 {
3783 rtx ret = simplify_gen_subreg (outermode: imode, op: cplx, innermode: cmode,
3784 byte: imag_p ? GET_MODE_SIZE (mode: imode) : 0);
3785 if (ret)
3786 return ret;
3787 else
3788 /* simplify_gen_subreg may fail for sub-word MEMs. */
3789 gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD);
3790 }
3791
3792 return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0,
3793 true, NULL_RTX, imode, imode, false, NULL);
3794}
3795
3796/* A subroutine of emit_move_insn_1. Yet another lowpart generator.
3797 NEW_MODE and OLD_MODE are the same size. Return NULL if X cannot be
3798 represented in NEW_MODE. If FORCE is true, this will never happen, as
3799 we'll force-create a SUBREG if needed. */
3800
3801static rtx
3802emit_move_change_mode (machine_mode new_mode,
3803 machine_mode old_mode, rtx x, bool force)
3804{
3805 rtx ret;
3806
3807 if (push_operand (x, GET_MODE (x)))
3808 {
3809 ret = gen_rtx_MEM (new_mode, XEXP (x, 0));
3810 MEM_COPY_ATTRIBUTES (ret, x);
3811 }
3812 else if (MEM_P (x))
3813 {
3814 /* We don't have to worry about changing the address since the
3815 size in bytes is supposed to be the same. */
3816 if (reload_in_progress)
3817 {
3818 /* Copy the MEM to change the mode and move any
3819 substitutions from the old MEM to the new one. */
3820 ret = adjust_address_nv (x, new_mode, 0);
3821 copy_replacements (x, ret);
3822 }
3823 else
3824 ret = adjust_address (x, new_mode, 0);
3825 }
3826 else
3827 {
3828 /* Note that we do want simplify_subreg's behavior of validating
3829 that the new mode is ok for a hard register. If we were to use
3830 simplify_gen_subreg, we would create the subreg, but would
3831 probably run into the target not being able to implement it. */
3832 /* Except, of course, when FORCE is true, when this is exactly what
3833 we want. Which is needed for CCmodes on some targets. */
3834 if (force)
3835 ret = simplify_gen_subreg (outermode: new_mode, op: x, innermode: old_mode, byte: 0);
3836 else
3837 ret = simplify_subreg (outermode: new_mode, op: x, innermode: old_mode, byte: 0);
3838 }
3839
3840 return ret;
3841}
3842
3843/* A subroutine of emit_move_insn_1. Generate a move from Y into X using
3844 an integer mode of the same size as MODE. Returns the instruction
3845 emitted, or NULL if such a move could not be generated. */
3846
3847static rtx_insn *
3848emit_move_via_integer (machine_mode mode, rtx x, rtx y, bool force)
3849{
3850 scalar_int_mode imode;
3851 enum insn_code code;
3852
3853 /* There must exist a mode of the exact size we require. */
3854 if (!int_mode_for_mode (mode).exists (mode: &imode))
3855 return NULL;
3856
3857 /* The target must support moves in this mode. */
3858 code = optab_handler (op: mov_optab, mode: imode);
3859 if (code == CODE_FOR_nothing)
3860 return NULL;
3861
3862 x = emit_move_change_mode (new_mode: imode, old_mode: mode, x, force);
3863 if (x == NULL_RTX)
3864 return NULL;
3865 y = emit_move_change_mode (new_mode: imode, old_mode: mode, x: y, force);
3866 if (y == NULL_RTX)
3867 return NULL;
3868 return emit_insn (GEN_FCN (code) (x, y));
3869}
3870
3871/* A subroutine of emit_move_insn_1. X is a push_operand in MODE.
3872 Return an equivalent MEM that does not use an auto-increment. */
3873
3874rtx
3875emit_move_resolve_push (machine_mode mode, rtx x)
3876{
3877 enum rtx_code code = GET_CODE (XEXP (x, 0));
3878 rtx temp;
3879
3880 poly_int64 adjust = GET_MODE_SIZE (mode);
3881#ifdef PUSH_ROUNDING
3882 adjust = PUSH_ROUNDING (adjust);
3883#endif
3884 if (code == PRE_DEC || code == POST_DEC)
3885 adjust = -adjust;
3886 else if (code == PRE_MODIFY || code == POST_MODIFY)
3887 {
3888 rtx expr = XEXP (XEXP (x, 0), 1);
3889
3890 gcc_assert (GET_CODE (expr) == PLUS || GET_CODE (expr) == MINUS);
3891 poly_int64 val = rtx_to_poly_int64 (XEXP (expr, 1));
3892 if (GET_CODE (expr) == MINUS)
3893 val = -val;
3894 gcc_assert (known_eq (adjust, val) || known_eq (adjust, -val));
3895 adjust = val;
3896 }
3897
3898 /* Do not use anti_adjust_stack, since we don't want to update
3899 stack_pointer_delta. */
3900 temp = expand_simple_binop (Pmode, PLUS, stack_pointer_rtx,
3901 gen_int_mode (adjust, Pmode), stack_pointer_rtx,
3902 0, OPTAB_LIB_WIDEN);
3903 if (temp != stack_pointer_rtx)
3904 emit_move_insn (stack_pointer_rtx, temp);
3905
3906 switch (code)
3907 {
3908 case PRE_INC:
3909 case PRE_DEC:
3910 case PRE_MODIFY:
3911 temp = stack_pointer_rtx;
3912 break;
3913 case POST_INC:
3914 case POST_DEC:
3915 case POST_MODIFY:
3916 temp = plus_constant (Pmode, stack_pointer_rtx, -adjust);
3917 break;
3918 default:
3919 gcc_unreachable ();
3920 }
3921
3922 return replace_equiv_address (x, temp);
3923}
3924
3925/* A subroutine of emit_move_complex. Generate a move from Y into X.
3926 X is known to satisfy push_operand, and MODE is known to be complex.
3927 Returns the last instruction emitted. */
3928
3929rtx_insn *
3930emit_move_complex_push (machine_mode mode, rtx x, rtx y)
3931{
3932 scalar_mode submode = GET_MODE_INNER (mode);
3933 bool imag_first;
3934
3935#ifdef PUSH_ROUNDING
3936 poly_int64 submodesize = GET_MODE_SIZE (mode: submode);
3937
3938 /* In case we output to the stack, but the size is smaller than the
3939 machine can push exactly, we need to use move instructions. */
3940 if (maybe_ne (PUSH_ROUNDING (submodesize), b: submodesize))
3941 {
3942 x = emit_move_resolve_push (mode, x);
3943 return emit_move_insn (x, y);
3944 }
3945#endif
3946
3947 /* Note that the real part always precedes the imag part in memory
3948 regardless of machine's endianness. */
3949 switch (GET_CODE (XEXP (x, 0)))
3950 {
3951 case PRE_DEC:
3952 case POST_DEC:
3953 imag_first = true;
3954 break;
3955 case PRE_INC:
3956 case POST_INC:
3957 imag_first = false;
3958 break;
3959 default:
3960 gcc_unreachable ();
3961 }
3962
3963 emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
3964 read_complex_part (cplx: y, imag_p: imag_first));
3965 return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)),
3966 read_complex_part (cplx: y, imag_p: !imag_first));
3967}
3968
3969/* A subroutine of emit_move_complex. Perform the move from Y to X
3970 via two moves of the parts. Returns the last instruction emitted. */
3971
3972rtx_insn *
3973emit_move_complex_parts (rtx x, rtx y)
3974{
3975 /* Show the output dies here. This is necessary for SUBREGs
3976 of pseudos since we cannot track their lifetimes correctly;
3977 hard regs shouldn't appear here except as return values. */
3978 if (!reload_completed && !reload_in_progress
3979 && REG_P (x) && !reg_overlap_mentioned_p (x, y))
3980 emit_clobber (x);
3981
3982 write_complex_part (cplx: x, val: read_complex_part (cplx: y, imag_p: false), imag_p: false, undefined_p: true);
3983 write_complex_part (cplx: x, val: read_complex_part (cplx: y, imag_p: true), imag_p: true, undefined_p: false);
3984
3985 return get_last_insn ();
3986}
3987
3988/* A subroutine of emit_move_insn_1. Generate a move from Y into X.
3989 MODE is known to be complex. Returns the last instruction emitted. */
3990
3991static rtx_insn *
3992emit_move_complex (machine_mode mode, rtx x, rtx y)
3993{
3994 bool try_int;
3995
3996 /* Need to take special care for pushes, to maintain proper ordering
3997 of the data, and possibly extra padding. */
3998 if (push_operand (x, mode))
3999 return emit_move_complex_push (mode, x, y);
4000
4001 /* See if we can coerce the target into moving both values at once, except
4002 for floating point where we favor moving as parts if this is easy. */
4003 if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
4004 && optab_handler (op: mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing
4005 && !(REG_P (x)
4006 && HARD_REGISTER_P (x)
4007 && REG_NREGS (x) == 1)
4008 && !(REG_P (y)
4009 && HARD_REGISTER_P (y)
4010 && REG_NREGS (y) == 1))
4011 try_int = false;
4012 /* Not possible if the values are inherently not adjacent. */
4013 else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
4014 try_int = false;
4015 /* Is possible if both are registers (or subregs of registers). */
4016 else if (register_operand (x, mode) && register_operand (y, mode))
4017 try_int = true;
4018 /* If one of the operands is a memory, and alignment constraints
4019 are friendly enough, we may be able to do combined memory operations.
4020 We do not attempt this if Y is a constant because that combination is
4021 usually better with the by-parts thing below. */
4022 else if ((MEM_P (x) ? !CONSTANT_P (y) : MEM_P (y))
4023 && (!STRICT_ALIGNMENT
4024 || get_mode_alignment (mode) == BIGGEST_ALIGNMENT))
4025 try_int = true;
4026 else
4027 try_int = false;
4028
4029 if (try_int)
4030 {
4031 rtx_insn *ret;
4032
4033 /* For memory to memory moves, optimal behavior can be had with the
4034 existing block move logic. But use normal expansion if optimizing
4035 for size. */
4036 if (MEM_P (x) && MEM_P (y))
4037 {
4038 emit_block_move (x, y, size: gen_int_mode (GET_MODE_SIZE (mode), Pmode),
4039 method: (optimize_insn_for_speed_p()
4040 ? BLOCK_OP_NO_LIBCALL : BLOCK_OP_NORMAL));
4041 return get_last_insn ();
4042 }
4043
4044 ret = emit_move_via_integer (mode, x, y, force: true);
4045 if (ret)
4046 return ret;
4047 }
4048
4049 return emit_move_complex_parts (x, y);
4050}
4051
4052/* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4053 MODE is known to be MODE_CC. Returns the last instruction emitted. */
4054
4055static rtx_insn *
4056emit_move_ccmode (machine_mode mode, rtx x, rtx y)
4057{
4058 rtx_insn *ret;
4059
4060 /* Assume all MODE_CC modes are equivalent; if we have movcc, use it. */
4061 if (mode != CCmode)
4062 {
4063 enum insn_code code = optab_handler (op: mov_optab, CCmode);
4064 if (code != CODE_FOR_nothing)
4065 {
4066 x = emit_move_change_mode (CCmode, old_mode: mode, x, force: true);
4067 y = emit_move_change_mode (CCmode, old_mode: mode, x: y, force: true);
4068 return emit_insn (GEN_FCN (code) (x, y));
4069 }
4070 }
4071
4072 /* Otherwise, find the MODE_INT mode of the same width. */
4073 ret = emit_move_via_integer (mode, x, y, force: false);
4074 gcc_assert (ret != NULL);
4075 return ret;
4076}
4077
4078/* Return true if word I of OP lies entirely in the
4079 undefined bits of a paradoxical subreg. */
4080
4081static bool
4082undefined_operand_subword_p (const_rtx op, int i)
4083{
4084 if (GET_CODE (op) != SUBREG)
4085 return false;
4086 machine_mode innermostmode = GET_MODE (SUBREG_REG (op));
4087 poly_int64 offset = i * UNITS_PER_WORD + subreg_memory_offset (op);
4088 return (known_ge (offset, GET_MODE_SIZE (innermostmode))
4089 || known_le (offset, -UNITS_PER_WORD));
4090}
4091
4092/* A subroutine of emit_move_insn_1. Generate a move from Y into X.
4093 MODE is any multi-word or full-word mode that lacks a move_insn
4094 pattern. Note that you will get better code if you define such
4095 patterns, even if they must turn into multiple assembler instructions. */
4096
4097static rtx_insn *
4098emit_move_multi_word (machine_mode mode, rtx x, rtx y)
4099{
4100 rtx_insn *last_insn = 0;
4101 rtx_insn *seq;
4102 rtx inner;
4103 bool need_clobber;
4104 int i, mode_size;
4105
4106 /* This function can only handle cases where the number of words is
4107 known at compile time. */
4108 mode_size = GET_MODE_SIZE (mode).to_constant ();
4109 gcc_assert (mode_size >= UNITS_PER_WORD);
4110
4111 /* If X is a push on the stack, do the push now and replace
4112 X with a reference to the stack pointer. */
4113 if (push_operand (x, mode))
4114 x = emit_move_resolve_push (mode, x);
4115
4116 /* If we are in reload, see if either operand is a MEM whose address
4117 is scheduled for replacement. */
4118 if (reload_in_progress && MEM_P (x)
4119 && (inner = find_replacement (&XEXP (x, 0))) != XEXP (x, 0))
4120 x = replace_equiv_address_nv (x, inner);
4121 if (reload_in_progress && MEM_P (y)
4122 && (inner = find_replacement (&XEXP (y, 0))) != XEXP (y, 0))
4123 y = replace_equiv_address_nv (y, inner);
4124
4125 start_sequence ();
4126
4127 need_clobber = false;
4128 for (i = 0; i < CEIL (mode_size, UNITS_PER_WORD); i++)
4129 {
4130 /* Do not generate code for a move if it would go entirely
4131 to the non-existing bits of a paradoxical subreg. */
4132 if (undefined_operand_subword_p (op: x, i))
4133 continue;
4134
4135 rtx xpart = operand_subword (x, i, 1, mode);
4136 rtx ypart;
4137
4138 /* Do not generate code for a move if it would come entirely
4139 from the undefined bits of a paradoxical subreg. */
4140 if (undefined_operand_subword_p (op: y, i))
4141 continue;
4142
4143 ypart = operand_subword (y, i, 1, mode);
4144
4145 /* If we can't get a part of Y, put Y into memory if it is a
4146 constant. Otherwise, force it into a register. Then we must
4147 be able to get a part of Y. */
4148 if (ypart == 0 && CONSTANT_P (y))
4149 {
4150 y = use_anchored_address (force_const_mem (mode, y));
4151 ypart = operand_subword (y, i, 1, mode);
4152 }
4153 else if (ypart == 0)
4154 ypart = operand_subword_force (y, i, mode);
4155
4156 gcc_assert (xpart && ypart);
4157
4158 need_clobber |= (GET_CODE (xpart) == SUBREG);
4159
4160 last_insn = emit_move_insn (xpart, ypart);
4161 }
4162
4163 seq = get_insns ();
4164 end_sequence ();
4165
4166 /* Show the output dies here. This is necessary for SUBREGs
4167 of pseudos since we cannot track their lifetimes correctly;
4168 hard regs shouldn't appear here except as return values.
4169 We never want to emit such a clobber after reload. */
4170 if (x != y
4171 && ! (reload_in_progress || reload_completed)
4172 && need_clobber != 0)
4173 emit_clobber (x);
4174
4175 emit_insn (seq);
4176
4177 return last_insn;
4178}
4179
4180/* Low level part of emit_move_insn.
4181 Called just like emit_move_insn, but assumes X and Y
4182 are basically valid. */
4183
4184rtx_insn *
4185emit_move_insn_1 (rtx x, rtx y)
4186{
4187 machine_mode mode = GET_MODE (x);
4188 enum insn_code code;
4189
4190 gcc_assert ((unsigned int) mode < (unsigned int) MAX_MACHINE_MODE);
4191
4192 code = optab_handler (op: mov_optab, mode);
4193 if (code != CODE_FOR_nothing)
4194 return emit_insn (GEN_FCN (code) (x, y));
4195
4196 /* Expand complex moves by moving real part and imag part. */
4197 if (COMPLEX_MODE_P (mode))
4198 return emit_move_complex (mode, x, y);
4199
4200 if (GET_MODE_CLASS (mode) == MODE_DECIMAL_FLOAT
4201 || ALL_FIXED_POINT_MODE_P (mode))
4202 {
4203 rtx_insn *result = emit_move_via_integer (mode, x, y, force: true);
4204
4205 /* If we can't find an integer mode, use multi words. */
4206 if (result)
4207 return result;
4208 else
4209 return emit_move_multi_word (mode, x, y);
4210 }
4211
4212 if (GET_MODE_CLASS (mode) == MODE_CC)
4213 return emit_move_ccmode (mode, x, y);
4214
4215 /* Try using a move pattern for the corresponding integer mode. This is
4216 only safe when simplify_subreg can convert MODE constants into integer
4217 constants. At present, it can only do this reliably if the value
4218 fits within a HOST_WIDE_INT. */
4219 if (!CONSTANT_P (y)
4220 || known_le (GET_MODE_BITSIZE (mode), HOST_BITS_PER_WIDE_INT))
4221 {
4222 rtx_insn *ret = emit_move_via_integer (mode, x, y, force: lra_in_progress);
4223
4224 if (ret)
4225 {
4226 if (! lra_in_progress || recog (PATTERN (insn: ret), ret, 0) >= 0)
4227 return ret;
4228 }
4229 }
4230
4231 return emit_move_multi_word (mode, x, y);
4232}
4233
4234/* Generate code to copy Y into X.
4235 Both Y and X must have the same mode, except that
4236 Y can be a constant with VOIDmode.
4237 This mode cannot be BLKmode; use emit_block_move for that.
4238
4239 Return the last instruction emitted. */
4240
4241rtx_insn *
4242emit_move_insn (rtx x, rtx y)
4243{
4244 machine_mode mode = GET_MODE (x);
4245 rtx y_cst = NULL_RTX;
4246 rtx_insn *last_insn;
4247 rtx set;
4248
4249 gcc_assert (mode != BLKmode
4250 && (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode));
4251
4252 /* If we have a copy that looks like one of the following patterns:
4253 (set (subreg:M1 (reg:M2 ...)) (subreg:M1 (reg:M2 ...)))
4254 (set (subreg:M1 (reg:M2 ...)) (mem:M1 ADDR))
4255 (set (mem:M1 ADDR) (subreg:M1 (reg:M2 ...)))
4256 (set (subreg:M1 (reg:M2 ...)) (constant C))
4257 where mode M1 is equal in size to M2, try to detect whether the
4258 mode change involves an implicit round trip through memory.
4259 If so, see if we can avoid that by removing the subregs and
4260 doing the move in mode M2 instead. */
4261
4262 rtx x_inner = NULL_RTX;
4263 rtx y_inner = NULL_RTX;
4264
4265 auto candidate_subreg_p = [&](rtx subreg) {
4266 return (REG_P (SUBREG_REG (subreg))
4267 && known_eq (GET_MODE_SIZE (GET_MODE (SUBREG_REG (subreg))),
4268 GET_MODE_SIZE (GET_MODE (subreg)))
4269 && optab_handler (op: mov_optab, GET_MODE (SUBREG_REG (subreg)))
4270 != CODE_FOR_nothing);
4271 };
4272
4273 auto candidate_mem_p = [&](machine_mode innermode, rtx mem) {
4274 return (!targetm.can_change_mode_class (innermode, GET_MODE (mem), ALL_REGS)
4275 && !push_operand (mem, GET_MODE (mem))
4276 /* Not a candiate if innermode requires too much alignment. */
4277 && (MEM_ALIGN (mem) >= GET_MODE_ALIGNMENT (innermode)
4278 || targetm.slow_unaligned_access (GET_MODE (mem),
4279 MEM_ALIGN (mem))
4280 || !targetm.slow_unaligned_access (innermode,
4281 MEM_ALIGN (mem))));
4282 };
4283
4284 if (SUBREG_P (x) && candidate_subreg_p (x))
4285 x_inner = SUBREG_REG (x);
4286
4287 if (SUBREG_P (y) && candidate_subreg_p (y))
4288 y_inner = SUBREG_REG (y);
4289
4290 if (x_inner != NULL_RTX
4291 && y_inner != NULL_RTX
4292 && GET_MODE (x_inner) == GET_MODE (y_inner)
4293 && !targetm.can_change_mode_class (GET_MODE (x_inner), mode, ALL_REGS))
4294 {
4295 x = x_inner;
4296 y = y_inner;
4297 mode = GET_MODE (x_inner);
4298 }
4299 else if (x_inner != NULL_RTX
4300 && MEM_P (y)
4301 && candidate_mem_p (GET_MODE (x_inner), y))
4302 {
4303 x = x_inner;
4304 y = adjust_address (y, GET_MODE (x_inner), 0);
4305 mode = GET_MODE (x_inner);
4306 }
4307 else if (y_inner != NULL_RTX
4308 && MEM_P (x)
4309 && candidate_mem_p (GET_MODE (y_inner), x))
4310 {
4311 x = adjust_address (x, GET_MODE (y_inner), 0);
4312 y = y_inner;
4313 mode = GET_MODE (y_inner);
4314 }
4315 else if (x_inner != NULL_RTX
4316 && CONSTANT_P (y)
4317 && !targetm.can_change_mode_class (GET_MODE (x_inner),
4318 mode, ALL_REGS)
4319 && (y_inner = simplify_subreg (GET_MODE (x_inner), op: y, innermode: mode, byte: 0)))
4320 {
4321 x = x_inner;
4322 y = y_inner;
4323 mode = GET_MODE (x_inner);
4324 }
4325
4326 if (CONSTANT_P (y))
4327 {
4328 if (optimize
4329 && SCALAR_FLOAT_MODE_P (GET_MODE (x))
4330 && (last_insn = compress_float_constant (x, y)))
4331 return last_insn;
4332
4333 y_cst = y;
4334
4335 if (!targetm.legitimate_constant_p (mode, y))
4336 {
4337 y = force_const_mem (mode, y);
4338
4339 /* If the target's cannot_force_const_mem prevented the spill,
4340 assume that the target's move expanders will also take care
4341 of the non-legitimate constant. */
4342 if (!y)
4343 y = y_cst;
4344 else
4345 y = use_anchored_address (y);
4346 }
4347 }
4348
4349 /* If X or Y are memory references, verify that their addresses are valid
4350 for the machine. */
4351 if (MEM_P (x)
4352 && (! memory_address_addr_space_p (GET_MODE (x), XEXP (x, 0),
4353 MEM_ADDR_SPACE (x))
4354 && ! push_operand (x, GET_MODE (x))))
4355 x = validize_mem (x);
4356
4357 if (MEM_P (y)
4358 && ! memory_address_addr_space_p (GET_MODE (y), XEXP (y, 0),
4359 MEM_ADDR_SPACE (y)))
4360 y = validize_mem (y);
4361
4362 gcc_assert (mode != BLKmode);
4363
4364 last_insn = emit_move_insn_1 (x, y);
4365
4366 if (y_cst && REG_P (x)
4367 && (set = single_set (insn: last_insn)) != NULL_RTX
4368 && SET_DEST (set) == x
4369 && ! rtx_equal_p (y_cst, SET_SRC (set)))
4370 set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));
4371
4372 return last_insn;
4373}
4374
4375/* Generate the body of an instruction to copy Y into X.
4376 It may be a list of insns, if one insn isn't enough. */
4377
4378rtx_insn *
4379gen_move_insn (rtx x, rtx y)
4380{
4381 rtx_insn *seq;
4382
4383 start_sequence ();
4384 emit_move_insn_1 (x, y);
4385 seq = get_insns ();
4386 end_sequence ();
4387 return seq;
4388}
4389
4390/* If Y is representable exactly in a narrower mode, and the target can
4391 perform the extension directly from constant or memory, then emit the
4392 move as an extension. */
4393
4394static rtx_insn *
4395compress_float_constant (rtx x, rtx y)
4396{
4397 machine_mode dstmode = GET_MODE (x);
4398 machine_mode orig_srcmode = GET_MODE (y);
4399 machine_mode srcmode;
4400 const REAL_VALUE_TYPE *r;
4401 int oldcost, newcost;
4402 bool speed = optimize_insn_for_speed_p ();
4403
4404 r = CONST_DOUBLE_REAL_VALUE (y);
4405
4406 if (targetm.legitimate_constant_p (dstmode, y))
4407 oldcost = set_src_cost (x: y, mode: orig_srcmode, speed_p: speed);
4408 else
4409 oldcost = set_src_cost (x: force_const_mem (dstmode, y), mode: dstmode, speed_p: speed);
4410
4411 FOR_EACH_MODE_UNTIL (srcmode, orig_srcmode)
4412 {
4413 enum insn_code ic;
4414 rtx trunc_y;
4415 rtx_insn *last_insn;
4416
4417 /* Skip if the target can't extend this way. */
4418 ic = can_extend_p (dstmode, srcmode, 0);
4419 if (ic == CODE_FOR_nothing)
4420 continue;
4421
4422 /* Skip if the narrowed value isn't exact. */
4423 if (! exact_real_truncate (srcmode, r))
4424 continue;
4425
4426 trunc_y = const_double_from_real_value (*r, srcmode);
4427
4428 if (targetm.legitimate_constant_p (srcmode, trunc_y))
4429 {
4430 /* Skip if the target needs extra instructions to perform
4431 the extension. */
4432 if (!insn_operand_matches (icode: ic, opno: 1, operand: trunc_y))
4433 continue;
4434 /* This is valid, but may not be cheaper than the original. */
4435 newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4436 mode: dstmode, speed_p: speed);
4437 if (oldcost < newcost)
4438 continue;
4439 }
4440 else if (float_extend_from_mem[dstmode][srcmode])
4441 {
4442 trunc_y = force_const_mem (srcmode, trunc_y);
4443 /* This is valid, but may not be cheaper than the original. */
4444 newcost = set_src_cost (gen_rtx_FLOAT_EXTEND (dstmode, trunc_y),
4445 mode: dstmode, speed_p: speed);
4446 if (oldcost < newcost)
4447 continue;
4448 trunc_y = validize_mem (trunc_y);
4449 }
4450 else
4451 continue;
4452
4453 /* For CSE's benefit, force the compressed constant pool entry
4454 into a new pseudo. This constant may be used in different modes,
4455 and if not, combine will put things back together for us. */
4456 trunc_y = force_reg (srcmode, trunc_y);
4457
4458 /* If x is a hard register, perform the extension into a pseudo,
4459 so that e.g. stack realignment code is aware of it. */
4460 rtx target = x;
4461 if (REG_P (x) && HARD_REGISTER_P (x))
4462 target = gen_reg_rtx (dstmode);
4463
4464 emit_unop_insn (ic, target, trunc_y, UNKNOWN);
4465 last_insn = get_last_insn ();
4466
4467 if (REG_P (target))
4468 set_unique_reg_note (last_insn, REG_EQUAL, y);
4469
4470 if (target != x)
4471 return emit_move_insn (x, y: target);
4472 return last_insn;
4473 }
4474
4475 return NULL;
4476}
4477
4478/* Pushing data onto the stack. */
4479
4480/* Push a block of length SIZE (perhaps variable)
4481 and return an rtx to address the beginning of the block.
4482 The value may be virtual_outgoing_args_rtx.
4483
4484 EXTRA is the number of bytes of padding to push in addition to SIZE.
4485 BELOW nonzero means this padding comes at low addresses;
4486 otherwise, the padding comes at high addresses. */
4487
4488rtx
4489push_block (rtx size, poly_int64 extra, int below)
4490{
4491 rtx temp;
4492
4493 size = convert_modes (Pmode, oldmode: ptr_mode, x: size, unsignedp: 1);
4494 if (CONSTANT_P (size))
4495 anti_adjust_stack (plus_constant (Pmode, size, extra));
4496 else if (REG_P (size) && known_eq (extra, 0))
4497 anti_adjust_stack (size);
4498 else
4499 {
4500 temp = copy_to_mode_reg (Pmode, size);
4501 if (maybe_ne (a: extra, b: 0))
4502 temp = expand_binop (Pmode, add_optab, temp,
4503 gen_int_mode (extra, Pmode),
4504 temp, 0, OPTAB_LIB_WIDEN);
4505 anti_adjust_stack (temp);
4506 }
4507
4508 if (STACK_GROWS_DOWNWARD)
4509 {
4510 temp = virtual_outgoing_args_rtx;
4511 if (maybe_ne (a: extra, b: 0) && below)
4512 temp = plus_constant (Pmode, temp, extra);
4513 }
4514 else
4515 {
4516 poly_int64 csize;
4517 if (poly_int_rtx_p (x: size, res: &csize))
4518 temp = plus_constant (Pmode, virtual_outgoing_args_rtx,
4519 -csize - (below ? 0 : extra));
4520 else if (maybe_ne (a: extra, b: 0) && !below)
4521 temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4522 negate_rtx (Pmode, plus_constant (Pmode, size,
4523 extra)));
4524 else
4525 temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
4526 negate_rtx (Pmode, size));
4527 }
4528
4529 return memory_address (NARROWEST_INT_MODE, temp);
4530}
4531
4532/* A utility routine that returns the base of an auto-inc memory, or NULL. */
4533
4534static rtx
4535mem_autoinc_base (rtx mem)
4536{
4537 if (MEM_P (mem))
4538 {
4539 rtx addr = XEXP (mem, 0);
4540 if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
4541 return XEXP (addr, 0);
4542 }
4543 return NULL;
4544}
4545
4546/* A utility routine used here, in reload, and in try_split. The insns
4547 after PREV up to and including LAST are known to adjust the stack,
4548 with a final value of END_ARGS_SIZE. Iterate backward from LAST
4549 placing notes as appropriate. PREV may be NULL, indicating the
4550 entire insn sequence prior to LAST should be scanned.
4551
4552 The set of allowed stack pointer modifications is small:
4553 (1) One or more auto-inc style memory references (aka pushes),
4554 (2) One or more addition/subtraction with the SP as destination,
4555 (3) A single move insn with the SP as destination,
4556 (4) A call_pop insn,
4557 (5) Noreturn call insns if !ACCUMULATE_OUTGOING_ARGS.
4558
4559 Insns in the sequence that do not modify the SP are ignored,
4560 except for noreturn calls.
4561
4562 The return value is the amount of adjustment that can be trivially
4563 verified, via immediate operand or auto-inc. If the adjustment
4564 cannot be trivially extracted, the return value is HOST_WIDE_INT_MIN. */
4565
4566poly_int64
4567find_args_size_adjust (rtx_insn *insn)
4568{
4569 rtx dest, set, pat;
4570 int i;
4571
4572 pat = PATTERN (insn);
4573 set = NULL;
4574
4575 /* Look for a call_pop pattern. */
4576 if (CALL_P (insn))
4577 {
4578 /* We have to allow non-call_pop patterns for the case
4579 of emit_single_push_insn of a TLS address. */
4580 if (GET_CODE (pat) != PARALLEL)
4581 return 0;
4582
4583 /* All call_pop have a stack pointer adjust in the parallel.
4584 The call itself is always first, and the stack adjust is
4585 usually last, so search from the end. */
4586 for (i = XVECLEN (pat, 0) - 1; i > 0; --i)
4587 {
4588 set = XVECEXP (pat, 0, i);
4589 if (GET_CODE (set) != SET)
4590 continue;
4591 dest = SET_DEST (set);
4592 if (dest == stack_pointer_rtx)
4593 break;
4594 }
4595 /* We'd better have found the stack pointer adjust. */
4596 if (i == 0)
4597 return 0;
4598 /* Fall through to process the extracted SET and DEST
4599 as if it was a standalone insn. */
4600 }
4601 else if (GET_CODE (pat) == SET)
4602 set = pat;
4603 else if ((set = single_set (insn)) != NULL)
4604 ;
4605 else if (GET_CODE (pat) == PARALLEL)
4606 {
4607 /* ??? Some older ports use a parallel with a stack adjust
4608 and a store for a PUSH_ROUNDING pattern, rather than a
4609 PRE/POST_MODIFY rtx. Don't force them to update yet... */
4610 /* ??? See h8300 and m68k, pushqi1. */
4611 for (i = XVECLEN (pat, 0) - 1; i >= 0; --i)
4612 {
4613 set = XVECEXP (pat, 0, i);
4614 if (GET_CODE (set) != SET)
4615 continue;
4616 dest = SET_DEST (set);
4617 if (dest == stack_pointer_rtx)
4618 break;
4619
4620 /* We do not expect an auto-inc of the sp in the parallel. */
4621 gcc_checking_assert (mem_autoinc_base (dest) != stack_pointer_rtx);
4622 gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
4623 != stack_pointer_rtx);
4624 }
4625 if (i < 0)
4626 return 0;
4627 }
4628 else
4629 return 0;
4630
4631 dest = SET_DEST (set);
4632
4633 /* Look for direct modifications of the stack pointer. */
4634 if (REG_P (dest) && REGNO (dest) == STACK_POINTER_REGNUM)
4635 {
4636 /* Look for a trivial adjustment, otherwise assume nothing. */
4637 /* Note that the SPU restore_stack_block pattern refers to
4638 the stack pointer in V4SImode. Consider that non-trivial. */
4639 poly_int64 offset;
4640 if (SCALAR_INT_MODE_P (GET_MODE (dest))
4641 && strip_offset (SET_SRC (set), &offset) == stack_pointer_rtx)
4642 return offset;
4643 /* ??? Reload can generate no-op moves, which will be cleaned
4644 up later. Recognize it and continue searching. */
4645 else if (rtx_equal_p (dest, SET_SRC (set)))
4646 return 0;
4647 else
4648 return HOST_WIDE_INT_MIN;
4649 }
4650 else
4651 {
4652 rtx mem, addr;
4653
4654 /* Otherwise only think about autoinc patterns. */
4655 if (mem_autoinc_base (mem: dest) == stack_pointer_rtx)
4656 {
4657 mem = dest;
4658 gcc_checking_assert (mem_autoinc_base (SET_SRC (set))
4659 != stack_pointer_rtx);
4660 }
4661 else if (mem_autoinc_base (SET_SRC (set)) == stack_pointer_rtx)
4662 mem = SET_SRC (set);
4663 else
4664 return 0;
4665
4666 addr = XEXP (mem, 0);
4667 switch (GET_CODE (addr))
4668 {
4669 case PRE_INC:
4670 case POST_INC:
4671 return GET_MODE_SIZE (GET_MODE (mem));
4672 case PRE_DEC:
4673 case POST_DEC:
4674 return -GET_MODE_SIZE (GET_MODE (mem));
4675 case PRE_MODIFY:
4676 case POST_MODIFY:
4677 addr = XEXP (addr, 1);
4678 gcc_assert (GET_CODE (addr) == PLUS);
4679 gcc_assert (XEXP (addr, 0) == stack_pointer_rtx);
4680 return rtx_to_poly_int64 (XEXP (addr, 1));
4681 default:
4682 gcc_unreachable ();
4683 }
4684 }
4685}
4686
4687poly_int64
4688fixup_args_size_notes (rtx_insn *prev, rtx_insn *last,
4689 poly_int64 end_args_size)
4690{
4691 poly_int64 args_size = end_args_size;
4692 bool saw_unknown = false;
4693 rtx_insn *insn;
4694
4695 for (insn = last; insn != prev; insn = PREV_INSN (insn))
4696 {
4697 if (!NONDEBUG_INSN_P (insn))
4698 continue;
4699
4700 /* We might have existing REG_ARGS_SIZE notes, e.g. when pushing
4701 a call argument containing a TLS address that itself requires
4702 a call to __tls_get_addr. The handling of stack_pointer_delta
4703 in emit_single_push_insn is supposed to ensure that any such
4704 notes are already correct. */
4705 rtx note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
4706 gcc_assert (!note || known_eq (args_size, get_args_size (note)));
4707
4708 poly_int64 this_delta = find_args_size_adjust (insn);
4709 if (known_eq (this_delta, 0))
4710 {
4711 if (!CALL_P (insn)
4712 || ACCUMULATE_OUTGOING_ARGS
4713 || find_reg_note (insn, REG_NORETURN, NULL_RTX) == NULL_RTX)
4714 continue;
4715 }
4716
4717 gcc_assert (!saw_unknown);
4718 if (known_eq (this_delta, HOST_WIDE_INT_MIN))
4719 saw_unknown = true;
4720
4721 if (!note)
4722 add_args_size_note (insn, args_size);
4723 if (STACK_GROWS_DOWNWARD)
4724 this_delta = -poly_uint64 (this_delta);
4725
4726 if (saw_unknown)
4727 args_size = HOST_WIDE_INT_MIN;
4728 else
4729 args_size -= this_delta;
4730 }
4731
4732 return args_size;
4733}
4734
4735#ifdef PUSH_ROUNDING
4736/* Emit single push insn. */
4737
4738static void
4739emit_single_push_insn_1 (machine_mode mode, rtx x, tree type)
4740{
4741 rtx dest_addr;
4742 poly_int64 rounded_size = PUSH_ROUNDING (GET_MODE_SIZE (mode));
4743 rtx dest;
4744 enum insn_code icode;
4745
4746 /* If there is push pattern, use it. Otherwise try old way of throwing
4747 MEM representing push operation to move expander. */
4748 icode = optab_handler (op: push_optab, mode);
4749 if (icode != CODE_FOR_nothing)
4750 {
4751 class expand_operand ops[1];
4752
4753 create_input_operand (op: &ops[0], value: x, mode);
4754 if (maybe_expand_insn (icode, nops: 1, ops))
4755 return;
4756 }
4757 if (known_eq (GET_MODE_SIZE (mode), rounded_size))
4758 dest_addr = gen_rtx_fmt_e (STACK_PUSH_CODE, Pmode, stack_pointer_rtx);
4759 /* If we are to pad downward, adjust the stack pointer first and
4760 then store X into the stack location using an offset. This is
4761 because emit_move_insn does not know how to pad; it does not have
4762 access to type. */
4763 else if (targetm.calls.function_arg_padding (mode, type) == PAD_DOWNWARD)
4764 {
4765 emit_move_insn (stack_pointer_rtx,
4766 y: expand_binop (Pmode,
4767 STACK_GROWS_DOWNWARD ? sub_optab
4768 : add_optab,
4769 stack_pointer_rtx,
4770 gen_int_mode (rounded_size, Pmode),
4771 NULL_RTX, 0, OPTAB_LIB_WIDEN));
4772
4773 poly_int64 offset = rounded_size - GET_MODE_SIZE (mode);
4774 if (STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_DEC)
4775 /* We have already decremented the stack pointer, so get the
4776 previous value. */
4777 offset += rounded_size;
4778
4779 if (!STACK_GROWS_DOWNWARD && STACK_PUSH_CODE == POST_INC)
4780 /* We have already incremented the stack pointer, so get the
4781 previous value. */
4782 offset -= rounded_size;
4783
4784 dest_addr = plus_constant (Pmode, stack_pointer_rtx, offset);
4785 }
4786 else
4787 {
4788 if (STACK_GROWS_DOWNWARD)
4789 /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */
4790 dest_addr = plus_constant (Pmode, stack_pointer_rtx, -rounded_size);
4791 else
4792 /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */
4793 dest_addr = plus_constant (Pmode, stack_pointer_rtx, rounded_size);
4794
4795 dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
4796 }
4797
4798 dest = gen_rtx_MEM (mode, dest_addr);
4799
4800 if (type != 0)
4801 {
4802 set_mem_attributes (dest, type, 1);
4803
4804 if (cfun->tail_call_marked)
4805 /* Function incoming arguments may overlap with sibling call
4806 outgoing arguments and we cannot allow reordering of reads
4807 from function arguments with stores to outgoing arguments
4808 of sibling calls. */
4809 set_mem_alias_set (dest, 0);
4810 }
4811 emit_move_insn (x: dest, y: x);
4812}
4813
4814/* Emit and annotate a single push insn. */
4815
4816static void
4817emit_single_push_insn (machine_mode mode, rtx x, tree type)
4818{
4819 poly_int64 delta, old_delta = stack_pointer_delta;
4820 rtx_insn *prev = get_last_insn ();
4821 rtx_insn *last;
4822
4823 emit_single_push_insn_1 (mode, x, type);
4824
4825 /* Adjust stack_pointer_delta to describe the situation after the push
4826 we just performed. Note that we must do this after the push rather
4827 than before the push in case calculating X needs pushes and pops of
4828 its own (e.g. if calling __tls_get_addr). The REG_ARGS_SIZE notes
4829 for such pushes and pops must not include the effect of the future
4830 push of X. */
4831 stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
4832
4833 last = get_last_insn ();
4834
4835 /* Notice the common case where we emitted exactly one insn. */
4836 if (PREV_INSN (insn: last) == prev)
4837 {
4838 add_args_size_note (last, stack_pointer_delta);
4839 return;
4840 }
4841
4842 delta = fixup_args_size_notes (prev, last, stack_pointer_delta);
4843 gcc_assert (known_eq (delta, HOST_WIDE_INT_MIN)
4844 || known_eq (delta, old_delta));
4845}
4846#endif
4847
4848/* If reading SIZE bytes from X will end up reading from
4849 Y return the number of bytes that overlap. Return -1
4850 if there is no overlap or -2 if we can't determine
4851 (for example when X and Y have different base registers). */
4852
4853static int
4854memory_load_overlap (rtx x, rtx y, HOST_WIDE_INT size)
4855{
4856 rtx tmp = plus_constant (Pmode, x, size);
4857 rtx sub = simplify_gen_binary (code: MINUS, Pmode, op0: tmp, op1: y);
4858
4859 if (!CONST_INT_P (sub))
4860 return -2;
4861
4862 HOST_WIDE_INT val = INTVAL (sub);
4863
4864 return IN_RANGE (val, 1, size) ? val : -1;
4865}
4866
4867/* Generate code to push X onto the stack, assuming it has mode MODE and
4868 type TYPE.
4869 MODE is redundant except when X is a CONST_INT (since they don't
4870 carry mode info).
4871 SIZE is an rtx for the size of data to be copied (in bytes),
4872 needed only if X is BLKmode.
4873 Return true if successful. May return false if asked to push a
4874 partial argument during a sibcall optimization (as specified by
4875 SIBCALL_P) and the incoming and outgoing pointers cannot be shown
4876 to not overlap.
4877
4878 ALIGN (in bits) is maximum alignment we can assume.
4879
4880 If PARTIAL and REG are both nonzero, then copy that many of the first
4881 bytes of X into registers starting with REG, and push the rest of X.
4882 The amount of space pushed is decreased by PARTIAL bytes.
4883 REG must be a hard register in this case.
4884 If REG is zero but PARTIAL is not, take any all others actions for an
4885 argument partially in registers, but do not actually load any
4886 registers.
4887
4888 EXTRA is the amount in bytes of extra space to leave next to this arg.
4889 This is ignored if an argument block has already been allocated.
4890
4891 On a machine that lacks real push insns, ARGS_ADDR is the address of
4892 the bottom of the argument block for this call. We use indexing off there
4893 to store the arg. On machines with push insns, ARGS_ADDR is 0 when a
4894 argument block has not been preallocated.
4895
4896 ARGS_SO_FAR is the size of args previously pushed for this call.
4897
4898 REG_PARM_STACK_SPACE is nonzero if functions require stack space
4899 for arguments passed in registers. If nonzero, it will be the number
4900 of bytes required. */
4901
4902bool
4903emit_push_insn (rtx x, machine_mode mode, tree type, rtx size,
4904 unsigned int align, int partial, rtx reg, poly_int64 extra,
4905 rtx args_addr, rtx args_so_far, int reg_parm_stack_space,
4906 rtx alignment_pad, bool sibcall_p)
4907{
4908 rtx xinner;
4909 pad_direction stack_direction
4910 = STACK_GROWS_DOWNWARD ? PAD_DOWNWARD : PAD_UPWARD;
4911
4912 /* Decide where to pad the argument: PAD_DOWNWARD for below,
4913 PAD_UPWARD for above, or PAD_NONE for don't pad it.
4914 Default is below for small data on big-endian machines; else above. */
4915 pad_direction where_pad = targetm.calls.function_arg_padding (mode, type);
4916
4917 /* Invert direction if stack is post-decrement.
4918 FIXME: why? */
4919 if (STACK_PUSH_CODE == POST_DEC)
4920 if (where_pad != PAD_NONE)
4921 where_pad = (where_pad == PAD_DOWNWARD ? PAD_UPWARD : PAD_DOWNWARD);
4922
4923 xinner = x;
4924
4925 int nregs = partial / UNITS_PER_WORD;
4926 rtx *tmp_regs = NULL;
4927 int overlapping = 0;
4928
4929 if (mode == BLKmode
4930 || (STRICT_ALIGNMENT && align < GET_MODE_ALIGNMENT (mode)))
4931 {
4932 /* Copy a block into the stack, entirely or partially. */
4933
4934 rtx temp;
4935 int used;
4936 int offset;
4937 int skip;
4938
4939 offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
4940 used = partial - offset;
4941
4942 if (mode != BLKmode)
4943 {
4944 /* A value is to be stored in an insufficiently aligned
4945 stack slot; copy via a suitably aligned slot if
4946 necessary. */
4947 size = gen_int_mode (GET_MODE_SIZE (mode), Pmode);
4948 if (!MEM_P (xinner))
4949 {
4950 temp = assign_temp (type, 1, 1);
4951 emit_move_insn (x: temp, y: xinner);
4952 xinner = temp;
4953 }
4954 }
4955
4956 gcc_assert (size);
4957
4958 /* USED is now the # of bytes we need not copy to the stack
4959 because registers will take care of them. */
4960
4961 if (partial != 0)
4962 xinner = adjust_address (xinner, BLKmode, used);
4963
4964 /* If the partial register-part of the arg counts in its stack size,
4965 skip the part of stack space corresponding to the registers.
4966 Otherwise, start copying to the beginning of the stack space,
4967 by setting SKIP to 0. */
4968 skip = (reg_parm_stack_space == 0) ? 0 : used;
4969
4970#ifdef PUSH_ROUNDING
4971 /* NB: Let the backend known the number of bytes to push and
4972 decide if push insns should be generated. */
4973 unsigned int push_size;
4974 if (CONST_INT_P (size))
4975 push_size = INTVAL (size);
4976 else
4977 push_size = 0;
4978
4979 /* Do it with several push insns if that doesn't take lots of insns
4980 and if there is no difficulty with push insns that skip bytes
4981 on the stack for alignment purposes. */
4982 if (args_addr == 0
4983 && targetm.calls.push_argument (push_size)
4984 && CONST_INT_P (size)
4985 && skip == 0
4986 && MEM_ALIGN (xinner) >= align
4987 && can_move_by_pieces (len: (unsigned) INTVAL (size) - used, align)
4988 /* Here we avoid the case of a structure whose weak alignment
4989 forces many pushes of a small amount of data,
4990 and such small pushes do rounding that causes trouble. */
4991 && ((!targetm.slow_unaligned_access (word_mode, align))
4992 || align >= BIGGEST_ALIGNMENT
4993 || known_eq (PUSH_ROUNDING (align / BITS_PER_UNIT),
4994 align / BITS_PER_UNIT))
4995 && known_eq (PUSH_ROUNDING (INTVAL (size)), INTVAL (size)))
4996 {
4997 /* Push padding now if padding above and stack grows down,
4998 or if padding below and stack grows up.
4999 But if space already allocated, this has already been done. */
5000 if (maybe_ne (a: extra, b: 0)
5001 && args_addr == 0
5002 && where_pad != PAD_NONE
5003 && where_pad != stack_direction)
5004 anti_adjust_stack (gen_int_mode (extra, Pmode));
5005
5006 move_by_pieces (NULL, from: xinner, INTVAL (size) - used, align,
5007 retmode: RETURN_BEGIN);
5008 }
5009 else
5010#endif /* PUSH_ROUNDING */
5011 {
5012 rtx target;
5013
5014 /* Otherwise make space on the stack and copy the data
5015 to the address of that space. */
5016
5017 /* Deduct words put into registers from the size we must copy. */
5018 if (partial != 0)
5019 {
5020 if (CONST_INT_P (size))
5021 size = GEN_INT (INTVAL (size) - used);
5022 else
5023 size = expand_binop (GET_MODE (size), sub_optab, size,
5024 gen_int_mode (used, GET_MODE (size)),
5025 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5026 }
5027
5028 /* Get the address of the stack space.
5029 In this case, we do not deal with EXTRA separately.
5030 A single stack adjust will do. */
5031 poly_int64 const_args_so_far;
5032 if (! args_addr)
5033 {
5034 temp = push_block (size, extra, below: where_pad == PAD_DOWNWARD);
5035 extra = 0;
5036 }
5037 else if (poly_int_rtx_p (x: args_so_far, res: &const_args_so_far))
5038 temp = memory_address (BLKmode,
5039 plus_constant (Pmode, args_addr,
5040 skip + const_args_so_far));
5041 else
5042 temp = memory_address (BLKmode,
5043 plus_constant (Pmode,
5044 gen_rtx_PLUS (Pmode,
5045 args_addr,
5046 args_so_far),
5047 skip));
5048
5049 if (!ACCUMULATE_OUTGOING_ARGS)
5050 {
5051 /* If the source is referenced relative to the stack pointer,
5052 copy it to another register to stabilize it. We do not need
5053 to do this if we know that we won't be changing sp. */
5054
5055 if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
5056 || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
5057 temp = copy_to_reg (temp);
5058 }
5059
5060 target = gen_rtx_MEM (BLKmode, temp);
5061
5062 /* We do *not* set_mem_attributes here, because incoming arguments
5063 may overlap with sibling call outgoing arguments and we cannot
5064 allow reordering of reads from function arguments with stores
5065 to outgoing arguments of sibling calls. We do, however, want
5066 to record the alignment of the stack slot. */
5067 /* ALIGN may well be better aligned than TYPE, e.g. due to
5068 PARM_BOUNDARY. Assume the caller isn't lying. */
5069 set_mem_align (target, align);
5070
5071 /* If part should go in registers and pushing to that part would
5072 overwrite some of the values that need to go into regs, load the
5073 overlapping values into temporary pseudos to be moved into the hard
5074 regs at the end after the stack pushing has completed.
5075 We cannot load them directly into the hard regs here because
5076 they can be clobbered by the block move expansions.
5077 See PR 65358. */
5078
5079 if (partial > 0 && reg != 0 && mode == BLKmode
5080 && GET_CODE (reg) != PARALLEL)
5081 {
5082 overlapping = memory_load_overlap (XEXP (x, 0), y: temp, size: partial);
5083 if (overlapping > 0)
5084 {
5085 gcc_assert (overlapping % UNITS_PER_WORD == 0);
5086 overlapping /= UNITS_PER_WORD;
5087
5088 tmp_regs = XALLOCAVEC (rtx, overlapping);
5089
5090 for (int i = 0; i < overlapping; i++)
5091 tmp_regs[i] = gen_reg_rtx (word_mode);
5092
5093 for (int i = 0; i < overlapping; i++)
5094 emit_move_insn (x: tmp_regs[i],
5095 y: operand_subword_force (target, i, mode));
5096 }
5097 else if (overlapping == -1)
5098 overlapping = 0;
5099 /* Could not determine whether there is overlap.
5100 Fail the sibcall. */
5101 else
5102 {
5103 overlapping = 0;
5104 if (sibcall_p)
5105 return false;
5106 }
5107 }
5108
5109 /* If source is a constant VAR_DECL with a simple constructor,
5110 store the constructor to the stack instead of moving it. */
5111 const_tree decl;
5112 if (partial == 0
5113 && MEM_P (xinner)
5114 && SYMBOL_REF_P (XEXP (xinner, 0))
5115 && (decl = SYMBOL_REF_DECL (XEXP (xinner, 0))) != NULL_TREE
5116 && VAR_P (decl)
5117 && TREE_READONLY (decl)
5118 && !TREE_SIDE_EFFECTS (decl)
5119 && immediate_const_ctor_p (DECL_INITIAL (decl), words: 2))
5120 store_constructor (DECL_INITIAL (decl), target, 0,
5121 int_expr_size (DECL_INITIAL (decl)), false);
5122 else
5123 emit_block_move (x: target, y: xinner, size, method: BLOCK_OP_CALL_PARM);
5124 }
5125 }
5126 else if (partial > 0)
5127 {
5128 /* Scalar partly in registers. This case is only supported
5129 for fixed-wdth modes. */
5130 int num_words = GET_MODE_SIZE (mode).to_constant ();
5131 num_words /= UNITS_PER_WORD;
5132 int i;
5133 int not_stack;
5134 /* # bytes of start of argument
5135 that we must make space for but need not store. */
5136 int offset = partial % (PARM_BOUNDARY / BITS_PER_UNIT);
5137 int args_offset = INTVAL (args_so_far);
5138 int skip;
5139
5140 /* Push padding now if padding above and stack grows down,
5141 or if padding below and stack grows up.
5142 But if space already allocated, this has already been done. */
5143 if (maybe_ne (a: extra, b: 0)
5144 && args_addr == 0
5145 && where_pad != PAD_NONE
5146 && where_pad != stack_direction)
5147 anti_adjust_stack (gen_int_mode (extra, Pmode));
5148
5149 /* If we make space by pushing it, we might as well push
5150 the real data. Otherwise, we can leave OFFSET nonzero
5151 and leave the space uninitialized. */
5152 if (args_addr == 0)
5153 offset = 0;
5154
5155 /* Now NOT_STACK gets the number of words that we don't need to
5156 allocate on the stack. Convert OFFSET to words too. */
5157 not_stack = (partial - offset) / UNITS_PER_WORD;
5158 offset /= UNITS_PER_WORD;
5159
5160 /* If the partial register-part of the arg counts in its stack size,
5161 skip the part of stack space corresponding to the registers.
5162 Otherwise, start copying to the beginning of the stack space,
5163 by setting SKIP to 0. */
5164 skip = (reg_parm_stack_space == 0) ? 0 : not_stack;
5165
5166 if (CONSTANT_P (x) && !targetm.legitimate_constant_p (mode, x))
5167 x = validize_mem (force_const_mem (mode, x));
5168
5169 /* If X is a hard register in a non-integer mode, copy it into a pseudo;
5170 SUBREGs of such registers are not allowed. */
5171 if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER
5172 && GET_MODE_CLASS (GET_MODE (x)) != MODE_INT))
5173 x = copy_to_reg (x);
5174
5175 /* Loop over all the words allocated on the stack for this arg. */
5176 /* We can do it by words, because any scalar bigger than a word
5177 has a size a multiple of a word. */
5178 for (i = num_words - 1; i >= not_stack; i--)
5179 if (i >= not_stack + offset)
5180 if (!emit_push_insn (x: operand_subword_force (x, i, mode),
5181 mode: word_mode, NULL_TREE, NULL_RTX, align, partial: 0, NULL_RTX,
5182 extra: 0, args_addr,
5183 GEN_INT (args_offset + ((i - not_stack + skip)
5184 * UNITS_PER_WORD)),
5185 reg_parm_stack_space, alignment_pad, sibcall_p))
5186 return false;
5187 }
5188 else
5189 {
5190 rtx addr;
5191 rtx dest;
5192
5193 /* Push padding now if padding above and stack grows down,
5194 or if padding below and stack grows up.
5195 But if space already allocated, this has already been done. */
5196 if (maybe_ne (a: extra, b: 0)
5197 && args_addr == 0
5198 && where_pad != PAD_NONE
5199 && where_pad != stack_direction)
5200 anti_adjust_stack (gen_int_mode (extra, Pmode));
5201
5202#ifdef PUSH_ROUNDING
5203 if (args_addr == 0 && targetm.calls.push_argument (0))
5204 emit_single_push_insn (mode, x, type);
5205 else
5206#endif
5207 {
5208 addr = simplify_gen_binary (code: PLUS, Pmode, op0: args_addr, op1: args_so_far);
5209 dest = gen_rtx_MEM (mode, memory_address (mode, addr));
5210
5211 /* We do *not* set_mem_attributes here, because incoming arguments
5212 may overlap with sibling call outgoing arguments and we cannot
5213 allow reordering of reads from function arguments with stores
5214 to outgoing arguments of sibling calls. We do, however, want
5215 to record the alignment of the stack slot. */
5216 /* ALIGN may well be better aligned than TYPE, e.g. due to
5217 PARM_BOUNDARY. Assume the caller isn't lying. */
5218 set_mem_align (dest, align);
5219
5220 emit_move_insn (x: dest, y: x);
5221 }
5222 }
5223
5224 /* Move the partial arguments into the registers and any overlapping
5225 values that we moved into the pseudos in tmp_regs. */
5226 if (partial > 0 && reg != 0)
5227 {
5228 /* Handle calls that pass values in multiple non-contiguous locations.
5229 The Irix 6 ABI has examples of this. */
5230 if (GET_CODE (reg) == PARALLEL)
5231 emit_group_load (dst: reg, src: x, type, ssize: -1);
5232 else
5233 {
5234 gcc_assert (partial % UNITS_PER_WORD == 0);
5235 move_block_to_reg (REGNO (reg), x, nregs: nregs - overlapping, mode);
5236
5237 for (int i = 0; i < overlapping; i++)
5238 emit_move_insn (x: gen_rtx_REG (word_mode, REGNO (reg)
5239 + nregs - overlapping + i),
5240 y: tmp_regs[i]);
5241
5242 }
5243 }
5244
5245 if (maybe_ne (a: extra, b: 0) && args_addr == 0 && where_pad == stack_direction)
5246 anti_adjust_stack (gen_int_mode (extra, Pmode));
5247
5248 if (alignment_pad && args_addr == 0)
5249 anti_adjust_stack (alignment_pad);
5250
5251 return true;
5252}
5253
5254/* Return X if X can be used as a subtarget in a sequence of arithmetic
5255 operations. */
5256
5257static rtx
5258get_subtarget (rtx x)
5259{
5260 return (optimize
5261 || x == 0
5262 /* Only registers can be subtargets. */
5263 || !REG_P (x)
5264 /* Don't use hard regs to avoid extending their life. */
5265 || REGNO (x) < FIRST_PSEUDO_REGISTER
5266 ? 0 : x);
5267}
5268
5269/* A subroutine of expand_assignment. Optimize FIELD op= VAL, where
5270 FIELD is a bitfield. Returns true if the optimization was successful,
5271 and there's nothing else to do. */
5272
5273static bool
5274optimize_bitfield_assignment_op (poly_uint64 pbitsize,
5275 poly_uint64 pbitpos,
5276 poly_uint64 pbitregion_start,
5277 poly_uint64 pbitregion_end,
5278 machine_mode mode1, rtx str_rtx,
5279 tree to, tree src, bool reverse)
5280{
5281 /* str_mode is not guaranteed to be a scalar type. */
5282 machine_mode str_mode = GET_MODE (str_rtx);
5283 unsigned int str_bitsize;
5284 tree op0, op1;
5285 rtx value, result;
5286 optab binop;
5287 gimple *srcstmt;
5288 enum tree_code code;
5289
5290 unsigned HOST_WIDE_INT bitsize, bitpos, bitregion_start, bitregion_end;
5291 if (mode1 != VOIDmode
5292 || !pbitsize.is_constant (const_value: &bitsize)
5293 || !pbitpos.is_constant (const_value: &bitpos)
5294 || !pbitregion_start.is_constant (const_value: &bitregion_start)
5295 || !pbitregion_end.is_constant (const_value: &bitregion_end)
5296 || bitsize >= BITS_PER_WORD
5297 || !GET_MODE_BITSIZE (mode: str_mode).is_constant (const_value: &str_bitsize)
5298 || str_bitsize > BITS_PER_WORD
5299 || TREE_SIDE_EFFECTS (to)
5300 || TREE_THIS_VOLATILE (to))
5301 return false;
5302
5303 STRIP_NOPS (src);
5304 if (TREE_CODE (src) != SSA_NAME)
5305 return false;
5306 if (TREE_CODE (TREE_TYPE (src)) != INTEGER_TYPE)
5307 return false;
5308
5309 srcstmt = get_gimple_for_ssa_name (exp: src);
5310 if (!srcstmt
5311 || TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
5312 return false;
5313
5314 code = gimple_assign_rhs_code (gs: srcstmt);
5315
5316 op0 = gimple_assign_rhs1 (gs: srcstmt);
5317
5318 /* If OP0 is an SSA_NAME, then we want to walk the use-def chain
5319 to find its initialization. Hopefully the initialization will
5320 be from a bitfield load. */
5321 if (TREE_CODE (op0) == SSA_NAME)
5322 {
5323 gimple *op0stmt = get_gimple_for_ssa_name (exp: op0);
5324
5325 /* We want to eventually have OP0 be the same as TO, which
5326 should be a bitfield. */
5327 if (!op0stmt
5328 || !is_gimple_assign (gs: op0stmt)
5329 || gimple_assign_rhs_code (gs: op0stmt) != TREE_CODE (to))
5330 return false;
5331 op0 = gimple_assign_rhs1 (gs: op0stmt);
5332 }
5333
5334 op1 = gimple_assign_rhs2 (gs: srcstmt);
5335
5336 if (!operand_equal_p (to, op0, flags: 0))
5337 return false;
5338
5339 if (MEM_P (str_rtx))
5340 {
5341 unsigned HOST_WIDE_INT offset1;
5342
5343 if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
5344 str_bitsize = BITS_PER_WORD;
5345
5346 scalar_int_mode best_mode;
5347 if (!get_best_mode (bitsize, bitpos, bitregion_start, bitregion_end,
5348 MEM_ALIGN (str_rtx), str_bitsize, false, &best_mode))
5349 return false;
5350 str_mode = best_mode;
5351 str_bitsize = GET_MODE_BITSIZE (mode: best_mode);
5352
5353 offset1 = bitpos;
5354 bitpos %= str_bitsize;
5355 offset1 = (offset1 - bitpos) / BITS_PER_UNIT;
5356 str_rtx = adjust_address (str_rtx, str_mode, offset1);
5357 }
5358 else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG)
5359 return false;
5360
5361 /* If the bit field covers the whole REG/MEM, store_field
5362 will likely generate better code. */
5363 if (bitsize >= str_bitsize)
5364 return false;
5365
5366 /* We can't handle fields split across multiple entities. */
5367 if (bitpos + bitsize > str_bitsize)
5368 return false;
5369
5370 if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
5371 bitpos = str_bitsize - bitpos - bitsize;
5372
5373 switch (code)
5374 {
5375 case PLUS_EXPR:
5376 case MINUS_EXPR:
5377 /* For now, just optimize the case of the topmost bitfield
5378 where we don't need to do any masking and also
5379 1 bit bitfields where xor can be used.
5380 We might win by one instruction for the other bitfields
5381 too if insv/extv instructions aren't used, so that
5382 can be added later. */
5383 if ((reverse || bitpos + bitsize != str_bitsize)
5384 && (bitsize != 1 || TREE_CODE (op1) != INTEGER_CST))
5385 break;
5386
5387 value = expand_expr (exp: op1, NULL_RTX, mode: str_mode, modifier: EXPAND_NORMAL);
5388 value = convert_modes (mode: str_mode,
5389 TYPE_MODE (TREE_TYPE (op1)), x: value,
5390 TYPE_UNSIGNED (TREE_TYPE (op1)));
5391
5392 /* We may be accessing data outside the field, which means
5393 we can alias adjacent data. */
5394 if (MEM_P (str_rtx))
5395 {
5396 str_rtx = shallow_copy_rtx (str_rtx);
5397 set_mem_alias_set (str_rtx, 0);
5398 set_mem_expr (str_rtx, 0);
5399 }
5400
5401 if (bitsize == 1 && (reverse || bitpos + bitsize != str_bitsize))
5402 {
5403 value = expand_and (str_mode, value, const1_rtx, NULL);
5404 binop = xor_optab;
5405 }
5406 else
5407 binop = code == PLUS_EXPR ? add_optab : sub_optab;
5408
5409 value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5410 if (reverse)
5411 value = flip_storage_order (str_mode, value);
5412 result = expand_binop (str_mode, binop, str_rtx,
5413 value, str_rtx, 1, OPTAB_WIDEN);
5414 if (result != str_rtx)
5415 emit_move_insn (x: str_rtx, y: result);
5416 return true;
5417
5418 case BIT_IOR_EXPR:
5419 case BIT_XOR_EXPR:
5420 if (TREE_CODE (op1) != INTEGER_CST)
5421 break;
5422 value = expand_expr (exp: op1, NULL_RTX, mode: str_mode, modifier: EXPAND_NORMAL);
5423 value = convert_modes (mode: str_mode,
5424 TYPE_MODE (TREE_TYPE (op1)), x: value,
5425 TYPE_UNSIGNED (TREE_TYPE (op1)));
5426
5427 /* We may be accessing data outside the field, which means
5428 we can alias adjacent data. */
5429 if (MEM_P (str_rtx))
5430 {
5431 str_rtx = shallow_copy_rtx (str_rtx);
5432 set_mem_alias_set (str_rtx, 0);
5433 set_mem_expr (str_rtx, 0);
5434 }
5435
5436 binop = code == BIT_IOR_EXPR ? ior_optab : xor_optab;
5437 if (bitpos + bitsize != str_bitsize)
5438 {
5439 rtx mask = gen_int_mode ((HOST_WIDE_INT_1U << bitsize) - 1,
5440 str_mode);
5441 value = expand_and (str_mode, value, mask, NULL_RTX);
5442 }
5443 value = expand_shift (LSHIFT_EXPR, str_mode, value, bitpos, NULL_RTX, 1);
5444 if (reverse)
5445 value = flip_storage_order (str_mode, value);
5446 result = expand_binop (str_mode, binop, str_rtx,
5447 value, str_rtx, 1, OPTAB_WIDEN);
5448 if (result != str_rtx)
5449 emit_move_insn (x: str_rtx, y: result);
5450 return true;
5451
5452 default:
5453 break;
5454 }
5455
5456 return false;
5457}
5458
5459/* In the C++ memory model, consecutive bit fields in a structure are
5460 considered one memory location.
5461
5462 Given a COMPONENT_REF EXP at position (BITPOS, OFFSET), this function
5463 returns the bit range of consecutive bits in which this COMPONENT_REF
5464 belongs. The values are returned in *BITSTART and *BITEND. *BITPOS
5465 and *OFFSET may be adjusted in the process.
5466
5467 If the access does not need to be restricted, 0 is returned in both
5468 *BITSTART and *BITEND. */
5469
5470void
5471get_bit_range (poly_uint64 *bitstart, poly_uint64 *bitend, tree exp,
5472 poly_int64 *bitpos, tree *offset)
5473{
5474 poly_int64 bitoffset;
5475 tree field, repr;
5476
5477 gcc_assert (TREE_CODE (exp) == COMPONENT_REF);
5478
5479 field = TREE_OPERAND (exp, 1);
5480 repr = DECL_BIT_FIELD_REPRESENTATIVE (field);
5481 /* If we do not have a DECL_BIT_FIELD_REPRESENTATIVE there is no
5482 need to limit the range we can access. */
5483 if (!repr)
5484 {
5485 *bitstart = *bitend = 0;
5486 return;
5487 }
5488
5489 /* If we have a DECL_BIT_FIELD_REPRESENTATIVE but the enclosing record is
5490 part of a larger bit field, then the representative does not serve any
5491 useful purpose. This can occur in Ada. */
5492 if (handled_component_p (TREE_OPERAND (exp, 0)))
5493 {
5494 machine_mode rmode;
5495 poly_int64 rbitsize, rbitpos;
5496 tree roffset;
5497 int unsignedp, reversep, volatilep = 0;
5498 get_inner_reference (TREE_OPERAND (exp, 0), &rbitsize, &rbitpos,
5499 &roffset, &rmode, &unsignedp, &reversep,
5500 &volatilep);
5501 if (!multiple_p (a: rbitpos, BITS_PER_UNIT))
5502 {
5503 *bitstart = *bitend = 0;
5504 return;
5505 }
5506 }
5507
5508 /* Compute the adjustment to bitpos from the offset of the field
5509 relative to the representative. DECL_FIELD_OFFSET of field and
5510 repr are the same by construction if they are not constants,
5511 see finish_bitfield_layout. */
5512 poly_uint64 field_offset, repr_offset;
5513 if (poly_int_tree_p (DECL_FIELD_OFFSET (field), value: &field_offset)
5514 && poly_int_tree_p (DECL_FIELD_OFFSET (repr), value: &repr_offset))
5515 bitoffset = (field_offset - repr_offset) * BITS_PER_UNIT;
5516 else
5517 bitoffset = 0;
5518 bitoffset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
5519 - tree_to_uhwi (DECL_FIELD_BIT_OFFSET (repr)));
5520
5521 /* If the adjustment is larger than bitpos, we would have a negative bit
5522 position for the lower bound and this may wreak havoc later. Adjust
5523 offset and bitpos to make the lower bound non-negative in that case. */
5524 if (maybe_gt (bitoffset, *bitpos))
5525 {
5526 poly_int64 adjust_bits = upper_bound (a: bitoffset, b: *bitpos) - *bitpos;
5527 poly_int64 adjust_bytes = exact_div (a: adjust_bits, BITS_PER_UNIT);
5528
5529 *bitpos += adjust_bits;
5530 if (*offset == NULL_TREE)
5531 *offset = size_int (-adjust_bytes);
5532 else
5533 *offset = size_binop (MINUS_EXPR, *offset, size_int (adjust_bytes));
5534 *bitstart = 0;
5535 }
5536 else
5537 *bitstart = *bitpos - bitoffset;
5538
5539 *bitend = *bitstart + tree_to_poly_uint64 (DECL_SIZE (repr)) - 1;
5540}
5541
5542/* Returns true if BASE is a DECL that does not reside in memory and
5543 has non-BLKmode. DECL_RTL must not be a MEM; if
5544 DECL_RTL was not set yet, return false. */
5545
5546bool
5547non_mem_decl_p (tree base)
5548{
5549 if (!DECL_P (base)
5550 || TREE_ADDRESSABLE (base)
5551 || DECL_MODE (base) == BLKmode)
5552 return false;
5553
5554 if (!DECL_RTL_SET_P (base))
5555 return false;
5556
5557 return (!MEM_P (DECL_RTL (base)));
5558}
5559
5560/* Returns true if REF refers to an object that does not
5561 reside in memory and has non-BLKmode. */
5562
5563bool
5564mem_ref_refers_to_non_mem_p (tree ref)
5565{
5566 tree base;
5567
5568 if (TREE_CODE (ref) == MEM_REF
5569 || TREE_CODE (ref) == TARGET_MEM_REF)
5570 {
5571 tree addr = TREE_OPERAND (ref, 0);
5572
5573 if (TREE_CODE (addr) != ADDR_EXPR)
5574 return false;
5575
5576 base = TREE_OPERAND (addr, 0);
5577 }
5578 else
5579 base = ref;
5580
5581 return non_mem_decl_p (base);
5582}
5583
5584/* Expand an assignment that stores the value of FROM into TO. If NONTEMPORAL
5585 is true, try generating a nontemporal store. */
5586
5587void
5588expand_assignment (tree to, tree from, bool nontemporal)
5589{
5590 rtx to_rtx = 0;
5591 rtx result;
5592 machine_mode mode;
5593 unsigned int align;
5594 enum insn_code icode;
5595
5596 /* Don't crash if the lhs of the assignment was erroneous. */
5597 if (TREE_CODE (to) == ERROR_MARK)
5598 {
5599 expand_normal (exp: from);
5600 return;
5601 }
5602
5603 /* Optimize away no-op moves without side-effects. */
5604 if (operand_equal_p (to, from, flags: 0))
5605 return;
5606
5607 /* Handle misaligned stores. */
5608 mode = TYPE_MODE (TREE_TYPE (to));
5609 if ((TREE_CODE (to) == MEM_REF
5610 || TREE_CODE (to) == TARGET_MEM_REF
5611 || DECL_P (to))
5612 && mode != BLKmode
5613 && !mem_ref_refers_to_non_mem_p (ref: to)
5614 && ((align = get_object_alignment (to))
5615 < GET_MODE_ALIGNMENT (mode))
5616 && (((icode = optab_handler (op: movmisalign_optab, mode))
5617 != CODE_FOR_nothing)
5618 || targetm.slow_unaligned_access (mode, align)))
5619 {
5620 rtx reg, mem;
5621
5622 reg = expand_expr (exp: from, NULL_RTX, VOIDmode, modifier: EXPAND_NORMAL);
5623 /* Handle PARALLEL. */
5624 reg = maybe_emit_group_store (x: reg, TREE_TYPE (from));
5625 reg = force_not_mem (reg);
5626 mem = expand_expr (exp: to, NULL_RTX, VOIDmode, modifier: EXPAND_WRITE);
5627 if (TREE_CODE (to) == MEM_REF && REF_REVERSE_STORAGE_ORDER (to))
5628 reg = flip_storage_order (mode, reg);
5629
5630 if (icode != CODE_FOR_nothing)
5631 {
5632 class expand_operand ops[2];
5633
5634 create_fixed_operand (op: &ops[0], x: mem);
5635 create_input_operand (op: &ops[1], value: reg, mode);
5636 /* The movmisalign<mode> pattern cannot fail, else the assignment
5637 would silently be omitted. */
5638 expand_insn (icode, nops: 2, ops);
5639 }
5640 else
5641 store_bit_field (mem, GET_MODE_BITSIZE (mode), 0, 0, 0, mode, reg,
5642 false, false);
5643 return;
5644 }
5645
5646 /* Assignment of a structure component needs special treatment
5647 if the structure component's rtx is not simply a MEM.
5648 Assignment of an array element at a constant index, and assignment of
5649 an array element in an unaligned packed structure field, has the same
5650 problem. Same for (partially) storing into a non-memory object. */
5651 if (handled_component_p (t: to)
5652 || (TREE_CODE (to) == MEM_REF
5653 && (REF_REVERSE_STORAGE_ORDER (to)
5654 || mem_ref_refers_to_non_mem_p (ref: to)))
5655 || TREE_CODE (TREE_TYPE (to)) == ARRAY_TYPE)
5656 {
5657 machine_mode mode1;
5658 poly_int64 bitsize, bitpos;
5659 poly_uint64 bitregion_start = 0;
5660 poly_uint64 bitregion_end = 0;
5661 tree offset;
5662 int unsignedp, reversep, volatilep = 0;
5663 tree tem;
5664
5665 push_temp_slots ();
5666 tem = get_inner_reference (to, &bitsize, &bitpos, &offset, &mode1,
5667 &unsignedp, &reversep, &volatilep);
5668
5669 /* Make sure bitpos is not negative, it can wreak havoc later. */
5670 if (maybe_lt (a: bitpos, b: 0))
5671 {
5672 gcc_assert (offset == NULL_TREE);
5673 offset = size_int (bits_to_bytes_round_down (bitpos));
5674 bitpos = num_trailing_bits (bitpos);
5675 }
5676
5677 if (TREE_CODE (to) == COMPONENT_REF
5678 && DECL_BIT_FIELD_TYPE (TREE_OPERAND (to, 1)))
5679 get_bit_range (bitstart: &bitregion_start, bitend: &bitregion_end, exp: to, bitpos: &bitpos, offset: &offset);
5680 /* The C++ memory model naturally applies to byte-aligned fields.
5681 However, if we do not have a DECL_BIT_FIELD_TYPE but BITPOS or
5682 BITSIZE are not byte-aligned, there is no need to limit the range
5683 we can access. This can occur with packed structures in Ada. */
5684 else if (maybe_gt (bitsize, 0)
5685 && multiple_p (a: bitsize, BITS_PER_UNIT)
5686 && multiple_p (a: bitpos, BITS_PER_UNIT))
5687 {
5688 bitregion_start = bitpos;
5689 bitregion_end = bitpos + bitsize - 1;
5690 }
5691
5692 to_rtx = expand_expr (exp: tem, NULL_RTX, VOIDmode, modifier: EXPAND_WRITE);
5693
5694 /* If the field has a mode, we want to access it in the
5695 field's mode, not the computed mode.
5696 If a MEM has VOIDmode (external with incomplete type),
5697 use BLKmode for it instead. */
5698 if (MEM_P (to_rtx))
5699 {
5700 if (mode1 != VOIDmode)
5701 to_rtx = adjust_address (to_rtx, mode1, 0);
5702 else if (GET_MODE (to_rtx) == VOIDmode)
5703 to_rtx = adjust_address (to_rtx, BLKmode, 0);
5704 }
5705
5706 if (offset != 0)
5707 {
5708 machine_mode address_mode;
5709 rtx offset_rtx;
5710
5711 if (!MEM_P (to_rtx))
5712 {
5713 /* We can get constant negative offsets into arrays with broken
5714 user code. Translate this to a trap instead of ICEing. */
5715 gcc_assert (TREE_CODE (offset) == INTEGER_CST);
5716 expand_builtin_trap ();
5717 to_rtx = gen_rtx_MEM (BLKmode, const0_rtx);
5718 }
5719
5720 offset_rtx = expand_expr (exp: offset, NULL_RTX, VOIDmode, modifier: EXPAND_SUM);
5721 address_mode = get_address_mode (mem: to_rtx);
5722 if (GET_MODE (offset_rtx) != address_mode)
5723 {
5724 /* We cannot be sure that the RTL in offset_rtx is valid outside
5725 of a memory address context, so force it into a register
5726 before attempting to convert it to the desired mode. */
5727 offset_rtx = force_operand (offset_rtx, NULL_RTX);
5728 offset_rtx = convert_to_mode (mode: address_mode, x: offset_rtx, unsignedp: 0);
5729 }
5730
5731 /* If we have an expression in OFFSET_RTX and a non-zero
5732 byte offset in BITPOS, adding the byte offset before the
5733 OFFSET_RTX results in better intermediate code, which makes
5734 later rtl optimization passes perform better.
5735
5736 We prefer intermediate code like this:
5737
5738 r124:DI=r123:DI+0x18
5739 [r124:DI]=r121:DI
5740
5741 ... instead of ...
5742
5743 r124:DI=r123:DI+0x10
5744 [r124:DI+0x8]=r121:DI
5745
5746 This is only done for aligned data values, as these can
5747 be expected to result in single move instructions. */
5748 poly_int64 bytepos;
5749 if (mode1 != VOIDmode
5750 && maybe_ne (a: bitpos, b: 0)
5751 && maybe_gt (bitsize, 0)
5752 && multiple_p (a: bitpos, BITS_PER_UNIT, multiple: &bytepos)
5753 && multiple_p (a: bitpos, b: bitsize)
5754 && multiple_p (a: bitsize, GET_MODE_ALIGNMENT (mode1))
5755 && MEM_ALIGN (to_rtx) >= GET_MODE_ALIGNMENT (mode1))
5756 {
5757 to_rtx = adjust_address (to_rtx, mode1, bytepos);
5758 bitregion_start = 0;
5759 if (known_ge (bitregion_end, poly_uint64 (bitpos)))
5760 bitregion_end -= bitpos;
5761 bitpos = 0;
5762 }
5763
5764 to_rtx = offset_address (to_rtx, offset_rtx,
5765 highest_pow2_factor_for_target (to,
5766 offset));
5767 }
5768
5769 /* No action is needed if the target is not a memory and the field
5770 lies completely outside that target. This can occur if the source
5771 code contains an out-of-bounds access to a small array. */
5772 if (!MEM_P (to_rtx)
5773 && GET_MODE (to_rtx) != BLKmode
5774 && known_ge (bitpos, GET_MODE_PRECISION (GET_MODE (to_rtx))))
5775 {
5776 expand_normal (exp: from);
5777 result = NULL;
5778 }
5779 /* Handle expand_expr of a complex value returning a CONCAT. */
5780 else if (GET_CODE (to_rtx) == CONCAT)
5781 {
5782 machine_mode to_mode = GET_MODE (to_rtx);
5783 gcc_checking_assert (COMPLEX_MODE_P (to_mode));
5784 poly_int64 mode_bitsize = GET_MODE_BITSIZE (mode: to_mode);
5785 unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode);
5786 if (TYPE_MODE (TREE_TYPE (from)) == to_mode
5787 && known_eq (bitpos, 0)
5788 && known_eq (bitsize, mode_bitsize))
5789 result = store_expr (from, to_rtx, false, nontemporal, reversep);
5790 else if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE_INNER (to_mode)
5791 && known_eq (bitsize, inner_bitsize)
5792 && (known_eq (bitpos, 0)
5793 || known_eq (bitpos, inner_bitsize)))
5794 result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)),
5795 false, nontemporal, reversep);
5796 else if (known_le (bitpos + bitsize, inner_bitsize))
5797 result = store_field (XEXP (to_rtx, 0), bitsize, bitpos,
5798 bitregion_start, bitregion_end,
5799 mode1, from, get_alias_set (to),
5800 nontemporal, reversep);
5801 else if (known_ge (bitpos, inner_bitsize))
5802 result = store_field (XEXP (to_rtx, 1), bitsize,
5803 bitpos - inner_bitsize,
5804 bitregion_start, bitregion_end,
5805 mode1, from, get_alias_set (to),
5806 nontemporal, reversep);
5807 else if (known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize))
5808 {
5809 result = expand_normal (exp: from);
5810 if (GET_CODE (result) == CONCAT)
5811 {
5812 to_mode = GET_MODE_INNER (to_mode);
5813 machine_mode from_mode = GET_MODE_INNER (GET_MODE (result));
5814 rtx from_real
5815 = simplify_gen_subreg (outermode: to_mode, XEXP (result, 0),
5816 innermode: from_mode, byte: 0);
5817 rtx from_imag
5818 = simplify_gen_subreg (outermode: to_mode, XEXP (result, 1),
5819 innermode: from_mode, byte: 0);
5820 if (!from_real || !from_imag)
5821 goto concat_store_slow;
5822 emit_move_insn (XEXP (to_rtx, 0), y: from_real);
5823 emit_move_insn (XEXP (to_rtx, 1), y: from_imag);
5824 }
5825 else
5826 {
5827 machine_mode from_mode
5828 = GET_MODE (result) == VOIDmode
5829 ? TYPE_MODE (TREE_TYPE (from))
5830 : GET_MODE (result);
5831 rtx from_rtx;
5832 if (MEM_P (result))
5833 from_rtx = change_address (result, to_mode, NULL_RTX);
5834 else
5835 from_rtx
5836 = simplify_gen_subreg (outermode: to_mode, op: result, innermode: from_mode, byte: 0);
5837 if (from_rtx)
5838 {
5839 emit_move_insn (XEXP (to_rtx, 0),
5840 y: read_complex_part (cplx: from_rtx, imag_p: false));
5841 emit_move_insn (XEXP (to_rtx, 1),
5842 y: read_complex_part (cplx: from_rtx, imag_p: true));
5843 }
5844 else
5845 {
5846 to_mode = GET_MODE_INNER (to_mode);
5847 rtx from_real
5848 = simplify_gen_subreg (outermode: to_mode, op: result, innermode: from_mode, byte: 0);
5849 rtx from_imag
5850 = simplify_gen_subreg (outermode: to_mode, op: result, innermode: from_mode,
5851 byte: GET_MODE_SIZE (mode: to_mode));
5852 if (!from_real || !from_imag)
5853 goto concat_store_slow;
5854 emit_move_insn (XEXP (to_rtx, 0), y: from_real);
5855 emit_move_insn (XEXP (to_rtx, 1), y: from_imag);
5856 }
5857 }
5858 }
5859 else
5860 {
5861 concat_store_slow:;
5862 rtx temp = assign_stack_temp (GET_MODE (to_rtx),
5863 GET_MODE_SIZE (GET_MODE (to_rtx)));
5864 write_complex_part (cplx: temp, XEXP (to_rtx, 0), imag_p: false, undefined_p: true);
5865 write_complex_part (cplx: temp, XEXP (to_rtx, 1), imag_p: true, undefined_p: false);
5866 result = store_field (temp, bitsize, bitpos,
5867 bitregion_start, bitregion_end,
5868 mode1, from, get_alias_set (to),
5869 nontemporal, reversep);
5870 emit_move_insn (XEXP (to_rtx, 0), y: read_complex_part (cplx: temp, imag_p: false));
5871 emit_move_insn (XEXP (to_rtx, 1), y: read_complex_part (cplx: temp, imag_p: true));
5872 }
5873 }
5874 /* For calls to functions returning variable length structures, if TO_RTX
5875 is not a MEM, go through a MEM because we must not create temporaries
5876 of the VLA type. */
5877 else if (!MEM_P (to_rtx)
5878 && TREE_CODE (from) == CALL_EXPR
5879 && COMPLETE_TYPE_P (TREE_TYPE (from))
5880 && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
5881 {
5882 rtx temp = assign_stack_temp (GET_MODE (to_rtx),
5883 GET_MODE_SIZE (GET_MODE (to_rtx)));
5884 result = store_field (temp, bitsize, bitpos, bitregion_start,
5885 bitregion_end, mode1, from, get_alias_set (to),
5886 nontemporal, reversep);
5887 emit_move_insn (x: to_rtx, y: temp);
5888 }
5889 else
5890 {
5891 if (MEM_P (to_rtx))
5892 {
5893 /* If the field is at offset zero, we could have been given the
5894 DECL_RTX of the parent struct. Don't munge it. */
5895 to_rtx = shallow_copy_rtx (to_rtx);
5896 set_mem_attributes_minus_bitpos (to_rtx, to, 0, bitpos);
5897 if (volatilep)
5898 MEM_VOLATILE_P (to_rtx) = 1;
5899 }
5900
5901 gcc_checking_assert (known_ge (bitpos, 0));
5902 if (optimize_bitfield_assignment_op (pbitsize: bitsize, pbitpos: bitpos,
5903 pbitregion_start: bitregion_start, pbitregion_end: bitregion_end,
5904 mode1, str_rtx: to_rtx, to, src: from,
5905 reverse: reversep))
5906 result = NULL;
5907 else if (SUBREG_P (to_rtx)
5908 && SUBREG_PROMOTED_VAR_P (to_rtx))
5909 {
5910 /* If to_rtx is a promoted subreg, we need to zero or sign
5911 extend the value afterwards. */
5912 if (TREE_CODE (to) == MEM_REF
5913 && TYPE_MODE (TREE_TYPE (from)) != BLKmode
5914 && !REF_REVERSE_STORAGE_ORDER (to)
5915 && known_eq (bitpos, 0)
5916 && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (to_rtx))))
5917 result = store_expr (from, to_rtx, 0, nontemporal, false);
5918 else
5919 {
5920 rtx to_rtx1
5921 = lowpart_subreg (outermode: subreg_unpromoted_mode (x: to_rtx),
5922 SUBREG_REG (to_rtx),
5923 innermode: subreg_promoted_mode (x: to_rtx));
5924 result = store_field (to_rtx1, bitsize, bitpos,
5925 bitregion_start, bitregion_end,
5926 mode1, from, get_alias_set (to),
5927 nontemporal, reversep);
5928 convert_move (SUBREG_REG (to_rtx), from: to_rtx1,
5929 SUBREG_PROMOTED_SIGN (to_rtx));
5930 }
5931 }
5932 else
5933 result = store_field (to_rtx, bitsize, bitpos,
5934 bitregion_start, bitregion_end,
5935 mode1, from, get_alias_set (to),
5936 nontemporal, reversep);
5937 }
5938
5939 if (result)
5940 preserve_temp_slots (result);
5941 pop_temp_slots ();
5942 return;
5943 }
5944
5945 /* If the rhs is a function call and its value is not an aggregate,
5946 call the function before we start to compute the lhs.
5947 This is needed for correct code for cases such as
5948 val = setjmp (buf) on machines where reference to val
5949 requires loading up part of an address in a separate insn.
5950
5951 Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
5952 since it might be a promoted variable where the zero- or sign- extension
5953 needs to be done. Handling this in the normal way is safe because no
5954 computation is done before the call. The same is true for SSA names. */
5955 if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
5956 && COMPLETE_TYPE_P (TREE_TYPE (from))
5957 && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
5958 && ! (((VAR_P (to)
5959 || TREE_CODE (to) == PARM_DECL
5960 || TREE_CODE (to) == RESULT_DECL)
5961 && REG_P (DECL_RTL (to)))
5962 || TREE_CODE (to) == SSA_NAME))
5963 {
5964 rtx value;
5965
5966 push_temp_slots ();
5967 value = expand_normal (exp: from);
5968
5969 if (to_rtx == 0)
5970 to_rtx = expand_expr (exp: to, NULL_RTX, VOIDmode, modifier: EXPAND_WRITE);
5971
5972 /* Handle calls that return values in multiple non-contiguous locations.
5973 The Irix 6 ABI has examples of this. */
5974 if (GET_CODE (to_rtx) == PARALLEL)
5975 {
5976 if (GET_CODE (value) == PARALLEL)
5977 emit_group_move (dst: to_rtx, src: value);
5978 else
5979 emit_group_load (dst: to_rtx, src: value, TREE_TYPE (from),
5980 ssize: int_size_in_bytes (TREE_TYPE (from)));
5981 }
5982 else if (GET_CODE (value) == PARALLEL)
5983 emit_group_store (orig_dst: to_rtx, src: value, TREE_TYPE (from),
5984 ssize: int_size_in_bytes (TREE_TYPE (from)));
5985 else if (GET_MODE (to_rtx) == BLKmode)
5986 {
5987 /* Handle calls that return BLKmode values in registers. */
5988 if (REG_P (value))
5989 copy_blkmode_from_reg (target: to_rtx, srcreg: value, TREE_TYPE (from));
5990 else
5991 emit_block_move (x: to_rtx, y: value, size: expr_size (from), method: BLOCK_OP_NORMAL);
5992 }
5993 else
5994 {
5995 if (POINTER_TYPE_P (TREE_TYPE (to)))
5996 value = convert_memory_address_addr_space
5997 (as_a <scalar_int_mode> (GET_MODE (to_rtx)), value,
5998 TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (to))));
5999
6000 emit_move_insn (x: to_rtx, y: value);
6001 }
6002
6003 preserve_temp_slots (to_rtx);
6004 pop_temp_slots ();
6005 return;
6006 }
6007
6008 /* Ordinary treatment. Expand TO to get a REG or MEM rtx. */
6009 to_rtx = expand_expr (exp: to, NULL_RTX, VOIDmode, modifier: EXPAND_WRITE);
6010
6011 /* Don't move directly into a return register. */
6012 if (TREE_CODE (to) == RESULT_DECL
6013 && (REG_P (to_rtx) || GET_CODE (to_rtx) == PARALLEL))
6014 {
6015 rtx temp;
6016
6017 push_temp_slots ();
6018
6019 /* If the source is itself a return value, it still is in a pseudo at
6020 this point so we can move it back to the return register directly. */
6021 if (REG_P (to_rtx)
6022 && TYPE_MODE (TREE_TYPE (from)) == BLKmode
6023 && TREE_CODE (from) != CALL_EXPR)
6024 temp = copy_blkmode_to_reg (GET_MODE (to_rtx), src: from);
6025 else
6026 temp = expand_expr (exp: from, NULL_RTX, GET_MODE (to_rtx), modifier: EXPAND_NORMAL);
6027
6028 /* Handle calls that return values in multiple non-contiguous locations.
6029 The Irix 6 ABI has examples of this. */
6030 if (GET_CODE (to_rtx) == PARALLEL)
6031 {
6032 if (GET_CODE (temp) == PARALLEL)
6033 emit_group_move (dst: to_rtx, src: temp);
6034 else
6035 emit_group_load (dst: to_rtx, src: temp, TREE_TYPE (from),
6036 ssize: int_size_in_bytes (TREE_TYPE (from)));
6037 }
6038 else if (temp)
6039 emit_move_insn (x: to_rtx, y: temp);
6040
6041 preserve_temp_slots (to_rtx);
6042 pop_temp_slots ();
6043 return;
6044 }
6045
6046 /* In case we are returning the contents of an object which overlaps
6047 the place the value is being stored, use a safe function when copying
6048 a value through a pointer into a structure value return block. */
6049 if (TREE_CODE (to) == RESULT_DECL
6050 && TREE_CODE (from) == INDIRECT_REF
6051 && ADDR_SPACE_GENERIC_P
6052 (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (from, 0)))))
6053 && refs_may_alias_p (to, from)
6054 && cfun->returns_struct
6055 && !cfun->returns_pcc_struct)
6056 {
6057 rtx from_rtx, size;
6058
6059 push_temp_slots ();
6060 size = expr_size (from);
6061 from_rtx = expand_normal (exp: from);
6062
6063 emit_block_move_via_libcall (XEXP (to_rtx, 0), XEXP (from_rtx, 0), size);
6064
6065 preserve_temp_slots (to_rtx);
6066 pop_temp_slots ();
6067 return;
6068 }
6069
6070 /* Compute FROM and store the value in the rtx we got. */
6071
6072 push_temp_slots ();
6073 result = store_expr (from, to_rtx, 0, nontemporal, false);
6074 preserve_temp_slots (result);
6075 pop_temp_slots ();
6076 return;
6077}
6078
6079/* Emits nontemporal store insn that moves FROM to TO. Returns true if this
6080 succeeded, false otherwise. */
6081
6082bool
6083emit_storent_insn (rtx to, rtx from)
6084{
6085 class expand_operand ops[2];
6086 machine_mode mode = GET_MODE (to);
6087 enum insn_code code = optab_handler (op: storent_optab, mode);
6088
6089 if (code == CODE_FOR_nothing)
6090 return false;
6091
6092 create_fixed_operand (op: &ops[0], x: to);
6093 create_input_operand (op: &ops[1], value: from, mode);
6094 return maybe_expand_insn (icode: code, nops: 2, ops);
6095}
6096
6097/* Helper function for store_expr storing of STRING_CST. */
6098
6099static rtx
6100string_cst_read_str (void *data, void *, HOST_WIDE_INT offset,
6101 fixed_size_mode mode)
6102{
6103 tree str = (tree) data;
6104
6105 gcc_assert (offset >= 0);
6106 if (offset >= TREE_STRING_LENGTH (str))
6107 return const0_rtx;
6108
6109 if ((unsigned HOST_WIDE_INT) offset + GET_MODE_SIZE (mode)
6110 > (unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (str))
6111 {
6112 char *p = XALLOCAVEC (char, GET_MODE_SIZE (mode));
6113 size_t l = TREE_STRING_LENGTH (str) - offset;
6114 memcpy (dest: p, TREE_STRING_POINTER (str) + offset, n: l);
6115 memset (s: p + l, c: '\0', n: GET_MODE_SIZE (mode) - l);
6116 return c_readstr (p, mode, false);
6117 }
6118
6119 return c_readstr (TREE_STRING_POINTER (str) + offset, mode, false);
6120}
6121
6122/* Generate code for computing expression EXP,
6123 and storing the value into TARGET.
6124
6125 If the mode is BLKmode then we may return TARGET itself.
6126 It turns out that in BLKmode it doesn't cause a problem.
6127 because C has no operators that could combine two different
6128 assignments into the same BLKmode object with different values
6129 with no sequence point. Will other languages need this to
6130 be more thorough?
6131
6132 If CALL_PARAM_P is nonzero, this is a store into a call param on the
6133 stack, and block moves may need to be treated specially.
6134
6135 If NONTEMPORAL is true, try using a nontemporal store instruction.
6136
6137 If REVERSE is true, the store is to be done in reverse order. */
6138
6139rtx
6140store_expr (tree exp, rtx target, int call_param_p,
6141 bool nontemporal, bool reverse)
6142{
6143 rtx temp;
6144 rtx alt_rtl = NULL_RTX;
6145 location_t loc = curr_insn_location ();
6146 bool shortened_string_cst = false;
6147
6148 if (VOID_TYPE_P (TREE_TYPE (exp)))
6149 {
6150 /* C++ can generate ?: expressions with a throw expression in one
6151 branch and an rvalue in the other. Here, we resolve attempts to
6152 store the throw expression's nonexistent result. */
6153 gcc_assert (!call_param_p);
6154 expand_expr (exp, const0_rtx, VOIDmode, modifier: EXPAND_NORMAL);
6155 return NULL_RTX;
6156 }
6157 if (TREE_CODE (exp) == COMPOUND_EXPR)
6158 {
6159 /* Perform first part of compound expression, then assign from second
6160 part. */
6161 expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
6162 modifier: call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6163 return store_expr (TREE_OPERAND (exp, 1), target,
6164 call_param_p, nontemporal, reverse);
6165 }
6166 else if (TREE_CODE (exp) == COND_EXPR && GET_MODE (target) == BLKmode)
6167 {
6168 /* For conditional expression, get safe form of the target. Then
6169 test the condition, doing the appropriate assignment on either
6170 side. This avoids the creation of unnecessary temporaries.
6171 For non-BLKmode, it is more efficient not to do this. */
6172
6173 rtx_code_label *lab1 = gen_label_rtx (), *lab2 = gen_label_rtx ();
6174
6175 do_pending_stack_adjust ();
6176 NO_DEFER_POP;
6177 jumpifnot (TREE_OPERAND (exp, 0), label: lab1,
6178 prob: profile_probability::uninitialized ());
6179 store_expr (TREE_OPERAND (exp, 1), target, call_param_p,
6180 nontemporal, reverse);
6181 emit_jump_insn (targetm.gen_jump (lab2));
6182 emit_barrier ();
6183 emit_label (lab1);
6184 store_expr (TREE_OPERAND (exp, 2), target, call_param_p,
6185 nontemporal, reverse);
6186 emit_label (lab2);
6187 OK_DEFER_POP;
6188
6189 return NULL_RTX;
6190 }
6191 else if (GET_CODE (target) == SUBREG && SUBREG_PROMOTED_VAR_P (target))
6192 /* If this is a scalar in a register that is stored in a wider mode
6193 than the declared mode, compute the result into its declared mode
6194 and then convert to the wider mode. Our value is the computed
6195 expression. */
6196 {
6197 rtx inner_target = 0;
6198 scalar_int_mode outer_mode = subreg_unpromoted_mode (x: target);
6199 scalar_int_mode inner_mode = subreg_promoted_mode (x: target);
6200
6201 /* We can do the conversion inside EXP, which will often result
6202 in some optimizations. Do the conversion in two steps: first
6203 change the signedness, if needed, then the extend. But don't
6204 do this if the type of EXP is a subtype of something else
6205 since then the conversion might involve more than just
6206 converting modes. */
6207 if (INTEGRAL_TYPE_P (TREE_TYPE (exp))
6208 && TREE_TYPE (TREE_TYPE (exp)) == 0
6209 && GET_MODE_PRECISION (mode: outer_mode)
6210 == TYPE_PRECISION (TREE_TYPE (exp)))
6211 {
6212 if (!SUBREG_CHECK_PROMOTED_SIGN (target,
6213 TYPE_UNSIGNED (TREE_TYPE (exp))))
6214 {
6215 /* Some types, e.g. Fortran's logical*4, won't have a signed
6216 version, so use the mode instead. */
6217 tree ntype
6218 = (signed_or_unsigned_type_for
6219 (SUBREG_PROMOTED_SIGN (target), TREE_TYPE (exp)));
6220 if (ntype == NULL)
6221 ntype = lang_hooks.types.type_for_mode
6222 (TYPE_MODE (TREE_TYPE (exp)),
6223 SUBREG_PROMOTED_SIGN (target));
6224
6225 exp = fold_convert_loc (loc, ntype, exp);
6226 }
6227
6228 exp = fold_convert_loc (loc, lang_hooks.types.type_for_mode
6229 (inner_mode, SUBREG_PROMOTED_SIGN (target)),
6230 exp);
6231
6232 inner_target = SUBREG_REG (target);
6233 }
6234
6235 temp = expand_expr (exp, target: inner_target, VOIDmode,
6236 modifier: call_param_p ? EXPAND_STACK_PARM : EXPAND_NORMAL);
6237
6238
6239 /* If TEMP is a VOIDmode constant, use convert_modes to make
6240 sure that we properly convert it. */
6241 if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode)
6242 {
6243 temp = convert_modes (mode: outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6244 x: temp, SUBREG_PROMOTED_SIGN (target));
6245 temp = convert_modes (mode: inner_mode, oldmode: outer_mode, x: temp,
6246 SUBREG_PROMOTED_SIGN (target));
6247 }
6248 else if (!SCALAR_INT_MODE_P (GET_MODE (temp)))
6249 temp = convert_modes (mode: outer_mode, TYPE_MODE (TREE_TYPE (exp)),
6250 x: temp, SUBREG_PROMOTED_SIGN (target));
6251
6252 convert_move (SUBREG_REG (target), from: temp,
6253 SUBREG_PROMOTED_SIGN (target));
6254
6255 return NULL_RTX;
6256 }
6257 else if ((TREE_CODE (exp) == STRING_CST
6258 || (TREE_CODE (exp) == MEM_REF
6259 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
6260 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
6261 == STRING_CST
6262 && integer_zerop (TREE_OPERAND (exp, 1))))
6263 && !nontemporal && !call_param_p
6264 && MEM_P (target))
6265 {
6266 /* Optimize initialization of an array with a STRING_CST. */
6267 HOST_WIDE_INT exp_len, str_copy_len;
6268 rtx dest_mem;
6269 tree str = TREE_CODE (exp) == STRING_CST
6270 ? exp : TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
6271
6272 exp_len = int_expr_size (exp);
6273 if (exp_len <= 0)
6274 goto normal_expr;
6275
6276 if (TREE_STRING_LENGTH (str) <= 0)
6277 goto normal_expr;
6278
6279 if (can_store_by_pieces (len: exp_len, constfun: string_cst_read_str, constfundata: (void *) str,
6280 MEM_ALIGN (target), memsetp: false))
6281 {
6282 store_by_pieces (to: target, len: exp_len, constfun: string_cst_read_str, constfundata: (void *) str,
6283 MEM_ALIGN (target), memsetp: false, retmode: RETURN_BEGIN);
6284 return NULL_RTX;
6285 }
6286
6287 str_copy_len = TREE_STRING_LENGTH (str);
6288
6289 /* Trailing NUL bytes in EXP will be handled by the call to
6290 clear_storage, which is more efficient than copying them from
6291 the STRING_CST, so trim those from STR_COPY_LEN. */
6292 while (str_copy_len)
6293 {
6294 if (TREE_STRING_POINTER (str)[str_copy_len - 1])
6295 break;
6296 str_copy_len--;
6297 }
6298
6299 if ((STORE_MAX_PIECES & (STORE_MAX_PIECES - 1)) == 0)
6300 {
6301 str_copy_len += STORE_MAX_PIECES - 1;
6302 str_copy_len &= ~(STORE_MAX_PIECES - 1);
6303 }
6304 if (str_copy_len >= exp_len)
6305 goto normal_expr;
6306
6307 if (!can_store_by_pieces (len: str_copy_len, constfun: string_cst_read_str,
6308 constfundata: (void *) str, MEM_ALIGN (target), memsetp: false))
6309 goto normal_expr;
6310
6311 dest_mem = store_by_pieces (to: target, len: str_copy_len, constfun: string_cst_read_str,
6312 constfundata: (void *) str, MEM_ALIGN (target), memsetp: false,
6313 retmode: RETURN_END);
6314 clear_storage (object: adjust_address_1 (dest_mem, BLKmode, 0, 1, 1, 0,
6315 exp_len - str_copy_len),
6316 GEN_INT (exp_len - str_copy_len), method: BLOCK_OP_NORMAL);
6317 return NULL_RTX;
6318 }
6319 else
6320 {
6321 rtx tmp_target;
6322
6323 normal_expr:
6324 /* If we want to use a nontemporal or a reverse order store, force the
6325 value into a register first. */
6326 tmp_target = nontemporal || reverse ? NULL_RTX : target;
6327 tree rexp = exp;
6328 if (TREE_CODE (exp) == STRING_CST
6329 && tmp_target == target
6330 && GET_MODE (target) == BLKmode
6331 && TYPE_MODE (TREE_TYPE (exp)) == BLKmode)
6332 {
6333 rtx size = expr_size (exp);
6334 if (CONST_INT_P (size)
6335 && size != const0_rtx
6336 && (UINTVAL (size)
6337 > ((unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (exp) + 32)))
6338 {
6339 /* If the STRING_CST has much larger array type than
6340 TREE_STRING_LENGTH, only emit the TREE_STRING_LENGTH part of
6341 it into the rodata section as the code later on will use
6342 memset zero for the remainder anyway. See PR95052. */
6343 tmp_target = NULL_RTX;
6344 rexp = copy_node (exp);
6345 tree index
6346 = build_index_type (size_int (TREE_STRING_LENGTH (exp) - 1));
6347 TREE_TYPE (rexp) = build_array_type (TREE_TYPE (TREE_TYPE (exp)),
6348 index);
6349 shortened_string_cst = true;
6350 }
6351 }
6352 temp = expand_expr_real (rexp, tmp_target, GET_MODE (target),
6353 (call_param_p
6354 ? EXPAND_STACK_PARM : EXPAND_NORMAL),
6355 &alt_rtl, false);
6356 if (shortened_string_cst)
6357 {
6358 gcc_assert (MEM_P (temp));
6359 temp = change_address (temp, BLKmode, NULL_RTX);
6360 }
6361 }
6362
6363 /* If TEMP is a VOIDmode constant and the mode of the type of EXP is not
6364 the same as that of TARGET, adjust the constant. This is needed, for
6365 example, in case it is a CONST_DOUBLE or CONST_WIDE_INT and we want
6366 only a word-sized value. */
6367 if (CONSTANT_P (temp) && GET_MODE (temp) == VOIDmode
6368 && TREE_CODE (exp) != ERROR_MARK
6369 && GET_MODE (target) != TYPE_MODE (TREE_TYPE (exp)))
6370 {
6371 gcc_assert (!shortened_string_cst);
6372 if (GET_MODE_CLASS (GET_MODE (target))
6373 != GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (exp)))
6374 && known_eq (GET_MODE_BITSIZE (GET_MODE (target)),
6375 GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (exp)))))
6376 {
6377 rtx t = simplify_gen_subreg (GET_MODE (target), op: temp,
6378 TYPE_MODE (TREE_TYPE (exp)), byte: 0);
6379 if (t)
6380 temp = t;
6381 }
6382 if (GET_MODE (temp) == VOIDmode)
6383 temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
6384 x: temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6385 }
6386
6387 /* If value was not generated in the target, store it there.
6388 Convert the value to TARGET's type first if necessary and emit the
6389 pending incrementations that have been queued when expanding EXP.
6390 Note that we cannot emit the whole queue blindly because this will
6391 effectively disable the POST_INC optimization later.
6392
6393 If TEMP and TARGET compare equal according to rtx_equal_p, but
6394 one or both of them are volatile memory refs, we have to distinguish
6395 two cases:
6396 - expand_expr has used TARGET. In this case, we must not generate
6397 another copy. This can be detected by TARGET being equal according
6398 to == .
6399 - expand_expr has not used TARGET - that means that the source just
6400 happens to have the same RTX form. Since temp will have been created
6401 by expand_expr, it will compare unequal according to == .
6402 We must generate a copy in this case, to reach the correct number
6403 of volatile memory references. */
6404
6405 if ((! rtx_equal_p (temp, target)
6406 || (temp != target && (side_effects_p (temp)
6407 || side_effects_p (target)
6408 || (MEM_P (temp)
6409 && !mems_same_for_tbaa_p (temp, target)))))
6410 && TREE_CODE (exp) != ERROR_MARK
6411 /* If store_expr stores a DECL whose DECL_RTL(exp) == TARGET,
6412 but TARGET is not valid memory reference, TEMP will differ
6413 from TARGET although it is really the same location. */
6414 && !(alt_rtl
6415 && rtx_equal_p (alt_rtl, target)
6416 && !side_effects_p (alt_rtl)
6417 && !side_effects_p (target))
6418 /* If there's nothing to copy, don't bother. Don't call
6419 expr_size unless necessary, because some front-ends (C++)
6420 expr_size-hook must not be given objects that are not
6421 supposed to be bit-copied or bit-initialized. */
6422 && expr_size (exp) != const0_rtx)
6423 {
6424 if (GET_MODE (temp) != GET_MODE (target) && GET_MODE (temp) != VOIDmode)
6425 {
6426 gcc_assert (!shortened_string_cst);
6427 if (GET_MODE (target) == BLKmode)
6428 {
6429 /* Handle calls that return BLKmode values in registers. */
6430 if (REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
6431 copy_blkmode_from_reg (target, srcreg: temp, TREE_TYPE (exp));
6432 else
6433 store_bit_field (target,
6434 rtx_to_poly_int64 (x: expr_size (exp))
6435 * BITS_PER_UNIT,
6436 0, 0, 0, GET_MODE (temp), temp, reverse,
6437 false);
6438 }
6439 else
6440 convert_move (to: target, from: temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
6441 }
6442
6443 else if (GET_MODE (temp) == BLKmode && TREE_CODE (exp) == STRING_CST)
6444 {
6445 /* Handle copying a string constant into an array. The string
6446 constant may be shorter than the array. So copy just the string's
6447 actual length, and clear the rest. First get the size of the data
6448 type of the string, which is actually the size of the target. */
6449 rtx size = expr_size (exp);
6450
6451 if (CONST_INT_P (size)
6452 && INTVAL (size) < TREE_STRING_LENGTH (exp))
6453 emit_block_move (x: target, y: temp, size,
6454 method: (call_param_p
6455 ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6456 else
6457 {
6458 machine_mode pointer_mode
6459 = targetm.addr_space.pointer_mode (MEM_ADDR_SPACE (target));
6460 machine_mode address_mode = get_address_mode (mem: target);
6461
6462 /* Compute the size of the data to copy from the string. */
6463 tree copy_size
6464 = size_binop_loc (loc, MIN_EXPR,
6465 make_tree (sizetype, size),
6466 size_int (TREE_STRING_LENGTH (exp)));
6467 rtx copy_size_rtx
6468 = expand_expr (exp: copy_size, NULL_RTX, VOIDmode,
6469 modifier: (call_param_p
6470 ? EXPAND_STACK_PARM : EXPAND_NORMAL));
6471 rtx_code_label *label = 0;
6472
6473 /* Copy that much. */
6474 copy_size_rtx = convert_to_mode (mode: pointer_mode, x: copy_size_rtx,
6475 TYPE_UNSIGNED (sizetype));
6476 emit_block_move (x: target, y: temp, size: copy_size_rtx,
6477 method: (call_param_p
6478 ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6479
6480 /* Figure out how much is left in TARGET that we have to clear.
6481 Do all calculations in pointer_mode. */
6482 poly_int64 const_copy_size;
6483 if (poly_int_rtx_p (x: copy_size_rtx, res: &const_copy_size))
6484 {
6485 size = plus_constant (address_mode, size, -const_copy_size);
6486 target = adjust_address (target, BLKmode, const_copy_size);
6487 }
6488 else
6489 {
6490 size = expand_binop (TYPE_MODE (sizetype), sub_optab, size,
6491 copy_size_rtx, NULL_RTX, 0,
6492 OPTAB_LIB_WIDEN);
6493
6494 if (GET_MODE (copy_size_rtx) != address_mode)
6495 copy_size_rtx = convert_to_mode (mode: address_mode,
6496 x: copy_size_rtx,
6497 TYPE_UNSIGNED (sizetype));
6498
6499 target = offset_address (target, copy_size_rtx,
6500 highest_pow2_factor (copy_size));
6501 label = gen_label_rtx ();
6502 emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX,
6503 GET_MODE (size), 0, label);
6504 }
6505
6506 if (size != const0_rtx)
6507 clear_storage (object: target, size, method: BLOCK_OP_NORMAL);
6508
6509 if (label)
6510 emit_label (label);
6511 }
6512 }
6513 else if (shortened_string_cst)
6514 gcc_unreachable ();
6515 /* Handle calls that return values in multiple non-contiguous locations.
6516 The Irix 6 ABI has examples of this. */
6517 else if (GET_CODE (target) == PARALLEL)
6518 {
6519 if (GET_CODE (temp) == PARALLEL)
6520 emit_group_move (dst: target, src: temp);
6521 else
6522 emit_group_load (dst: target, src: temp, TREE_TYPE (exp),
6523 ssize: int_size_in_bytes (TREE_TYPE (exp)));
6524 }
6525 else if (GET_CODE (temp) == PARALLEL)
6526 emit_group_store (orig_dst: target, src: temp, TREE_TYPE (exp),
6527 ssize: int_size_in_bytes (TREE_TYPE (exp)));
6528 else if (GET_MODE (temp) == BLKmode)
6529 emit_block_move (x: target, y: temp, size: expr_size (exp),
6530 method: (call_param_p
6531 ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
6532 /* If we emit a nontemporal store, there is nothing else to do. */
6533 else if (nontemporal && emit_storent_insn (to: target, from: temp))
6534 ;
6535 else
6536 {
6537 if (reverse)
6538 temp = flip_storage_order (GET_MODE (target), temp);
6539 temp = force_operand (temp, target);
6540 if (temp != target)
6541 emit_move_insn (x: target, y: temp);
6542 }
6543 }
6544 else
6545 gcc_assert (!shortened_string_cst);
6546
6547 return NULL_RTX;
6548}
6549
6550/* Return true if field F of structure TYPE is a flexible array. */
6551
6552static bool
6553flexible_array_member_p (const_tree f, const_tree type)
6554{
6555 const_tree tf;
6556
6557 tf = TREE_TYPE (f);
6558 return (DECL_CHAIN (f) == NULL
6559 && TREE_CODE (tf) == ARRAY_TYPE
6560 && TYPE_DOMAIN (tf)
6561 && TYPE_MIN_VALUE (TYPE_DOMAIN (tf))
6562 && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf)))
6563 && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf))
6564 && int_size_in_bytes (type) >= 0);
6565}
6566
6567/* If FOR_CTOR_P, return the number of top-level elements that a constructor
6568 must have in order for it to completely initialize a value of type TYPE.
6569 Return -1 if the number isn't known.
6570
6571 If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE. */
6572
6573static HOST_WIDE_INT
6574count_type_elements (const_tree type, bool for_ctor_p)
6575{
6576 switch (TREE_CODE (type))
6577 {
6578 case ARRAY_TYPE:
6579 {
6580 tree nelts;
6581
6582 nelts = array_type_nelts (type);
6583 if (nelts && tree_fits_uhwi_p (nelts))
6584 {
6585 unsigned HOST_WIDE_INT n;
6586
6587 n = tree_to_uhwi (nelts) + 1;
6588 if (n == 0 || for_ctor_p)
6589 return n;
6590 else
6591 return n * count_type_elements (TREE_TYPE (type), for_ctor_p: false);
6592 }
6593 return for_ctor_p ? -1 : 1;
6594 }
6595
6596 case RECORD_TYPE:
6597 {
6598 unsigned HOST_WIDE_INT n;
6599 tree f;
6600
6601 n = 0;
6602 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
6603 if (TREE_CODE (f) == FIELD_DECL)
6604 {
6605 if (!for_ctor_p)
6606 n += count_type_elements (TREE_TYPE (f), for_ctor_p: false);
6607 else if (!flexible_array_member_p (f, type))
6608 /* Don't count flexible arrays, which are not supposed
6609 to be initialized. */
6610 n += 1;
6611 }
6612
6613 return n;
6614 }
6615
6616 case UNION_TYPE:
6617 case QUAL_UNION_TYPE:
6618 {
6619 tree f;
6620 HOST_WIDE_INT n, m;
6621
6622 gcc_assert (!for_ctor_p);
6623 /* Estimate the number of scalars in each field and pick the
6624 maximum. Other estimates would do instead; the idea is simply
6625 to make sure that the estimate is not sensitive to the ordering
6626 of the fields. */
6627 n = 1;
6628 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
6629 if (TREE_CODE (f) == FIELD_DECL)
6630 {
6631 m = count_type_elements (TREE_TYPE (f), for_ctor_p: false);
6632 /* If the field doesn't span the whole union, add an extra
6633 scalar for the rest. */
6634 if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)),
6635 TYPE_SIZE (type)) != 1)
6636 m++;
6637 if (n < m)
6638 n = m;
6639 }
6640 return n;
6641 }
6642
6643 case COMPLEX_TYPE:
6644 return 2;
6645
6646 case VECTOR_TYPE:
6647 {
6648 unsigned HOST_WIDE_INT nelts;
6649 if (TYPE_VECTOR_SUBPARTS (node: type).is_constant (const_value: &nelts))
6650 return nelts;
6651 else
6652 return -1;
6653 }
6654
6655 case INTEGER_TYPE:
6656 case REAL_TYPE:
6657 case FIXED_POINT_TYPE:
6658 case ENUMERAL_TYPE:
6659 case BOOLEAN_TYPE:
6660 case POINTER_TYPE:
6661 case OFFSET_TYPE:
6662 case REFERENCE_TYPE:
6663 case NULLPTR_TYPE:
6664 case OPAQUE_TYPE:
6665 return 1;
6666
6667 case ERROR_MARK:
6668 return 0;
6669
6670 case VOID_TYPE:
6671 case METHOD_TYPE:
6672 case FUNCTION_TYPE:
6673 case LANG_TYPE:
6674 default:
6675 gcc_unreachable ();
6676 }
6677}
6678
6679/* Helper for categorize_ctor_elements. Identical interface. */
6680
6681static bool
6682categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
6683 HOST_WIDE_INT *p_unique_nz_elts,
6684 HOST_WIDE_INT *p_init_elts, bool *p_complete)
6685{
6686 unsigned HOST_WIDE_INT idx;
6687 HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
6688 tree value, purpose, elt_type;
6689
6690 /* Whether CTOR is a valid constant initializer, in accordance with what
6691 initializer_constant_valid_p does. If inferred from the constructor
6692 elements, true until proven otherwise. */
6693 bool const_from_elts_p = constructor_static_from_elts_p (ctor);
6694 bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
6695
6696 nz_elts = 0;
6697 unique_nz_elts = 0;
6698 init_elts = 0;
6699 num_fields = 0;
6700 elt_type = NULL_TREE;
6701
6702 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value)
6703 {
6704 HOST_WIDE_INT mult = 1;
6705
6706 if (purpose && TREE_CODE (purpose) == RANGE_EXPR)
6707 {
6708 tree lo_index = TREE_OPERAND (purpose, 0);
6709 tree hi_index = TREE_OPERAND (purpose, 1);
6710
6711 if (tree_fits_uhwi_p (lo_index) && tree_fits_uhwi_p (hi_index))
6712 mult = (tree_to_uhwi (hi_index)
6713 - tree_to_uhwi (lo_index) + 1);
6714 }
6715 num_fields += mult;
6716 elt_type = TREE_TYPE (value);
6717
6718 switch (TREE_CODE (value))
6719 {
6720 case CONSTRUCTOR:
6721 {
6722 HOST_WIDE_INT nz = 0, unz = 0, ic = 0;
6723
6724 bool const_elt_p = categorize_ctor_elements_1 (ctor: value, p_nz_elts: &nz, p_unique_nz_elts: &unz,
6725 p_init_elts: &ic, p_complete);
6726
6727 nz_elts += mult * nz;
6728 unique_nz_elts += unz;
6729 init_elts += mult * ic;
6730
6731 if (const_from_elts_p && const_p)
6732 const_p = const_elt_p;
6733 }
6734 break;
6735
6736 case INTEGER_CST:
6737 case REAL_CST:
6738 case FIXED_CST:
6739 if (!initializer_zerop (value))
6740 {
6741 nz_elts += mult;
6742 unique_nz_elts++;
6743 }
6744 init_elts += mult;
6745 break;
6746
6747 case STRING_CST:
6748 nz_elts += mult * TREE_STRING_LENGTH (value);
6749 unique_nz_elts += TREE_STRING_LENGTH (value);
6750 init_elts += mult * TREE_STRING_LENGTH (value);
6751 break;
6752
6753 case COMPLEX_CST:
6754 if (!initializer_zerop (TREE_REALPART (value)))
6755 {
6756 nz_elts += mult;
6757 unique_nz_elts++;
6758 }
6759 if (!initializer_zerop (TREE_IMAGPART (value)))
6760 {
6761 nz_elts += mult;
6762 unique_nz_elts++;
6763 }
6764 init_elts += 2 * mult;
6765 break;
6766
6767 case VECTOR_CST:
6768 {
6769 /* We can only construct constant-length vectors using
6770 CONSTRUCTOR. */
6771 unsigned int nunits = VECTOR_CST_NELTS (value).to_constant ();
6772 for (unsigned int i = 0; i < nunits; ++i)
6773 {
6774 tree v = VECTOR_CST_ELT (value, i);
6775 if (!initializer_zerop (v))
6776 {
6777 nz_elts += mult;
6778 unique_nz_elts++;
6779 }
6780 init_elts += mult;
6781 }
6782 }
6783 break;
6784
6785 default:
6786 {
6787 HOST_WIDE_INT tc = count_type_elements (type: elt_type, for_ctor_p: false);
6788 nz_elts += mult * tc;
6789 unique_nz_elts += tc;
6790 init_elts += mult * tc;
6791
6792 if (const_from_elts_p && const_p)
6793 const_p
6794 = initializer_constant_valid_p (value,
6795 elt_type,
6796 TYPE_REVERSE_STORAGE_ORDER
6797 (TREE_TYPE (ctor)))
6798 != NULL_TREE;
6799 }
6800 break;
6801 }
6802 }
6803
6804 if (*p_complete && !complete_ctor_at_level_p (TREE_TYPE (ctor),
6805 num_fields, elt_type))
6806 *p_complete = false;
6807
6808 *p_nz_elts += nz_elts;
6809 *p_unique_nz_elts += unique_nz_elts;
6810 *p_init_elts += init_elts;
6811
6812 return const_p;
6813}
6814
6815/* Examine CTOR to discover:
6816 * how many scalar fields are set to nonzero values,
6817 and place it in *P_NZ_ELTS;
6818 * the same, but counting RANGE_EXPRs as multiplier of 1 instead of
6819 high - low + 1 (this can be useful for callers to determine ctors
6820 that could be cheaply initialized with - perhaps nested - loops
6821 compared to copied from huge read-only data),
6822 and place it in *P_UNIQUE_NZ_ELTS;
6823 * how many scalar fields in total are in CTOR,
6824 and place it in *P_ELT_COUNT.
6825 * whether the constructor is complete -- in the sense that every
6826 meaningful byte is explicitly given a value --
6827 and place it in *P_COMPLETE.
6828
6829 Return whether or not CTOR is a valid static constant initializer, the same
6830 as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */
6831
6832bool
6833categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
6834 HOST_WIDE_INT *p_unique_nz_elts,
6835 HOST_WIDE_INT *p_init_elts, bool *p_complete)
6836{
6837 *p_nz_elts = 0;
6838 *p_unique_nz_elts = 0;
6839 *p_init_elts = 0;
6840 *p_complete = true;
6841
6842 return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
6843 p_init_elts, p_complete);
6844}
6845
6846/* Return true if constructor CTOR is simple enough to be materialized
6847 in an integer mode register. Limit the size to WORDS words, which
6848 is 1 by default. */
6849
6850bool
6851immediate_const_ctor_p (const_tree ctor, unsigned int words)
6852{
6853 /* Allow function to be called with a VAR_DECL's DECL_INITIAL. */
6854 if (!ctor || TREE_CODE (ctor) != CONSTRUCTOR)
6855 return false;
6856
6857 return TREE_CONSTANT (ctor)
6858 && !TREE_ADDRESSABLE (ctor)
6859 && CONSTRUCTOR_NELTS (ctor)
6860 && TREE_CODE (TREE_TYPE (ctor)) != ARRAY_TYPE
6861 && int_expr_size (exp: ctor) <= words * UNITS_PER_WORD
6862 && initializer_constant_valid_for_bitfield_p (ctor);
6863}
6864
6865/* TYPE is initialized by a constructor with NUM_ELTS elements, the last
6866 of which had type LAST_TYPE. Each element was itself a complete
6867 initializer, in the sense that every meaningful byte was explicitly
6868 given a value. Return true if the same is true for the constructor
6869 as a whole. */
6870
6871bool
6872complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts,
6873 const_tree last_type)
6874{
6875 if (TREE_CODE (type) == UNION_TYPE
6876 || TREE_CODE (type) == QUAL_UNION_TYPE)
6877 {
6878 if (num_elts == 0)
6879 return false;
6880
6881 gcc_assert (num_elts == 1 && last_type);
6882
6883 /* ??? We could look at each element of the union, and find the
6884 largest element. Which would avoid comparing the size of the
6885 initialized element against any tail padding in the union.
6886 Doesn't seem worth the effort... */
6887 return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1;
6888 }
6889
6890 return count_type_elements (type, for_ctor_p: true) == num_elts;
6891}
6892
6893/* Return true if EXP contains mostly (3/4) zeros. */
6894
6895static bool
6896mostly_zeros_p (const_tree exp)
6897{
6898 if (TREE_CODE (exp) == CONSTRUCTOR)
6899 {
6900 HOST_WIDE_INT nz_elts, unz_elts, init_elts;
6901 bool complete_p;
6902
6903 categorize_ctor_elements (ctor: exp, p_nz_elts: &nz_elts, p_unique_nz_elts: &unz_elts, p_init_elts: &init_elts,
6904 p_complete: &complete_p);
6905 return !complete_p || nz_elts < init_elts / 4;
6906 }
6907
6908 return initializer_zerop (exp);
6909}
6910
6911/* Return true if EXP contains all zeros. */
6912
6913static bool
6914all_zeros_p (const_tree exp)
6915{
6916 if (TREE_CODE (exp) == CONSTRUCTOR)
6917 {
6918 HOST_WIDE_INT nz_elts, unz_elts, init_elts;
6919 bool complete_p;
6920
6921 categorize_ctor_elements (ctor: exp, p_nz_elts: &nz_elts, p_unique_nz_elts: &unz_elts, p_init_elts: &init_elts,
6922 p_complete: &complete_p);
6923 return nz_elts == 0;
6924 }
6925
6926 return initializer_zerop (exp);
6927}
6928
6929/* Helper function for store_constructor.
6930 TARGET, BITSIZE, BITPOS, MODE, EXP are as for store_field.
6931 CLEARED is as for store_constructor.
6932 ALIAS_SET is the alias set to use for any stores.
6933 If REVERSE is true, the store is to be done in reverse order.
6934
6935 This provides a recursive shortcut back to store_constructor when it isn't
6936 necessary to go through store_field. This is so that we can pass through
6937 the cleared field to let store_constructor know that we may not have to
6938 clear a substructure if the outer structure has already been cleared. */
6939
6940static void
6941store_constructor_field (rtx target, poly_uint64 bitsize, poly_int64 bitpos,
6942 poly_uint64 bitregion_start,
6943 poly_uint64 bitregion_end,
6944 machine_mode mode,
6945 tree exp, int cleared,
6946 alias_set_type alias_set, bool reverse)
6947{
6948 poly_int64 bytepos;
6949 poly_uint64 bytesize;
6950 if (TREE_CODE (exp) == CONSTRUCTOR
6951 /* We can only call store_constructor recursively if the size and
6952 bit position are on a byte boundary. */
6953 && multiple_p (a: bitpos, BITS_PER_UNIT, multiple: &bytepos)
6954 && maybe_ne (a: bitsize, b: 0U)
6955 && multiple_p (a: bitsize, BITS_PER_UNIT, multiple: &bytesize)
6956 /* If we have a nonzero bitpos for a register target, then we just
6957 let store_field do the bitfield handling. This is unlikely to
6958 generate unnecessary clear instructions anyways. */
6959 && (known_eq (bitpos, 0) || MEM_P (target)))
6960 {
6961 if (MEM_P (target))
6962 {
6963 machine_mode target_mode = GET_MODE (target);
6964 if (target_mode != BLKmode
6965 && !multiple_p (a: bitpos, GET_MODE_ALIGNMENT (target_mode)))
6966 target_mode = BLKmode;
6967 target = adjust_address (target, target_mode, bytepos);
6968 }
6969
6970
6971 /* Update the alias set, if required. */
6972 if (MEM_P (target) && ! MEM_KEEP_ALIAS_SET_P (target)
6973 && MEM_ALIAS_SET (target) != 0)
6974 {
6975 target = copy_rtx (target);
6976 set_mem_alias_set (target, alias_set);
6977 }
6978
6979 store_constructor (exp, target, cleared, bytesize, reverse);
6980 }
6981 else
6982 store_field (target, bitsize, bitpos, bitregion_start, bitregion_end, mode,
6983 exp, alias_set, false, reverse);
6984}
6985
6986
6987/* Returns the number of FIELD_DECLs in TYPE. */
6988
6989static int
6990fields_length (const_tree type)
6991{
6992 tree t = TYPE_FIELDS (type);
6993 int count = 0;
6994
6995 for (; t; t = DECL_CHAIN (t))
6996 if (TREE_CODE (t) == FIELD_DECL)
6997 ++count;
6998
6999 return count;
7000}
7001
7002
7003/* Store the value of constructor EXP into the rtx TARGET.
7004 TARGET is either a REG or a MEM; we know it cannot conflict, since
7005 safe_from_p has been called.
7006 CLEARED is true if TARGET is known to have been zero'd.
7007 SIZE is the number of bytes of TARGET we are allowed to modify: this
7008 may not be the same as the size of EXP if we are assigning to a field
7009 which has been packed to exclude padding bits.
7010 If REVERSE is true, the store is to be done in reverse order. */
7011
7012void
7013store_constructor (tree exp, rtx target, int cleared, poly_int64 size,
7014 bool reverse)
7015{
7016 tree type = TREE_TYPE (exp);
7017 HOST_WIDE_INT exp_size = int_size_in_bytes (type);
7018 poly_int64 bitregion_end = known_gt (size, 0) ? size * BITS_PER_UNIT - 1 : 0;
7019
7020 switch (TREE_CODE (type))
7021 {
7022 case RECORD_TYPE:
7023 case UNION_TYPE:
7024 case QUAL_UNION_TYPE:
7025 {
7026 unsigned HOST_WIDE_INT idx;
7027 tree field, value;
7028
7029 /* The storage order is specified for every aggregate type. */
7030 reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7031
7032 /* If size is zero or the target is already cleared, do nothing. */
7033 if (known_eq (size, 0) || cleared)
7034 cleared = 1;
7035 /* We either clear the aggregate or indicate the value is dead. */
7036 else if ((TREE_CODE (type) == UNION_TYPE
7037 || TREE_CODE (type) == QUAL_UNION_TYPE)
7038 && ! CONSTRUCTOR_ELTS (exp))
7039 /* If the constructor is empty, clear the union. */
7040 {
7041 clear_storage (object: target, size: expr_size (exp), method: BLOCK_OP_NORMAL);
7042 cleared = 1;
7043 }
7044
7045 /* If we are building a static constructor into a register,
7046 set the initial value as zero so we can fold the value into
7047 a constant. But if more than one register is involved,
7048 this probably loses. */
7049 else if (REG_P (target) && TREE_STATIC (exp)
7050 && known_le (GET_MODE_SIZE (GET_MODE (target)),
7051 REGMODE_NATURAL_SIZE (GET_MODE (target))))
7052 {
7053 emit_move_insn (x: target, CONST0_RTX (GET_MODE (target)));
7054 cleared = 1;
7055 }
7056
7057 /* If the constructor has fewer fields than the structure or
7058 if we are initializing the structure to mostly zeros, clear
7059 the whole structure first. Don't do this if TARGET is a
7060 register whose mode size isn't equal to SIZE since
7061 clear_storage can't handle this case. */
7062 else if (known_size_p (a: size)
7063 && (((int) CONSTRUCTOR_NELTS (exp) != fields_length (type))
7064 || mostly_zeros_p (exp))
7065 && (!REG_P (target)
7066 || known_eq (GET_MODE_SIZE (GET_MODE (target)), size)))
7067 {
7068 clear_storage (object: target, size: gen_int_mode (size, Pmode),
7069 method: BLOCK_OP_NORMAL);
7070 cleared = 1;
7071 }
7072
7073 if (REG_P (target) && !cleared)
7074 emit_clobber (target);
7075
7076 /* Store each element of the constructor into the
7077 corresponding field of TARGET. */
7078 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, field, value)
7079 {
7080 machine_mode mode;
7081 HOST_WIDE_INT bitsize;
7082 HOST_WIDE_INT bitpos = 0;
7083 tree offset;
7084 rtx to_rtx = target;
7085
7086 /* Just ignore missing fields. We cleared the whole
7087 structure, above, if any fields are missing. */
7088 if (field == 0)
7089 continue;
7090
7091 if (cleared && initializer_zerop (value))
7092 continue;
7093
7094 if (tree_fits_uhwi_p (DECL_SIZE (field)))
7095 bitsize = tree_to_uhwi (DECL_SIZE (field));
7096 else
7097 gcc_unreachable ();
7098
7099 mode = DECL_MODE (field);
7100 if (DECL_BIT_FIELD (field))
7101 mode = VOIDmode;
7102
7103 offset = DECL_FIELD_OFFSET (field);
7104 if (tree_fits_shwi_p (offset)
7105 && tree_fits_shwi_p (bit_position (field)))
7106 {
7107 bitpos = int_bit_position (field);
7108 offset = NULL_TREE;
7109 }
7110 else
7111 gcc_unreachable ();
7112
7113 /* If this initializes a field that is smaller than a
7114 word, at the start of a word, try to widen it to a full
7115 word. This special case allows us to output C++ member
7116 function initializations in a form that the optimizers
7117 can understand. */
7118 if (WORD_REGISTER_OPERATIONS
7119 && REG_P (target)
7120 && bitsize < BITS_PER_WORD
7121 && bitpos % BITS_PER_WORD == 0
7122 && GET_MODE_CLASS (mode) == MODE_INT
7123 && TREE_CODE (value) == INTEGER_CST
7124 && exp_size >= 0
7125 && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
7126 {
7127 type = TREE_TYPE (value);
7128
7129 if (TYPE_PRECISION (type) < BITS_PER_WORD)
7130 {
7131 type = lang_hooks.types.type_for_mode
7132 (word_mode, TYPE_UNSIGNED (type));
7133 value = fold_convert (type, value);
7134 /* Make sure the bits beyond the original bitsize are zero
7135 so that we can correctly avoid extra zeroing stores in
7136 later constructor elements. */
7137 tree bitsize_mask
7138 = wide_int_to_tree (type, cst: wi::mask (width: bitsize, negate_p: false,
7139 BITS_PER_WORD));
7140 value = fold_build2 (BIT_AND_EXPR, type, value, bitsize_mask);
7141 }
7142
7143 if (BYTES_BIG_ENDIAN)
7144 value
7145 = fold_build2 (LSHIFT_EXPR, type, value,
7146 build_int_cst (type,
7147 BITS_PER_WORD - bitsize));
7148 bitsize = BITS_PER_WORD;
7149 mode = word_mode;
7150 }
7151
7152 if (MEM_P (to_rtx) && !MEM_KEEP_ALIAS_SET_P (to_rtx)
7153 && DECL_NONADDRESSABLE_P (field))
7154 {
7155 to_rtx = copy_rtx (to_rtx);
7156 MEM_KEEP_ALIAS_SET_P (to_rtx) = 1;
7157 }
7158
7159 store_constructor_field (target: to_rtx, bitsize, bitpos,
7160 bitregion_start: 0, bitregion_end, mode,
7161 exp: value, cleared,
7162 alias_set: get_alias_set (TREE_TYPE (field)),
7163 reverse);
7164 }
7165 break;
7166 }
7167 case ARRAY_TYPE:
7168 {
7169 tree value, index;
7170 unsigned HOST_WIDE_INT i;
7171 bool need_to_clear;
7172 tree domain;
7173 tree elttype = TREE_TYPE (type);
7174 bool const_bounds_p;
7175 HOST_WIDE_INT minelt = 0;
7176 HOST_WIDE_INT maxelt = 0;
7177
7178 /* The storage order is specified for every aggregate type. */
7179 reverse = TYPE_REVERSE_STORAGE_ORDER (type);
7180
7181 domain = TYPE_DOMAIN (type);
7182 const_bounds_p = (TYPE_MIN_VALUE (domain)
7183 && TYPE_MAX_VALUE (domain)
7184 && tree_fits_shwi_p (TYPE_MIN_VALUE (domain))
7185 && tree_fits_shwi_p (TYPE_MAX_VALUE (domain)));
7186
7187 /* If we have constant bounds for the range of the type, get them. */
7188 if (const_bounds_p)
7189 {
7190 minelt = tree_to_shwi (TYPE_MIN_VALUE (domain));
7191 maxelt = tree_to_shwi (TYPE_MAX_VALUE (domain));
7192 }
7193
7194 /* If the constructor has fewer elements than the array, clear
7195 the whole array first. Similarly if this is static
7196 constructor of a non-BLKmode object. */
7197 if (cleared)
7198 need_to_clear = false;
7199 else if (REG_P (target) && TREE_STATIC (exp))
7200 need_to_clear = true;
7201 else
7202 {
7203 unsigned HOST_WIDE_INT idx;
7204 HOST_WIDE_INT count = 0, zero_count = 0;
7205 need_to_clear = ! const_bounds_p;
7206
7207 /* This loop is a more accurate version of the loop in
7208 mostly_zeros_p (it handles RANGE_EXPR in an index). It
7209 is also needed to check for missing elements. */
7210 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), idx, index, value)
7211 {
7212 HOST_WIDE_INT this_node_count;
7213
7214 if (need_to_clear)
7215 break;
7216
7217 if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7218 {
7219 tree lo_index = TREE_OPERAND (index, 0);
7220 tree hi_index = TREE_OPERAND (index, 1);
7221
7222 if (! tree_fits_uhwi_p (lo_index)
7223 || ! tree_fits_uhwi_p (hi_index))
7224 {
7225 need_to_clear = true;
7226 break;
7227 }
7228
7229 this_node_count = (tree_to_uhwi (hi_index)
7230 - tree_to_uhwi (lo_index) + 1);
7231 }
7232 else
7233 this_node_count = 1;
7234
7235 count += this_node_count;
7236 if (mostly_zeros_p (exp: value))
7237 zero_count += this_node_count;
7238 }
7239
7240 /* Clear the entire array first if there are any missing
7241 elements, or if the incidence of zero elements is >=
7242 75%. */
7243 if (! need_to_clear
7244 && (count < maxelt - minelt + 1
7245 || 4 * zero_count >= 3 * count))
7246 need_to_clear = true;
7247 }
7248
7249 if (need_to_clear && maybe_gt (size, 0))
7250 {
7251 if (REG_P (target))
7252 emit_move_insn (x: target, CONST0_RTX (GET_MODE (target)));
7253 else
7254 clear_storage (object: target, size: gen_int_mode (size, Pmode),
7255 method: BLOCK_OP_NORMAL);
7256 cleared = 1;
7257 }
7258
7259 if (!cleared && REG_P (target))
7260 /* Inform later passes that the old value is dead. */
7261 emit_clobber (target);
7262
7263 /* Store each element of the constructor into the
7264 corresponding element of TARGET, determined by counting the
7265 elements. */
7266 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (exp), i, index, value)
7267 {
7268 machine_mode mode;
7269 poly_int64 bitsize;
7270 HOST_WIDE_INT bitpos;
7271 rtx xtarget = target;
7272
7273 if (cleared && initializer_zerop (value))
7274 continue;
7275
7276 mode = TYPE_MODE (elttype);
7277 if (mode != BLKmode)
7278 bitsize = GET_MODE_BITSIZE (mode);
7279 else if (!poly_int_tree_p (TYPE_SIZE (elttype), value: &bitsize))
7280 bitsize = -1;
7281
7282 if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
7283 {
7284 tree lo_index = TREE_OPERAND (index, 0);
7285 tree hi_index = TREE_OPERAND (index, 1);
7286 rtx index_r, pos_rtx;
7287 HOST_WIDE_INT lo, hi, count;
7288 tree position;
7289
7290 /* If the range is constant and "small", unroll the loop. */
7291 if (const_bounds_p
7292 && tree_fits_shwi_p (lo_index)
7293 && tree_fits_shwi_p (hi_index)
7294 && (lo = tree_to_shwi (lo_index),
7295 hi = tree_to_shwi (hi_index),
7296 count = hi - lo + 1,
7297 (!MEM_P (target)
7298 || count <= 2
7299 || (tree_fits_uhwi_p (TYPE_SIZE (elttype))
7300 && (tree_to_uhwi (TYPE_SIZE (elttype)) * count
7301 <= 40 * 8)))))
7302 {
7303 lo -= minelt; hi -= minelt;
7304 for (; lo <= hi; lo++)
7305 {
7306 bitpos = lo * tree_to_shwi (TYPE_SIZE (elttype));
7307
7308 if (MEM_P (target)
7309 && !MEM_KEEP_ALIAS_SET_P (target)
7310 && TREE_CODE (type) == ARRAY_TYPE
7311 && TYPE_NONALIASED_COMPONENT (type))
7312 {
7313 target = copy_rtx (target);
7314 MEM_KEEP_ALIAS_SET_P (target) = 1;
7315 }
7316
7317 store_constructor_field
7318 (target, bitsize, bitpos, bitregion_start: 0, bitregion_end,
7319 mode, exp: value, cleared,
7320 alias_set: get_alias_set (elttype), reverse);
7321 }
7322 }
7323 else
7324 {
7325 rtx_code_label *loop_start = gen_label_rtx ();
7326 rtx_code_label *loop_end = gen_label_rtx ();
7327 tree exit_cond;
7328
7329 expand_normal (exp: hi_index);
7330
7331 index = build_decl (EXPR_LOCATION (exp),
7332 VAR_DECL, NULL_TREE, domain);
7333 index_r = gen_reg_rtx (promote_decl_mode (index, NULL));
7334 SET_DECL_RTL (index, index_r);
7335 store_expr (exp: lo_index, target: index_r, call_param_p: 0, nontemporal: false, reverse);
7336
7337 /* Build the head of the loop. */
7338 do_pending_stack_adjust ();
7339 emit_label (loop_start);
7340
7341 /* Assign value to element index. */
7342 position =
7343 fold_convert (ssizetype,
7344 fold_build2 (MINUS_EXPR,
7345 TREE_TYPE (index),
7346 index,
7347 TYPE_MIN_VALUE (domain)));
7348
7349 position =
7350 size_binop (MULT_EXPR, position,
7351 fold_convert (ssizetype,
7352 TYPE_SIZE_UNIT (elttype)));
7353
7354 pos_rtx = expand_normal (exp: position);
7355 xtarget = offset_address (target, pos_rtx,
7356 highest_pow2_factor (position));
7357 xtarget = adjust_address (xtarget, mode, 0);
7358 if (TREE_CODE (value) == CONSTRUCTOR)
7359 store_constructor (exp: value, target: xtarget, cleared,
7360 size: exact_div (a: bitsize, BITS_PER_UNIT),
7361 reverse);
7362 else
7363 store_expr (exp: value, target: xtarget, call_param_p: 0, nontemporal: false, reverse);
7364
7365 /* Generate a conditional jump to exit the loop. */
7366 exit_cond = build2 (LT_EXPR, integer_type_node,
7367 index, hi_index);
7368 jumpif (exp: exit_cond, label: loop_end,
7369 prob: profile_probability::uninitialized ());
7370
7371 /* Update the loop counter, and jump to the head of
7372 the loop. */
7373 expand_assignment (to: index,
7374 from: build2 (PLUS_EXPR, TREE_TYPE (index),
7375 index, integer_one_node),
7376 nontemporal: false);
7377
7378 emit_jump (loop_start);
7379
7380 /* Build the end of the loop. */
7381 emit_label (loop_end);
7382 }
7383 }
7384 else if ((index != 0 && ! tree_fits_shwi_p (index))
7385 || ! tree_fits_uhwi_p (TYPE_SIZE (elttype)))
7386 {
7387 tree position;
7388
7389 if (index == 0)
7390 index = ssize_int (1);
7391
7392 if (minelt)
7393 index = fold_convert (ssizetype,
7394 fold_build2 (MINUS_EXPR,
7395 TREE_TYPE (index),
7396 index,
7397 TYPE_MIN_VALUE (domain)));
7398
7399 position =
7400 size_binop (MULT_EXPR, index,
7401 fold_convert (ssizetype,
7402 TYPE_SIZE_UNIT (elttype)));
7403 xtarget = offset_address (target,
7404 expand_normal (exp: position),
7405 highest_pow2_factor (position));
7406 xtarget = adjust_address (xtarget, mode, 0);
7407 store_expr (exp: value, target: xtarget, call_param_p: 0, nontemporal: false, reverse);
7408 }
7409 else
7410 {
7411 if (index != 0)
7412 bitpos = ((tree_to_shwi (index) - minelt)
7413 * tree_to_uhwi (TYPE_SIZE (elttype)));
7414 else
7415 bitpos = (i * tree_to_uhwi (TYPE_SIZE (elttype)));
7416
7417 if (MEM_P (target) && !MEM_KEEP_ALIAS_SET_P (target)
7418 && TREE_CODE (type) == ARRAY_TYPE
7419 && TYPE_NONALIASED_COMPONENT (type))
7420 {
7421 target = copy_rtx (target);
7422 MEM_KEEP_ALIAS_SET_P (target) = 1;
7423 }
7424 store_constructor_field (target, bitsize, bitpos, bitregion_start: 0,
7425 bitregion_end, mode, exp: value,
7426 cleared, alias_set: get_alias_set (elttype),
7427 reverse);
7428 }
7429 }
7430 break;
7431 }
7432
7433 case VECTOR_TYPE:
7434 {
7435 unsigned HOST_WIDE_INT idx;
7436 constructor_elt *ce;
7437 int i;
7438 bool need_to_clear;
7439 insn_code icode = CODE_FOR_nothing;
7440 tree elt;
7441 tree elttype = TREE_TYPE (type);
7442 int elt_size = vector_element_bits (type);
7443 machine_mode eltmode = TYPE_MODE (elttype);
7444 HOST_WIDE_INT bitsize;
7445 HOST_WIDE_INT bitpos;
7446 rtvec vector = NULL;
7447 poly_uint64 n_elts;
7448 unsigned HOST_WIDE_INT const_n_elts;
7449 alias_set_type alias;
7450 bool vec_vec_init_p = false;
7451 machine_mode mode = GET_MODE (target);
7452
7453 gcc_assert (eltmode != BLKmode);
7454
7455 /* Try using vec_duplicate_optab for uniform vectors. */
7456 if (!TREE_SIDE_EFFECTS (exp)
7457 && VECTOR_MODE_P (mode)
7458 && eltmode == GET_MODE_INNER (mode)
7459 && ((icode = optab_handler (op: vec_duplicate_optab, mode))
7460 != CODE_FOR_nothing)
7461 && (elt = uniform_vector_p (exp))
7462 && !VECTOR_TYPE_P (TREE_TYPE (elt)))
7463 {
7464 class expand_operand ops[2];
7465 create_output_operand (op: &ops[0], x: target, mode);
7466 create_input_operand (op: &ops[1], value: expand_normal (exp: elt), mode: eltmode);
7467 expand_insn (icode, nops: 2, ops);
7468 if (!rtx_equal_p (target, ops[0].value))
7469 emit_move_insn (x: target, y: ops[0].value);
7470 break;
7471 }
7472 /* Use sign-extension for uniform boolean vectors with
7473 integer modes. */
7474 if (!TREE_SIDE_EFFECTS (exp)
7475 && VECTOR_BOOLEAN_TYPE_P (type)
7476 && SCALAR_INT_MODE_P (mode)
7477 && (elt = uniform_vector_p (exp))
7478 && !VECTOR_TYPE_P (TREE_TYPE (elt)))
7479 {
7480 rtx op0 = force_reg (TYPE_MODE (TREE_TYPE (elt)),
7481 expand_normal (exp: elt));
7482 convert_move (to: target, from: op0, unsignedp: 0);
7483 break;
7484 }
7485
7486 n_elts = TYPE_VECTOR_SUBPARTS (node: type);
7487 if (REG_P (target)
7488 && VECTOR_MODE_P (mode)
7489 && n_elts.is_constant (const_value: &const_n_elts))
7490 {
7491 machine_mode emode = eltmode;
7492 bool vector_typed_elts_p = false;
7493
7494 if (CONSTRUCTOR_NELTS (exp)
7495 && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value))
7496 == VECTOR_TYPE))
7497 {
7498 tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value);
7499 gcc_assert (known_eq (CONSTRUCTOR_NELTS (exp)
7500 * TYPE_VECTOR_SUBPARTS (etype),
7501 n_elts));
7502 emode = TYPE_MODE (etype);
7503 vector_typed_elts_p = true;
7504 }
7505 icode = convert_optab_handler (op: vec_init_optab, to_mode: mode, from_mode: emode);
7506 if (icode != CODE_FOR_nothing)
7507 {
7508 unsigned int n = const_n_elts;
7509
7510 if (vector_typed_elts_p)
7511 {
7512 n = CONSTRUCTOR_NELTS (exp);
7513 vec_vec_init_p = true;
7514 }
7515 vector = rtvec_alloc (n);
7516 for (unsigned int k = 0; k < n; k++)
7517 RTVEC_ELT (vector, k) = CONST0_RTX (emode);
7518 }
7519 }
7520
7521 /* Compute the size of the elements in the CTOR. It differs
7522 from the size of the vector type elements only when the
7523 CTOR elements are vectors themselves. */
7524 tree val_type = (CONSTRUCTOR_NELTS (exp) != 0
7525 ? TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)
7526 : elttype);
7527 if (VECTOR_TYPE_P (val_type))
7528 bitsize = tree_to_uhwi (TYPE_SIZE (val_type));
7529 else
7530 bitsize = elt_size;
7531
7532 /* If the constructor has fewer elements than the vector,
7533 clear the whole array first. Similarly if this is static
7534 constructor of a non-BLKmode object. */
7535 if (cleared)
7536 need_to_clear = false;
7537 else if (REG_P (target) && TREE_STATIC (exp))
7538 need_to_clear = true;
7539 else
7540 {
7541 unsigned HOST_WIDE_INT count = 0, zero_count = 0;
7542 tree value;
7543
7544 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
7545 {
7546 int n_elts_here = bitsize / elt_size;
7547 count += n_elts_here;
7548 if (mostly_zeros_p (exp: value))
7549 zero_count += n_elts_here;
7550 }
7551
7552 /* Clear the entire vector first if there are any missing elements,
7553 or if the incidence of zero elements is >= 75%. */
7554 need_to_clear = (maybe_lt (a: count, b: n_elts)
7555 || 4 * zero_count >= 3 * count);
7556 }
7557
7558 if (need_to_clear && maybe_gt (size, 0) && !vector)
7559 {
7560 if (REG_P (target))
7561 emit_move_insn (x: target, CONST0_RTX (mode));
7562 else
7563 clear_storage (object: target, size: gen_int_mode (size, Pmode),
7564 method: BLOCK_OP_NORMAL);
7565 cleared = 1;
7566 }
7567
7568 /* Inform later passes that the old value is dead. */
7569 if (!cleared && !vector && REG_P (target) && maybe_gt (n_elts, 1u))
7570 {
7571 emit_move_insn (x: target, CONST0_RTX (mode));
7572 cleared = 1;
7573 }
7574
7575 if (MEM_P (target))
7576 alias = MEM_ALIAS_SET (target);
7577 else
7578 alias = get_alias_set (elttype);
7579
7580 /* Store each element of the constructor into the corresponding
7581 element of TARGET, determined by counting the elements. */
7582 for (idx = 0, i = 0;
7583 vec_safe_iterate (CONSTRUCTOR_ELTS (exp), ix: idx, ptr: &ce);
7584 idx++, i += bitsize / elt_size)
7585 {
7586 HOST_WIDE_INT eltpos;
7587 tree value = ce->value;
7588
7589 if (cleared && initializer_zerop (value))
7590 continue;
7591
7592 if (ce->index)
7593 eltpos = tree_to_uhwi (ce->index);
7594 else
7595 eltpos = i;
7596
7597 if (vector)
7598 {
7599 if (vec_vec_init_p)
7600 {
7601 gcc_assert (ce->index == NULL_TREE);
7602 gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE);
7603 eltpos = idx;
7604 }
7605 else
7606 gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE);
7607 RTVEC_ELT (vector, eltpos) = expand_normal (exp: value);
7608 }
7609 else
7610 {
7611 machine_mode value_mode
7612 = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE
7613 ? TYPE_MODE (TREE_TYPE (value)) : eltmode);
7614 bitpos = eltpos * elt_size;
7615 store_constructor_field (target, bitsize, bitpos, bitregion_start: 0,
7616 bitregion_end, mode: value_mode,
7617 exp: value, cleared, alias_set: alias, reverse);
7618 }
7619 }
7620
7621 if (vector)
7622 emit_insn (GEN_FCN (icode) (target,
7623 gen_rtx_PARALLEL (mode, vector)));
7624 break;
7625 }
7626
7627 default:
7628 gcc_unreachable ();
7629 }
7630}
7631
7632/* Store the value of EXP (an expression tree)
7633 into a subfield of TARGET which has mode MODE and occupies
7634 BITSIZE bits, starting BITPOS bits from the start of TARGET.
7635 If MODE is VOIDmode, it means that we are storing into a bit-field.
7636
7637 BITREGION_START is bitpos of the first bitfield in this region.
7638 BITREGION_END is the bitpos of the ending bitfield in this region.
7639 These two fields are 0, if the C++ memory model does not apply,
7640 or we are not interested in keeping track of bitfield regions.
7641
7642 Always return const0_rtx unless we have something particular to
7643 return.
7644
7645 ALIAS_SET is the alias set for the destination. This value will
7646 (in general) be different from that for TARGET, since TARGET is a
7647 reference to the containing structure.
7648
7649 If NONTEMPORAL is true, try generating a nontemporal store.
7650
7651 If REVERSE is true, the store is to be done in reverse order. */
7652
7653static rtx
7654store_field (rtx target, poly_int64 bitsize, poly_int64 bitpos,
7655 poly_uint64 bitregion_start, poly_uint64 bitregion_end,
7656 machine_mode mode, tree exp,
7657 alias_set_type alias_set, bool nontemporal, bool reverse)
7658{
7659 if (TREE_CODE (exp) == ERROR_MARK)
7660 return const0_rtx;
7661
7662 /* If we have nothing to store, do nothing unless the expression has
7663 side-effects. Don't do that for zero sized addressable lhs of
7664 calls. */
7665 if (known_eq (bitsize, 0)
7666 && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
7667 || TREE_CODE (exp) != CALL_EXPR))
7668 return expand_expr (exp, const0_rtx, VOIDmode, modifier: EXPAND_NORMAL);
7669
7670 if (GET_CODE (target) == CONCAT)
7671 {
7672 /* We're storing into a struct containing a single __complex. */
7673
7674 gcc_assert (known_eq (bitpos, 0));
7675 return store_expr (exp, target, call_param_p: 0, nontemporal, reverse);
7676 }
7677
7678 /* If the structure is in a register or if the component
7679 is a bit field, we cannot use addressing to access it.
7680 Use bit-field techniques or SUBREG to store in it. */
7681
7682 poly_int64 decl_bitsize;
7683 if (mode == VOIDmode
7684 || (mode != BLKmode && ! direct_store[(int) mode]
7685 && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
7686 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
7687 || REG_P (target)
7688 || GET_CODE (target) == SUBREG
7689 /* If the field isn't aligned enough to store as an ordinary memref,
7690 store it as a bit field. */
7691 || (mode != BLKmode
7692 && ((((MEM_ALIGN (target) < GET_MODE_ALIGNMENT (mode))
7693 || !multiple_p (a: bitpos, GET_MODE_ALIGNMENT (mode)))
7694 && targetm.slow_unaligned_access (mode, MEM_ALIGN (target)))
7695 || !multiple_p (a: bitpos, BITS_PER_UNIT)))
7696 || (known_size_p (a: bitsize)
7697 && mode != BLKmode
7698 && maybe_gt (GET_MODE_BITSIZE (mode), bitsize))
7699 /* If the RHS and field are a constant size and the size of the
7700 RHS isn't the same size as the bitfield, we must use bitfield
7701 operations. */
7702 || (known_size_p (a: bitsize)
7703 && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
7704 && maybe_ne (a: wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
7705 b: bitsize)
7706 /* Except for initialization of full bytes from a CONSTRUCTOR, which
7707 we will handle specially below. */
7708 && !(TREE_CODE (exp) == CONSTRUCTOR
7709 && multiple_p (a: bitsize, BITS_PER_UNIT))
7710 /* And except for bitwise copying of TREE_ADDRESSABLE types,
7711 where the FIELD_DECL has the right bitsize, but TREE_TYPE (exp)
7712 includes some extra padding. store_expr / expand_expr will in
7713 that case call get_inner_reference that will have the bitsize
7714 we check here and thus the block move will not clobber the
7715 padding that shouldn't be clobbered. In the future we could
7716 replace the TREE_ADDRESSABLE check with a check that
7717 get_base_address needs to live in memory. */
7718 && (!TREE_ADDRESSABLE (TREE_TYPE (exp))
7719 || TREE_CODE (exp) != COMPONENT_REF
7720 || !multiple_p (a: bitsize, BITS_PER_UNIT)
7721 || !multiple_p (a: bitpos, BITS_PER_UNIT)
7722 || !poly_int_tree_p (DECL_SIZE (TREE_OPERAND (exp, 1)),
7723 value: &decl_bitsize)
7724 || maybe_ne (a: decl_bitsize, b: bitsize))
7725 /* A call with an addressable return type and return-slot
7726 optimization must not need bitfield operations but we must
7727 pass down the original target. */
7728 && (TREE_CODE (exp) != CALL_EXPR
7729 || !TREE_ADDRESSABLE (TREE_TYPE (exp))
7730 || !CALL_EXPR_RETURN_SLOT_OPT (exp)))
7731 /* If we are expanding a MEM_REF of a non-BLKmode non-addressable
7732 decl we must use bitfield operations. */
7733 || (known_size_p (a: bitsize)
7734 && TREE_CODE (exp) == MEM_REF
7735 && TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR
7736 && DECL_P (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
7737 && !TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))
7738 && DECL_MODE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0)) != BLKmode))
7739 {
7740 rtx temp;
7741 gimple *nop_def;
7742
7743 /* If EXP is a NOP_EXPR of precision less than its mode, then that
7744 implies a mask operation. If the precision is the same size as
7745 the field we're storing into, that mask is redundant. This is
7746 particularly common with bit field assignments generated by the
7747 C front end. */
7748 nop_def = get_def_for_expr (name: exp, code: NOP_EXPR);
7749 if (nop_def)
7750 {
7751 tree type = TREE_TYPE (exp);
7752 if (INTEGRAL_TYPE_P (type)
7753 && maybe_ne (TYPE_PRECISION (type),
7754 b: GET_MODE_BITSIZE (TYPE_MODE (type)))
7755 && known_eq (bitsize, TYPE_PRECISION (type)))
7756 {
7757 tree op = gimple_assign_rhs1 (gs: nop_def);
7758 type = TREE_TYPE (op);
7759 if (INTEGRAL_TYPE_P (type)
7760 && known_ge (TYPE_PRECISION (type), bitsize))
7761 exp = op;
7762 }
7763 }
7764
7765 temp = expand_normal (exp);
7766
7767 /* We don't support variable-sized BLKmode bitfields, since our
7768 handling of BLKmode is bound up with the ability to break
7769 things into words. */
7770 gcc_assert (mode != BLKmode || bitsize.is_constant ());
7771
7772 /* Handle calls that return values in multiple non-contiguous locations.
7773 The Irix 6 ABI has examples of this. */
7774 if (GET_CODE (temp) == PARALLEL)
7775 {
7776 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
7777 machine_mode temp_mode = GET_MODE (temp);
7778 if (temp_mode == BLKmode || temp_mode == VOIDmode)
7779 temp_mode = smallest_int_mode_for_size (size: size * BITS_PER_UNIT);
7780 rtx temp_target = gen_reg_rtx (temp_mode);
7781 emit_group_store (orig_dst: temp_target, src: temp, TREE_TYPE (exp), ssize: size);
7782 temp = temp_target;
7783 }
7784
7785 /* Handle calls that return BLKmode values in registers. */
7786 else if (mode == BLKmode && REG_P (temp) && TREE_CODE (exp) == CALL_EXPR)
7787 {
7788 rtx temp_target = gen_reg_rtx (GET_MODE (temp));
7789 copy_blkmode_from_reg (target: temp_target, srcreg: temp, TREE_TYPE (exp));
7790 temp = temp_target;
7791 }
7792
7793 /* If the value has aggregate type and an integral mode then, if BITSIZE
7794 is narrower than this mode and this is for big-endian data, we first
7795 need to put the value into the low-order bits for store_bit_field,
7796 except when MODE is BLKmode and BITSIZE larger than the word size
7797 (see the handling of fields larger than a word in store_bit_field).
7798 Moreover, the field may be not aligned on a byte boundary; in this
7799 case, if it has reverse storage order, it needs to be accessed as a
7800 scalar field with reverse storage order and we must first put the
7801 value into target order. */
7802 scalar_int_mode temp_mode;
7803 if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
7804 && is_int_mode (GET_MODE (temp), int_mode: &temp_mode))
7805 {
7806 HOST_WIDE_INT size = GET_MODE_BITSIZE (mode: temp_mode);
7807
7808 reverse = TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (exp));
7809
7810 if (reverse)
7811 temp = flip_storage_order (temp_mode, temp);
7812
7813 gcc_checking_assert (known_le (bitsize, size));
7814 if (maybe_lt (a: bitsize, b: size)
7815 && reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN
7816 /* Use of to_constant for BLKmode was checked above. */
7817 && !(mode == BLKmode && bitsize.to_constant () > BITS_PER_WORD))
7818 temp = expand_shift (RSHIFT_EXPR, temp_mode, temp,
7819 size - bitsize, NULL_RTX, 1);
7820 }
7821
7822 /* Unless MODE is VOIDmode or BLKmode, convert TEMP to MODE. */
7823 if (mode != VOIDmode && mode != BLKmode
7824 && mode != TYPE_MODE (TREE_TYPE (exp)))
7825 temp = convert_modes (mode, TYPE_MODE (TREE_TYPE (exp)), x: temp, unsignedp: 1);
7826
7827 /* If the mode of TEMP and TARGET is BLKmode, both must be in memory
7828 and BITPOS must be aligned on a byte boundary. If so, we simply do
7829 a block copy. Likewise for a BLKmode-like TARGET. */
7830 if (GET_MODE (temp) == BLKmode
7831 && (GET_MODE (target) == BLKmode
7832 || (MEM_P (target)
7833 && GET_MODE_CLASS (GET_MODE (target)) == MODE_INT
7834 && multiple_p (a: bitpos, BITS_PER_UNIT)
7835 && multiple_p (a: bitsize, BITS_PER_UNIT))))
7836 {
7837 gcc_assert (MEM_P (target) && MEM_P (temp));
7838 poly_int64 bytepos = exact_div (a: bitpos, BITS_PER_UNIT);
7839 poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
7840
7841 target = adjust_address (target, VOIDmode, bytepos);
7842 emit_block_move (x: target, y: temp,
7843 size: gen_int_mode (bytesize, Pmode),
7844 method: BLOCK_OP_NORMAL);
7845
7846 return const0_rtx;
7847 }
7848
7849 /* If the mode of TEMP is still BLKmode and BITSIZE not larger than the
7850 word size, we need to load the value (see again store_bit_field). */
7851 if (GET_MODE (temp) == BLKmode && known_le (bitsize, BITS_PER_WORD))
7852 {
7853 temp_mode = smallest_int_mode_for_size (size: bitsize);
7854 temp = extract_bit_field (temp, bitsize, 0, 1, NULL_RTX, temp_mode,
7855 temp_mode, false, NULL);
7856 }
7857
7858 /* Store the value in the bitfield. */
7859 gcc_checking_assert (known_ge (bitpos, 0));
7860 store_bit_field (target, bitsize, bitpos,
7861 bitregion_start, bitregion_end,
7862 mode, temp, reverse, false);
7863
7864 return const0_rtx;
7865 }
7866 else
7867 {
7868 /* Now build a reference to just the desired component. */
7869 rtx to_rtx = adjust_address (target, mode,
7870 exact_div (bitpos, BITS_PER_UNIT));
7871
7872 if (to_rtx == target)
7873 to_rtx = copy_rtx (to_rtx);
7874
7875 if (!MEM_KEEP_ALIAS_SET_P (to_rtx) && MEM_ALIAS_SET (to_rtx) != 0)
7876 set_mem_alias_set (to_rtx, alias_set);
7877
7878 /* Above we avoided using bitfield operations for storing a CONSTRUCTOR
7879 into a target smaller than its type; handle that case now. */
7880 if (TREE_CODE (exp) == CONSTRUCTOR && known_size_p (a: bitsize))
7881 {
7882 poly_int64 bytesize = exact_div (a: bitsize, BITS_PER_UNIT);
7883 store_constructor (exp, target: to_rtx, cleared: 0, size: bytesize, reverse);
7884 return to_rtx;
7885 }
7886
7887 return store_expr (exp, target: to_rtx, call_param_p: 0, nontemporal, reverse);
7888 }
7889}
7890
7891/* Given an expression EXP that may be a COMPONENT_REF, a BIT_FIELD_REF,
7892 an ARRAY_REF, or an ARRAY_RANGE_REF, look for nested operations of these
7893 codes and find the ultimate containing object, which we return.
7894
7895 We set *PBITSIZE to the size in bits that we want, *PBITPOS to the
7896 bit position, *PUNSIGNEDP to the signedness and *PREVERSEP to the
7897 storage order of the field.
7898 If the position of the field is variable, we store a tree
7899 giving the variable offset (in units) in *POFFSET.
7900 This offset is in addition to the bit position.
7901 If the position is not variable, we store 0 in *POFFSET.
7902
7903 If any of the extraction expressions is volatile,
7904 we store 1 in *PVOLATILEP. Otherwise we don't change that.
7905
7906 If the field is a non-BLKmode bit-field, *PMODE is set to VOIDmode.
7907 Otherwise, it is a mode that can be used to access the field.
7908
7909 If the field describes a variable-sized object, *PMODE is set to
7910 BLKmode and *PBITSIZE is set to -1. An access cannot be made in
7911 this case, but the address of the object can be found. */
7912
7913tree
7914get_inner_reference (tree exp, poly_int64 *pbitsize,
7915 poly_int64 *pbitpos, tree *poffset,
7916 machine_mode *pmode, int *punsignedp,
7917 int *preversep, int *pvolatilep)
7918{
7919 tree size_tree = 0;
7920 machine_mode mode = VOIDmode;
7921 bool blkmode_bitfield = false;
7922 tree offset = size_zero_node;
7923 poly_offset_int bit_offset = 0;
7924
7925 /* First get the mode, signedness, storage order and size. We do this from
7926 just the outermost expression. */
7927 *pbitsize = -1;
7928 if (TREE_CODE (exp) == COMPONENT_REF)
7929 {
7930 tree field = TREE_OPERAND (exp, 1);
7931 size_tree = DECL_SIZE (field);
7932 if (flag_strict_volatile_bitfields > 0
7933 && TREE_THIS_VOLATILE (exp)
7934 && DECL_BIT_FIELD_TYPE (field)
7935 && DECL_MODE (field) != BLKmode)
7936 /* Volatile bitfields should be accessed in the mode of the
7937 field's type, not the mode computed based on the bit
7938 size. */
7939 mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field));
7940 else if (!DECL_BIT_FIELD (field))
7941 {
7942 mode = DECL_MODE (field);
7943 /* For vector fields re-check the target flags, as DECL_MODE
7944 could have been set with different target flags than
7945 the current function has. */
7946 if (VECTOR_TYPE_P (TREE_TYPE (field))
7947 && VECTOR_MODE_P (TYPE_MODE_RAW (TREE_TYPE (field))))
7948 mode = TYPE_MODE (TREE_TYPE (field));
7949 }
7950 else if (DECL_MODE (field) == BLKmode)
7951 blkmode_bitfield = true;
7952
7953 *punsignedp = DECL_UNSIGNED (field);
7954 }
7955 else if (TREE_CODE (exp) == BIT_FIELD_REF)
7956 {
7957 size_tree = TREE_OPERAND (exp, 1);
7958 *punsignedp = (! INTEGRAL_TYPE_P (TREE_TYPE (exp))
7959 || TYPE_UNSIGNED (TREE_TYPE (exp)));
7960
7961 /* For vector element types with the correct size of access or for
7962 vector typed accesses use the mode of the access type. */
7963 if ((TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == VECTOR_TYPE
7964 && TREE_TYPE (exp) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0)))
7965 && tree_int_cst_equal (size_tree, TYPE_SIZE (TREE_TYPE (exp))))
7966 || VECTOR_TYPE_P (TREE_TYPE (exp)))
7967 mode = TYPE_MODE (TREE_TYPE (exp));
7968 }
7969 else
7970 {
7971 mode = TYPE_MODE (TREE_TYPE (exp));
7972 *punsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
7973
7974 if (mode == BLKmode)
7975 size_tree = TYPE_SIZE (TREE_TYPE (exp));
7976 else
7977 *pbitsize = GET_MODE_BITSIZE (mode);
7978 }
7979
7980 if (size_tree != 0)
7981 {
7982 if (! tree_fits_uhwi_p (size_tree))
7983 mode = BLKmode, *pbitsize = -1;
7984 else
7985 *pbitsize = tree_to_uhwi (size_tree);
7986 }
7987
7988 *preversep = reverse_storage_order_for_component_p (t: exp);
7989
7990 /* Compute cumulative bit-offset for nested component-refs and array-refs,
7991 and find the ultimate containing object. */
7992 while (1)
7993 {
7994 switch (TREE_CODE (exp))
7995 {
7996 case BIT_FIELD_REF:
7997 bit_offset += wi::to_poly_offset (TREE_OPERAND (exp, 2));
7998 break;
7999
8000 case COMPONENT_REF:
8001 {
8002 tree field = TREE_OPERAND (exp, 1);
8003 tree this_offset = component_ref_field_offset (exp);
8004
8005 /* If this field hasn't been filled in yet, don't go past it.
8006 This should only happen when folding expressions made during
8007 type construction. */
8008 if (this_offset == 0)
8009 break;
8010
8011 offset = size_binop (PLUS_EXPR, offset, this_offset);
8012 bit_offset += wi::to_poly_offset (DECL_FIELD_BIT_OFFSET (field));
8013
8014 /* ??? Right now we don't do anything with DECL_OFFSET_ALIGN. */
8015 }
8016 break;
8017
8018 case ARRAY_REF:
8019 case ARRAY_RANGE_REF:
8020 {
8021 tree index = TREE_OPERAND (exp, 1);
8022 tree low_bound = array_ref_low_bound (exp);
8023 tree unit_size = array_ref_element_size (exp);
8024
8025 /* We assume all arrays have sizes that are a multiple of a byte.
8026 First subtract the lower bound, if any, in the type of the
8027 index, then convert to sizetype and multiply by the size of
8028 the array element. */
8029 if (! integer_zerop (low_bound))
8030 index = fold_build2 (MINUS_EXPR, TREE_TYPE (index),
8031 index, low_bound);
8032
8033 offset = size_binop (PLUS_EXPR, offset,
8034 size_binop (MULT_EXPR,
8035 fold_convert (sizetype, index),
8036 unit_size));
8037 }
8038 break;
8039
8040 case REALPART_EXPR:
8041 break;
8042
8043 case IMAGPART_EXPR:
8044 bit_offset += *pbitsize;
8045 break;
8046
8047 case VIEW_CONVERT_EXPR:
8048 break;
8049
8050 case MEM_REF:
8051 /* Hand back the decl for MEM[&decl, off]. */
8052 if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR)
8053 {
8054 tree off = TREE_OPERAND (exp, 1);
8055 if (!integer_zerop (off))
8056 {
8057 poly_offset_int boff = mem_ref_offset (exp);
8058 boff <<= LOG2_BITS_PER_UNIT;
8059 bit_offset += boff;
8060 }
8061 exp = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
8062 }
8063 goto done;
8064
8065 default:
8066 goto done;
8067 }
8068
8069 /* If any reference in the chain is volatile, the effect is volatile. */
8070 if (TREE_THIS_VOLATILE (exp))
8071 *pvolatilep = 1;
8072
8073 exp = TREE_OPERAND (exp, 0);
8074 }
8075 done:
8076
8077 /* If OFFSET is constant, see if we can return the whole thing as a
8078 constant bit position. Make sure to handle overflow during
8079 this conversion. */
8080 if (poly_int_tree_p (t: offset))
8081 {
8082 poly_offset_int tem = wi::sext (a: wi::to_poly_offset (t: offset),
8083 TYPE_PRECISION (sizetype));
8084 tem <<= LOG2_BITS_PER_UNIT;
8085 tem += bit_offset;
8086 if (tem.to_shwi (r: pbitpos))
8087 *poffset = offset = NULL_TREE;
8088 }
8089
8090 /* Otherwise, split it up. */
8091 if (offset)
8092 {
8093 /* Avoid returning a negative bitpos as this may wreak havoc later. */
8094 if (!bit_offset.to_shwi (r: pbitpos) || maybe_lt (a: *pbitpos, b: 0))
8095 {
8096 *pbitpos = num_trailing_bits (bit_offset.force_shwi ());
8097 poly_offset_int bytes = bits_to_bytes_round_down (bit_offset);
8098 offset = size_binop (PLUS_EXPR, offset,
8099 build_int_cst (sizetype, bytes.force_shwi ()));
8100 }
8101
8102 *poffset = offset;
8103 }
8104
8105 /* We can use BLKmode for a byte-aligned BLKmode bitfield. */
8106 if (mode == VOIDmode
8107 && blkmode_bitfield
8108 && multiple_p (a: *pbitpos, BITS_PER_UNIT)
8109 && multiple_p (a: *pbitsize, BITS_PER_UNIT))
8110 *pmode = BLKmode;
8111 else
8112 *pmode = mode;
8113
8114 return exp;
8115}
8116
8117/* Alignment in bits the TARGET of an assignment may be assumed to have. */
8118
8119static unsigned HOST_WIDE_INT
8120target_align (const_tree target)
8121{
8122 /* We might have a chain of nested references with intermediate misaligning
8123 bitfields components, so need to recurse to find out. */
8124
8125 unsigned HOST_WIDE_INT this_align, outer_align;
8126
8127 switch (TREE_CODE (target))
8128 {
8129 case BIT_FIELD_REF:
8130 return 1;
8131
8132 case COMPONENT_REF:
8133 this_align = DECL_ALIGN (TREE_OPERAND (target, 1));
8134 outer_align = target_align (TREE_OPERAND (target, 0));
8135 return MIN (this_align, outer_align);
8136
8137 case ARRAY_REF:
8138 case ARRAY_RANGE_REF:
8139 this_align = TYPE_ALIGN (TREE_TYPE (target));
8140 outer_align = target_align (TREE_OPERAND (target, 0));
8141 return MIN (this_align, outer_align);
8142
8143 CASE_CONVERT:
8144 case NON_LVALUE_EXPR:
8145 case VIEW_CONVERT_EXPR:
8146 this_align = TYPE_ALIGN (TREE_TYPE (target));
8147 outer_align = target_align (TREE_OPERAND (target, 0));
8148 return MAX (this_align, outer_align);
8149
8150 default:
8151 return TYPE_ALIGN (TREE_TYPE (target));
8152 }
8153}
8154
8155
8156/* Given an rtx VALUE that may contain additions and multiplications, return
8157 an equivalent value that just refers to a register, memory, or constant.
8158 This is done by generating instructions to perform the arithmetic and
8159 returning a pseudo-register containing the value.
8160
8161 The returned value may be a REG, SUBREG, MEM or constant. */
8162
8163rtx
8164force_operand (rtx value, rtx target)
8165{
8166 rtx op1, op2;
8167 /* Use subtarget as the target for operand 0 of a binary operation. */
8168 rtx subtarget = get_subtarget (x: target);
8169 enum rtx_code code = GET_CODE (value);
8170
8171 /* Check for subreg applied to an expression produced by loop optimizer. */
8172 if (code == SUBREG
8173 && !REG_P (SUBREG_REG (value))
8174 && !MEM_P (SUBREG_REG (value)))
8175 {
8176 value
8177 = simplify_gen_subreg (GET_MODE (value),
8178 op: force_reg (GET_MODE (SUBREG_REG (value)),
8179 force_operand (SUBREG_REG (value),
8180 NULL_RTX)),
8181 GET_MODE (SUBREG_REG (value)),
8182 SUBREG_BYTE (value));
8183 code = GET_CODE (value);
8184 }
8185
8186 /* Check for a PIC address load. */
8187 if ((code == PLUS || code == MINUS)
8188 && XEXP (value, 0) == pic_offset_table_rtx
8189 && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF
8190 || GET_CODE (XEXP (value, 1)) == LABEL_REF
8191 || GET_CODE (XEXP (value, 1)) == CONST))
8192 {
8193 if (!subtarget)
8194 subtarget = gen_reg_rtx (GET_MODE (value));
8195 emit_move_insn (x: subtarget, y: value);
8196 return subtarget;
8197 }
8198
8199 if (ARITHMETIC_P (value))
8200 {
8201 op2 = XEXP (value, 1);
8202 if (!CONSTANT_P (op2) && !(REG_P (op2) && op2 != subtarget))
8203 subtarget = 0;
8204 if (code == MINUS && CONST_INT_P (op2))
8205 {
8206 code = PLUS;
8207 op2 = negate_rtx (GET_MODE (value), op2);
8208 }
8209
8210 /* Check for an addition with OP2 a constant integer and our first
8211 operand a PLUS of a virtual register and something else. In that
8212 case, we want to emit the sum of the virtual register and the
8213 constant first and then add the other value. This allows virtual
8214 register instantiation to simply modify the constant rather than
8215 creating another one around this addition. */
8216 if (code == PLUS && CONST_INT_P (op2)
8217 && GET_CODE (XEXP (value, 0)) == PLUS
8218 && REG_P (XEXP (XEXP (value, 0), 0))
8219 && VIRTUAL_REGISTER_P (XEXP (XEXP (value, 0), 0)))
8220 {
8221 rtx temp = expand_simple_binop (GET_MODE (value), code,
8222 XEXP (XEXP (value, 0), 0), op2,
8223 subtarget, 0, OPTAB_LIB_WIDEN);
8224 return expand_simple_binop (GET_MODE (value), code, temp,
8225 force_operand (XEXP (XEXP (value,
8226 0), 1), target: 0),
8227 target, 0, OPTAB_LIB_WIDEN);
8228 }
8229
8230 op1 = force_operand (XEXP (value, 0), target: subtarget);
8231 op2 = force_operand (value: op2, NULL_RTX);
8232 switch (code)
8233 {
8234 case MULT:
8235 return expand_mult (GET_MODE (value), op1, op2, target, 1);
8236 case DIV:
8237 if (!INTEGRAL_MODE_P (GET_MODE (value)))
8238 return expand_simple_binop (GET_MODE (value), code, op1, op2,
8239 target, 1, OPTAB_LIB_WIDEN);
8240 else
8241 return expand_divmod (0,
8242 FLOAT_MODE_P (GET_MODE (value))
8243 ? RDIV_EXPR : TRUNC_DIV_EXPR,
8244 GET_MODE (value), op1, op2, target, 0);
8245 case MOD:
8246 return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8247 target, 0);
8248 case UDIV:
8249 return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2,
8250 target, 1);
8251 case UMOD:
8252 return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2,
8253 target, 1);
8254 case ASHIFTRT:
8255 return expand_simple_binop (GET_MODE (value), code, op1, op2,
8256 target, 0, OPTAB_LIB_WIDEN);
8257 default:
8258 return expand_simple_binop (GET_MODE (value), code, op1, op2,
8259 target, 1, OPTAB_LIB_WIDEN);
8260 }
8261 }
8262 if (UNARY_P (value))
8263 {
8264 if (!target)
8265 target = gen_reg_rtx (GET_MODE (value));
8266 op1 = force_operand (XEXP (value, 0), NULL_RTX);
8267 switch (code)
8268 {
8269 case ZERO_EXTEND:
8270 case SIGN_EXTEND:
8271 case TRUNCATE:
8272 case FLOAT_EXTEND:
8273 case FLOAT_TRUNCATE:
8274 convert_move (to: target, from: op1, unsignedp: code == ZERO_EXTEND);
8275 return target;
8276
8277 case FIX:
8278 case UNSIGNED_FIX:
8279 expand_fix (target, op1, code == UNSIGNED_FIX);
8280 return target;
8281
8282 case FLOAT:
8283 case UNSIGNED_FLOAT:
8284 expand_float (target, op1, code == UNSIGNED_FLOAT);
8285 return target;
8286
8287 default:
8288 return expand_simple_unop (GET_MODE (value), code, op1, target, 0);
8289 }
8290 }
8291
8292#ifdef INSN_SCHEDULING
8293 /* On machines that have insn scheduling, we want all memory reference to be
8294 explicit, so we need to deal with such paradoxical SUBREGs. */
8295 if (paradoxical_subreg_p (x: value) && MEM_P (SUBREG_REG (value)))
8296 value
8297 = simplify_gen_subreg (GET_MODE (value),
8298 op: force_reg (GET_MODE (SUBREG_REG (value)),
8299 force_operand (SUBREG_REG (value),
8300 NULL_RTX)),
8301 GET_MODE (SUBREG_REG (value)),
8302 SUBREG_BYTE (value));
8303#endif
8304
8305 return value;
8306}
8307
8308/* Subroutine of expand_expr: return true iff there is no way that
8309 EXP can reference X, which is being modified. TOP_P is nonzero if this
8310 call is going to be used to determine whether we need a temporary
8311 for EXP, as opposed to a recursive call to this function.
8312
8313 It is always safe for this routine to return false since it merely
8314 searches for optimization opportunities. */
8315
8316bool
8317safe_from_p (const_rtx x, tree exp, int top_p)
8318{
8319 rtx exp_rtl = 0;
8320 int i, nops;
8321
8322 if (x == 0
8323 /* If EXP has varying size, we MUST use a target since we currently
8324 have no way of allocating temporaries of variable size
8325 (except for arrays that have TYPE_ARRAY_MAX_SIZE set).
8326 So we assume here that something at a higher level has prevented a
8327 clash. This is somewhat bogus, but the best we can do. Only
8328 do this when X is BLKmode and when we are at the top level. */
8329 || (top_p && TREE_TYPE (exp) != 0 && COMPLETE_TYPE_P (TREE_TYPE (exp))
8330 && TREE_CODE (TYPE_SIZE (TREE_TYPE (exp))) != INTEGER_CST
8331 && (TREE_CODE (TREE_TYPE (exp)) != ARRAY_TYPE
8332 || TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)) == NULL_TREE
8333 || TREE_CODE (TYPE_ARRAY_MAX_SIZE (TREE_TYPE (exp)))
8334 != INTEGER_CST)
8335 && GET_MODE (x) == BLKmode)
8336 /* If X is in the outgoing argument area, it is always safe. */
8337 || (MEM_P (x)
8338 && (XEXP (x, 0) == virtual_outgoing_args_rtx
8339 || (GET_CODE (XEXP (x, 0)) == PLUS
8340 && XEXP (XEXP (x, 0), 0) == virtual_outgoing_args_rtx))))
8341 return true;
8342
8343 /* If this is a subreg of a hard register, declare it unsafe, otherwise,
8344 find the underlying pseudo. */
8345 if (GET_CODE (x) == SUBREG)
8346 {
8347 x = SUBREG_REG (x);
8348 if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
8349 return false;
8350 }
8351
8352 /* Now look at our tree code and possibly recurse. */
8353 switch (TREE_CODE_CLASS (TREE_CODE (exp)))
8354 {
8355 case tcc_declaration:
8356 exp_rtl = DECL_RTL_IF_SET (exp);
8357 break;
8358
8359 case tcc_constant:
8360 return true;
8361
8362 case tcc_exceptional:
8363 if (TREE_CODE (exp) == TREE_LIST)
8364 {
8365 while (1)
8366 {
8367 if (TREE_VALUE (exp) && !safe_from_p (x, TREE_VALUE (exp), top_p: 0))
8368 return false;
8369 exp = TREE_CHAIN (exp);
8370 if (!exp)
8371 return true;
8372 if (TREE_CODE (exp) != TREE_LIST)
8373 return safe_from_p (x, exp, top_p: 0);
8374 }
8375 }
8376 else if (TREE_CODE (exp) == CONSTRUCTOR)
8377 {
8378 constructor_elt *ce;
8379 unsigned HOST_WIDE_INT idx;
8380
8381 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (exp), idx, ce)
8382 if ((ce->index != NULL_TREE && !safe_from_p (x, exp: ce->index, top_p: 0))
8383 || !safe_from_p (x, exp: ce->value, top_p: 0))
8384 return false;
8385 return true;
8386 }
8387 else if (TREE_CODE (exp) == ERROR_MARK)
8388 return true; /* An already-visited SAVE_EXPR? */
8389 else
8390 return false;
8391
8392 case tcc_statement:
8393 /* The only case we look at here is the DECL_INITIAL inside a
8394 DECL_EXPR. */
8395 return (TREE_CODE (exp) != DECL_EXPR
8396 || TREE_CODE (DECL_EXPR_DECL (exp)) != VAR_DECL
8397 || !DECL_INITIAL (DECL_EXPR_DECL (exp))
8398 || safe_from_p (x, DECL_INITIAL (DECL_EXPR_DECL (exp)), top_p: 0));
8399
8400 case tcc_binary:
8401 case tcc_comparison:
8402 if (!safe_from_p (x, TREE_OPERAND (exp, 1), top_p: 0))
8403 return false;
8404 /* Fall through. */
8405
8406 case tcc_unary:
8407 return safe_from_p (x, TREE_OPERAND (exp, 0), top_p: 0);
8408
8409 case tcc_expression:
8410 case tcc_reference:
8411 case tcc_vl_exp:
8412 /* Now do code-specific tests. EXP_RTL is set to any rtx we find in
8413 the expression. If it is set, we conflict iff we are that rtx or
8414 both are in memory. Otherwise, we check all operands of the
8415 expression recursively. */
8416
8417 switch (TREE_CODE (exp))
8418 {
8419 case ADDR_EXPR:
8420 /* If the operand is static or we are static, we can't conflict.
8421 Likewise if we don't conflict with the operand at all. */
8422 if (staticp (TREE_OPERAND (exp, 0))
8423 || TREE_STATIC (exp)
8424 || safe_from_p (x, TREE_OPERAND (exp, 0), top_p: 0))
8425 return true;
8426
8427 /* Otherwise, the only way this can conflict is if we are taking
8428 the address of a DECL a that address if part of X, which is
8429 very rare. */
8430 exp = TREE_OPERAND (exp, 0);
8431 if (DECL_P (exp))
8432 {
8433 if (!DECL_RTL_SET_P (exp)
8434 || !MEM_P (DECL_RTL (exp)))
8435 return false;
8436 else
8437 exp_rtl = XEXP (DECL_RTL (exp), 0);
8438 }
8439 break;
8440
8441 case MEM_REF:
8442 if (MEM_P (x)
8443 && alias_sets_conflict_p (MEM_ALIAS_SET (x),
8444 get_alias_set (exp)))
8445 return false;
8446 break;
8447
8448 case CALL_EXPR:
8449 /* Assume that the call will clobber all hard registers and
8450 all of memory. */
8451 if ((REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
8452 || MEM_P (x))
8453 return false;
8454 break;
8455
8456 case WITH_CLEANUP_EXPR:
8457 case CLEANUP_POINT_EXPR:
8458 /* Lowered by gimplify.cc. */
8459 gcc_unreachable ();
8460
8461 case SAVE_EXPR:
8462 return safe_from_p (x, TREE_OPERAND (exp, 0), top_p: 0);
8463
8464 default:
8465 break;
8466 }
8467
8468 /* If we have an rtx, we do not need to scan our operands. */
8469 if (exp_rtl)
8470 break;
8471
8472 nops = TREE_OPERAND_LENGTH (exp);
8473 for (i = 0; i < nops; i++)
8474 if (TREE_OPERAND (exp, i) != 0
8475 && ! safe_from_p (x, TREE_OPERAND (exp, i), top_p: 0))
8476 return false;
8477
8478 break;
8479
8480 case tcc_type:
8481 /* Should never get a type here. */
8482 gcc_unreachable ();
8483 }
8484
8485 /* If we have an rtl, find any enclosed object. Then see if we conflict
8486 with it. */
8487 if (exp_rtl)
8488 {
8489 if (GET_CODE (exp_rtl) == SUBREG)
8490 {
8491 exp_rtl = SUBREG_REG (exp_rtl);
8492 if (REG_P (exp_rtl)
8493 && REGNO (exp_rtl) < FIRST_PSEUDO_REGISTER)
8494 return false;
8495 }
8496
8497 /* If the rtl is X, then it is not safe. Otherwise, it is unless both
8498 are memory and they conflict. */
8499 return ! (rtx_equal_p (x, exp_rtl)
8500 || (MEM_P (x) && MEM_P (exp_rtl)
8501 && true_dependence (exp_rtl, VOIDmode, x)));
8502 }
8503
8504 /* If we reach here, it is safe. */
8505 return true;
8506}
8507
8508
8509/* Return the highest power of two that EXP is known to be a multiple of.
8510 This is used in updating alignment of MEMs in array references. */
8511
8512unsigned HOST_WIDE_INT
8513highest_pow2_factor (const_tree exp)
8514{
8515 unsigned HOST_WIDE_INT ret;
8516 int trailing_zeros = tree_ctz (exp);
8517 if (trailing_zeros >= HOST_BITS_PER_WIDE_INT)
8518 return BIGGEST_ALIGNMENT;
8519 ret = HOST_WIDE_INT_1U << trailing_zeros;
8520 if (ret > BIGGEST_ALIGNMENT)
8521 return BIGGEST_ALIGNMENT;
8522 return ret;
8523}
8524
8525/* Similar, except that the alignment requirements of TARGET are
8526 taken into account. Assume it is at least as aligned as its
8527 type, unless it is a COMPONENT_REF in which case the layout of
8528 the structure gives the alignment. */
8529
8530static unsigned HOST_WIDE_INT
8531highest_pow2_factor_for_target (const_tree target, const_tree exp)
8532{
8533 unsigned HOST_WIDE_INT talign = target_align (target) / BITS_PER_UNIT;
8534 unsigned HOST_WIDE_INT factor = highest_pow2_factor (exp);
8535
8536 return MAX (factor, talign);
8537}
8538
8539/* Convert the tree comparison code TCODE to the rtl one where the
8540 signedness is UNSIGNEDP. */
8541
8542static enum rtx_code
8543convert_tree_comp_to_rtx (enum tree_code tcode, int unsignedp)
8544{
8545 enum rtx_code code;
8546 switch (tcode)
8547 {
8548 case EQ_EXPR:
8549 code = EQ;
8550 break;
8551 case NE_EXPR:
8552 code = NE;
8553 break;
8554 case LT_EXPR:
8555 code = unsignedp ? LTU : LT;
8556 break;
8557 case LE_EXPR:
8558 code = unsignedp ? LEU : LE;
8559 break;
8560 case GT_EXPR:
8561 code = unsignedp ? GTU : GT;
8562 break;
8563 case GE_EXPR:
8564 code = unsignedp ? GEU : GE;
8565 break;
8566 case UNORDERED_EXPR:
8567 code = UNORDERED;
8568 break;
8569 case ORDERED_EXPR:
8570 code = ORDERED;
8571 break;
8572 case UNLT_EXPR:
8573 code = UNLT;
8574 break;
8575 case UNLE_EXPR:
8576 code = UNLE;
8577 break;
8578 case UNGT_EXPR:
8579 code = UNGT;
8580 break;
8581 case UNGE_EXPR:
8582 code = UNGE;
8583 break;
8584 case UNEQ_EXPR:
8585 code = UNEQ;
8586 break;
8587 case LTGT_EXPR:
8588 code = LTGT;
8589 break;
8590
8591 default:
8592 gcc_unreachable ();
8593 }
8594 return code;
8595}
8596
8597/* Subroutine of expand_expr. Expand the two operands of a binary
8598 expression EXP0 and EXP1 placing the results in OP0 and OP1.
8599 The value may be stored in TARGET if TARGET is nonzero. The
8600 MODIFIER argument is as documented by expand_expr. */
8601
8602void
8603expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1,
8604 enum expand_modifier modifier)
8605{
8606 if (! safe_from_p (x: target, exp: exp1, top_p: 1))
8607 target = 0;
8608 if (operand_equal_p (exp0, exp1, flags: 0))
8609 {
8610 *op0 = expand_expr (exp: exp0, target, VOIDmode, modifier);
8611 *op1 = copy_rtx (*op0);
8612 }
8613 else
8614 {
8615 *op0 = expand_expr (exp: exp0, target, VOIDmode, modifier);
8616 *op1 = expand_expr (exp: exp1, NULL_RTX, VOIDmode, modifier);
8617 }
8618}
8619
8620
8621/* Return a MEM that contains constant EXP. DEFER is as for
8622 output_constant_def and MODIFIER is as for expand_expr. */
8623
8624static rtx
8625expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
8626{
8627 rtx mem;
8628
8629 mem = output_constant_def (exp, defer);
8630 if (modifier != EXPAND_INITIALIZER)
8631 mem = use_anchored_address (mem);
8632 return mem;
8633}
8634
8635/* A subroutine of expand_expr_addr_expr. Evaluate the address of EXP.
8636 The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
8637
8638static rtx
8639expand_expr_addr_expr_1 (tree exp, rtx target, scalar_int_mode tmode,
8640 enum expand_modifier modifier, addr_space_t as)
8641{
8642 rtx result, subtarget;
8643 tree inner, offset;
8644 poly_int64 bitsize, bitpos;
8645 int unsignedp, reversep, volatilep = 0;
8646 machine_mode mode1;
8647
8648 /* If we are taking the address of a constant and are at the top level,
8649 we have to use output_constant_def since we can't call force_const_mem
8650 at top level. */
8651 /* ??? This should be considered a front-end bug. We should not be
8652 generating ADDR_EXPR of something that isn't an LVALUE. The only
8653 exception here is STRING_CST. */
8654 if (CONSTANT_CLASS_P (exp))
8655 {
8656 result = XEXP (expand_expr_constant (exp, 0, modifier), 0);
8657 if (modifier < EXPAND_SUM)
8658 result = force_operand (value: result, target);
8659 return result;
8660 }
8661
8662 /* Everything must be something allowed by is_gimple_addressable. */
8663 switch (TREE_CODE (exp))
8664 {
8665 case INDIRECT_REF:
8666 /* This case will happen via recursion for &a->b. */
8667 return expand_expr (TREE_OPERAND (exp, 0), target, mode: tmode, modifier);
8668
8669 case MEM_REF:
8670 {
8671 tree tem = TREE_OPERAND (exp, 0);
8672 if (!integer_zerop (TREE_OPERAND (exp, 1)))
8673 tem = fold_build_pointer_plus (tem, TREE_OPERAND (exp, 1));
8674 return expand_expr (exp: tem, target, mode: tmode, modifier);
8675 }
8676
8677 case TARGET_MEM_REF:
8678 return addr_for_mem_ref (exp, as, really_expand: true);
8679
8680 case CONST_DECL:
8681 /* Expand the initializer like constants above. */
8682 result = XEXP (expand_expr_constant (DECL_INITIAL (exp),
8683 0, modifier), 0);
8684 if (modifier < EXPAND_SUM)
8685 result = force_operand (value: result, target);
8686 return result;
8687
8688 case REALPART_EXPR:
8689 /* The real part of the complex number is always first, therefore
8690 the address is the same as the address of the parent object. */
8691 offset = 0;
8692 bitpos = 0;
8693 inner = TREE_OPERAND (exp, 0);
8694 break;
8695
8696 case IMAGPART_EXPR:
8697 /* The imaginary part of the complex number is always second.
8698 The expression is therefore always offset by the size of the
8699 scalar type. */
8700 offset = 0;
8701 bitpos = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (exp)));
8702 inner = TREE_OPERAND (exp, 0);
8703 break;
8704
8705 case COMPOUND_LITERAL_EXPR:
8706 /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from
8707 initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL
8708 with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static
8709 array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL;
8710 the initializers aren't gimplified. */
8711 if (COMPOUND_LITERAL_EXPR_DECL (exp)
8712 && is_global_var (COMPOUND_LITERAL_EXPR_DECL (exp)))
8713 return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
8714 target, tmode, modifier, as);
8715 /* FALLTHRU */
8716 default:
8717 /* If the object is a DECL, then expand it for its rtl. Don't bypass
8718 expand_expr, as that can have various side effects; LABEL_DECLs for
8719 example, may not have their DECL_RTL set yet. Expand the rtl of
8720 CONSTRUCTORs too, which should yield a memory reference for the
8721 constructor's contents. Assume language specific tree nodes can
8722 be expanded in some interesting way. */
8723 gcc_assert (TREE_CODE (exp) < LAST_AND_UNUSED_TREE_CODE);
8724 if (DECL_P (exp)
8725 || TREE_CODE (exp) == CONSTRUCTOR
8726 || TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
8727 {
8728 result = expand_expr (exp, target, mode: tmode,
8729 modifier: modifier == EXPAND_INITIALIZER
8730 ? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
8731
8732 /* If the DECL isn't in memory, then the DECL wasn't properly
8733 marked TREE_ADDRESSABLE, which will be either a front-end
8734 or a tree optimizer bug. */
8735
8736 gcc_assert (MEM_P (result));
8737 result = XEXP (result, 0);
8738
8739 /* ??? Is this needed anymore? */
8740 if (DECL_P (exp))
8741 TREE_USED (exp) = 1;
8742
8743 if (modifier != EXPAND_INITIALIZER
8744 && modifier != EXPAND_CONST_ADDRESS
8745 && modifier != EXPAND_SUM)
8746 result = force_operand (value: result, target);
8747 return result;
8748 }
8749
8750 /* Pass FALSE as the last argument to get_inner_reference although
8751 we are expanding to RTL. The rationale is that we know how to
8752 handle "aligning nodes" here: we can just bypass them because
8753 they won't change the final object whose address will be returned
8754 (they actually exist only for that purpose). */
8755 inner = get_inner_reference (exp, pbitsize: &bitsize, pbitpos: &bitpos, poffset: &offset, pmode: &mode1,
8756 punsignedp: &unsignedp, preversep: &reversep, pvolatilep: &volatilep);
8757 break;
8758 }
8759
8760 /* We must have made progress. */
8761 gcc_assert (inner != exp);
8762
8763 subtarget = offset || maybe_ne (a: bitpos, b: 0) ? NULL_RTX : target;
8764 /* For VIEW_CONVERT_EXPR, where the outer alignment is bigger than
8765 inner alignment, force the inner to be sufficiently aligned. */
8766 if (CONSTANT_CLASS_P (inner)
8767 && TYPE_ALIGN (TREE_TYPE (inner)) < TYPE_ALIGN (TREE_TYPE (exp)))
8768 {
8769 inner = copy_node (inner);
8770 TREE_TYPE (inner) = copy_node (TREE_TYPE (inner));
8771 SET_TYPE_ALIGN (TREE_TYPE (inner), TYPE_ALIGN (TREE_TYPE (exp)));
8772 TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
8773 }
8774 result = expand_expr_addr_expr_1 (exp: inner, target: subtarget, tmode, modifier, as);
8775
8776 if (offset)
8777 {
8778 rtx tmp;
8779
8780 if (modifier != EXPAND_NORMAL)
8781 result = force_operand (value: result, NULL);
8782 tmp = expand_expr (exp: offset, NULL_RTX, mode: tmode,
8783 modifier: modifier == EXPAND_INITIALIZER
8784 ? EXPAND_INITIALIZER : EXPAND_NORMAL);
8785
8786 /* expand_expr is allowed to return an object in a mode other
8787 than TMODE. If it did, we need to convert. */
8788 if (GET_MODE (tmp) != VOIDmode && tmode != GET_MODE (tmp))
8789 tmp = convert_modes (mode: tmode, GET_MODE (tmp),
8790 x: tmp, TYPE_UNSIGNED (TREE_TYPE (offset)));
8791 result = convert_memory_address_addr_space (tmode, result, as);
8792 tmp = convert_memory_address_addr_space (tmode, tmp, as);
8793
8794 if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
8795 result = simplify_gen_binary (code: PLUS, mode: tmode, op0: result, op1: tmp);
8796 else
8797 {
8798 subtarget = maybe_ne (a: bitpos, b: 0) ? NULL_RTX : target;
8799 result = expand_simple_binop (tmode, PLUS, result, tmp, subtarget,
8800 1, OPTAB_LIB_WIDEN);
8801 }
8802 }
8803
8804 if (maybe_ne (a: bitpos, b: 0))
8805 {
8806 /* Someone beforehand should have rejected taking the address
8807 of an object that isn't byte-aligned. */
8808 poly_int64 bytepos = exact_div (a: bitpos, BITS_PER_UNIT);
8809 result = convert_memory_address_addr_space (tmode, result, as);
8810 result = plus_constant (tmode, result, bytepos);
8811 if (modifier < EXPAND_SUM)
8812 result = force_operand (value: result, target);
8813 }
8814
8815 return result;
8816}
8817
8818/* A subroutine of expand_expr. Evaluate EXP, which is an ADDR_EXPR.
8819 The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
8820
8821static rtx
8822expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
8823 enum expand_modifier modifier)
8824{
8825 addr_space_t as = ADDR_SPACE_GENERIC;
8826 scalar_int_mode address_mode = Pmode;
8827 scalar_int_mode pointer_mode = ptr_mode;
8828 machine_mode rmode;
8829 rtx result;
8830
8831 /* Target mode of VOIDmode says "whatever's natural". */
8832 if (tmode == VOIDmode)
8833 tmode = TYPE_MODE (TREE_TYPE (exp));
8834
8835 if (POINTER_TYPE_P (TREE_TYPE (exp)))
8836 {
8837 as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (exp)));
8838 address_mode = targetm.addr_space.address_mode (as);
8839 pointer_mode = targetm.addr_space.pointer_mode (as);
8840 }
8841
8842 /* We can get called with some Weird Things if the user does silliness
8843 like "(short) &a". In that case, convert_memory_address won't do
8844 the right thing, so ignore the given target mode. */
8845 scalar_int_mode new_tmode = (tmode == pointer_mode
8846 ? pointer_mode
8847 : address_mode);
8848
8849 result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
8850 tmode: new_tmode, modifier, as);
8851
8852 /* Despite expand_expr claims concerning ignoring TMODE when not
8853 strictly convenient, stuff breaks if we don't honor it. Note
8854 that combined with the above, we only do this for pointer modes. */
8855 rmode = GET_MODE (result);
8856 if (rmode == VOIDmode)
8857 rmode = new_tmode;
8858 if (rmode != new_tmode)
8859 result = convert_memory_address_addr_space (new_tmode, result, as);
8860
8861 return result;
8862}
8863
8864/* Generate code for computing CONSTRUCTOR EXP.
8865 An rtx for the computed value is returned. If AVOID_TEMP_MEM
8866 is TRUE, instead of creating a temporary variable in memory
8867 NULL is returned and the caller needs to handle it differently. */
8868
8869static rtx
8870expand_constructor (tree exp, rtx target, enum expand_modifier modifier,
8871 bool avoid_temp_mem)
8872{
8873 tree type = TREE_TYPE (exp);
8874 machine_mode mode = TYPE_MODE (type);
8875
8876 /* Try to avoid creating a temporary at all. This is possible
8877 if all of the initializer is zero.
8878 FIXME: try to handle all [0..255] initializers we can handle
8879 with memset. */
8880 if (TREE_STATIC (exp)
8881 && !TREE_ADDRESSABLE (exp)
8882 && target != 0 && mode == BLKmode
8883 && all_zeros_p (exp))
8884 {
8885 clear_storage (object: target, size: expr_size (exp), method: BLOCK_OP_NORMAL);
8886 return target;
8887 }
8888
8889 /* All elts simple constants => refer to a constant in memory. But
8890 if this is a non-BLKmode mode, let it store a field at a time
8891 since that should make a CONST_INT, CONST_WIDE_INT or
8892 CONST_DOUBLE when we fold. Likewise, if we have a target we can
8893 use, it is best to store directly into the target unless the type
8894 is large enough that memcpy will be used. If we are making an
8895 initializer and all operands are constant, put it in memory as
8896 well.
8897
8898 FIXME: Avoid trying to fill vector constructors piece-meal.
8899 Output them with output_constant_def below unless we're sure
8900 they're zeros. This should go away when vector initializers
8901 are treated like VECTOR_CST instead of arrays. */
8902 if ((TREE_STATIC (exp)
8903 && ((mode == BLKmode
8904 && ! (target != 0 && safe_from_p (x: target, exp, top_p: 1)))
8905 || TREE_ADDRESSABLE (exp)
8906 || (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
8907 && (! can_move_by_pieces
8908 (len: tree_to_uhwi (TYPE_SIZE_UNIT (type)),
8909 TYPE_ALIGN (type)))
8910 && ! mostly_zeros_p (exp))))
8911 || ((modifier == EXPAND_INITIALIZER || modifier == EXPAND_CONST_ADDRESS)
8912 && TREE_CONSTANT (exp)))
8913 {
8914 rtx constructor;
8915
8916 if (avoid_temp_mem)
8917 return NULL_RTX;
8918
8919 constructor = expand_expr_constant (exp, defer: 1, modifier);
8920
8921 if (modifier != EXPAND_CONST_ADDRESS
8922 && modifier != EXPAND_INITIALIZER
8923 && modifier != EXPAND_SUM)
8924 constructor = validize_mem (constructor);
8925
8926 return constructor;
8927 }
8928
8929 /* If the CTOR is available in static storage and not mostly
8930 zeros and we can move it by pieces prefer to do so since
8931 that's usually more efficient than performing a series of
8932 stores from immediates. */
8933 if (avoid_temp_mem
8934 && TREE_STATIC (exp)
8935 && TREE_CONSTANT (exp)
8936 && tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))
8937 && can_move_by_pieces (len: tree_to_uhwi (TYPE_SIZE_UNIT (type)),
8938 TYPE_ALIGN (type))
8939 && ! mostly_zeros_p (exp))
8940 return NULL_RTX;
8941
8942 /* Handle calls that pass values in multiple non-contiguous
8943 locations. The Irix 6 ABI has examples of this. */
8944 if (target == 0 || ! safe_from_p (x: target, exp, top_p: 1)
8945 || GET_CODE (target) == PARALLEL || modifier == EXPAND_STACK_PARM
8946 /* Also make a temporary if the store is to volatile memory, to
8947 avoid individual accesses to aggregate members. */
8948 || (GET_CODE (target) == MEM
8949 && MEM_VOLATILE_P (target)
8950 && !TREE_ADDRESSABLE (TREE_TYPE (exp))))
8951 {
8952 if (avoid_temp_mem)
8953 return NULL_RTX;
8954
8955 target = assign_temp (type, TREE_ADDRESSABLE (exp), 1);
8956 }
8957
8958 store_constructor (exp, target, cleared: 0, size: int_expr_size (exp), reverse: false);
8959 return target;
8960}
8961
8962
8963/* expand_expr: generate code for computing expression EXP.
8964 An rtx for the computed value is returned. The value is never null.
8965 In the case of a void EXP, const0_rtx is returned.
8966
8967 The value may be stored in TARGET if TARGET is nonzero.
8968 TARGET is just a suggestion; callers must assume that
8969 the rtx returned may not be the same as TARGET.
8970
8971 If TARGET is CONST0_RTX, it means that the value will be ignored.
8972
8973 If TMODE is not VOIDmode, it suggests generating the
8974 result in mode TMODE. But this is done only when convenient.
8975 Otherwise, TMODE is ignored and the value generated in its natural mode.
8976 TMODE is just a suggestion; callers must assume that
8977 the rtx returned may not have mode TMODE.
8978
8979 Note that TARGET may have neither TMODE nor MODE. In that case, it
8980 probably will not be used.
8981
8982 If MODIFIER is EXPAND_SUM then when EXP is an addition
8983 we can return an rtx of the form (MULT (REG ...) (CONST_INT ...))
8984 or a nest of (PLUS ...) and (MINUS ...) where the terms are
8985 products as above, or REG or MEM, or constant.
8986 Ordinarily in such cases we would output mul or add instructions
8987 and then return a pseudo reg containing the sum.
8988
8989 EXPAND_INITIALIZER is much like EXPAND_SUM except that
8990 it also marks a label as absolutely required (it can't be dead).
8991 It also makes a ZERO_EXTEND or SIGN_EXTEND instead of emitting extend insns.
8992 This is used for outputting expressions used in initializers.
8993
8994 EXPAND_CONST_ADDRESS says that it is okay to return a MEM
8995 with a constant address even if that address is not normally legitimate.
8996 EXPAND_INITIALIZER and EXPAND_SUM also have this effect.
8997
8998 EXPAND_STACK_PARM is used when expanding to a TARGET on the stack for
8999 a call parameter. Such targets require special care as we haven't yet
9000 marked TARGET so that it's safe from being trashed by libcalls. We
9001 don't want to use TARGET for anything but the final result;
9002 Intermediate values must go elsewhere. Additionally, calls to
9003 emit_block_move will be flagged with BLOCK_OP_CALL_PARM.
9004
9005 If EXP is a VAR_DECL whose DECL_RTL was a MEM with an invalid
9006 address, and ALT_RTL is non-NULL, then *ALT_RTL is set to the
9007 DECL_RTL of the VAR_DECL. *ALT_RTL is also set if EXP is a
9008 COMPOUND_EXPR whose second argument is such a VAR_DECL, and so on
9009 recursively.
9010 If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9011 then *ALT_RTL is set to TARGET (before legitimziation).
9012
9013 If INNER_REFERENCE_P is true, we are expanding an inner reference.
9014 In this case, we don't adjust a returned MEM rtx that wouldn't be
9015 sufficiently aligned for its mode; instead, it's up to the caller
9016 to deal with it afterwards. This is used to make sure that unaligned
9017 base objects for which out-of-bounds accesses are supported, for
9018 example record types with trailing arrays, aren't realigned behind
9019 the back of the caller.
9020 The normal operating mode is to pass FALSE for this parameter. */
9021
9022rtx
9023expand_expr_real (tree exp, rtx target, machine_mode tmode,
9024 enum expand_modifier modifier, rtx *alt_rtl,
9025 bool inner_reference_p)
9026{
9027 rtx ret;
9028
9029 /* Handle ERROR_MARK before anybody tries to access its type. */
9030 if (TREE_CODE (exp) == ERROR_MARK
9031 || (TREE_CODE (TREE_TYPE (exp)) == ERROR_MARK))
9032 {
9033 ret = CONST0_RTX (tmode);
9034 return ret ? ret : const0_rtx;
9035 }
9036
9037 ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl,
9038 inner_reference_p);
9039 return ret;
9040}
9041
9042/* Try to expand the conditional expression which is represented by
9043 TREEOP0 ? TREEOP1 : TREEOP2 using conditonal moves. If it succeeds
9044 return the rtl reg which represents the result. Otherwise return
9045 NULL_RTX. */
9046
9047static rtx
9048expand_cond_expr_using_cmove (tree treeop0 ATTRIBUTE_UNUSED,
9049 tree treeop1 ATTRIBUTE_UNUSED,
9050 tree treeop2 ATTRIBUTE_UNUSED)
9051{
9052 rtx insn;
9053 rtx op00, op01, op1, op2;
9054 enum rtx_code comparison_code;
9055 machine_mode comparison_mode;
9056 gimple *srcstmt;
9057 rtx temp;
9058 tree type = TREE_TYPE (treeop1);
9059 int unsignedp = TYPE_UNSIGNED (type);
9060 machine_mode mode = TYPE_MODE (type);
9061 machine_mode orig_mode = mode;
9062 static bool expanding_cond_expr_using_cmove = false;
9063
9064 /* Conditional move expansion can end up TERing two operands which,
9065 when recursively hitting conditional expressions can result in
9066 exponential behavior if the cmove expansion ultimatively fails.
9067 It's hardly profitable to TER a cmove into a cmove so avoid doing
9068 that by failing early if we end up recursing. */
9069 if (expanding_cond_expr_using_cmove)
9070 return NULL_RTX;
9071
9072 /* If we cannot do a conditional move on the mode, try doing it
9073 with the promoted mode. */
9074 if (!can_conditionally_move_p (mode))
9075 {
9076 mode = promote_mode (type, mode, &unsignedp);
9077 if (!can_conditionally_move_p (mode))
9078 return NULL_RTX;
9079 temp = assign_temp (type, 0, 0); /* Use promoted mode for temp. */
9080 }
9081 else
9082 temp = assign_temp (type, 0, 1);
9083
9084 expanding_cond_expr_using_cmove = true;
9085 start_sequence ();
9086 expand_operands (exp0: treeop1, exp1: treeop2,
9087 target: mode == orig_mode ? temp : NULL_RTX, op0: &op1, op1: &op2,
9088 modifier: EXPAND_NORMAL);
9089
9090 if (TREE_CODE (treeop0) == SSA_NAME
9091 && (srcstmt = get_def_for_expr_class (name: treeop0, tclass: tcc_comparison)))
9092 {
9093 type = TREE_TYPE (gimple_assign_rhs1 (srcstmt));
9094 enum tree_code cmpcode = gimple_assign_rhs_code (gs: srcstmt);
9095 op00 = expand_normal (exp: gimple_assign_rhs1 (gs: srcstmt));
9096 op01 = expand_normal (exp: gimple_assign_rhs2 (gs: srcstmt));
9097 comparison_mode = TYPE_MODE (type);
9098 unsignedp = TYPE_UNSIGNED (type);
9099 comparison_code = convert_tree_comp_to_rtx (tcode: cmpcode, unsignedp);
9100 }
9101 else if (COMPARISON_CLASS_P (treeop0))
9102 {
9103 type = TREE_TYPE (TREE_OPERAND (treeop0, 0));
9104 enum tree_code cmpcode = TREE_CODE (treeop0);
9105 op00 = expand_normal (TREE_OPERAND (treeop0, 0));
9106 op01 = expand_normal (TREE_OPERAND (treeop0, 1));
9107 unsignedp = TYPE_UNSIGNED (type);
9108 comparison_mode = TYPE_MODE (type);
9109 comparison_code = convert_tree_comp_to_rtx (tcode: cmpcode, unsignedp);
9110 }
9111 else
9112 {
9113 op00 = expand_normal (exp: treeop0);
9114 op01 = const0_rtx;
9115 comparison_code = NE;
9116 comparison_mode = GET_MODE (op00);
9117 if (comparison_mode == VOIDmode)
9118 comparison_mode = TYPE_MODE (TREE_TYPE (treeop0));
9119 }
9120 expanding_cond_expr_using_cmove = false;
9121
9122 if (GET_MODE (op1) != mode)
9123 op1 = gen_lowpart (mode, op1);
9124
9125 if (GET_MODE (op2) != mode)
9126 op2 = gen_lowpart (mode, op2);
9127
9128 /* Try to emit the conditional move. */
9129 insn = emit_conditional_move (temp,
9130 { .code: comparison_code, .op0: op00, .op1: op01,
9131 .mode: comparison_mode },
9132 op1, op2, mode,
9133 unsignedp);
9134
9135 /* If we could do the conditional move, emit the sequence,
9136 and return. */
9137 if (insn)
9138 {
9139 rtx_insn *seq = get_insns ();
9140 end_sequence ();
9141 emit_insn (seq);
9142 return convert_modes (mode: orig_mode, oldmode: mode, x: temp, unsignedp: 0);
9143 }
9144
9145 /* Otherwise discard the sequence and fall back to code with
9146 branches. */
9147 end_sequence ();
9148 return NULL_RTX;
9149}
9150
9151/* A helper function for expand_expr_real_2 to be used with a
9152 misaligned mem_ref TEMP. Assume an unsigned type if UNSIGNEDP
9153 is nonzero, with alignment ALIGN in bits.
9154 Store the value at TARGET if possible (if TARGET is nonzero).
9155 Regardless of TARGET, we return the rtx for where the value is placed.
9156 If the result can be stored at TARGET, and ALT_RTL is non-NULL,
9157 then *ALT_RTL is set to TARGET (before legitimziation). */
9158
9159static rtx
9160expand_misaligned_mem_ref (rtx temp, machine_mode mode, int unsignedp,
9161 unsigned int align, rtx target, rtx *alt_rtl)
9162{
9163 enum insn_code icode;
9164
9165 if ((icode = optab_handler (op: movmisalign_optab, mode))
9166 != CODE_FOR_nothing)
9167 {
9168 class expand_operand ops[2];
9169
9170 /* We've already validated the memory, and we're creating a
9171 new pseudo destination. The predicates really can't fail,
9172 nor can the generator. */
9173 create_output_operand (op: &ops[0], NULL_RTX, mode);
9174 create_fixed_operand (op: &ops[1], x: temp);
9175 expand_insn (icode, nops: 2, ops);
9176 temp = ops[0].value;
9177 }
9178 else if (targetm.slow_unaligned_access (mode, align))
9179 temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode),
9180 0, unsignedp, target,
9181 mode, mode, false, alt_rtl);
9182 return temp;
9183}
9184
9185/* Helper function of expand_expr_2, expand a division or modulo.
9186 op0 and op1 should be already expanded treeop0 and treeop1, using
9187 expand_operands. */
9188
9189static rtx
9190expand_expr_divmod (tree_code code, machine_mode mode, tree treeop0,
9191 tree treeop1, rtx op0, rtx op1, rtx target, int unsignedp)
9192{
9193 bool mod_p = (code == TRUNC_MOD_EXPR || code == FLOOR_MOD_EXPR
9194 || code == CEIL_MOD_EXPR || code == ROUND_MOD_EXPR);
9195 if (SCALAR_INT_MODE_P (mode)
9196 && optimize >= 2
9197 && get_range_pos_neg (treeop0) == 1
9198 && get_range_pos_neg (treeop1) == 1)
9199 {
9200 /* If both arguments are known to be positive when interpreted
9201 as signed, we can expand it as both signed and unsigned
9202 division or modulo. Choose the cheaper sequence in that case. */
9203 bool speed_p = optimize_insn_for_speed_p ();
9204 do_pending_stack_adjust ();
9205 start_sequence ();
9206 rtx uns_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 1);
9207 rtx_insn *uns_insns = get_insns ();
9208 end_sequence ();
9209 start_sequence ();
9210 rtx sgn_ret = expand_divmod (mod_p, code, mode, op0, op1, target, 0);
9211 rtx_insn *sgn_insns = get_insns ();
9212 end_sequence ();
9213 unsigned uns_cost = seq_cost (uns_insns, speed_p);
9214 unsigned sgn_cost = seq_cost (sgn_insns, speed_p);
9215
9216 /* If costs are the same then use as tie breaker the other other
9217 factor. */
9218 if (uns_cost == sgn_cost)
9219 {
9220 uns_cost = seq_cost (uns_insns, !speed_p);
9221 sgn_cost = seq_cost (sgn_insns, !speed_p);
9222 }
9223
9224 if (uns_cost < sgn_cost || (uns_cost == sgn_cost && unsignedp))
9225 {
9226 emit_insn (uns_insns);
9227 return uns_ret;
9228 }
9229 emit_insn (sgn_insns);
9230 return sgn_ret;
9231 }
9232 return expand_divmod (mod_p, code, mode, op0, op1, target, unsignedp);
9233}
9234
9235rtx
9236expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
9237 enum expand_modifier modifier)
9238{
9239 rtx op0, op1, op2, temp;
9240 rtx_code_label *lab;
9241 tree type;
9242 int unsignedp;
9243 machine_mode mode;
9244 scalar_int_mode int_mode;
9245 enum tree_code code = ops->code;
9246 optab this_optab;
9247 rtx subtarget, original_target;
9248 int ignore;
9249 bool reduce_bit_field;
9250 location_t loc = ops->location;
9251 tree treeop0, treeop1, treeop2;
9252#define REDUCE_BIT_FIELD(expr) (reduce_bit_field \
9253 ? reduce_to_bit_field_precision ((expr), \
9254 target, \
9255 type) \
9256 : (expr))
9257
9258 type = ops->type;
9259 mode = TYPE_MODE (type);
9260 unsignedp = TYPE_UNSIGNED (type);
9261
9262 treeop0 = ops->op0;
9263 treeop1 = ops->op1;
9264 treeop2 = ops->op2;
9265
9266 /* We should be called only on simple (binary or unary) expressions,
9267 exactly those that are valid in gimple expressions that aren't
9268 GIMPLE_SINGLE_RHS (or invalid). */
9269 gcc_assert (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS
9270 || get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS
9271 || get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS);
9272
9273 ignore = (target == const0_rtx
9274 || ((CONVERT_EXPR_CODE_P (code)
9275 || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
9276 && TREE_CODE (type) == VOID_TYPE));
9277
9278 /* We should be called only if we need the result. */
9279 gcc_assert (!ignore);
9280
9281 /* An operation in what may be a bit-field type needs the
9282 result to be reduced to the precision of the bit-field type,
9283 which is narrower than that of the type's mode. */
9284 reduce_bit_field = (INTEGRAL_TYPE_P (type)
9285 && !type_has_mode_precision_p (t: type));
9286
9287 if (reduce_bit_field
9288 && (modifier == EXPAND_STACK_PARM
9289 || (target && GET_MODE (target) != mode)))
9290 target = 0;
9291
9292 /* Use subtarget as the target for operand 0 of a binary operation. */
9293 subtarget = get_subtarget (x: target);
9294 original_target = target;
9295
9296 switch (code)
9297 {
9298 case NON_LVALUE_EXPR:
9299 case PAREN_EXPR:
9300 CASE_CONVERT:
9301 if (treeop0 == error_mark_node)
9302 return const0_rtx;
9303
9304 if (TREE_CODE (type) == UNION_TYPE)
9305 {
9306 tree valtype = TREE_TYPE (treeop0);
9307
9308 /* If both input and output are BLKmode, this conversion isn't doing
9309 anything except possibly changing memory attribute. */
9310 if (mode == BLKmode && TYPE_MODE (valtype) == BLKmode)
9311 {
9312 rtx result = expand_expr (exp: treeop0, target, mode: tmode,
9313 modifier);
9314
9315 result = copy_rtx (result);
9316 set_mem_attributes (result, type, 0);
9317 return result;
9318 }
9319
9320 if (target == 0)
9321 {
9322 if (TYPE_MODE (type) != BLKmode)
9323 target = gen_reg_rtx (TYPE_MODE (type));
9324 else
9325 target = assign_temp (type, 1, 1);
9326 }
9327
9328 if (MEM_P (target))
9329 /* Store data into beginning of memory target. */
9330 store_expr (exp: treeop0,
9331 adjust_address (target, TYPE_MODE (valtype), 0),
9332 call_param_p: modifier == EXPAND_STACK_PARM,
9333 nontemporal: false, TYPE_REVERSE_STORAGE_ORDER (type));
9334
9335 else
9336 {
9337 gcc_assert (REG_P (target)
9338 && !TYPE_REVERSE_STORAGE_ORDER (type));
9339
9340 /* Store this field into a union of the proper type. */
9341 poly_uint64 op0_size
9342 = tree_to_poly_uint64 (TYPE_SIZE (TREE_TYPE (treeop0)));
9343 poly_uint64 union_size = GET_MODE_BITSIZE (mode);
9344 store_field (target,
9345 /* The conversion must be constructed so that
9346 we know at compile time how many bits
9347 to preserve. */
9348 bitsize: ordered_min (a: op0_size, b: union_size),
9349 bitpos: 0, bitregion_start: 0, bitregion_end: 0, TYPE_MODE (valtype), exp: treeop0, alias_set: 0,
9350 nontemporal: false, reverse: false);
9351 }
9352
9353 /* Return the entire union. */
9354 return target;
9355 }
9356
9357 if (mode == TYPE_MODE (TREE_TYPE (treeop0)))
9358 {
9359 op0 = expand_expr (exp: treeop0, target, VOIDmode,
9360 modifier);
9361
9362 return REDUCE_BIT_FIELD (op0);
9363 }
9364
9365 op0 = expand_expr (exp: treeop0, NULL_RTX, mode,
9366 modifier: modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier);
9367 if (GET_MODE (op0) == mode)
9368 ;
9369
9370 /* If OP0 is a constant, just convert it into the proper mode. */
9371 else if (CONSTANT_P (op0))
9372 {
9373 tree inner_type = TREE_TYPE (treeop0);
9374 machine_mode inner_mode = GET_MODE (op0);
9375
9376 if (inner_mode == VOIDmode)
9377 inner_mode = TYPE_MODE (inner_type);
9378
9379 if (modifier == EXPAND_INITIALIZER)
9380 op0 = lowpart_subreg (outermode: mode, op: op0, innermode: inner_mode);
9381 else
9382 op0= convert_modes (mode, oldmode: inner_mode, x: op0,
9383 TYPE_UNSIGNED (inner_type));
9384 }
9385
9386 else if (modifier == EXPAND_INITIALIZER)
9387 op0 = gen_rtx_fmt_e (TYPE_UNSIGNED (TREE_TYPE (treeop0))
9388 ? ZERO_EXTEND : SIGN_EXTEND, mode, op0);
9389
9390 else if (target == 0)
9391 op0 = convert_to_mode (mode, x: op0,
9392 TYPE_UNSIGNED (TREE_TYPE
9393 (treeop0)));
9394 else
9395 {
9396 convert_move (to: target, from: op0,
9397 TYPE_UNSIGNED (TREE_TYPE (treeop0)));
9398 op0 = target;
9399 }
9400
9401 return REDUCE_BIT_FIELD (op0);
9402
9403 case ADDR_SPACE_CONVERT_EXPR:
9404 {
9405 tree treeop0_type = TREE_TYPE (treeop0);
9406
9407 gcc_assert (POINTER_TYPE_P (type));
9408 gcc_assert (POINTER_TYPE_P (treeop0_type));
9409
9410 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type));
9411 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (treeop0_type));
9412
9413 /* Conversions between pointers to the same address space should
9414 have been implemented via CONVERT_EXPR / NOP_EXPR. */
9415 gcc_assert (as_to != as_from);
9416
9417 op0 = expand_expr (exp: treeop0, NULL_RTX, VOIDmode, modifier);
9418
9419 /* Ask target code to handle conversion between pointers
9420 to overlapping address spaces. */
9421 if (targetm.addr_space.subset_p (as_to, as_from)
9422 || targetm.addr_space.subset_p (as_from, as_to))
9423 {
9424 op0 = targetm.addr_space.convert (op0, treeop0_type, type);
9425 }
9426 else
9427 {
9428 /* For disjoint address spaces, converting anything but a null
9429 pointer invokes undefined behavior. We truncate or extend the
9430 value as if we'd converted via integers, which handles 0 as
9431 required, and all others as the programmer likely expects. */
9432#ifndef POINTERS_EXTEND_UNSIGNED
9433 const int POINTERS_EXTEND_UNSIGNED = 1;
9434#endif
9435 op0 = convert_modes (mode, TYPE_MODE (treeop0_type),
9436 x: op0, POINTERS_EXTEND_UNSIGNED);
9437 }
9438 gcc_assert (op0);
9439 return op0;
9440 }
9441
9442 case POINTER_PLUS_EXPR:
9443 /* Even though the sizetype mode and the pointer's mode can be different
9444 expand is able to handle this correctly and get the correct result out
9445 of the PLUS_EXPR code. */
9446 /* Make sure to sign-extend the sizetype offset in a POINTER_PLUS_EXPR
9447 if sizetype precision is smaller than pointer precision. */
9448 if (TYPE_PRECISION (sizetype) < TYPE_PRECISION (type))
9449 treeop1 = fold_convert_loc (loc, type,
9450 fold_convert_loc (loc, ssizetype,
9451 treeop1));
9452 /* If sizetype precision is larger than pointer precision, truncate the
9453 offset to have matching modes. */
9454 else if (TYPE_PRECISION (sizetype) > TYPE_PRECISION (type))
9455 treeop1 = fold_convert_loc (loc, type, treeop1);
9456 /* FALLTHRU */
9457
9458 case PLUS_EXPR:
9459 /* If we are adding a constant, a VAR_DECL that is sp, fp, or ap, and
9460 something else, make sure we add the register to the constant and
9461 then to the other thing. This case can occur during strength
9462 reduction and doing it this way will produce better code if the
9463 frame pointer or argument pointer is eliminated.
9464
9465 fold-const.cc will ensure that the constant is always in the inner
9466 PLUS_EXPR, so the only case we need to do anything about is if
9467 sp, ap, or fp is our second argument, in which case we must swap
9468 the innermost first argument and our second argument. */
9469
9470 if (TREE_CODE (treeop0) == PLUS_EXPR
9471 && TREE_CODE (TREE_OPERAND (treeop0, 1)) == INTEGER_CST
9472 && VAR_P (treeop1)
9473 && (DECL_RTL (treeop1) == frame_pointer_rtx
9474 || DECL_RTL (treeop1) == stack_pointer_rtx
9475 || DECL_RTL (treeop1) == arg_pointer_rtx))
9476 {
9477 gcc_unreachable ();
9478 }
9479
9480 /* If the result is to be ptr_mode and we are adding an integer to
9481 something, we might be forming a constant. So try to use
9482 plus_constant. If it produces a sum and we can't accept it,
9483 use force_operand. This allows P = &ARR[const] to generate
9484 efficient code on machines where a SYMBOL_REF is not a valid
9485 address.
9486
9487 If this is an EXPAND_SUM call, always return the sum. */
9488 if (modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER
9489 || (mode == ptr_mode && (unsignedp || ! flag_trapv)))
9490 {
9491 if (modifier == EXPAND_STACK_PARM)
9492 target = 0;
9493 if (TREE_CODE (treeop0) == INTEGER_CST
9494 && HWI_COMPUTABLE_MODE_P (mode)
9495 && TREE_CONSTANT (treeop1))
9496 {
9497 rtx constant_part;
9498 HOST_WIDE_INT wc;
9499 machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop1));
9500
9501 op1 = expand_expr (exp: treeop1, target: subtarget, VOIDmode,
9502 modifier: EXPAND_SUM);
9503 /* Use wi::shwi to ensure that the constant is
9504 truncated according to the mode of OP1, then sign extended
9505 to a HOST_WIDE_INT. Using the constant directly can result
9506 in non-canonical RTL in a 64x32 cross compile. */
9507 wc = TREE_INT_CST_LOW (treeop0);
9508 constant_part =
9509 immed_wide_int_const (wi::shwi (val: wc, mode: wmode), wmode);
9510 op1 = plus_constant (mode, op1, INTVAL (constant_part));
9511 if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
9512 op1 = force_operand (value: op1, target);
9513 return REDUCE_BIT_FIELD (op1);
9514 }
9515
9516 else if (TREE_CODE (treeop1) == INTEGER_CST
9517 && HWI_COMPUTABLE_MODE_P (mode)
9518 && TREE_CONSTANT (treeop0))
9519 {
9520 rtx constant_part;
9521 HOST_WIDE_INT wc;
9522 machine_mode wmode = TYPE_MODE (TREE_TYPE (treeop0));
9523
9524 op0 = expand_expr (exp: treeop0, target: subtarget, VOIDmode,
9525 modifier: (modifier == EXPAND_INITIALIZER
9526 ? EXPAND_INITIALIZER : EXPAND_SUM));
9527 if (! CONSTANT_P (op0))
9528 {
9529 op1 = expand_expr (exp: treeop1, NULL_RTX,
9530 VOIDmode, modifier);
9531 /* Return a PLUS if modifier says it's OK. */
9532 if (modifier == EXPAND_SUM
9533 || modifier == EXPAND_INITIALIZER)
9534 return simplify_gen_binary (code: PLUS, mode, op0, op1);
9535 goto binop2;
9536 }
9537 /* Use wi::shwi to ensure that the constant is
9538 truncated according to the mode of OP1, then sign extended
9539 to a HOST_WIDE_INT. Using the constant directly can result
9540 in non-canonical RTL in a 64x32 cross compile. */
9541 wc = TREE_INT_CST_LOW (treeop1);
9542 constant_part
9543 = immed_wide_int_const (wi::shwi (val: wc, mode: wmode), wmode);
9544 op0 = plus_constant (mode, op0, INTVAL (constant_part));
9545 if (modifier != EXPAND_SUM && modifier != EXPAND_INITIALIZER)
9546 op0 = force_operand (value: op0, target);
9547 return REDUCE_BIT_FIELD (op0);
9548 }
9549 }
9550
9551 /* Use TER to expand pointer addition of a negated value
9552 as pointer subtraction. */
9553 if ((POINTER_TYPE_P (TREE_TYPE (treeop0))
9554 || (TREE_CODE (TREE_TYPE (treeop0)) == VECTOR_TYPE
9555 && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))))
9556 && TREE_CODE (treeop1) == SSA_NAME
9557 && TYPE_MODE (TREE_TYPE (treeop0))
9558 == TYPE_MODE (TREE_TYPE (treeop1)))
9559 {
9560 gimple *def = get_def_for_expr (name: treeop1, code: NEGATE_EXPR);
9561 if (def)
9562 {
9563 treeop1 = gimple_assign_rhs1 (gs: def);
9564 code = MINUS_EXPR;
9565 goto do_minus;
9566 }
9567 }
9568
9569 /* No sense saving up arithmetic to be done
9570 if it's all in the wrong mode to form part of an address.
9571 And force_operand won't know whether to sign-extend or
9572 zero-extend. */
9573 if (modifier != EXPAND_INITIALIZER
9574 && (modifier != EXPAND_SUM || mode != ptr_mode))
9575 {
9576 expand_operands (exp0: treeop0, exp1: treeop1,
9577 target: subtarget, op0: &op0, op1: &op1, modifier);
9578 if (op0 == const0_rtx)
9579 return op1;
9580 if (op1 == const0_rtx)
9581 return op0;
9582 goto binop2;
9583 }
9584
9585 expand_operands (exp0: treeop0, exp1: treeop1,
9586 target: subtarget, op0: &op0, op1: &op1, modifier);
9587 return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
9588
9589 case MINUS_EXPR:
9590 case POINTER_DIFF_EXPR:
9591 do_minus:
9592 /* For initializers, we are allowed to return a MINUS of two
9593 symbolic constants. Here we handle all cases when both operands
9594 are constant. */
9595 /* Handle difference of two symbolic constants,
9596 for the sake of an initializer. */
9597 if ((modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
9598 && really_constant_p (treeop0)
9599 && really_constant_p (treeop1))
9600 {
9601 expand_operands (exp0: treeop0, exp1: treeop1,
9602 NULL_RTX, op0: &op0, op1: &op1, modifier);
9603 return simplify_gen_binary (code: MINUS, mode, op0, op1);
9604 }
9605
9606 /* No sense saving up arithmetic to be done
9607 if it's all in the wrong mode to form part of an address.
9608 And force_operand won't know whether to sign-extend or
9609 zero-extend. */
9610 if (modifier != EXPAND_INITIALIZER
9611 && (modifier != EXPAND_SUM || mode != ptr_mode))
9612 goto binop;
9613
9614 expand_operands (exp0: treeop0, exp1: treeop1,
9615 target: subtarget, op0: &op0, op1: &op1, modifier);
9616
9617 /* Convert A - const to A + (-const). */
9618 if (CONST_INT_P (op1))
9619 {
9620 op1 = negate_rtx (mode, op1);
9621 return REDUCE_BIT_FIELD (simplify_gen_binary (PLUS, mode, op0, op1));
9622 }
9623
9624 goto binop2;
9625
9626 case WIDEN_MULT_PLUS_EXPR:
9627 case WIDEN_MULT_MINUS_EXPR:
9628 expand_operands (exp0: treeop0, exp1: treeop1, NULL_RTX, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
9629 op2 = expand_normal (exp: treeop2);
9630 target = expand_widen_pattern_expr (ops, op0, op1, op2,
9631 target, unsignedp);
9632 return target;
9633
9634 case WIDEN_MULT_EXPR:
9635 /* If first operand is constant, swap them.
9636 Thus the following special case checks need only
9637 check the second operand. */
9638 if (TREE_CODE (treeop0) == INTEGER_CST)
9639 std::swap (a&: treeop0, b&: treeop1);
9640
9641 /* First, check if we have a multiplication of one signed and one
9642 unsigned operand. */
9643 if (TREE_CODE (treeop1) != INTEGER_CST
9644 && (TYPE_UNSIGNED (TREE_TYPE (treeop0))
9645 != TYPE_UNSIGNED (TREE_TYPE (treeop1))))
9646 {
9647 machine_mode innermode = TYPE_MODE (TREE_TYPE (treeop0));
9648 this_optab = usmul_widen_optab;
9649 if (find_widening_optab_handler (this_optab, mode, innermode)
9650 != CODE_FOR_nothing)
9651 {
9652 if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
9653 expand_operands (exp0: treeop0, exp1: treeop1, NULL_RTX, op0: &op0, op1: &op1,
9654 modifier: EXPAND_NORMAL);
9655 else
9656 expand_operands (exp0: treeop0, exp1: treeop1, NULL_RTX, op0: &op1, op1: &op0,
9657 modifier: EXPAND_NORMAL);
9658 /* op0 and op1 might still be constant, despite the above
9659 != INTEGER_CST check. Handle it. */
9660 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
9661 {
9662 op0 = convert_modes (mode, oldmode: innermode, x: op0, unsignedp: true);
9663 op1 = convert_modes (mode, oldmode: innermode, x: op1, unsignedp: false);
9664 return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
9665 target, unsignedp));
9666 }
9667 goto binop3;
9668 }
9669 }
9670 /* Check for a multiplication with matching signedness. */
9671 else if ((TREE_CODE (treeop1) == INTEGER_CST
9672 && int_fits_type_p (treeop1, TREE_TYPE (treeop0)))
9673 || (TYPE_UNSIGNED (TREE_TYPE (treeop1))
9674 == TYPE_UNSIGNED (TREE_TYPE (treeop0))))
9675 {
9676 tree op0type = TREE_TYPE (treeop0);
9677 machine_mode innermode = TYPE_MODE (op0type);
9678 bool zextend_p = TYPE_UNSIGNED (op0type);
9679 optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
9680 this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
9681
9682 if (TREE_CODE (treeop0) != INTEGER_CST)
9683 {
9684 if (find_widening_optab_handler (this_optab, mode, innermode)
9685 != CODE_FOR_nothing)
9686 {
9687 expand_operands (exp0: treeop0, exp1: treeop1, NULL_RTX, op0: &op0, op1: &op1,
9688 modifier: EXPAND_NORMAL);
9689 /* op0 and op1 might still be constant, despite the above
9690 != INTEGER_CST check. Handle it. */
9691 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
9692 {
9693 widen_mult_const:
9694 op0 = convert_modes (mode, oldmode: innermode, x: op0, unsignedp: zextend_p);
9695 op1
9696 = convert_modes (mode, oldmode: innermode, x: op1,
9697 TYPE_UNSIGNED (TREE_TYPE (treeop1)));
9698 return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
9699 target,
9700 unsignedp));
9701 }
9702 temp = expand_widening_mult (mode, op0, op1, target,
9703 unsignedp, this_optab);
9704 return REDUCE_BIT_FIELD (temp);
9705 }
9706 if (find_widening_optab_handler (other_optab, mode, innermode)
9707 != CODE_FOR_nothing
9708 && innermode == word_mode)
9709 {
9710 rtx htem, hipart;
9711 op0 = expand_normal (exp: treeop0);
9712 op1 = expand_normal (exp: treeop1);
9713 /* op0 and op1 might be constants, despite the above
9714 != INTEGER_CST check. Handle it. */
9715 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
9716 goto widen_mult_const;
9717 temp = expand_binop (mode, other_optab, op0, op1, target,
9718 unsignedp, OPTAB_LIB_WIDEN);
9719 hipart = gen_highpart (word_mode, temp);
9720 htem = expand_mult_highpart_adjust (word_mode, hipart,
9721 op0, op1, hipart,
9722 zextend_p);
9723 if (htem != hipart)
9724 emit_move_insn (x: hipart, y: htem);
9725 return REDUCE_BIT_FIELD (temp);
9726 }
9727 }
9728 }
9729 treeop0 = fold_build1 (CONVERT_EXPR, type, treeop0);
9730 treeop1 = fold_build1 (CONVERT_EXPR, type, treeop1);
9731 expand_operands (exp0: treeop0, exp1: treeop1, target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
9732 return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
9733
9734 case MULT_EXPR:
9735 /* If this is a fixed-point operation, then we cannot use the code
9736 below because "expand_mult" doesn't support sat/no-sat fixed-point
9737 multiplications. */
9738 if (ALL_FIXED_POINT_MODE_P (mode))
9739 goto binop;
9740
9741 /* If first operand is constant, swap them.
9742 Thus the following special case checks need only
9743 check the second operand. */
9744 if (TREE_CODE (treeop0) == INTEGER_CST)
9745 std::swap (a&: treeop0, b&: treeop1);
9746
9747 /* Attempt to return something suitable for generating an
9748 indexed address, for machines that support that. */
9749
9750 if (modifier == EXPAND_SUM && mode == ptr_mode
9751 && tree_fits_shwi_p (treeop1))
9752 {
9753 tree exp1 = treeop1;
9754
9755 op0 = expand_expr (exp: treeop0, target: subtarget, VOIDmode,
9756 modifier: EXPAND_SUM);
9757
9758 if (!REG_P (op0))
9759 op0 = force_operand (value: op0, NULL_RTX);
9760 if (!REG_P (op0))
9761 op0 = copy_to_mode_reg (mode, op0);
9762
9763 op1 = gen_int_mode (tree_to_shwi (exp1),
9764 TYPE_MODE (TREE_TYPE (exp1)));
9765 return REDUCE_BIT_FIELD (gen_rtx_MULT (mode, op0, op1));
9766 }
9767
9768 if (modifier == EXPAND_STACK_PARM)
9769 target = 0;
9770
9771 if (SCALAR_INT_MODE_P (mode) && optimize >= 2)
9772 {
9773 gimple *def_stmt0 = get_def_for_expr (name: treeop0, code: TRUNC_DIV_EXPR);
9774 gimple *def_stmt1 = get_def_for_expr (name: treeop1, code: TRUNC_DIV_EXPR);
9775 if (def_stmt0
9776 && !operand_equal_p (treeop1, gimple_assign_rhs2 (gs: def_stmt0), flags: 0))
9777 def_stmt0 = NULL;
9778 if (def_stmt1
9779 && !operand_equal_p (treeop0, gimple_assign_rhs2 (gs: def_stmt1), flags: 0))
9780 def_stmt1 = NULL;
9781
9782 if (def_stmt0 || def_stmt1)
9783 {
9784 /* X / Y * Y can be expanded as X - X % Y too.
9785 Choose the cheaper sequence of those two. */
9786 if (def_stmt0)
9787 treeop0 = gimple_assign_rhs1 (gs: def_stmt0);
9788 else
9789 {
9790 treeop1 = treeop0;
9791 treeop0 = gimple_assign_rhs1 (gs: def_stmt1);
9792 }
9793 expand_operands (exp0: treeop0, exp1: treeop1, target: subtarget, op0: &op0, op1: &op1,
9794 modifier: EXPAND_NORMAL);
9795 bool speed_p = optimize_insn_for_speed_p ();
9796 do_pending_stack_adjust ();
9797 start_sequence ();
9798 rtx divmul_ret
9799 = expand_expr_divmod (code: TRUNC_DIV_EXPR, mode, treeop0, treeop1,
9800 op0, op1, NULL_RTX, unsignedp);
9801 divmul_ret = expand_mult (mode, divmul_ret, op1, target,
9802 unsignedp);
9803 rtx_insn *divmul_insns = get_insns ();
9804 end_sequence ();
9805 start_sequence ();
9806 rtx modsub_ret
9807 = expand_expr_divmod (code: TRUNC_MOD_EXPR, mode, treeop0, treeop1,
9808 op0, op1, NULL_RTX, unsignedp);
9809 this_optab = optab_for_tree_code (MINUS_EXPR, type,
9810 optab_default);
9811 modsub_ret = expand_binop (mode, this_optab, op0, modsub_ret,
9812 target, unsignedp, OPTAB_LIB_WIDEN);
9813 rtx_insn *modsub_insns = get_insns ();
9814 end_sequence ();
9815 unsigned divmul_cost = seq_cost (divmul_insns, speed_p);
9816 unsigned modsub_cost = seq_cost (modsub_insns, speed_p);
9817 /* If costs are the same then use as tie breaker the other other
9818 factor. */
9819 if (divmul_cost == modsub_cost)
9820 {
9821 divmul_cost = seq_cost (divmul_insns, !speed_p);
9822 modsub_cost = seq_cost (modsub_insns, !speed_p);
9823 }
9824
9825 if (divmul_cost <= modsub_cost)
9826 {
9827 emit_insn (divmul_insns);
9828 return REDUCE_BIT_FIELD (divmul_ret);
9829 }
9830 emit_insn (modsub_insns);
9831 return REDUCE_BIT_FIELD (modsub_ret);
9832 }
9833 }
9834
9835 expand_operands (exp0: treeop0, exp1: treeop1, target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
9836
9837 /* Expand X*Y as X&-Y when Y must be zero or one. */
9838 if (SCALAR_INT_MODE_P (mode))
9839 {
9840 bool bit0_p = tree_nonzero_bits (treeop0) == 1;
9841 bool bit1_p = tree_nonzero_bits (treeop1) == 1;
9842
9843 /* Expand X*Y as X&Y when both X and Y must be zero or one. */
9844 if (bit0_p && bit1_p)
9845 return REDUCE_BIT_FIELD (expand_and (mode, op0, op1, target));
9846
9847 if (bit0_p || bit1_p)
9848 {
9849 bool speed = optimize_insn_for_speed_p ();
9850 int cost = add_cost (speed, mode) + neg_cost (speed, mode);
9851 struct algorithm algorithm;
9852 enum mult_variant variant;
9853 if (CONST_INT_P (op1)
9854 ? !choose_mult_variant (mode, INTVAL (op1),
9855 &algorithm, &variant, cost)
9856 : cost < mul_cost (speed, mode))
9857 {
9858 target = bit0_p ? expand_and (mode, negate_rtx (mode, op0),
9859 op1, target)
9860 : expand_and (mode, op0,
9861 negate_rtx (mode, op1),
9862 target);
9863 return REDUCE_BIT_FIELD (target);
9864 }
9865 }
9866 }
9867
9868 return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1, target, unsignedp));
9869
9870 case TRUNC_MOD_EXPR:
9871 case FLOOR_MOD_EXPR:
9872 case CEIL_MOD_EXPR:
9873 case ROUND_MOD_EXPR:
9874
9875 case TRUNC_DIV_EXPR:
9876 case FLOOR_DIV_EXPR:
9877 case CEIL_DIV_EXPR:
9878 case ROUND_DIV_EXPR:
9879 case EXACT_DIV_EXPR:
9880 /* If this is a fixed-point operation, then we cannot use the code
9881 below because "expand_divmod" doesn't support sat/no-sat fixed-point
9882 divisions. */
9883 if (ALL_FIXED_POINT_MODE_P (mode))
9884 goto binop;
9885
9886 if (modifier == EXPAND_STACK_PARM)
9887 target = 0;
9888 /* Possible optimization: compute the dividend with EXPAND_SUM
9889 then if the divisor is constant can optimize the case
9890 where some terms of the dividend have coeffs divisible by it. */
9891 expand_operands (exp0: treeop0, exp1: treeop1, target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
9892 return expand_expr_divmod (code, mode, treeop0, treeop1, op0, op1,
9893 target, unsignedp);
9894
9895 case RDIV_EXPR:
9896 goto binop;
9897
9898 case MULT_HIGHPART_EXPR:
9899 expand_operands (exp0: treeop0, exp1: treeop1, target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
9900 temp = expand_mult_highpart (mode, op0, op1, target, unsignedp);
9901 gcc_assert (temp);
9902 return temp;
9903
9904 case FIXED_CONVERT_EXPR:
9905 op0 = expand_normal (exp: treeop0);
9906 if (target == 0 || modifier == EXPAND_STACK_PARM)
9907 target = gen_reg_rtx (mode);
9908
9909 if ((TREE_CODE (TREE_TYPE (treeop0)) == INTEGER_TYPE
9910 && TYPE_UNSIGNED (TREE_TYPE (treeop0)))
9911 || (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type)))
9912 expand_fixed_convert (target, op0, 1, TYPE_SATURATING (type));
9913 else
9914 expand_fixed_convert (target, op0, 0, TYPE_SATURATING (type));
9915 return target;
9916
9917 case FIX_TRUNC_EXPR:
9918 op0 = expand_normal (exp: treeop0);
9919 if (target == 0 || modifier == EXPAND_STACK_PARM)
9920 target = gen_reg_rtx (mode);
9921 expand_fix (target, op0, unsignedp);
9922 return target;
9923
9924 case FLOAT_EXPR:
9925 op0 = expand_normal (exp: treeop0);
9926 if (target == 0 || modifier == EXPAND_STACK_PARM)
9927 target = gen_reg_rtx (mode);
9928 /* expand_float can't figure out what to do if FROM has VOIDmode.
9929 So give it the correct mode. With -O, cse will optimize this. */
9930 if (GET_MODE (op0) == VOIDmode)
9931 op0 = copy_to_mode_reg (TYPE_MODE (TREE_TYPE (treeop0)),
9932 op0);
9933 expand_float (target, op0,
9934 TYPE_UNSIGNED (TREE_TYPE (treeop0)));
9935 return target;
9936
9937 case NEGATE_EXPR:
9938 op0 = expand_expr (exp: treeop0, target: subtarget,
9939 VOIDmode, modifier: EXPAND_NORMAL);
9940 if (modifier == EXPAND_STACK_PARM)
9941 target = 0;
9942 temp = expand_unop (mode,
9943 optab_for_tree_code (NEGATE_EXPR, type,
9944 optab_default),
9945 op0, target, 0);
9946 gcc_assert (temp);
9947 return REDUCE_BIT_FIELD (temp);
9948
9949 case ABS_EXPR:
9950 case ABSU_EXPR:
9951 op0 = expand_expr (exp: treeop0, target: subtarget,
9952 VOIDmode, modifier: EXPAND_NORMAL);
9953 if (modifier == EXPAND_STACK_PARM)
9954 target = 0;
9955
9956 /* ABS_EXPR is not valid for complex arguments. */
9957 gcc_assert (GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
9958 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT);
9959
9960 /* Unsigned abs is simply the operand. Testing here means we don't
9961 risk generating incorrect code below. */
9962 if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
9963 return op0;
9964
9965 return expand_abs (mode, op0, target, unsignedp,
9966 safe_from_p (x: target, exp: treeop0, top_p: 1));
9967
9968 case MAX_EXPR:
9969 case MIN_EXPR:
9970 target = original_target;
9971 if (target == 0
9972 || modifier == EXPAND_STACK_PARM
9973 || (MEM_P (target) && MEM_VOLATILE_P (target))
9974 || GET_MODE (target) != mode
9975 || (REG_P (target)
9976 && REGNO (target) < FIRST_PSEUDO_REGISTER))
9977 target = gen_reg_rtx (mode);
9978 expand_operands (exp0: treeop0, exp1: treeop1,
9979 target, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
9980
9981 /* First try to do it with a special MIN or MAX instruction.
9982 If that does not win, use a conditional jump to select the proper
9983 value. */
9984 this_optab = optab_for_tree_code (code, type, optab_default);
9985 temp = expand_binop (mode, this_optab, op0, op1, target, unsignedp,
9986 OPTAB_WIDEN);
9987 if (temp != 0)
9988 return temp;
9989
9990 if (VECTOR_TYPE_P (type))
9991 gcc_unreachable ();
9992
9993 /* At this point, a MEM target is no longer useful; we will get better
9994 code without it. */
9995
9996 if (! REG_P (target))
9997 target = gen_reg_rtx (mode);
9998
9999 /* If op1 was placed in target, swap op0 and op1. */
10000 if (target != op0 && target == op1)
10001 std::swap (a&: op0, b&: op1);
10002
10003 /* We generate better code and avoid problems with op1 mentioning
10004 target by forcing op1 into a pseudo if it isn't a constant. */
10005 if (! CONSTANT_P (op1))
10006 op1 = force_reg (mode, op1);
10007
10008 {
10009 enum rtx_code comparison_code;
10010 rtx cmpop1 = op1;
10011
10012 if (code == MAX_EXPR)
10013 comparison_code = unsignedp ? GEU : GE;
10014 else
10015 comparison_code = unsignedp ? LEU : LE;
10016
10017 /* Canonicalize to comparisons against 0. */
10018 if (op1 == const1_rtx)
10019 {
10020 /* Converting (a >= 1 ? a : 1) into (a > 0 ? a : 1)
10021 or (a != 0 ? a : 1) for unsigned.
10022 For MIN we are safe converting (a <= 1 ? a : 1)
10023 into (a <= 0 ? a : 1) */
10024 cmpop1 = const0_rtx;
10025 if (code == MAX_EXPR)
10026 comparison_code = unsignedp ? NE : GT;
10027 }
10028 if (op1 == constm1_rtx && !unsignedp)
10029 {
10030 /* Converting (a >= -1 ? a : -1) into (a >= 0 ? a : -1)
10031 and (a <= -1 ? a : -1) into (a < 0 ? a : -1) */
10032 cmpop1 = const0_rtx;
10033 if (code == MIN_EXPR)
10034 comparison_code = LT;
10035 }
10036
10037 /* Use a conditional move if possible. */
10038 if (can_conditionally_move_p (mode))
10039 {
10040 rtx insn;
10041
10042 start_sequence ();
10043
10044 /* Try to emit the conditional move. */
10045 insn = emit_conditional_move (target,
10046 { .code: comparison_code,
10047 .op0: op0, .op1: cmpop1, .mode: mode },
10048 op0, op1, mode,
10049 unsignedp);
10050
10051 /* If we could do the conditional move, emit the sequence,
10052 and return. */
10053 if (insn)
10054 {
10055 rtx_insn *seq = get_insns ();
10056 end_sequence ();
10057 emit_insn (seq);
10058 return target;
10059 }
10060
10061 /* Otherwise discard the sequence and fall back to code with
10062 branches. */
10063 end_sequence ();
10064 }
10065
10066 if (target != op0)
10067 emit_move_insn (x: target, y: op0);
10068
10069 lab = gen_label_rtx ();
10070 do_compare_rtx_and_jump (target, cmpop1, comparison_code,
10071 unsignedp, mode, NULL_RTX, NULL, lab,
10072 profile_probability::uninitialized ());
10073 }
10074 emit_move_insn (x: target, y: op1);
10075 emit_label (lab);
10076 return target;
10077
10078 case BIT_NOT_EXPR:
10079 op0 = expand_expr (exp: treeop0, target: subtarget,
10080 VOIDmode, modifier: EXPAND_NORMAL);
10081 if (modifier == EXPAND_STACK_PARM)
10082 target = 0;
10083 /* In case we have to reduce the result to bitfield precision
10084 for unsigned bitfield expand this as XOR with a proper constant
10085 instead. */
10086 if (reduce_bit_field && TYPE_UNSIGNED (type))
10087 {
10088 int_mode = SCALAR_INT_TYPE_MODE (type);
10089 wide_int mask = wi::mask (TYPE_PRECISION (type),
10090 negate_p: false, precision: GET_MODE_PRECISION (mode: int_mode));
10091
10092 temp = expand_binop (int_mode, xor_optab, op0,
10093 immed_wide_int_const (mask, int_mode),
10094 target, 1, OPTAB_LIB_WIDEN);
10095 }
10096 else
10097 temp = expand_unop (mode, one_cmpl_optab, op0, target, 1);
10098 gcc_assert (temp);
10099 return temp;
10100
10101 /* ??? Can optimize bitwise operations with one arg constant.
10102 Can optimize (a bitwise1 n) bitwise2 (a bitwise3 b)
10103 and (a bitwise1 b) bitwise2 b (etc)
10104 but that is probably not worth while. */
10105
10106 case BIT_AND_EXPR:
10107 case BIT_IOR_EXPR:
10108 case BIT_XOR_EXPR:
10109 goto binop;
10110
10111 case LROTATE_EXPR:
10112 case RROTATE_EXPR:
10113 gcc_assert (VECTOR_MODE_P (TYPE_MODE (type))
10114 || type_has_mode_precision_p (type));
10115 /* fall through */
10116
10117 case LSHIFT_EXPR:
10118 case RSHIFT_EXPR:
10119 {
10120 /* If this is a fixed-point operation, then we cannot use the code
10121 below because "expand_shift" doesn't support sat/no-sat fixed-point
10122 shifts. */
10123 if (ALL_FIXED_POINT_MODE_P (mode))
10124 goto binop;
10125
10126 if (! safe_from_p (x: subtarget, exp: treeop1, top_p: 1))
10127 subtarget = 0;
10128 if (modifier == EXPAND_STACK_PARM)
10129 target = 0;
10130 op0 = expand_expr (exp: treeop0, target: subtarget,
10131 VOIDmode, modifier: EXPAND_NORMAL);
10132
10133 /* Left shift optimization when shifting across word_size boundary.
10134
10135 If mode == GET_MODE_WIDER_MODE (word_mode), then normally
10136 there isn't native instruction to support this wide mode
10137 left shift. Given below scenario:
10138
10139 Type A = (Type) B << C
10140
10141 |< T >|
10142 | dest_high | dest_low |
10143
10144 | word_size |
10145
10146 If the shift amount C caused we shift B to across the word
10147 size boundary, i.e part of B shifted into high half of
10148 destination register, and part of B remains in the low
10149 half, then GCC will use the following left shift expand
10150 logic:
10151
10152 1. Initialize dest_low to B.
10153 2. Initialize every bit of dest_high to the sign bit of B.
10154 3. Logic left shift dest_low by C bit to finalize dest_low.
10155 The value of dest_low before this shift is kept in a temp D.
10156 4. Logic left shift dest_high by C.
10157 5. Logic right shift D by (word_size - C).
10158 6. Or the result of 4 and 5 to finalize dest_high.
10159
10160 While, by checking gimple statements, if operand B is
10161 coming from signed extension, then we can simplify above
10162 expand logic into:
10163
10164 1. dest_high = src_low >> (word_size - C).
10165 2. dest_low = src_low << C.
10166
10167 We can use one arithmetic right shift to finish all the
10168 purpose of steps 2, 4, 5, 6, thus we reduce the steps
10169 needed from 6 into 2.
10170
10171 The case is similar for zero extension, except that we
10172 initialize dest_high to zero rather than copies of the sign
10173 bit from B. Furthermore, we need to use a logical right shift
10174 in this case.
10175
10176 The choice of sign-extension versus zero-extension is
10177 determined entirely by whether or not B is signed and is
10178 independent of the current setting of unsignedp. */
10179
10180 temp = NULL_RTX;
10181 if (code == LSHIFT_EXPR
10182 && target
10183 && REG_P (target)
10184 && GET_MODE_2XWIDER_MODE (m: word_mode).exists (mode: &int_mode)
10185 && mode == int_mode
10186 && TREE_CONSTANT (treeop1)
10187 && TREE_CODE (treeop0) == SSA_NAME)
10188 {
10189 gimple *def = SSA_NAME_DEF_STMT (treeop0);
10190 if (is_gimple_assign (gs: def)
10191 && gimple_assign_rhs_code (gs: def) == NOP_EXPR)
10192 {
10193 scalar_int_mode rmode = SCALAR_INT_TYPE_MODE
10194 (TREE_TYPE (gimple_assign_rhs1 (def)));
10195
10196 if (GET_MODE_SIZE (mode: rmode) < GET_MODE_SIZE (mode: int_mode)
10197 && TREE_INT_CST_LOW (treeop1) < GET_MODE_BITSIZE (mode: word_mode)
10198 && ((TREE_INT_CST_LOW (treeop1) + GET_MODE_BITSIZE (mode: rmode))
10199 >= GET_MODE_BITSIZE (mode: word_mode)))
10200 {
10201 rtx_insn *seq, *seq_old;
10202 poly_uint64 high_off = subreg_highpart_offset (outermode: word_mode,
10203 innermode: int_mode);
10204 bool extend_unsigned
10205 = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def)));
10206 rtx low = lowpart_subreg (outermode: word_mode, op: op0, innermode: int_mode);
10207 rtx dest_low = lowpart_subreg (outermode: word_mode, op: target, innermode: int_mode);
10208 rtx dest_high = simplify_gen_subreg (outermode: word_mode, op: target,
10209 innermode: int_mode, byte: high_off);
10210 HOST_WIDE_INT ramount = (BITS_PER_WORD
10211 - TREE_INT_CST_LOW (treeop1));
10212 tree rshift = build_int_cst (TREE_TYPE (treeop1), ramount);
10213
10214 start_sequence ();
10215 /* dest_high = src_low >> (word_size - C). */
10216 temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low,
10217 rshift, dest_high,
10218 extend_unsigned);
10219 if (temp != dest_high)
10220 emit_move_insn (x: dest_high, y: temp);
10221
10222 /* dest_low = src_low << C. */
10223 temp = expand_variable_shift (LSHIFT_EXPR, word_mode, low,
10224 treeop1, dest_low, unsignedp);
10225 if (temp != dest_low)
10226 emit_move_insn (x: dest_low, y: temp);
10227
10228 seq = get_insns ();
10229 end_sequence ();
10230 temp = target ;
10231
10232 if (have_insn_for (ASHIFT, int_mode))
10233 {
10234 bool speed_p = optimize_insn_for_speed_p ();
10235 start_sequence ();
10236 rtx ret_old = expand_variable_shift (code, int_mode,
10237 op0, treeop1,
10238 target,
10239 unsignedp);
10240
10241 seq_old = get_insns ();
10242 end_sequence ();
10243 if (seq_cost (seq, speed_p)
10244 >= seq_cost (seq_old, speed_p))
10245 {
10246 seq = seq_old;
10247 temp = ret_old;
10248 }
10249 }
10250 emit_insn (seq);
10251 }
10252 }
10253 }
10254
10255 if (temp == NULL_RTX)
10256 temp = expand_variable_shift (code, mode, op0, treeop1, target,
10257 unsignedp);
10258 if (code == LSHIFT_EXPR)
10259 temp = REDUCE_BIT_FIELD (temp);
10260 return temp;
10261 }
10262
10263 /* Could determine the answer when only additive constants differ. Also,
10264 the addition of one can be handled by changing the condition. */
10265 case LT_EXPR:
10266 case LE_EXPR:
10267 case GT_EXPR:
10268 case GE_EXPR:
10269 case EQ_EXPR:
10270 case NE_EXPR:
10271 case UNORDERED_EXPR:
10272 case ORDERED_EXPR:
10273 case UNLT_EXPR:
10274 case UNLE_EXPR:
10275 case UNGT_EXPR:
10276 case UNGE_EXPR:
10277 case UNEQ_EXPR:
10278 case LTGT_EXPR:
10279 {
10280 temp = do_store_flag (ops,
10281 modifier != EXPAND_STACK_PARM ? target : NULL_RTX,
10282 tmode != VOIDmode ? tmode : mode);
10283 if (temp)
10284 return temp;
10285
10286 /* Use a compare and a jump for BLKmode comparisons, or for function
10287 type comparisons is have_canonicalize_funcptr_for_compare. */
10288
10289 if ((target == 0
10290 || modifier == EXPAND_STACK_PARM
10291 || ! safe_from_p (x: target, exp: treeop0, top_p: 1)
10292 || ! safe_from_p (x: target, exp: treeop1, top_p: 1)
10293 /* Make sure we don't have a hard reg (such as function's return
10294 value) live across basic blocks, if not optimizing. */
10295 || (!optimize && REG_P (target)
10296 && REGNO (target) < FIRST_PSEUDO_REGISTER)))
10297 target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
10298
10299 emit_move_insn (x: target, const0_rtx);
10300
10301 rtx_code_label *lab1 = gen_label_rtx ();
10302 jumpifnot_1 (code, treeop0, treeop1, lab1,
10303 profile_probability::uninitialized ());
10304
10305 if (TYPE_PRECISION (type) == 1 && !TYPE_UNSIGNED (type))
10306 emit_move_insn (x: target, constm1_rtx);
10307 else
10308 emit_move_insn (x: target, const1_rtx);
10309
10310 emit_label (lab1);
10311 return target;
10312 }
10313 case COMPLEX_EXPR:
10314 /* Get the rtx code of the operands. */
10315 op0 = expand_normal (exp: treeop0);
10316 op1 = expand_normal (exp: treeop1);
10317
10318 if (!target)
10319 target = gen_reg_rtx (TYPE_MODE (type));
10320 else
10321 /* If target overlaps with op1, then either we need to force
10322 op1 into a pseudo (if target also overlaps with op0),
10323 or write the complex parts in reverse order. */
10324 switch (GET_CODE (target))
10325 {
10326 case CONCAT:
10327 if (reg_overlap_mentioned_p (XEXP (target, 0), op1))
10328 {
10329 if (reg_overlap_mentioned_p (XEXP (target, 1), op0))
10330 {
10331 complex_expr_force_op1:
10332 temp = gen_reg_rtx (GET_MODE_INNER (GET_MODE (target)));
10333 emit_move_insn (x: temp, y: op1);
10334 op1 = temp;
10335 break;
10336 }
10337 complex_expr_swap_order:
10338 /* Move the imaginary (op1) and real (op0) parts to their
10339 location. */
10340 write_complex_part (cplx: target, val: op1, imag_p: true, undefined_p: true);
10341 write_complex_part (cplx: target, val: op0, imag_p: false, undefined_p: false);
10342
10343 return target;
10344 }
10345 break;
10346 case MEM:
10347 temp = adjust_address_nv (target,
10348 GET_MODE_INNER (GET_MODE (target)), 0);
10349 if (reg_overlap_mentioned_p (temp, op1))
10350 {
10351 scalar_mode imode = GET_MODE_INNER (GET_MODE (target));
10352 temp = adjust_address_nv (target, imode,
10353 GET_MODE_SIZE (imode));
10354 if (reg_overlap_mentioned_p (temp, op0))
10355 goto complex_expr_force_op1;
10356 goto complex_expr_swap_order;
10357 }
10358 break;
10359 default:
10360 if (reg_overlap_mentioned_p (target, op1))
10361 {
10362 if (reg_overlap_mentioned_p (target, op0))
10363 goto complex_expr_force_op1;
10364 goto complex_expr_swap_order;
10365 }
10366 break;
10367 }
10368
10369 /* Move the real (op0) and imaginary (op1) parts to their location. */
10370 write_complex_part (cplx: target, val: op0, imag_p: false, undefined_p: true);
10371 write_complex_part (cplx: target, val: op1, imag_p: true, undefined_p: false);
10372
10373 return target;
10374
10375 case WIDEN_SUM_EXPR:
10376 {
10377 tree oprnd0 = treeop0;
10378 tree oprnd1 = treeop1;
10379
10380 expand_operands (exp0: oprnd0, exp1: oprnd1, NULL_RTX, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10381 target = expand_widen_pattern_expr (ops, op0, NULL_RTX, op1,
10382 target, unsignedp);
10383 return target;
10384 }
10385
10386 case VEC_UNPACK_HI_EXPR:
10387 case VEC_UNPACK_LO_EXPR:
10388 case VEC_UNPACK_FIX_TRUNC_HI_EXPR:
10389 case VEC_UNPACK_FIX_TRUNC_LO_EXPR:
10390 {
10391 op0 = expand_normal (exp: treeop0);
10392 temp = expand_widen_pattern_expr (ops, op0, NULL_RTX, NULL_RTX,
10393 target, unsignedp);
10394 gcc_assert (temp);
10395 return temp;
10396 }
10397
10398 case VEC_UNPACK_FLOAT_HI_EXPR:
10399 case VEC_UNPACK_FLOAT_LO_EXPR:
10400 {
10401 op0 = expand_normal (exp: treeop0);
10402 /* The signedness is determined from input operand. */
10403 temp = expand_widen_pattern_expr
10404 (ops, op0, NULL_RTX, NULL_RTX,
10405 target, TYPE_UNSIGNED (TREE_TYPE (treeop0)));
10406
10407 gcc_assert (temp);
10408 return temp;
10409 }
10410
10411 case VEC_WIDEN_MULT_HI_EXPR:
10412 case VEC_WIDEN_MULT_LO_EXPR:
10413 case VEC_WIDEN_MULT_EVEN_EXPR:
10414 case VEC_WIDEN_MULT_ODD_EXPR:
10415 case VEC_WIDEN_LSHIFT_HI_EXPR:
10416 case VEC_WIDEN_LSHIFT_LO_EXPR:
10417 expand_operands (exp0: treeop0, exp1: treeop1, NULL_RTX, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10418 target = expand_widen_pattern_expr (ops, op0, op1, NULL_RTX,
10419 target, unsignedp);
10420 gcc_assert (target);
10421 return target;
10422
10423 case VEC_PACK_SAT_EXPR:
10424 case VEC_PACK_FIX_TRUNC_EXPR:
10425 mode = TYPE_MODE (TREE_TYPE (treeop0));
10426 subtarget = NULL_RTX;
10427 goto binop;
10428
10429 case VEC_PACK_TRUNC_EXPR:
10430 if (VECTOR_BOOLEAN_TYPE_P (type)
10431 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (treeop0))
10432 && mode == TYPE_MODE (TREE_TYPE (treeop0))
10433 && SCALAR_INT_MODE_P (mode))
10434 {
10435 class expand_operand eops[4];
10436 machine_mode imode = TYPE_MODE (TREE_TYPE (treeop0));
10437 expand_operands (exp0: treeop0, exp1: treeop1,
10438 target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10439 this_optab = vec_pack_sbool_trunc_optab;
10440 enum insn_code icode = optab_handler (op: this_optab, mode: imode);
10441 create_output_operand (op: &eops[0], x: target, mode);
10442 create_convert_operand_from (op: &eops[1], value: op0, mode: imode, unsigned_p: false);
10443 create_convert_operand_from (op: &eops[2], value: op1, mode: imode, unsigned_p: false);
10444 temp = GEN_INT (TYPE_VECTOR_SUBPARTS (type).to_constant ());
10445 create_input_operand (op: &eops[3], value: temp, mode: imode);
10446 expand_insn (icode, nops: 4, ops: eops);
10447 return eops[0].value;
10448 }
10449 mode = TYPE_MODE (TREE_TYPE (treeop0));
10450 subtarget = NULL_RTX;
10451 goto binop;
10452
10453 case VEC_PACK_FLOAT_EXPR:
10454 mode = TYPE_MODE (TREE_TYPE (treeop0));
10455 expand_operands (exp0: treeop0, exp1: treeop1,
10456 target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10457 this_optab = optab_for_tree_code (code, TREE_TYPE (treeop0),
10458 optab_default);
10459 target = expand_binop (mode, this_optab, op0, op1, target,
10460 TYPE_UNSIGNED (TREE_TYPE (treeop0)),
10461 OPTAB_LIB_WIDEN);
10462 gcc_assert (target);
10463 return target;
10464
10465 case VEC_PERM_EXPR:
10466 {
10467 expand_operands (exp0: treeop0, exp1: treeop1, target, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10468 vec_perm_builder sel;
10469 if (TREE_CODE (treeop2) == VECTOR_CST
10470 && tree_to_vec_perm_builder (&sel, treeop2))
10471 {
10472 machine_mode sel_mode = TYPE_MODE (TREE_TYPE (treeop2));
10473 temp = expand_vec_perm_const (mode, op0, op1, sel,
10474 sel_mode, target);
10475 }
10476 else
10477 {
10478 op2 = expand_normal (exp: treeop2);
10479 temp = expand_vec_perm_var (mode, op0, op1, op2, target);
10480 }
10481 gcc_assert (temp);
10482 return temp;
10483 }
10484
10485 case DOT_PROD_EXPR:
10486 {
10487 tree oprnd0 = treeop0;
10488 tree oprnd1 = treeop1;
10489 tree oprnd2 = treeop2;
10490
10491 expand_operands (exp0: oprnd0, exp1: oprnd1, NULL_RTX, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10492 op2 = expand_normal (exp: oprnd2);
10493 target = expand_widen_pattern_expr (ops, op0, op1, op2,
10494 target, unsignedp);
10495 return target;
10496 }
10497
10498 case SAD_EXPR:
10499 {
10500 tree oprnd0 = treeop0;
10501 tree oprnd1 = treeop1;
10502 tree oprnd2 = treeop2;
10503
10504 expand_operands (exp0: oprnd0, exp1: oprnd1, NULL_RTX, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10505 op2 = expand_normal (exp: oprnd2);
10506 target = expand_widen_pattern_expr (ops, op0, op1, op2,
10507 target, unsignedp);
10508 return target;
10509 }
10510
10511 case REALIGN_LOAD_EXPR:
10512 {
10513 tree oprnd0 = treeop0;
10514 tree oprnd1 = treeop1;
10515 tree oprnd2 = treeop2;
10516
10517 this_optab = optab_for_tree_code (code, type, optab_default);
10518 expand_operands (exp0: oprnd0, exp1: oprnd1, NULL_RTX, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10519 op2 = expand_normal (exp: oprnd2);
10520 temp = expand_ternary_op (mode, ternary_optab: this_optab, op0, op1, op2,
10521 target, unsignedp);
10522 gcc_assert (temp);
10523 return temp;
10524 }
10525
10526 case COND_EXPR:
10527 {
10528 /* A COND_EXPR with its type being VOID_TYPE represents a
10529 conditional jump and is handled in
10530 expand_gimple_cond_expr. */
10531 gcc_assert (!VOID_TYPE_P (type));
10532
10533 /* Note that COND_EXPRs whose type is a structure or union
10534 are required to be constructed to contain assignments of
10535 a temporary variable, so that we can evaluate them here
10536 for side effect only. If type is void, we must do likewise. */
10537
10538 gcc_assert (!TREE_ADDRESSABLE (type)
10539 && !ignore
10540 && TREE_TYPE (treeop1) != void_type_node
10541 && TREE_TYPE (treeop2) != void_type_node);
10542
10543 temp = expand_cond_expr_using_cmove (treeop0, treeop1, treeop2);
10544 if (temp)
10545 return temp;
10546
10547 /* If we are not to produce a result, we have no target. Otherwise,
10548 if a target was specified use it; it will not be used as an
10549 intermediate target unless it is safe. If no target, use a
10550 temporary. */
10551
10552 if (modifier != EXPAND_STACK_PARM
10553 && original_target
10554 && safe_from_p (x: original_target, exp: treeop0, top_p: 1)
10555 && GET_MODE (original_target) == mode
10556 && !MEM_P (original_target))
10557 temp = original_target;
10558 else
10559 temp = assign_temp (type, 0, 1);
10560
10561 do_pending_stack_adjust ();
10562 NO_DEFER_POP;
10563 rtx_code_label *lab0 = gen_label_rtx ();
10564 rtx_code_label *lab1 = gen_label_rtx ();
10565 jumpifnot (exp: treeop0, label: lab0,
10566 prob: profile_probability::uninitialized ());
10567 store_expr (exp: treeop1, target: temp,
10568 call_param_p: modifier == EXPAND_STACK_PARM,
10569 nontemporal: false, reverse: false);
10570
10571 emit_jump_insn (targetm.gen_jump (lab1));
10572 emit_barrier ();
10573 emit_label (lab0);
10574 store_expr (exp: treeop2, target: temp,
10575 call_param_p: modifier == EXPAND_STACK_PARM,
10576 nontemporal: false, reverse: false);
10577
10578 emit_label (lab1);
10579 OK_DEFER_POP;
10580 return temp;
10581 }
10582
10583 case VEC_DUPLICATE_EXPR:
10584 op0 = expand_expr (exp: treeop0, NULL_RTX, VOIDmode, modifier);
10585 target = expand_vector_broadcast (mode, op0);
10586 gcc_assert (target);
10587 return target;
10588
10589 case VEC_SERIES_EXPR:
10590 expand_operands (exp0: treeop0, exp1: treeop1, NULL_RTX, op0: &op0, op1: &op1, modifier);
10591 return expand_vec_series_expr (mode, op0, op1, target);
10592
10593 case BIT_INSERT_EXPR:
10594 {
10595 unsigned bitpos = tree_to_uhwi (treeop2);
10596 unsigned bitsize;
10597 if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
10598 bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
10599 else
10600 bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
10601 op0 = expand_normal (exp: treeop0);
10602 op1 = expand_normal (exp: treeop1);
10603 rtx dst = gen_reg_rtx (mode);
10604 emit_move_insn (x: dst, y: op0);
10605 store_bit_field (dst, bitsize, bitpos, 0, 0,
10606 TYPE_MODE (TREE_TYPE (treeop1)), op1, false, false);
10607 return dst;
10608 }
10609
10610 default:
10611 gcc_unreachable ();
10612 }
10613
10614 /* Here to do an ordinary binary operator. */
10615 binop:
10616 expand_operands (exp0: treeop0, exp1: treeop1,
10617 target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
10618 binop2:
10619 this_optab = optab_for_tree_code (code, type, optab_default);
10620 binop3:
10621 if (modifier == EXPAND_STACK_PARM)
10622 target = 0;
10623 temp = expand_binop (mode, this_optab, op0, op1, target,
10624 unsignedp, OPTAB_LIB_WIDEN);
10625 gcc_assert (temp);
10626 /* Bitwise operations do not need bitfield reduction as we expect their
10627 operands being properly truncated. */
10628 if (code == BIT_XOR_EXPR
10629 || code == BIT_AND_EXPR
10630 || code == BIT_IOR_EXPR)
10631 return temp;
10632 return REDUCE_BIT_FIELD (temp);
10633}
10634#undef REDUCE_BIT_FIELD
10635
10636
10637/* Return TRUE if expression STMT is suitable for replacement.
10638 Never consider memory loads as replaceable, because those don't ever lead
10639 into constant expressions. */
10640
10641static bool
10642stmt_is_replaceable_p (gimple *stmt)
10643{
10644 if (ssa_is_replaceable_p (stmt))
10645 {
10646 /* Don't move around loads. */
10647 if (!gimple_assign_single_p (gs: stmt)
10648 || is_gimple_val (gimple_assign_rhs1 (gs: stmt)))
10649 return true;
10650 }
10651 return false;
10652}
10653
10654rtx
10655expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
10656 enum expand_modifier modifier, rtx *alt_rtl,
10657 bool inner_reference_p)
10658{
10659 rtx op0, op1, temp, decl_rtl;
10660 tree type;
10661 int unsignedp;
10662 machine_mode mode, dmode;
10663 enum tree_code code = TREE_CODE (exp);
10664 rtx subtarget, original_target;
10665 int ignore;
10666 bool reduce_bit_field;
10667 location_t loc = EXPR_LOCATION (exp);
10668 struct separate_ops ops;
10669 tree treeop0, treeop1, treeop2;
10670 tree ssa_name = NULL_TREE;
10671 gimple *g;
10672
10673 /* Some ABIs define padding bits in _BitInt uninitialized. Normally, RTL
10674 expansion sign/zero extends integral types with less than mode precision
10675 when reading from bit-fields and after arithmetic operations (see
10676 REDUCE_BIT_FIELD in expand_expr_real_2) and on subsequent loads relies
10677 on those extensions to have been already performed, but because of the
10678 above for _BitInt they need to be sign/zero extended when reading from
10679 locations that could be exposed to ABI boundaries (when loading from
10680 objects in memory, or function arguments, return value). Because we
10681 internally extend after arithmetic operations, we can avoid doing that
10682 when reading from SSA_NAMEs of vars. */
10683#define EXTEND_BITINT(expr) \
10684 ((TREE_CODE (type) == BITINT_TYPE \
10685 && reduce_bit_field \
10686 && mode != BLKmode \
10687 && modifier != EXPAND_MEMORY \
10688 && modifier != EXPAND_WRITE \
10689 && modifier != EXPAND_CONST_ADDRESS) \
10690 ? reduce_to_bit_field_precision ((expr), NULL_RTX, type) : (expr))
10691
10692 type = TREE_TYPE (exp);
10693 mode = TYPE_MODE (type);
10694 unsignedp = TYPE_UNSIGNED (type);
10695
10696 treeop0 = treeop1 = treeop2 = NULL_TREE;
10697 if (!VL_EXP_CLASS_P (exp))
10698 switch (TREE_CODE_LENGTH (code))
10699 {
10700 default:
10701 case 3: treeop2 = TREE_OPERAND (exp, 2); /* FALLTHRU */
10702 case 2: treeop1 = TREE_OPERAND (exp, 1); /* FALLTHRU */
10703 case 1: treeop0 = TREE_OPERAND (exp, 0); /* FALLTHRU */
10704 case 0: break;
10705 }
10706 ops.code = code;
10707 ops.type = type;
10708 ops.op0 = treeop0;
10709 ops.op1 = treeop1;
10710 ops.op2 = treeop2;
10711 ops.location = loc;
10712
10713 ignore = (target == const0_rtx
10714 || ((CONVERT_EXPR_CODE_P (code)
10715 || code == COND_EXPR || code == VIEW_CONVERT_EXPR)
10716 && TREE_CODE (type) == VOID_TYPE));
10717
10718 /* An operation in what may be a bit-field type needs the
10719 result to be reduced to the precision of the bit-field type,
10720 which is narrower than that of the type's mode. */
10721 reduce_bit_field = (!ignore
10722 && INTEGRAL_TYPE_P (type)
10723 && !type_has_mode_precision_p (t: type));
10724
10725 /* If we are going to ignore this result, we need only do something
10726 if there is a side-effect somewhere in the expression. If there
10727 is, short-circuit the most common cases here. Note that we must
10728 not call expand_expr with anything but const0_rtx in case this
10729 is an initial expansion of a size that contains a PLACEHOLDER_EXPR. */
10730
10731 if (ignore)
10732 {
10733 if (! TREE_SIDE_EFFECTS (exp))
10734 return const0_rtx;
10735
10736 /* Ensure we reference a volatile object even if value is ignored, but
10737 don't do this if all we are doing is taking its address. */
10738 if (TREE_THIS_VOLATILE (exp)
10739 && TREE_CODE (exp) != FUNCTION_DECL
10740 && mode != VOIDmode && mode != BLKmode
10741 && modifier != EXPAND_CONST_ADDRESS)
10742 {
10743 temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
10744 if (MEM_P (temp))
10745 copy_to_reg (temp);
10746 return const0_rtx;
10747 }
10748
10749 if (TREE_CODE_CLASS (code) == tcc_unary
10750 || code == BIT_FIELD_REF
10751 || code == COMPONENT_REF
10752 || code == INDIRECT_REF)
10753 return expand_expr (exp: treeop0, const0_rtx, VOIDmode,
10754 modifier);
10755
10756 else if (TREE_CODE_CLASS (code) == tcc_binary
10757 || TREE_CODE_CLASS (code) == tcc_comparison
10758 || code == ARRAY_REF || code == ARRAY_RANGE_REF)
10759 {
10760 expand_expr (exp: treeop0, const0_rtx, VOIDmode, modifier);
10761 expand_expr (exp: treeop1, const0_rtx, VOIDmode, modifier);
10762 return const0_rtx;
10763 }
10764
10765 target = 0;
10766 }
10767
10768 if (reduce_bit_field && modifier == EXPAND_STACK_PARM)
10769 target = 0;
10770
10771 /* Use subtarget as the target for operand 0 of a binary operation. */
10772 subtarget = get_subtarget (x: target);
10773 original_target = target;
10774
10775 switch (code)
10776 {
10777 case LABEL_DECL:
10778 {
10779 tree function = decl_function_context (exp);
10780
10781 temp = label_rtx (exp);
10782 temp = gen_rtx_LABEL_REF (Pmode, temp);
10783
10784 if (function != current_function_decl
10785 && function != 0)
10786 LABEL_REF_NONLOCAL_P (temp) = 1;
10787
10788 temp = gen_rtx_MEM (FUNCTION_MODE, temp);
10789 return temp;
10790 }
10791
10792 case SSA_NAME:
10793 /* ??? ivopts calls expander, without any preparation from
10794 out-of-ssa. So fake instructions as if this was an access to the
10795 base variable. This unnecessarily allocates a pseudo, see how we can
10796 reuse it, if partition base vars have it set already. */
10797 if (!currently_expanding_to_rtl)
10798 {
10799 tree var = SSA_NAME_VAR (exp);
10800 if (var && DECL_RTL_SET_P (var))
10801 return DECL_RTL (var);
10802 return gen_raw_REG (TYPE_MODE (TREE_TYPE (exp)),
10803 LAST_VIRTUAL_REGISTER + 1);
10804 }
10805
10806 g = get_gimple_for_ssa_name (exp);
10807 /* For EXPAND_INITIALIZER try harder to get something simpler. */
10808 if (g == NULL
10809 && modifier == EXPAND_INITIALIZER
10810 && !SSA_NAME_IS_DEFAULT_DEF (exp)
10811 && (optimize || !SSA_NAME_VAR (exp)
10812 || DECL_IGNORED_P (SSA_NAME_VAR (exp)))
10813 && stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
10814 g = SSA_NAME_DEF_STMT (exp);
10815 if (g)
10816 {
10817 rtx r;
10818 location_t saved_loc = curr_insn_location ();
10819 loc = gimple_location (g);
10820 if (loc != UNKNOWN_LOCATION)
10821 set_curr_insn_location (loc);
10822 ops.code = gimple_assign_rhs_code (gs: g);
10823 switch (get_gimple_rhs_class (code: ops.code))
10824 {
10825 case GIMPLE_TERNARY_RHS:
10826 ops.op2 = gimple_assign_rhs3 (gs: g);
10827 /* Fallthru */
10828 case GIMPLE_BINARY_RHS:
10829 ops.op1 = gimple_assign_rhs2 (gs: g);
10830
10831 /* Try to expand conditonal compare. */
10832 if (targetm.gen_ccmp_first)
10833 {
10834 gcc_checking_assert (targetm.gen_ccmp_next != NULL);
10835 r = expand_ccmp_expr (g, mode);
10836 if (r)
10837 break;
10838 }
10839 /* Fallthru */
10840 case GIMPLE_UNARY_RHS:
10841 ops.op0 = gimple_assign_rhs1 (gs: g);
10842 ops.type = TREE_TYPE (gimple_assign_lhs (g));
10843 ops.location = loc;
10844 r = expand_expr_real_2 (ops: &ops, target, tmode, modifier);
10845 break;
10846 case GIMPLE_SINGLE_RHS:
10847 {
10848 r = expand_expr_real (exp: gimple_assign_rhs1 (gs: g), target,
10849 tmode, modifier, alt_rtl,
10850 inner_reference_p);
10851 break;
10852 }
10853 default:
10854 gcc_unreachable ();
10855 }
10856 set_curr_insn_location (saved_loc);
10857 if (REG_P (r) && !REG_EXPR (r))
10858 set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (exp), x: r);
10859 return r;
10860 }
10861
10862 ssa_name = exp;
10863 decl_rtl = get_rtx_for_ssa_name (exp: ssa_name);
10864 exp = SSA_NAME_VAR (ssa_name);
10865 /* Optimize and avoid to EXTEND_BITINIT doing anything if it is an
10866 SSA_NAME computed within the current function. In such case the
10867 value have been already extended before. While if it is a function
10868 parameter, result or some memory location, we need to be prepared
10869 for some other compiler leaving the bits uninitialized. */
10870 if (!exp || VAR_P (exp))
10871 reduce_bit_field = false;
10872 goto expand_decl_rtl;
10873
10874 case VAR_DECL:
10875 /* Allow accel compiler to handle variables that require special
10876 treatment, e.g. if they have been modified in some way earlier in
10877 compilation by the adjust_private_decl OpenACC hook. */
10878 if (flag_openacc && targetm.goacc.expand_var_decl)
10879 {
10880 temp = targetm.goacc.expand_var_decl (exp);
10881 if (temp)
10882 return temp;
10883 }
10884 /* Expand const VAR_DECLs with CONSTRUCTOR initializers that
10885 have scalar integer modes to a reg via store_constructor. */
10886 if (TREE_READONLY (exp)
10887 && !TREE_SIDE_EFFECTS (exp)
10888 && (modifier == EXPAND_NORMAL || modifier == EXPAND_STACK_PARM)
10889 && immediate_const_ctor_p (DECL_INITIAL (exp))
10890 && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (exp)))
10891 && crtl->emit.regno_pointer_align_length
10892 && !target)
10893 {
10894 target = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
10895 store_constructor (DECL_INITIAL (exp), target, cleared: 0,
10896 size: int_expr_size (DECL_INITIAL (exp)), reverse: false);
10897 return target;
10898 }
10899 /* ... fall through ... */
10900
10901 case PARM_DECL:
10902 /* If a static var's type was incomplete when the decl was written,
10903 but the type is complete now, lay out the decl now. */
10904 if (DECL_SIZE (exp) == 0
10905 && COMPLETE_OR_UNBOUND_ARRAY_TYPE_P (TREE_TYPE (exp))
10906 && (TREE_STATIC (exp) || DECL_EXTERNAL (exp)))
10907 layout_decl (exp, 0);
10908
10909 /* fall through */
10910
10911 case FUNCTION_DECL:
10912 case RESULT_DECL:
10913 decl_rtl = DECL_RTL (exp);
10914 expand_decl_rtl:
10915 gcc_assert (decl_rtl);
10916
10917 /* DECL_MODE might change when TYPE_MODE depends on attribute target
10918 settings for VECTOR_TYPE_P that might switch for the function. */
10919 if (currently_expanding_to_rtl
10920 && code == VAR_DECL && MEM_P (decl_rtl)
10921 && VECTOR_TYPE_P (type) && exp && DECL_MODE (exp) != mode)
10922 decl_rtl = change_address (decl_rtl, TYPE_MODE (type), 0);
10923 else
10924 decl_rtl = copy_rtx (decl_rtl);
10925
10926 /* Record writes to register variables. */
10927 if (modifier == EXPAND_WRITE
10928 && REG_P (decl_rtl)
10929 && HARD_REGISTER_P (decl_rtl))
10930 add_to_hard_reg_set (regs: &crtl->asm_clobbers,
10931 GET_MODE (decl_rtl), REGNO (decl_rtl));
10932
10933 /* Ensure variable marked as used even if it doesn't go through
10934 a parser. If it hasn't be used yet, write out an external
10935 definition. */
10936 if (exp)
10937 TREE_USED (exp) = 1;
10938
10939 /* Show we haven't gotten RTL for this yet. */
10940 temp = 0;
10941
10942 /* Variables inherited from containing functions should have
10943 been lowered by this point. */
10944 if (exp)
10945 {
10946 tree context = decl_function_context (exp);
10947 gcc_assert (SCOPE_FILE_SCOPE_P (context)
10948 || context == current_function_decl
10949 || TREE_STATIC (exp)
10950 || DECL_EXTERNAL (exp)
10951 /* ??? C++ creates functions that are not
10952 TREE_STATIC. */
10953 || TREE_CODE (exp) == FUNCTION_DECL);
10954 }
10955
10956 /* This is the case of an array whose size is to be determined
10957 from its initializer, while the initializer is still being parsed.
10958 ??? We aren't parsing while expanding anymore. */
10959
10960 if (MEM_P (decl_rtl) && REG_P (XEXP (decl_rtl, 0)))
10961 temp = validize_mem (decl_rtl);
10962
10963 /* If DECL_RTL is memory, we are in the normal case and the
10964 address is not valid, get the address into a register. */
10965
10966 else if (MEM_P (decl_rtl) && modifier != EXPAND_INITIALIZER)
10967 {
10968 if (alt_rtl)
10969 *alt_rtl = decl_rtl;
10970 decl_rtl = use_anchored_address (decl_rtl);
10971 if (modifier != EXPAND_CONST_ADDRESS
10972 && modifier != EXPAND_SUM
10973 && !memory_address_addr_space_p (exp ? DECL_MODE (exp)
10974 : GET_MODE (decl_rtl),
10975 XEXP (decl_rtl, 0),
10976 MEM_ADDR_SPACE (decl_rtl)))
10977 temp = replace_equiv_address (decl_rtl,
10978 copy_rtx (XEXP (decl_rtl, 0)));
10979 }
10980
10981 /* If we got something, return it. But first, set the alignment
10982 if the address is a register. */
10983 if (temp != 0)
10984 {
10985 if (exp && MEM_P (temp) && REG_P (XEXP (temp, 0)))
10986 mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
10987 }
10988 else if (MEM_P (decl_rtl))
10989 temp = decl_rtl;
10990
10991 if (temp != 0)
10992 {
10993 if (MEM_P (temp)
10994 && modifier != EXPAND_WRITE
10995 && modifier != EXPAND_MEMORY
10996 && modifier != EXPAND_INITIALIZER
10997 && modifier != EXPAND_CONST_ADDRESS
10998 && modifier != EXPAND_SUM
10999 && !inner_reference_p
11000 && mode != BLKmode
11001 && MEM_ALIGN (temp) < GET_MODE_ALIGNMENT (mode))
11002 temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
11003 MEM_ALIGN (temp), NULL_RTX, NULL);
11004
11005 return EXTEND_BITINT (temp);
11006 }
11007
11008 if (exp)
11009 dmode = DECL_MODE (exp);
11010 else
11011 dmode = TYPE_MODE (TREE_TYPE (ssa_name));
11012
11013 /* If the mode of DECL_RTL does not match that of the decl,
11014 there are two cases: we are dealing with a BLKmode value
11015 that is returned in a register, or we are dealing with
11016 a promoted value. In the latter case, return a SUBREG
11017 of the wanted mode, but mark it so that we know that it
11018 was already extended. */
11019 if (REG_P (decl_rtl)
11020 && dmode != BLKmode
11021 && GET_MODE (decl_rtl) != dmode)
11022 {
11023 machine_mode pmode;
11024
11025 /* Get the signedness to be used for this variable. Ensure we get
11026 the same mode we got when the variable was declared. */
11027 if (code != SSA_NAME)
11028 pmode = promote_decl_mode (exp, &unsignedp);
11029 else if ((g = SSA_NAME_DEF_STMT (ssa_name))
11030 && gimple_code (g) == GIMPLE_CALL
11031 && !gimple_call_internal_p (gs: g))
11032 pmode = promote_function_mode (type, mode, &unsignedp,
11033 gimple_call_fntype (gs: g),
11034 2);
11035 else
11036 pmode = promote_ssa_mode (ssa_name, &unsignedp);
11037 gcc_assert (GET_MODE (decl_rtl) == pmode);
11038
11039 /* Some ABIs require scalar floating point modes to be passed
11040 in a wider scalar integer mode. We need to explicitly
11041 truncate to an integer mode of the correct precision before
11042 using a SUBREG to reinterpret as a floating point value. */
11043 if (SCALAR_FLOAT_MODE_P (mode)
11044 && SCALAR_INT_MODE_P (pmode)
11045 && known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (pmode)))
11046 return convert_wider_int_to_float (mode, imode: pmode, x: decl_rtl);
11047
11048 temp = gen_lowpart_SUBREG (mode, decl_rtl);
11049 SUBREG_PROMOTED_VAR_P (temp) = 1;
11050 SUBREG_PROMOTED_SET (temp, unsignedp);
11051 return EXTEND_BITINT (temp);
11052 }
11053
11054 return EXTEND_BITINT (decl_rtl);
11055
11056 case INTEGER_CST:
11057 {
11058 if (TREE_CODE (type) == BITINT_TYPE)
11059 {
11060 unsigned int prec = TYPE_PRECISION (type);
11061 struct bitint_info info;
11062 bool ok = targetm.c.bitint_type_info (prec, &info);
11063 gcc_assert (ok);
11064 scalar_int_mode limb_mode
11065 = as_a <scalar_int_mode> (m: info.limb_mode);
11066 unsigned int limb_prec = GET_MODE_PRECISION (mode: limb_mode);
11067 if (prec > limb_prec && prec > MAX_FIXED_MODE_SIZE)
11068 {
11069 /* Emit large/huge _BitInt INTEGER_CSTs into memory. */
11070 exp = tree_output_constant_def (exp);
11071 return expand_expr (exp, target, VOIDmode, modifier);
11072 }
11073 }
11074
11075 /* Given that TYPE_PRECISION (type) is not always equal to
11076 GET_MODE_PRECISION (TYPE_MODE (type)), we need to extend from
11077 the former to the latter according to the signedness of the
11078 type. */
11079 scalar_int_mode int_mode = SCALAR_INT_TYPE_MODE (type);
11080 temp = immed_wide_int_const
11081 (wi::to_wide (t: exp, prec: GET_MODE_PRECISION (mode: int_mode)), int_mode);
11082 return temp;
11083 }
11084
11085 case VECTOR_CST:
11086 {
11087 tree tmp = NULL_TREE;
11088 if (VECTOR_MODE_P (mode))
11089 return const_vector_from_tree (exp);
11090 scalar_int_mode int_mode;
11091 if (is_int_mode (mode, int_mode: &int_mode))
11092 {
11093 tree type_for_mode = lang_hooks.types.type_for_mode (int_mode, 1);
11094 if (type_for_mode)
11095 tmp = fold_unary_loc (loc, VIEW_CONVERT_EXPR,
11096 type_for_mode, exp);
11097 }
11098 if (!tmp)
11099 {
11100 vec<constructor_elt, va_gc> *v;
11101 /* Constructors need to be fixed-length. FIXME. */
11102 unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
11103 vec_alloc (v, nelems: nunits);
11104 for (unsigned int i = 0; i < nunits; ++i)
11105 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, VECTOR_CST_ELT (exp, i));
11106 tmp = build_constructor (type, v);
11107 }
11108 return expand_expr (exp: tmp, target: ignore ? const0_rtx : target,
11109 mode: tmode, modifier);
11110 }
11111
11112 case CONST_DECL:
11113 if (modifier == EXPAND_WRITE)
11114 {
11115 /* Writing into CONST_DECL is always invalid, but handle it
11116 gracefully. */
11117 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
11118 scalar_int_mode address_mode = targetm.addr_space.address_mode (as);
11119 op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, tmode: address_mode,
11120 modifier: EXPAND_NORMAL, as);
11121 op0 = memory_address_addr_space (mode, op0, as);
11122 temp = gen_rtx_MEM (mode, op0);
11123 set_mem_addr_space (temp, as);
11124 return temp;
11125 }
11126 return expand_expr (DECL_INITIAL (exp), target, VOIDmode, modifier);
11127
11128 case REAL_CST:
11129 /* If optimized, generate immediate CONST_DOUBLE
11130 which will be turned into memory by reload if necessary.
11131
11132 We used to force a register so that loop.c could see it. But
11133 this does not allow gen_* patterns to perform optimizations with
11134 the constants. It also produces two insns in cases like "x = 1.0;".
11135 On most machines, floating-point constants are not permitted in
11136 many insns, so we'd end up copying it to a register in any case.
11137
11138 Now, we do the copying in expand_binop, if appropriate. */
11139 return const_double_from_real_value (TREE_REAL_CST (exp),
11140 TYPE_MODE (TREE_TYPE (exp)));
11141
11142 case FIXED_CST:
11143 return CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (exp),
11144 TYPE_MODE (TREE_TYPE (exp)));
11145
11146 case COMPLEX_CST:
11147 /* Handle evaluating a complex constant in a CONCAT target. */
11148 if (original_target && GET_CODE (original_target) == CONCAT)
11149 {
11150 rtx rtarg, itarg;
11151
11152 mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (exp)));
11153 rtarg = XEXP (original_target, 0);
11154 itarg = XEXP (original_target, 1);
11155
11156 /* Move the real and imaginary parts separately. */
11157 op0 = expand_expr (TREE_REALPART (exp), target: rtarg, mode, modifier: EXPAND_NORMAL);
11158 op1 = expand_expr (TREE_IMAGPART (exp), target: itarg, mode, modifier: EXPAND_NORMAL);
11159
11160 if (op0 != rtarg)
11161 emit_move_insn (x: rtarg, y: op0);
11162 if (op1 != itarg)
11163 emit_move_insn (x: itarg, y: op1);
11164
11165 return original_target;
11166 }
11167
11168 /* fall through */
11169
11170 case STRING_CST:
11171 temp = expand_expr_constant (exp, defer: 1, modifier);
11172
11173 /* temp contains a constant address.
11174 On RISC machines where a constant address isn't valid,
11175 make some insns to get that address into a register. */
11176 if (modifier != EXPAND_CONST_ADDRESS
11177 && modifier != EXPAND_INITIALIZER
11178 && modifier != EXPAND_SUM
11179 && ! memory_address_addr_space_p (mode, XEXP (temp, 0),
11180 MEM_ADDR_SPACE (temp)))
11181 return replace_equiv_address (temp,
11182 copy_rtx (XEXP (temp, 0)));
11183 return temp;
11184
11185 case POLY_INT_CST:
11186 return immed_wide_int_const (poly_int_cst_value (x: exp), mode);
11187
11188 case SAVE_EXPR:
11189 {
11190 tree val = treeop0;
11191 rtx ret = expand_expr_real_1 (exp: val, target, tmode, modifier, alt_rtl,
11192 inner_reference_p);
11193
11194 if (!SAVE_EXPR_RESOLVED_P (exp))
11195 {
11196 /* We can indeed still hit this case, typically via builtin
11197 expanders calling save_expr immediately before expanding
11198 something. Assume this means that we only have to deal
11199 with non-BLKmode values. */
11200 gcc_assert (GET_MODE (ret) != BLKmode);
11201
11202 val = build_decl (curr_insn_location (),
11203 VAR_DECL, NULL, TREE_TYPE (exp));
11204 DECL_ARTIFICIAL (val) = 1;
11205 DECL_IGNORED_P (val) = 1;
11206 treeop0 = val;
11207 TREE_OPERAND (exp, 0) = treeop0;
11208 SAVE_EXPR_RESOLVED_P (exp) = 1;
11209
11210 if (!CONSTANT_P (ret))
11211 ret = copy_to_reg (ret);
11212 SET_DECL_RTL (val, ret);
11213 }
11214
11215 return ret;
11216 }
11217
11218
11219 case CONSTRUCTOR:
11220 /* If we don't need the result, just ensure we evaluate any
11221 subexpressions. */
11222 if (ignore)
11223 {
11224 unsigned HOST_WIDE_INT idx;
11225 tree value;
11226
11227 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
11228 expand_expr (exp: value, const0_rtx, VOIDmode, modifier: EXPAND_NORMAL);
11229
11230 return const0_rtx;
11231 }
11232
11233 return expand_constructor (exp, target, modifier, avoid_temp_mem: false);
11234
11235 case TARGET_MEM_REF:
11236 {
11237 addr_space_t as
11238 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
11239 unsigned int align;
11240
11241 op0 = addr_for_mem_ref (exp, as, really_expand: true);
11242 op0 = memory_address_addr_space (mode, op0, as);
11243 temp = gen_rtx_MEM (mode, op0);
11244 set_mem_attributes (temp, exp, 0);
11245 set_mem_addr_space (temp, as);
11246 align = get_object_alignment (exp);
11247 if (modifier != EXPAND_WRITE
11248 && modifier != EXPAND_MEMORY
11249 && mode != BLKmode
11250 && align < GET_MODE_ALIGNMENT (mode))
11251 temp = expand_misaligned_mem_ref (temp, mode, unsignedp,
11252 align, NULL_RTX, NULL);
11253 return EXTEND_BITINT (temp);
11254 }
11255
11256 case MEM_REF:
11257 {
11258 const bool reverse = REF_REVERSE_STORAGE_ORDER (exp);
11259 addr_space_t as
11260 = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (exp, 0))));
11261 machine_mode address_mode;
11262 tree base = TREE_OPERAND (exp, 0);
11263 gimple *def_stmt;
11264 unsigned align;
11265 /* Handle expansion of non-aliased memory with non-BLKmode. That
11266 might end up in a register. */
11267 if (mem_ref_refers_to_non_mem_p (ref: exp))
11268 {
11269 poly_int64 offset = mem_ref_offset (exp).force_shwi ();
11270 base = TREE_OPERAND (base, 0);
11271 poly_uint64 type_size;
11272 if (known_eq (offset, 0)
11273 && !reverse
11274 && poly_int_tree_p (TYPE_SIZE (type), value: &type_size)
11275 && known_eq (GET_MODE_BITSIZE (DECL_MODE (base)), type_size))
11276 return expand_expr (exp: build1 (VIEW_CONVERT_EXPR, type, base),
11277 target, mode: tmode, modifier);
11278 if (TYPE_MODE (type) == BLKmode)
11279 {
11280 temp = assign_stack_temp (DECL_MODE (base),
11281 GET_MODE_SIZE (DECL_MODE (base)));
11282 store_expr (exp: base, target: temp, call_param_p: 0, nontemporal: false, reverse: false);
11283 temp = adjust_address (temp, BLKmode, offset);
11284 set_mem_size (temp, int_size_in_bytes (type));
11285 return temp;
11286 }
11287 exp = build3 (BIT_FIELD_REF, type, base, TYPE_SIZE (type),
11288 bitsize_int (offset * BITS_PER_UNIT));
11289 REF_REVERSE_STORAGE_ORDER (exp) = reverse;
11290 return expand_expr (exp, target, mode: tmode, modifier);
11291 }
11292 address_mode = targetm.addr_space.address_mode (as);
11293 if ((def_stmt = get_def_for_expr (name: base, code: BIT_AND_EXPR)))
11294 {
11295 tree mask = gimple_assign_rhs2 (gs: def_stmt);
11296 base = build2 (BIT_AND_EXPR, TREE_TYPE (base),
11297 gimple_assign_rhs1 (gs: def_stmt), mask);
11298 TREE_OPERAND (exp, 0) = base;
11299 }
11300 align = get_object_alignment (exp);
11301 op0 = expand_expr (exp: base, NULL_RTX, VOIDmode, modifier: EXPAND_SUM);
11302 op0 = memory_address_addr_space (mode, op0, as);
11303 if (!integer_zerop (TREE_OPERAND (exp, 1)))
11304 {
11305 rtx off = immed_wide_int_const (mem_ref_offset (exp), address_mode);
11306 op0 = simplify_gen_binary (code: PLUS, mode: address_mode, op0, op1: off);
11307 op0 = memory_address_addr_space (mode, op0, as);
11308 }
11309 temp = gen_rtx_MEM (mode, op0);
11310 set_mem_attributes (temp, exp, 0);
11311 set_mem_addr_space (temp, as);
11312 if (TREE_THIS_VOLATILE (exp))
11313 MEM_VOLATILE_P (temp) = 1;
11314 if (modifier == EXPAND_WRITE || modifier == EXPAND_MEMORY)
11315 return temp;
11316 if (!inner_reference_p
11317 && mode != BLKmode
11318 && align < GET_MODE_ALIGNMENT (mode))
11319 temp = expand_misaligned_mem_ref (temp, mode, unsignedp, align,
11320 target: modifier == EXPAND_STACK_PARM
11321 ? NULL_RTX : target, alt_rtl);
11322 if (reverse)
11323 temp = flip_storage_order (mode, temp);
11324 return EXTEND_BITINT (temp);
11325 }
11326
11327 case ARRAY_REF:
11328
11329 {
11330 tree array = treeop0;
11331 tree index = treeop1;
11332 tree init;
11333
11334 /* Fold an expression like: "foo"[2].
11335 This is not done in fold so it won't happen inside &.
11336 Don't fold if this is for wide characters since it's too
11337 difficult to do correctly and this is a very rare case. */
11338
11339 if (modifier != EXPAND_CONST_ADDRESS
11340 && modifier != EXPAND_INITIALIZER
11341 && modifier != EXPAND_MEMORY)
11342 {
11343 tree t = fold_read_from_constant_string (exp);
11344
11345 if (t)
11346 return expand_expr (exp: t, target, mode: tmode, modifier);
11347 }
11348
11349 /* If this is a constant index into a constant array,
11350 just get the value from the array. Handle both the cases when
11351 we have an explicit constructor and when our operand is a variable
11352 that was declared const. */
11353
11354 if (modifier != EXPAND_CONST_ADDRESS
11355 && modifier != EXPAND_INITIALIZER
11356 && modifier != EXPAND_MEMORY
11357 && TREE_CODE (array) == CONSTRUCTOR
11358 && ! TREE_SIDE_EFFECTS (array)
11359 && TREE_CODE (index) == INTEGER_CST)
11360 {
11361 unsigned HOST_WIDE_INT ix;
11362 tree field, value;
11363
11364 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (array), ix,
11365 field, value)
11366 if (tree_int_cst_equal (field, index))
11367 {
11368 if (!TREE_SIDE_EFFECTS (value))
11369 return expand_expr (exp: fold (value), target, mode: tmode, modifier);
11370 break;
11371 }
11372 }
11373
11374 else if (optimize >= 1
11375 && modifier != EXPAND_CONST_ADDRESS
11376 && modifier != EXPAND_INITIALIZER
11377 && modifier != EXPAND_MEMORY
11378 && TREE_READONLY (array) && ! TREE_SIDE_EFFECTS (array)
11379 && TREE_CODE (index) == INTEGER_CST
11380 && (VAR_P (array) || TREE_CODE (array) == CONST_DECL)
11381 && (init = ctor_for_folding (array)) != error_mark_node)
11382 {
11383 if (init == NULL_TREE)
11384 {
11385 tree value = build_zero_cst (type);
11386 if (TREE_CODE (value) == CONSTRUCTOR)
11387 {
11388 /* If VALUE is a CONSTRUCTOR, this optimization is only
11389 useful if this doesn't store the CONSTRUCTOR into
11390 memory. If it does, it is more efficient to just
11391 load the data from the array directly. */
11392 rtx ret = expand_constructor (exp: value, target,
11393 modifier, avoid_temp_mem: true);
11394 if (ret == NULL_RTX)
11395 value = NULL_TREE;
11396 }
11397
11398 if (value)
11399 return expand_expr (exp: value, target, mode: tmode, modifier);
11400 }
11401 else if (TREE_CODE (init) == CONSTRUCTOR)
11402 {
11403 unsigned HOST_WIDE_INT ix;
11404 tree field, value;
11405
11406 FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), ix,
11407 field, value)
11408 if (tree_int_cst_equal (field, index))
11409 {
11410 if (TREE_SIDE_EFFECTS (value))
11411 break;
11412
11413 if (TREE_CODE (value) == CONSTRUCTOR)
11414 {
11415 /* If VALUE is a CONSTRUCTOR, this
11416 optimization is only useful if
11417 this doesn't store the CONSTRUCTOR
11418 into memory. If it does, it is more
11419 efficient to just load the data from
11420 the array directly. */
11421 rtx ret = expand_constructor (exp: value, target,
11422 modifier, avoid_temp_mem: true);
11423 if (ret == NULL_RTX)
11424 break;
11425 }
11426
11427 return
11428 expand_expr (exp: fold (value), target, mode: tmode, modifier);
11429 }
11430 }
11431 else if (TREE_CODE (init) == STRING_CST)
11432 {
11433 tree low_bound = array_ref_low_bound (exp);
11434 tree index1 = fold_convert_loc (loc, sizetype, treeop1);
11435
11436 /* Optimize the special case of a zero lower bound.
11437
11438 We convert the lower bound to sizetype to avoid problems
11439 with constant folding. E.g. suppose the lower bound is
11440 1 and its mode is QI. Without the conversion
11441 (ARRAY + (INDEX - (unsigned char)1))
11442 becomes
11443 (ARRAY + (-(unsigned char)1) + INDEX)
11444 which becomes
11445 (ARRAY + 255 + INDEX). Oops! */
11446 if (!integer_zerop (low_bound))
11447 index1 = size_diffop_loc (loc, index1,
11448 fold_convert_loc (loc, sizetype,
11449 low_bound));
11450
11451 if (tree_fits_uhwi_p (index1)
11452 && compare_tree_int (index1, TREE_STRING_LENGTH (init)) < 0)
11453 {
11454 tree char_type = TREE_TYPE (TREE_TYPE (init));
11455 scalar_int_mode char_mode;
11456
11457 if (is_int_mode (TYPE_MODE (char_type), int_mode: &char_mode)
11458 && GET_MODE_SIZE (mode: char_mode) == 1)
11459 return gen_int_mode (TREE_STRING_POINTER (init)
11460 [TREE_INT_CST_LOW (index1)],
11461 char_mode);
11462 }
11463 }
11464 }
11465 }
11466 goto normal_inner_ref;
11467
11468 case COMPONENT_REF:
11469 gcc_assert (TREE_CODE (treeop0) != CONSTRUCTOR);
11470 /* Fall through. */
11471 case BIT_FIELD_REF:
11472 case ARRAY_RANGE_REF:
11473 normal_inner_ref:
11474 {
11475 machine_mode mode1, mode2;
11476 poly_int64 bitsize, bitpos, bytepos;
11477 tree offset;
11478 int reversep, volatilep = 0;
11479 tree tem
11480 = get_inner_reference (exp, pbitsize: &bitsize, pbitpos: &bitpos, poffset: &offset, pmode: &mode1,
11481 punsignedp: &unsignedp, preversep: &reversep, pvolatilep: &volatilep);
11482 rtx orig_op0, memloc;
11483 bool clear_mem_expr = false;
11484 bool must_force_mem;
11485
11486 /* If we got back the original object, something is wrong. Perhaps
11487 we are evaluating an expression too early. In any event, don't
11488 infinitely recurse. */
11489 gcc_assert (tem != exp);
11490
11491 /* Make sure bitpos is not negative, this can wreak havoc later. */
11492 if (maybe_lt (a: bitpos, b: 0))
11493 {
11494 gcc_checking_assert (offset == NULL_TREE);
11495 offset = size_int (bits_to_bytes_round_down (bitpos));
11496 bitpos = num_trailing_bits (bitpos);
11497 }
11498
11499 /* If we have either an offset, a BLKmode result, or a reference
11500 outside the underlying object, we must force it to memory.
11501 Such a case can occur in Ada if we have unchecked conversion
11502 of an expression from a scalar type to an aggregate type or
11503 for an ARRAY_RANGE_REF whose type is BLKmode, or if we were
11504 passed a partially uninitialized object or a view-conversion
11505 to a larger size. */
11506 must_force_mem = offset != NULL_TREE
11507 || mode1 == BLKmode
11508 || (mode == BLKmode
11509 && !int_mode_for_size (size: bitsize, limit: 1).exists ());
11510
11511 const enum expand_modifier tem_modifier
11512 = must_force_mem
11513 ? EXPAND_MEMORY
11514 : modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier;
11515
11516 /* If TEM's type is a union of variable size, pass TARGET to the inner
11517 computation, since it will need a temporary and TARGET is known
11518 to have to do. This occurs in unchecked conversion in Ada. */
11519 const rtx tem_target
11520 = TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
11521 && COMPLETE_TYPE_P (TREE_TYPE (tem))
11522 && TREE_CODE (TYPE_SIZE (TREE_TYPE (tem))) != INTEGER_CST
11523 && modifier != EXPAND_STACK_PARM
11524 ? target
11525 : NULL_RTX;
11526
11527 orig_op0 = op0
11528 = expand_expr_real (exp: tem, target: tem_target, VOIDmode, modifier: tem_modifier, NULL,
11529 inner_reference_p: true);
11530
11531 /* If the field has a mode, we want to access it in the
11532 field's mode, not the computed mode.
11533 If a MEM has VOIDmode (external with incomplete type),
11534 use BLKmode for it instead. */
11535 if (MEM_P (op0))
11536 {
11537 if (mode1 != VOIDmode)
11538 op0 = adjust_address (op0, mode1, 0);
11539 else if (GET_MODE (op0) == VOIDmode)
11540 op0 = adjust_address (op0, BLKmode, 0);
11541 }
11542
11543 mode2
11544 = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0);
11545
11546 /* See above for the rationale. */
11547 if (maybe_gt (bitpos + bitsize, GET_MODE_BITSIZE (mode2)))
11548 must_force_mem = true;
11549
11550 /* Handle CONCAT first. */
11551 if (GET_CODE (op0) == CONCAT && !must_force_mem)
11552 {
11553 if (known_eq (bitpos, 0)
11554 && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
11555 && COMPLEX_MODE_P (mode1)
11556 && COMPLEX_MODE_P (GET_MODE (op0))
11557 && (GET_MODE_PRECISION (GET_MODE_INNER (mode1))
11558 == GET_MODE_PRECISION (GET_MODE_INNER (GET_MODE (op0)))))
11559 {
11560 if (reversep)
11561 op0 = flip_storage_order (GET_MODE (op0), op0);
11562 if (mode1 != GET_MODE (op0))
11563 {
11564 rtx parts[2];
11565 for (int i = 0; i < 2; i++)
11566 {
11567 rtx op = read_complex_part (cplx: op0, imag_p: i != 0);
11568 if (GET_CODE (op) == SUBREG)
11569 op = force_reg (GET_MODE (op), op);
11570 temp = gen_lowpart_common (GET_MODE_INNER (mode1), op);
11571 if (temp)
11572 op = temp;
11573 else
11574 {
11575 if (!REG_P (op) && !MEM_P (op))
11576 op = force_reg (GET_MODE (op), op);
11577 op = gen_lowpart (GET_MODE_INNER (mode1), op);
11578 }
11579 parts[i] = op;
11580 }
11581 op0 = gen_rtx_CONCAT (mode1, parts[0], parts[1]);
11582 }
11583 return op0;
11584 }
11585 if (known_eq (bitpos, 0)
11586 && known_eq (bitsize,
11587 GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
11588 && maybe_ne (a: bitsize, b: 0))
11589 {
11590 op0 = XEXP (op0, 0);
11591 mode2 = GET_MODE (op0);
11592 }
11593 else if (known_eq (bitpos,
11594 GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))))
11595 && known_eq (bitsize,
11596 GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 1))))
11597 && maybe_ne (a: bitpos, b: 0)
11598 && maybe_ne (a: bitsize, b: 0))
11599 {
11600 op0 = XEXP (op0, 1);
11601 bitpos = 0;
11602 mode2 = GET_MODE (op0);
11603 }
11604 else
11605 /* Otherwise force into memory. */
11606 must_force_mem = true;
11607 }
11608
11609 /* If this is a constant, put it in a register if it is a legitimate
11610 constant and we don't need a memory reference. */
11611 if (CONSTANT_P (op0)
11612 && mode2 != BLKmode
11613 && targetm.legitimate_constant_p (mode2, op0)
11614 && !must_force_mem)
11615 op0 = force_reg (mode2, op0);
11616
11617 /* Otherwise, if this is a constant, try to force it to the constant
11618 pool. Note that back-ends, e.g. MIPS, may refuse to do so if it
11619 is a legitimate constant. */
11620 else if (CONSTANT_P (op0) && (memloc = force_const_mem (mode2, op0)))
11621 op0 = validize_mem (memloc);
11622
11623 /* Otherwise, if this is a constant or the object is not in memory
11624 and need be, put it there. */
11625 else if (CONSTANT_P (op0) || (!MEM_P (op0) && must_force_mem))
11626 {
11627 memloc = assign_temp (TREE_TYPE (tem), 1, 1);
11628 emit_move_insn (x: memloc, y: op0);
11629 op0 = memloc;
11630 clear_mem_expr = true;
11631 }
11632
11633 if (offset)
11634 {
11635 machine_mode address_mode;
11636 rtx offset_rtx = expand_expr (exp: offset, NULL_RTX, VOIDmode,
11637 modifier: EXPAND_SUM);
11638
11639 gcc_assert (MEM_P (op0));
11640
11641 address_mode = get_address_mode (mem: op0);
11642 if (GET_MODE (offset_rtx) != address_mode)
11643 {
11644 /* We cannot be sure that the RTL in offset_rtx is valid outside
11645 of a memory address context, so force it into a register
11646 before attempting to convert it to the desired mode. */
11647 offset_rtx = force_operand (value: offset_rtx, NULL_RTX);
11648 offset_rtx = convert_to_mode (mode: address_mode, x: offset_rtx, unsignedp: 0);
11649 }
11650
11651 /* See the comment in expand_assignment for the rationale. */
11652 if (mode1 != VOIDmode
11653 && maybe_ne (a: bitpos, b: 0)
11654 && maybe_gt (bitsize, 0)
11655 && multiple_p (a: bitpos, BITS_PER_UNIT, multiple: &bytepos)
11656 && multiple_p (a: bitpos, b: bitsize)
11657 && multiple_p (a: bitsize, GET_MODE_ALIGNMENT (mode1))
11658 && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode1))
11659 {
11660 op0 = adjust_address (op0, mode1, bytepos);
11661 bitpos = 0;
11662 }
11663
11664 op0 = offset_address (op0, offset_rtx,
11665 highest_pow2_factor (exp: offset));
11666 }
11667
11668 /* If OFFSET is making OP0 more aligned than BIGGEST_ALIGNMENT,
11669 record its alignment as BIGGEST_ALIGNMENT. */
11670 if (MEM_P (op0)
11671 && known_eq (bitpos, 0)
11672 && offset != 0
11673 && is_aligning_offset (offset, tem))
11674 set_mem_align (op0, BIGGEST_ALIGNMENT);
11675
11676 /* Don't forget about volatility even if this is a bitfield. */
11677 if (MEM_P (op0) && volatilep && ! MEM_VOLATILE_P (op0))
11678 {
11679 if (op0 == orig_op0)
11680 op0 = copy_rtx (op0);
11681
11682 MEM_VOLATILE_P (op0) = 1;
11683 }
11684
11685 if (MEM_P (op0) && TREE_CODE (tem) == FUNCTION_DECL)
11686 {
11687 if (op0 == orig_op0)
11688 op0 = copy_rtx (op0);
11689
11690 set_mem_align (op0, BITS_PER_UNIT);
11691 }
11692
11693 /* In cases where an aligned union has an unaligned object
11694 as a field, we might be extracting a BLKmode value from
11695 an integer-mode (e.g., SImode) object. Handle this case
11696 by doing the extract into an object as wide as the field
11697 (which we know to be the width of a basic mode), then
11698 storing into memory, and changing the mode to BLKmode. */
11699 if (mode1 == VOIDmode
11700 || REG_P (op0) || GET_CODE (op0) == SUBREG
11701 || (mode1 != BLKmode && ! direct_load[(int) mode1]
11702 && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
11703 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT
11704 && modifier != EXPAND_CONST_ADDRESS
11705 && modifier != EXPAND_INITIALIZER
11706 && modifier != EXPAND_MEMORY)
11707 /* If the bitfield is volatile and the bitsize
11708 is narrower than the access size of the bitfield,
11709 we need to extract bitfields from the access. */
11710 || (volatilep && TREE_CODE (exp) == COMPONENT_REF
11711 && DECL_BIT_FIELD_TYPE (TREE_OPERAND (exp, 1))
11712 && mode1 != BLKmode
11713 && maybe_lt (a: bitsize, b: GET_MODE_SIZE (mode: mode1) * BITS_PER_UNIT))
11714 /* If the field isn't aligned enough to fetch as a memref,
11715 fetch it as a bit field. */
11716 || (mode1 != BLKmode
11717 && (((MEM_P (op0)
11718 ? MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode1)
11719 || !multiple_p (a: bitpos, GET_MODE_ALIGNMENT (mode1))
11720 : TYPE_ALIGN (TREE_TYPE (tem)) < GET_MODE_ALIGNMENT (mode)
11721 || !multiple_p (a: bitpos, GET_MODE_ALIGNMENT (mode)))
11722 && modifier != EXPAND_MEMORY
11723 && ((modifier == EXPAND_CONST_ADDRESS
11724 || modifier == EXPAND_INITIALIZER)
11725 ? STRICT_ALIGNMENT
11726 : targetm.slow_unaligned_access (mode1,
11727 MEM_ALIGN (op0))))
11728 || !multiple_p (a: bitpos, BITS_PER_UNIT)))
11729 /* If the type and the field are a constant size and the
11730 size of the type isn't the same size as the bitfield,
11731 we must use bitfield operations. */
11732 || (known_size_p (a: bitsize)
11733 && TYPE_SIZE (TREE_TYPE (exp))
11734 && poly_int_tree_p (TYPE_SIZE (TREE_TYPE (exp)))
11735 && maybe_ne (a: wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (exp))),
11736 b: bitsize)))
11737 {
11738 machine_mode ext_mode = mode;
11739
11740 if (ext_mode == BLKmode
11741 && ! (target != 0 && MEM_P (op0)
11742 && MEM_P (target)
11743 && multiple_p (a: bitpos, BITS_PER_UNIT)))
11744 ext_mode = int_mode_for_size (size: bitsize, limit: 1).else_blk ();
11745
11746 if (ext_mode == BLKmode)
11747 {
11748 if (target == 0)
11749 target = assign_temp (type, 1, 1);
11750
11751 /* ??? Unlike the similar test a few lines below, this one is
11752 very likely obsolete. */
11753 if (known_eq (bitsize, 0))
11754 return target;
11755
11756 /* In this case, BITPOS must start at a byte boundary and
11757 TARGET, if specified, must be a MEM. */
11758 gcc_assert (MEM_P (op0)
11759 && (!target || MEM_P (target)));
11760
11761 bytepos = exact_div (a: bitpos, BITS_PER_UNIT);
11762 poly_int64 bytesize = bits_to_bytes_round_up (bitsize);
11763 emit_block_move (x: target,
11764 adjust_address (op0, VOIDmode, bytepos),
11765 size: gen_int_mode (bytesize, Pmode),
11766 method: (modifier == EXPAND_STACK_PARM
11767 ? BLOCK_OP_CALL_PARM : BLOCK_OP_NORMAL));
11768
11769 return target;
11770 }
11771
11772 /* If we have nothing to extract, the result will be 0 for targets
11773 with SHIFT_COUNT_TRUNCATED == 0 and garbage otherwise. Always
11774 return 0 for the sake of consistency, as reading a zero-sized
11775 bitfield is valid in Ada and the value is fully specified. */
11776 if (known_eq (bitsize, 0))
11777 return const0_rtx;
11778
11779 op0 = validize_mem (op0);
11780
11781 if (MEM_P (op0) && REG_P (XEXP (op0, 0)))
11782 mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
11783
11784 /* If the result has aggregate type and the extraction is done in
11785 an integral mode, then the field may be not aligned on a byte
11786 boundary; in this case, if it has reverse storage order, it
11787 needs to be extracted as a scalar field with reverse storage
11788 order and put back into memory order afterwards. */
11789 if (AGGREGATE_TYPE_P (type)
11790 && GET_MODE_CLASS (ext_mode) == MODE_INT)
11791 reversep = TYPE_REVERSE_STORAGE_ORDER (type);
11792
11793 gcc_checking_assert (known_ge (bitpos, 0));
11794 op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp,
11795 (modifier == EXPAND_STACK_PARM
11796 ? NULL_RTX : target),
11797 ext_mode, ext_mode, reversep, alt_rtl);
11798
11799 /* If the result has aggregate type and the mode of OP0 is an
11800 integral mode then, if BITSIZE is narrower than this mode
11801 and this is for big-endian data, we must put the field
11802 into the high-order bits. And we must also put it back
11803 into memory order if it has been previously reversed. */
11804 scalar_int_mode op0_mode;
11805 if (AGGREGATE_TYPE_P (type)
11806 && is_int_mode (GET_MODE (op0), int_mode: &op0_mode))
11807 {
11808 HOST_WIDE_INT size = GET_MODE_BITSIZE (mode: op0_mode);
11809
11810 gcc_checking_assert (known_le (bitsize, size));
11811 if (maybe_lt (a: bitsize, b: size)
11812 && reversep ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
11813 op0 = expand_shift (LSHIFT_EXPR, op0_mode, op0,
11814 size - bitsize, op0, 1);
11815
11816 if (reversep)
11817 op0 = flip_storage_order (op0_mode, op0);
11818 }
11819
11820 /* If the result type is BLKmode, store the data into a temporary
11821 of the appropriate type, but with the mode corresponding to the
11822 mode for the data we have (op0's mode). */
11823 if (mode == BLKmode)
11824 {
11825 rtx new_rtx
11826 = assign_stack_temp_for_type (ext_mode,
11827 GET_MODE_BITSIZE (mode: ext_mode),
11828 type);
11829 emit_move_insn (x: new_rtx, y: op0);
11830 op0 = copy_rtx (new_rtx);
11831 PUT_MODE (x: op0, BLKmode);
11832 }
11833
11834 return op0;
11835 }
11836
11837 /* If the result is BLKmode, use that to access the object
11838 now as well. */
11839 if (mode == BLKmode)
11840 mode1 = BLKmode;
11841
11842 /* Get a reference to just this component. */
11843 bytepos = bits_to_bytes_round_down (bitpos);
11844 if (modifier == EXPAND_CONST_ADDRESS
11845 || modifier == EXPAND_SUM || modifier == EXPAND_INITIALIZER)
11846 op0 = adjust_address_nv (op0, mode1, bytepos);
11847 else
11848 op0 = adjust_address (op0, mode1, bytepos);
11849
11850 if (op0 == orig_op0)
11851 op0 = copy_rtx (op0);
11852
11853 /* Don't set memory attributes if the base expression is
11854 SSA_NAME that got expanded as a MEM or a CONSTANT. In that case,
11855 we should just honor its original memory attributes. */
11856 if (!(TREE_CODE (tem) == SSA_NAME
11857 && (MEM_P (orig_op0) || CONSTANT_P (orig_op0))))
11858 set_mem_attributes (op0, exp, 0);
11859
11860 if (REG_P (XEXP (op0, 0)))
11861 mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
11862
11863 /* If op0 is a temporary because the original expressions was forced
11864 to memory, clear MEM_EXPR so that the original expression cannot
11865 be marked as addressable through MEM_EXPR of the temporary. */
11866 if (clear_mem_expr)
11867 set_mem_expr (op0, NULL_TREE);
11868
11869 MEM_VOLATILE_P (op0) |= volatilep;
11870
11871 if (reversep
11872 && modifier != EXPAND_MEMORY
11873 && modifier != EXPAND_WRITE)
11874 op0 = flip_storage_order (mode1, op0);
11875
11876 op0 = EXTEND_BITINT (op0);
11877
11878 if (mode == mode1 || mode1 == BLKmode || mode1 == tmode
11879 || modifier == EXPAND_CONST_ADDRESS
11880 || modifier == EXPAND_INITIALIZER)
11881 return op0;
11882
11883 if (target == 0)
11884 target = gen_reg_rtx (tmode != VOIDmode ? tmode : mode);
11885
11886 convert_move (to: target, from: op0, unsignedp);
11887 return target;
11888 }
11889
11890 case OBJ_TYPE_REF:
11891 return expand_expr (OBJ_TYPE_REF_EXPR (exp), target, mode: tmode, modifier);
11892
11893 case CALL_EXPR:
11894 /* All valid uses of __builtin_va_arg_pack () are removed during
11895 inlining. */
11896 if (CALL_EXPR_VA_ARG_PACK (exp))
11897 error ("invalid use of %<__builtin_va_arg_pack ()%>");
11898 {
11899 tree fndecl = get_callee_fndecl (exp), attr;
11900
11901 if (fndecl
11902 /* Don't diagnose the error attribute in thunks, those are
11903 artificially created. */
11904 && !CALL_FROM_THUNK_P (exp)
11905 && (attr = lookup_attribute (attr_name: "error",
11906 DECL_ATTRIBUTES (fndecl))) != NULL)
11907 {
11908 const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
11909 error ("call to %qs declared with attribute error: %s",
11910 identifier_to_locale (ident),
11911 TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
11912 }
11913 if (fndecl
11914 /* Don't diagnose the warning attribute in thunks, those are
11915 artificially created. */
11916 && !CALL_FROM_THUNK_P (exp)
11917 && (attr = lookup_attribute (attr_name: "warning",
11918 DECL_ATTRIBUTES (fndecl))) != NULL)
11919 {
11920 const char *ident = lang_hooks.decl_printable_name (fndecl, 1);
11921 warning_at (EXPR_LOCATION (exp),
11922 OPT_Wattribute_warning,
11923 "call to %qs declared with attribute warning: %s",
11924 identifier_to_locale (ident),
11925 TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
11926 }
11927
11928 /* Check for a built-in function. */
11929 if (fndecl && fndecl_built_in_p (node: fndecl))
11930 {
11931 gcc_assert (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_FRONTEND);
11932 return expand_builtin (exp, target, subtarget, tmode, ignore);
11933 }
11934 }
11935 return expand_call (exp, target, ignore);
11936
11937 case VIEW_CONVERT_EXPR:
11938 op0 = NULL_RTX;
11939
11940 /* If we are converting to BLKmode, try to avoid an intermediate
11941 temporary by fetching an inner memory reference. */
11942 if (mode == BLKmode
11943 && poly_int_tree_p (TYPE_SIZE (type))
11944 && TYPE_MODE (TREE_TYPE (treeop0)) != BLKmode
11945 && handled_component_p (t: treeop0))
11946 {
11947 machine_mode mode1;
11948 poly_int64 bitsize, bitpos, bytepos;
11949 tree offset;
11950 int reversep, volatilep = 0;
11951 tree tem
11952 = get_inner_reference (exp: treeop0, pbitsize: &bitsize, pbitpos: &bitpos, poffset: &offset, pmode: &mode1,
11953 punsignedp: &unsignedp, preversep: &reversep, pvolatilep: &volatilep);
11954
11955 /* ??? We should work harder and deal with non-zero offsets. */
11956 if (!offset
11957 && multiple_p (a: bitpos, BITS_PER_UNIT, multiple: &bytepos)
11958 && !reversep
11959 && known_size_p (a: bitsize)
11960 && known_eq (wi::to_poly_offset (TYPE_SIZE (type)), bitsize))
11961 {
11962 /* See the normal_inner_ref case for the rationale. */
11963 rtx orig_op0
11964 = expand_expr_real (exp: tem,
11965 target: (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
11966 && (TREE_CODE (TYPE_SIZE (TREE_TYPE (tem)))
11967 != INTEGER_CST)
11968 && modifier != EXPAND_STACK_PARM
11969 ? target : NULL_RTX),
11970 VOIDmode,
11971 modifier: modifier == EXPAND_SUM ? EXPAND_NORMAL : modifier,
11972 NULL, inner_reference_p: true);
11973
11974 if (MEM_P (orig_op0))
11975 {
11976 op0 = orig_op0;
11977
11978 /* Get a reference to just this component. */
11979 if (modifier == EXPAND_CONST_ADDRESS
11980 || modifier == EXPAND_SUM
11981 || modifier == EXPAND_INITIALIZER)
11982 op0 = adjust_address_nv (op0, mode, bytepos);
11983 else
11984 op0 = adjust_address (op0, mode, bytepos);
11985
11986 if (op0 == orig_op0)
11987 op0 = copy_rtx (op0);
11988
11989 set_mem_attributes (op0, treeop0, 0);
11990 if (REG_P (XEXP (op0, 0)))
11991 mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0));
11992
11993 MEM_VOLATILE_P (op0) |= volatilep;
11994 }
11995 }
11996 }
11997
11998 if (!op0)
11999 op0 = expand_expr_real (exp: treeop0, NULL_RTX, VOIDmode, modifier,
12000 NULL, inner_reference_p);
12001
12002 /* If the input and output modes are both the same, we are done. */
12003 if (mode == GET_MODE (op0))
12004 ;
12005 /* If neither mode is BLKmode, and both modes are the same size
12006 then we can use gen_lowpart. */
12007 else if (mode != BLKmode
12008 && GET_MODE (op0) != BLKmode
12009 && known_eq (GET_MODE_PRECISION (mode),
12010 GET_MODE_PRECISION (GET_MODE (op0)))
12011 && !COMPLEX_MODE_P (GET_MODE (op0)))
12012 {
12013 if (GET_CODE (op0) == SUBREG)
12014 op0 = force_reg (GET_MODE (op0), op0);
12015 temp = gen_lowpart_common (mode, op0);
12016 if (temp)
12017 op0 = temp;
12018 else
12019 {
12020 if (!REG_P (op0) && !MEM_P (op0))
12021 op0 = force_reg (GET_MODE (op0), op0);
12022 op0 = gen_lowpart (mode, op0);
12023 }
12024 }
12025 /* If both types are integral, convert from one mode to the other. */
12026 else if (INTEGRAL_TYPE_P (type) && INTEGRAL_TYPE_P (TREE_TYPE (treeop0)))
12027 op0 = convert_modes (mode, GET_MODE (op0), x: op0,
12028 TYPE_UNSIGNED (TREE_TYPE (treeop0)));
12029 /* If the output type is a bit-field type, do an extraction. */
12030 else if (reduce_bit_field)
12031 return extract_bit_field (op0, TYPE_PRECISION (type), 0,
12032 TYPE_UNSIGNED (type), NULL_RTX,
12033 mode, mode, false, NULL);
12034 /* As a last resort, spill op0 to memory, and reload it in a
12035 different mode. */
12036 else if (!MEM_P (op0))
12037 {
12038 /* If the operand is not a MEM, force it into memory. Since we
12039 are going to be changing the mode of the MEM, don't call
12040 force_const_mem for constants because we don't allow pool
12041 constants to change mode. */
12042 tree inner_type = TREE_TYPE (treeop0);
12043
12044 gcc_assert (!TREE_ADDRESSABLE (exp));
12045
12046 if (target == 0 || GET_MODE (target) != TYPE_MODE (inner_type))
12047 target
12048 = assign_stack_temp_for_type
12049 (TYPE_MODE (inner_type),
12050 GET_MODE_SIZE (TYPE_MODE (inner_type)), inner_type);
12051
12052 emit_move_insn (x: target, y: op0);
12053 op0 = target;
12054 }
12055
12056 /* If OP0 is (now) a MEM, we need to deal with alignment issues. If the
12057 output type is such that the operand is known to be aligned, indicate
12058 that it is. Otherwise, we need only be concerned about alignment for
12059 non-BLKmode results. */
12060 if (MEM_P (op0))
12061 {
12062 enum insn_code icode;
12063
12064 if (modifier != EXPAND_WRITE
12065 && modifier != EXPAND_MEMORY
12066 && !inner_reference_p
12067 && mode != BLKmode
12068 && MEM_ALIGN (op0) < GET_MODE_ALIGNMENT (mode))
12069 {
12070 /* If the target does have special handling for unaligned
12071 loads of mode then use them. */
12072 if ((icode = optab_handler (op: movmisalign_optab, mode))
12073 != CODE_FOR_nothing)
12074 {
12075 rtx reg;
12076
12077 op0 = adjust_address (op0, mode, 0);
12078 /* We've already validated the memory, and we're creating a
12079 new pseudo destination. The predicates really can't
12080 fail. */
12081 reg = gen_reg_rtx (mode);
12082
12083 /* Nor can the insn generator. */
12084 rtx_insn *insn = GEN_FCN (icode) (reg, op0);
12085 emit_insn (insn);
12086 return reg;
12087 }
12088 else if (STRICT_ALIGNMENT)
12089 {
12090 poly_uint64 mode_size = GET_MODE_SIZE (mode);
12091 poly_uint64 temp_size = mode_size;
12092 if (GET_MODE (op0) != BLKmode)
12093 temp_size = upper_bound (a: temp_size,
12094 b: GET_MODE_SIZE (GET_MODE (op0)));
12095 rtx new_rtx
12096 = assign_stack_temp_for_type (mode, temp_size, type);
12097 rtx new_with_op0_mode
12098 = adjust_address (new_rtx, GET_MODE (op0), 0);
12099
12100 gcc_assert (!TREE_ADDRESSABLE (exp));
12101
12102 if (GET_MODE (op0) == BLKmode)
12103 {
12104 rtx size_rtx = gen_int_mode (mode_size, Pmode);
12105 emit_block_move (x: new_with_op0_mode, y: op0, size: size_rtx,
12106 method: (modifier == EXPAND_STACK_PARM
12107 ? BLOCK_OP_CALL_PARM
12108 : BLOCK_OP_NORMAL));
12109 }
12110 else
12111 emit_move_insn (x: new_with_op0_mode, y: op0);
12112
12113 op0 = new_rtx;
12114 }
12115 }
12116
12117 op0 = adjust_address (op0, mode, 0);
12118 }
12119
12120 return op0;
12121
12122 case MODIFY_EXPR:
12123 {
12124 tree lhs = treeop0;
12125 tree rhs = treeop1;
12126 gcc_assert (ignore);
12127
12128 /* Check for |= or &= of a bitfield of size one into another bitfield
12129 of size 1. In this case, (unless we need the result of the
12130 assignment) we can do this more efficiently with a
12131 test followed by an assignment, if necessary.
12132
12133 ??? At this point, we can't get a BIT_FIELD_REF here. But if
12134 things change so we do, this code should be enhanced to
12135 support it. */
12136 if (TREE_CODE (lhs) == COMPONENT_REF
12137 && (TREE_CODE (rhs) == BIT_IOR_EXPR
12138 || TREE_CODE (rhs) == BIT_AND_EXPR)
12139 && TREE_OPERAND (rhs, 0) == lhs
12140 && TREE_CODE (TREE_OPERAND (rhs, 1)) == COMPONENT_REF
12141 && integer_onep (DECL_SIZE (TREE_OPERAND (lhs, 1)))
12142 && integer_onep (DECL_SIZE (TREE_OPERAND (TREE_OPERAND (rhs, 1), 1))))
12143 {
12144 rtx_code_label *label = gen_label_rtx ();
12145 int value = TREE_CODE (rhs) == BIT_IOR_EXPR;
12146 profile_probability prob = profile_probability::uninitialized ();
12147 if (value)
12148 jumpifnot (TREE_OPERAND (rhs, 1), label, prob);
12149 else
12150 jumpif (TREE_OPERAND (rhs, 1), label, prob);
12151 expand_assignment (to: lhs, from: build_int_cst (TREE_TYPE (rhs), value),
12152 nontemporal: false);
12153 do_pending_stack_adjust ();
12154 emit_label (label);
12155 return const0_rtx;
12156 }
12157
12158 expand_assignment (to: lhs, from: rhs, nontemporal: false);
12159 return const0_rtx;
12160 }
12161
12162 case ADDR_EXPR:
12163 return expand_expr_addr_expr (exp, target, tmode, modifier);
12164
12165 case REALPART_EXPR:
12166 op0 = expand_normal (exp: treeop0);
12167 return read_complex_part (cplx: op0, imag_p: false);
12168
12169 case IMAGPART_EXPR:
12170 op0 = expand_normal (exp: treeop0);
12171 return read_complex_part (cplx: op0, imag_p: true);
12172
12173 case RETURN_EXPR:
12174 case LABEL_EXPR:
12175 case GOTO_EXPR:
12176 case SWITCH_EXPR:
12177 case ASM_EXPR:
12178 /* Expanded in cfgexpand.cc. */
12179 gcc_unreachable ();
12180
12181 case TRY_CATCH_EXPR:
12182 case CATCH_EXPR:
12183 case EH_FILTER_EXPR:
12184 case TRY_FINALLY_EXPR:
12185 case EH_ELSE_EXPR:
12186 /* Lowered by tree-eh.cc. */
12187 gcc_unreachable ();
12188
12189 case WITH_CLEANUP_EXPR:
12190 case CLEANUP_POINT_EXPR:
12191 case TARGET_EXPR:
12192 case CASE_LABEL_EXPR:
12193 case VA_ARG_EXPR:
12194 case BIND_EXPR:
12195 case INIT_EXPR:
12196 case CONJ_EXPR:
12197 case COMPOUND_EXPR:
12198 case PREINCREMENT_EXPR:
12199 case PREDECREMENT_EXPR:
12200 case POSTINCREMENT_EXPR:
12201 case POSTDECREMENT_EXPR:
12202 case LOOP_EXPR:
12203 case EXIT_EXPR:
12204 case COMPOUND_LITERAL_EXPR:
12205 /* Lowered by gimplify.cc. */
12206 gcc_unreachable ();
12207
12208 case FDESC_EXPR:
12209 /* Function descriptors are not valid except for as
12210 initialization constants, and should not be expanded. */
12211 gcc_unreachable ();
12212
12213 case WITH_SIZE_EXPR:
12214 /* WITH_SIZE_EXPR expands to its first argument. The caller should
12215 have pulled out the size to use in whatever context it needed. */
12216 return expand_expr_real (exp: treeop0, target: original_target, tmode,
12217 modifier, alt_rtl, inner_reference_p);
12218
12219 default:
12220 return expand_expr_real_2 (ops: &ops, target, tmode, modifier);
12221 }
12222}
12223#undef EXTEND_BITINT
12224
12225/* Subroutine of above: reduce EXP to the precision of TYPE (in the
12226 signedness of TYPE), possibly returning the result in TARGET.
12227 TYPE is known to be a partial integer type. */
12228static rtx
12229reduce_to_bit_field_precision (rtx exp, rtx target, tree type)
12230{
12231 scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type);
12232 HOST_WIDE_INT prec = TYPE_PRECISION (type);
12233 gcc_assert ((GET_MODE (exp) == VOIDmode || GET_MODE (exp) == mode)
12234 && (!target || GET_MODE (target) == mode));
12235
12236 /* For constant values, reduce using wide_int_to_tree. */
12237 if (poly_int_rtx_p (x: exp))
12238 {
12239 auto value = wi::to_poly_wide (x: exp, mode);
12240 tree t = wide_int_to_tree (type, cst: value);
12241 return expand_expr (exp: t, target, VOIDmode, modifier: EXPAND_NORMAL);
12242 }
12243 else if (TYPE_UNSIGNED (type))
12244 {
12245 rtx mask = immed_wide_int_const
12246 (wi::mask (width: prec, negate_p: false, precision: GET_MODE_PRECISION (mode)), mode);
12247 return expand_and (mode, exp, mask, target);
12248 }
12249 else
12250 {
12251 int count = GET_MODE_PRECISION (mode) - prec;
12252 exp = expand_shift (LSHIFT_EXPR, mode, exp, count, target, 0);
12253 return expand_shift (RSHIFT_EXPR, mode, exp, count, target, 0);
12254 }
12255}
12256
12257/* Subroutine of above: returns true if OFFSET corresponds to an offset that
12258 when applied to the address of EXP produces an address known to be
12259 aligned more than BIGGEST_ALIGNMENT. */
12260
12261static bool
12262is_aligning_offset (const_tree offset, const_tree exp)
12263{
12264 /* Strip off any conversions. */
12265 while (CONVERT_EXPR_P (offset))
12266 offset = TREE_OPERAND (offset, 0);
12267
12268 /* We must now have a BIT_AND_EXPR with a constant that is one less than
12269 power of 2 and which is larger than BIGGEST_ALIGNMENT. */
12270 if (TREE_CODE (offset) != BIT_AND_EXPR
12271 || !tree_fits_uhwi_p (TREE_OPERAND (offset, 1))
12272 || compare_tree_int (TREE_OPERAND (offset, 1),
12273 BIGGEST_ALIGNMENT / BITS_PER_UNIT) <= 0
12274 || !pow2p_hwi (x: tree_to_uhwi (TREE_OPERAND (offset, 1)) + 1))
12275 return false;
12276
12277 /* Look at the first operand of BIT_AND_EXPR and strip any conversion.
12278 It must be NEGATE_EXPR. Then strip any more conversions. */
12279 offset = TREE_OPERAND (offset, 0);
12280 while (CONVERT_EXPR_P (offset))
12281 offset = TREE_OPERAND (offset, 0);
12282
12283 if (TREE_CODE (offset) != NEGATE_EXPR)
12284 return false;
12285
12286 offset = TREE_OPERAND (offset, 0);
12287 while (CONVERT_EXPR_P (offset))
12288 offset = TREE_OPERAND (offset, 0);
12289
12290 /* This must now be the address of EXP. */
12291 return TREE_CODE (offset) == ADDR_EXPR && TREE_OPERAND (offset, 0) == exp;
12292}
12293
12294/* Return a STRING_CST corresponding to ARG's constant initializer either
12295 if it's a string constant, or, when VALREP is set, any other constant,
12296 or null otherwise.
12297 On success, set *PTR_OFFSET to the (possibly non-constant) byte offset
12298 within the byte string that ARG is references. If nonnull set *MEM_SIZE
12299 to the size of the byte string. If nonnull, set *DECL to the constant
12300 declaration ARG refers to. */
12301
12302static tree
12303constant_byte_string (tree arg, tree *ptr_offset, tree *mem_size, tree *decl,
12304 bool valrep = false)
12305{
12306 tree dummy = NULL_TREE;
12307 if (!mem_size)
12308 mem_size = &dummy;
12309
12310 /* Store the type of the original expression before conversions
12311 via NOP_EXPR or POINTER_PLUS_EXPR to other types have been
12312 removed. */
12313 tree argtype = TREE_TYPE (arg);
12314
12315 tree array;
12316 STRIP_NOPS (arg);
12317
12318 /* Non-constant index into the character array in an ARRAY_REF
12319 expression or null. */
12320 tree varidx = NULL_TREE;
12321
12322 poly_int64 base_off = 0;
12323
12324 if (TREE_CODE (arg) == ADDR_EXPR)
12325 {
12326 arg = TREE_OPERAND (arg, 0);
12327 tree ref = arg;
12328 if (TREE_CODE (arg) == ARRAY_REF)
12329 {
12330 tree idx = TREE_OPERAND (arg, 1);
12331 if (TREE_CODE (idx) != INTEGER_CST)
12332 {
12333 /* From a pointer (but not array) argument extract the variable
12334 index to prevent get_addr_base_and_unit_offset() from failing
12335 due to it. Use it later to compute the non-constant offset
12336 into the string and return it to the caller. */
12337 varidx = idx;
12338 ref = TREE_OPERAND (arg, 0);
12339
12340 if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
12341 return NULL_TREE;
12342
12343 if (!integer_zerop (array_ref_low_bound (arg)))
12344 return NULL_TREE;
12345
12346 if (!integer_onep (array_ref_element_size (arg)))
12347 return NULL_TREE;
12348 }
12349 }
12350 array = get_addr_base_and_unit_offset (ref, &base_off);
12351 if (!array
12352 || (TREE_CODE (array) != VAR_DECL
12353 && TREE_CODE (array) != CONST_DECL
12354 && TREE_CODE (array) != STRING_CST))
12355 return NULL_TREE;
12356 }
12357 else if (TREE_CODE (arg) == PLUS_EXPR || TREE_CODE (arg) == POINTER_PLUS_EXPR)
12358 {
12359 tree arg0 = TREE_OPERAND (arg, 0);
12360 tree arg1 = TREE_OPERAND (arg, 1);
12361
12362 tree offset;
12363 tree str = string_constant (arg0, &offset, mem_size, decl);
12364 if (!str)
12365 {
12366 str = string_constant (arg1, &offset, mem_size, decl);
12367 arg1 = arg0;
12368 }
12369
12370 if (str)
12371 {
12372 /* Avoid pointers to arrays (see bug 86622). */
12373 if (POINTER_TYPE_P (TREE_TYPE (arg))
12374 && TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
12375 && !(decl && !*decl)
12376 && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
12377 && tree_fits_uhwi_p (*mem_size)
12378 && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
12379 return NULL_TREE;
12380
12381 tree type = TREE_TYPE (offset);
12382 arg1 = fold_convert (type, arg1);
12383 *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, arg1);
12384 return str;
12385 }
12386 return NULL_TREE;
12387 }
12388 else if (TREE_CODE (arg) == SSA_NAME)
12389 {
12390 gimple *stmt = SSA_NAME_DEF_STMT (arg);
12391 if (!is_gimple_assign (gs: stmt))
12392 return NULL_TREE;
12393
12394 tree rhs1 = gimple_assign_rhs1 (gs: stmt);
12395 tree_code code = gimple_assign_rhs_code (gs: stmt);
12396 if (code == ADDR_EXPR)
12397 return string_constant (rhs1, ptr_offset, mem_size, decl);
12398 else if (code != POINTER_PLUS_EXPR)
12399 return NULL_TREE;
12400
12401 tree offset;
12402 if (tree str = string_constant (rhs1, &offset, mem_size, decl))
12403 {
12404 /* Avoid pointers to arrays (see bug 86622). */
12405 if (POINTER_TYPE_P (TREE_TYPE (rhs1))
12406 && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
12407 && !(decl && !*decl)
12408 && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
12409 && tree_fits_uhwi_p (*mem_size)
12410 && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
12411 return NULL_TREE;
12412
12413 tree rhs2 = gimple_assign_rhs2 (gs: stmt);
12414 tree type = TREE_TYPE (offset);
12415 rhs2 = fold_convert (type, rhs2);
12416 *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
12417 return str;
12418 }
12419 return NULL_TREE;
12420 }
12421 else if (DECL_P (arg))
12422 array = arg;
12423 else
12424 return NULL_TREE;
12425
12426 tree offset = wide_int_to_tree (sizetype, cst: base_off);
12427 if (varidx)
12428 {
12429 if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE)
12430 return NULL_TREE;
12431
12432 gcc_assert (TREE_CODE (arg) == ARRAY_REF);
12433 tree chartype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg, 0)));
12434 if (TREE_CODE (chartype) != INTEGER_TYPE)
12435 return NULL;
12436
12437 offset = fold_convert (sizetype, varidx);
12438 }
12439
12440 if (TREE_CODE (array) == STRING_CST)
12441 {
12442 *ptr_offset = fold_convert (sizetype, offset);
12443 *mem_size = TYPE_SIZE_UNIT (TREE_TYPE (array));
12444 if (decl)
12445 *decl = NULL_TREE;
12446 gcc_checking_assert (tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (array)))
12447 >= TREE_STRING_LENGTH (array));
12448 return array;
12449 }
12450
12451 tree init = ctor_for_folding (array);
12452 if (!init || init == error_mark_node)
12453 return NULL_TREE;
12454
12455 if (valrep)
12456 {
12457 HOST_WIDE_INT cstoff;
12458 if (!base_off.is_constant (const_value: &cstoff))
12459 return NULL_TREE;
12460
12461 /* Check that the host and target are sane. */
12462 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
12463 return NULL_TREE;
12464
12465 HOST_WIDE_INT typesz = int_size_in_bytes (TREE_TYPE (init));
12466 if (typesz <= 0 || (int) typesz != typesz)
12467 return NULL_TREE;
12468
12469 HOST_WIDE_INT size = typesz;
12470 if (VAR_P (array)
12471 && DECL_SIZE_UNIT (array)
12472 && tree_fits_shwi_p (DECL_SIZE_UNIT (array)))
12473 {
12474 size = tree_to_shwi (DECL_SIZE_UNIT (array));
12475 gcc_checking_assert (size >= typesz);
12476 }
12477
12478 /* If value representation was requested convert the initializer
12479 for the whole array or object into a string of bytes forming
12480 its value representation and return it. */
12481 unsigned char *bytes = XNEWVEC (unsigned char, size);
12482 int r = native_encode_initializer (init, bytes, size);
12483 if (r < typesz)
12484 {
12485 XDELETEVEC (bytes);
12486 return NULL_TREE;
12487 }
12488
12489 if (r < size)
12490 memset (s: bytes + r, c: '\0', n: size - r);
12491
12492 const char *p = reinterpret_cast<const char *>(bytes);
12493 init = build_string_literal (size, p, char_type_node);
12494 init = TREE_OPERAND (init, 0);
12495 init = TREE_OPERAND (init, 0);
12496 XDELETE (bytes);
12497
12498 *mem_size = size_int (TREE_STRING_LENGTH (init));
12499 *ptr_offset = wide_int_to_tree (ssizetype, cst: base_off);
12500
12501 if (decl)
12502 *decl = array;
12503
12504 return init;
12505 }
12506
12507 if (TREE_CODE (init) == CONSTRUCTOR)
12508 {
12509 /* Convert the 64-bit constant offset to a wider type to avoid
12510 overflow and use it to obtain the initializer for the subobject
12511 it points into. */
12512 offset_int wioff;
12513 if (!base_off.is_constant (const_value: &wioff))
12514 return NULL_TREE;
12515
12516 wioff *= BITS_PER_UNIT;
12517 if (!wi::fits_uhwi_p (x: wioff))
12518 return NULL_TREE;
12519
12520 base_off = wioff.to_uhwi ();
12521 unsigned HOST_WIDE_INT fieldoff = 0;
12522 init = fold_ctor_reference (TREE_TYPE (arg), init, base_off, 0, array,
12523 &fieldoff);
12524 if (!init || init == error_mark_node)
12525 return NULL_TREE;
12526
12527 HOST_WIDE_INT cstoff;
12528 if (!base_off.is_constant (const_value: &cstoff))
12529 return NULL_TREE;
12530
12531 cstoff = (cstoff - fieldoff) / BITS_PER_UNIT;
12532 tree off = build_int_cst (sizetype, cstoff);
12533 if (varidx)
12534 offset = fold_build2 (PLUS_EXPR, TREE_TYPE (offset), offset, off);
12535 else
12536 offset = off;
12537 }
12538
12539 *ptr_offset = offset;
12540
12541 tree inittype = TREE_TYPE (init);
12542
12543 if (TREE_CODE (init) == INTEGER_CST
12544 && (TREE_CODE (TREE_TYPE (array)) == INTEGER_TYPE
12545 || TYPE_MAIN_VARIANT (inittype) == char_type_node))
12546 {
12547 /* Check that the host and target are sane. */
12548 if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
12549 return NULL_TREE;
12550
12551 /* For a reference to (address of) a single constant character,
12552 store the native representation of the character in CHARBUF.
12553 If the reference is to an element of an array or a member
12554 of a struct, only consider narrow characters until ctors
12555 for wide character arrays are transformed to STRING_CSTs
12556 like those for narrow arrays. */
12557 unsigned char charbuf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
12558 int len = native_encode_expr (init, charbuf, sizeof charbuf, off: 0);
12559 if (len > 0)
12560 {
12561 /* Construct a string literal with elements of INITTYPE and
12562 the representation above. Then strip
12563 the ADDR_EXPR (ARRAY_REF (...)) around the STRING_CST. */
12564 init = build_string_literal (len, (char *)charbuf, inittype);
12565 init = TREE_OPERAND (TREE_OPERAND (init, 0), 0);
12566 }
12567 }
12568
12569 tree initsize = TYPE_SIZE_UNIT (inittype);
12570
12571 if (TREE_CODE (init) == CONSTRUCTOR && initializer_zerop (init))
12572 {
12573 /* Fold an empty/zero constructor for an implicitly initialized
12574 object or subobject into the empty string. */
12575
12576 /* Determine the character type from that of the original
12577 expression. */
12578 tree chartype = argtype;
12579 if (POINTER_TYPE_P (chartype))
12580 chartype = TREE_TYPE (chartype);
12581 while (TREE_CODE (chartype) == ARRAY_TYPE)
12582 chartype = TREE_TYPE (chartype);
12583
12584 if (INTEGRAL_TYPE_P (chartype)
12585 && TYPE_PRECISION (chartype) == TYPE_PRECISION (char_type_node))
12586 {
12587 /* Convert a char array to an empty STRING_CST having an array
12588 of the expected type and size. */
12589 if (!initsize)
12590 initsize = integer_zero_node;
12591
12592 unsigned HOST_WIDE_INT size = tree_to_uhwi (initsize);
12593 if (size > (unsigned HOST_WIDE_INT) INT_MAX)
12594 return NULL_TREE;
12595
12596 init = build_string_literal (size, NULL, chartype, size);
12597 init = TREE_OPERAND (init, 0);
12598 init = TREE_OPERAND (init, 0);
12599
12600 *ptr_offset = integer_zero_node;
12601 }
12602 }
12603
12604 if (decl)
12605 *decl = array;
12606
12607 if (TREE_CODE (init) != STRING_CST)
12608 return NULL_TREE;
12609
12610 *mem_size = initsize;
12611
12612 gcc_checking_assert (tree_to_shwi (initsize) >= TREE_STRING_LENGTH (init));
12613
12614 return init;
12615}
12616
12617/* Return STRING_CST if an ARG corresponds to a string constant or zero
12618 if it doesn't. If we return nonzero, set *PTR_OFFSET to the (possibly
12619 non-constant) offset in bytes within the string that ARG is accessing.
12620 If MEM_SIZE is non-zero the storage size of the memory is returned.
12621 If DECL is non-zero the constant declaration is returned if available. */
12622
12623tree
12624string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
12625{
12626 return constant_byte_string (arg, ptr_offset, mem_size, decl, valrep: false);
12627}
12628
12629/* Similar to string_constant, return a STRING_CST corresponding
12630 to the value representation of the first argument if it's
12631 a constant. */
12632
12633tree
12634byte_representation (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
12635{
12636 return constant_byte_string (arg, ptr_offset, mem_size, decl, valrep: true);
12637}
12638
12639/* Optimize x % C1 == C2 for signed modulo if C1 is a power of two and C2
12640 is non-zero and C3 ((1<<(prec-1)) | (C1 - 1)):
12641 for C2 > 0 to x & C3 == C2
12642 for C2 < 0 to x & C3 == (C2 & C3). */
12643enum tree_code
12644maybe_optimize_pow2p_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
12645{
12646 gimple *stmt = get_def_for_expr (name: *arg0, code: TRUNC_MOD_EXPR);
12647 tree treeop0 = gimple_assign_rhs1 (gs: stmt);
12648 tree treeop1 = gimple_assign_rhs2 (gs: stmt);
12649 tree type = TREE_TYPE (*arg0);
12650 scalar_int_mode mode;
12651 if (!is_a <scalar_int_mode> (TYPE_MODE (type), result: &mode))
12652 return code;
12653 if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
12654 || TYPE_PRECISION (type) <= 1
12655 || TYPE_UNSIGNED (type)
12656 /* Signed x % c == 0 should have been optimized into unsigned modulo
12657 earlier. */
12658 || integer_zerop (*arg1)
12659 /* If c is known to be non-negative, modulo will be expanded as unsigned
12660 modulo. */
12661 || get_range_pos_neg (treeop0) == 1)
12662 return code;
12663
12664 /* x % c == d where d < 0 && d <= -c should be always false. */
12665 if (tree_int_cst_sgn (*arg1) == -1
12666 && -wi::to_widest (t: treeop1) >= wi::to_widest (t: *arg1))
12667 return code;
12668
12669 int prec = TYPE_PRECISION (type);
12670 wide_int w = wi::to_wide (t: treeop1) - 1;
12671 w |= wi::shifted_mask (start: 0, width: prec - 1, negate_p: true, precision: prec);
12672 tree c3 = wide_int_to_tree (type, cst: w);
12673 tree c4 = *arg1;
12674 if (tree_int_cst_sgn (*arg1) == -1)
12675 c4 = wide_int_to_tree (type, cst: w & wi::to_wide (t: *arg1));
12676
12677 rtx op0 = expand_normal (exp: treeop0);
12678 treeop0 = make_tree (TREE_TYPE (treeop0), op0);
12679
12680 bool speed_p = optimize_insn_for_speed_p ();
12681
12682 do_pending_stack_adjust ();
12683
12684 location_t loc = gimple_location (g: stmt);
12685 struct separate_ops ops;
12686 ops.code = TRUNC_MOD_EXPR;
12687 ops.location = loc;
12688 ops.type = TREE_TYPE (treeop0);
12689 ops.op0 = treeop0;
12690 ops.op1 = treeop1;
12691 ops.op2 = NULL_TREE;
12692 start_sequence ();
12693 rtx mor = expand_expr_real_2 (ops: &ops, NULL_RTX, TYPE_MODE (ops.type),
12694 modifier: EXPAND_NORMAL);
12695 rtx_insn *moinsns = get_insns ();
12696 end_sequence ();
12697
12698 unsigned mocost = seq_cost (moinsns, speed_p);
12699 mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
12700 mocost += rtx_cost (expand_normal (exp: *arg1), mode, EQ, 1, speed_p);
12701
12702 ops.code = BIT_AND_EXPR;
12703 ops.location = loc;
12704 ops.type = TREE_TYPE (treeop0);
12705 ops.op0 = treeop0;
12706 ops.op1 = c3;
12707 ops.op2 = NULL_TREE;
12708 start_sequence ();
12709 rtx mur = expand_expr_real_2 (ops: &ops, NULL_RTX, TYPE_MODE (ops.type),
12710 modifier: EXPAND_NORMAL);
12711 rtx_insn *muinsns = get_insns ();
12712 end_sequence ();
12713
12714 unsigned mucost = seq_cost (muinsns, speed_p);
12715 mucost += rtx_cost (mur, mode, EQ, 0, speed_p);
12716 mucost += rtx_cost (expand_normal (exp: c4), mode, EQ, 1, speed_p);
12717
12718 if (mocost <= mucost)
12719 {
12720 emit_insn (moinsns);
12721 *arg0 = make_tree (TREE_TYPE (*arg0), mor);
12722 return code;
12723 }
12724
12725 emit_insn (muinsns);
12726 *arg0 = make_tree (TREE_TYPE (*arg0), mur);
12727 *arg1 = c4;
12728 return code;
12729}
12730
12731/* Attempt to optimize unsigned (X % C1) == C2 (or (X % C1) != C2).
12732 If C1 is odd to:
12733 (X - C2) * C3 <= C4 (or >), where
12734 C3 is modular multiplicative inverse of C1 and 1<<prec and
12735 C4 is ((1<<prec) - 1) / C1 or ((1<<prec) - 1) / C1 - 1 (the latter
12736 if C2 > ((1<<prec) - 1) % C1).
12737 If C1 is even, S = ctz (C1) and C2 is 0, use
12738 ((X * C3) r>> S) <= C4, where C3 is modular multiplicative
12739 inverse of C1>>S and 1<<prec and C4 is (((1<<prec) - 1) / (C1>>S)) >> S.
12740
12741 For signed (X % C1) == 0 if C1 is odd to (all operations in it
12742 unsigned):
12743 (X * C3) + C4 <= 2 * C4, where
12744 C3 is modular multiplicative inverse of (unsigned) C1 and 1<<prec and
12745 C4 is ((1<<(prec - 1) - 1) / C1).
12746 If C1 is even, S = ctz(C1), use
12747 ((X * C3) + C4) r>> S <= (C4 >> (S - 1))
12748 where C3 is modular multiplicative inverse of (unsigned)(C1>>S) and 1<<prec
12749 and C4 is ((1<<(prec - 1) - 1) / (C1>>S)) & (-1<<S).
12750
12751 See the Hacker's Delight book, section 10-17. */
12752enum tree_code
12753maybe_optimize_mod_cmp (enum tree_code code, tree *arg0, tree *arg1)
12754{
12755 gcc_checking_assert (code == EQ_EXPR || code == NE_EXPR);
12756 gcc_checking_assert (TREE_CODE (*arg1) == INTEGER_CST);
12757
12758 if (optimize < 2)
12759 return code;
12760
12761 gimple *stmt = get_def_for_expr (name: *arg0, code: TRUNC_MOD_EXPR);
12762 if (stmt == NULL)
12763 return code;
12764
12765 tree treeop0 = gimple_assign_rhs1 (gs: stmt);
12766 tree treeop1 = gimple_assign_rhs2 (gs: stmt);
12767 if (TREE_CODE (treeop0) != SSA_NAME
12768 || TREE_CODE (treeop1) != INTEGER_CST
12769 /* Don't optimize the undefined behavior case x % 0;
12770 x % 1 should have been optimized into zero, punt if
12771 it makes it here for whatever reason;
12772 x % -c should have been optimized into x % c. */
12773 || compare_tree_int (treeop1, 2) <= 0
12774 /* Likewise x % c == d where d >= c should be always false. */
12775 || tree_int_cst_le (t1: treeop1, t2: *arg1))
12776 return code;
12777
12778 /* Unsigned x % pow2 is handled right already, for signed
12779 modulo handle it in maybe_optimize_pow2p_mod_cmp. */
12780 if (integer_pow2p (treeop1))
12781 return maybe_optimize_pow2p_mod_cmp (code, arg0, arg1);
12782
12783 tree type = TREE_TYPE (*arg0);
12784 scalar_int_mode mode;
12785 if (!is_a <scalar_int_mode> (TYPE_MODE (type), result: &mode))
12786 return code;
12787 if (GET_MODE_BITSIZE (mode) != TYPE_PRECISION (type)
12788 || TYPE_PRECISION (type) <= 1)
12789 return code;
12790
12791 signop sgn = UNSIGNED;
12792 /* If both operands are known to have the sign bit clear, handle
12793 even the signed modulo case as unsigned. treeop1 is always
12794 positive >= 2, checked above. */
12795 if (!TYPE_UNSIGNED (type) && get_range_pos_neg (treeop0) != 1)
12796 sgn = SIGNED;
12797
12798 if (!TYPE_UNSIGNED (type))
12799 {
12800 if (tree_int_cst_sgn (*arg1) == -1)
12801 return code;
12802 type = unsigned_type_for (type);
12803 if (!type || TYPE_MODE (type) != TYPE_MODE (TREE_TYPE (*arg0)))
12804 return code;
12805 }
12806
12807 int prec = TYPE_PRECISION (type);
12808 wide_int w = wi::to_wide (t: treeop1);
12809 int shift = wi::ctz (w);
12810 /* Unsigned (X % C1) == C2 is equivalent to (X - C2) % C1 == 0 if
12811 C2 <= -1U % C1, because for any Z >= 0U - C2 in that case (Z % C1) != 0.
12812 If C1 is odd, we can handle all cases by subtracting
12813 C4 below. We could handle even the even C1 and C2 > -1U % C1 cases
12814 e.g. by testing for overflow on the subtraction, punt on that for now
12815 though. */
12816 if ((sgn == SIGNED || shift) && !integer_zerop (*arg1))
12817 {
12818 if (sgn == SIGNED)
12819 return code;
12820 wide_int x = wi::umod_trunc (x: wi::mask (width: prec, negate_p: false, precision: prec), y: w);
12821 if (wi::gtu_p (x: wi::to_wide (t: *arg1), y: x))
12822 return code;
12823 }
12824
12825 imm_use_iterator imm_iter;
12826 use_operand_p use_p;
12827 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, treeop0)
12828 {
12829 gimple *use_stmt = USE_STMT (use_p);
12830 /* Punt if treeop0 is used in the same bb in a division
12831 or another modulo with the same divisor. We should expect
12832 the division and modulo combined together. */
12833 if (use_stmt == stmt
12834 || gimple_bb (g: use_stmt) != gimple_bb (g: stmt))
12835 continue;
12836 if (!is_gimple_assign (gs: use_stmt)
12837 || (gimple_assign_rhs_code (gs: use_stmt) != TRUNC_DIV_EXPR
12838 && gimple_assign_rhs_code (gs: use_stmt) != TRUNC_MOD_EXPR))
12839 continue;
12840 if (gimple_assign_rhs1 (gs: use_stmt) != treeop0
12841 || !operand_equal_p (gimple_assign_rhs2 (gs: use_stmt), treeop1, flags: 0))
12842 continue;
12843 return code;
12844 }
12845
12846 w = wi::lrshift (x: w, y: shift);
12847 wide_int a = wide_int::from (x: w, precision: prec + 1, sgn: UNSIGNED);
12848 wide_int b = wi::shifted_mask (start: prec, width: 1, negate_p: false, precision: prec + 1);
12849 wide_int m = wide_int::from (x: wi::mod_inv (a, b), precision: prec, sgn: UNSIGNED);
12850 tree c3 = wide_int_to_tree (type, cst: m);
12851 tree c5 = NULL_TREE;
12852 wide_int d, e;
12853 if (sgn == UNSIGNED)
12854 {
12855 d = wi::divmod_trunc (x: wi::mask (width: prec, negate_p: false, precision: prec), y: w, sgn: UNSIGNED, remainder_ptr: &e);
12856 /* Use <= floor ((1<<prec) - 1) / C1 only if C2 <= ((1<<prec) - 1) % C1,
12857 otherwise use < or subtract one from C4. E.g. for
12858 x % 3U == 0 we transform this into x * 0xaaaaaaab <= 0x55555555, but
12859 x % 3U == 1 already needs to be
12860 (x - 1) * 0xaaaaaaabU <= 0x55555554. */
12861 if (!shift && wi::gtu_p (x: wi::to_wide (t: *arg1), y: e))
12862 d -= 1;
12863 if (shift)
12864 d = wi::lrshift (x: d, y: shift);
12865 }
12866 else
12867 {
12868 e = wi::udiv_trunc (x: wi::mask (width: prec - 1, negate_p: false, precision: prec), y: w);
12869 if (!shift)
12870 d = wi::lshift (x: e, y: 1);
12871 else
12872 {
12873 e = wi::bit_and (x: e, y: wi::mask (width: shift, negate_p: true, precision: prec));
12874 d = wi::lrshift (x: e, y: shift - 1);
12875 }
12876 c5 = wide_int_to_tree (type, cst: e);
12877 }
12878 tree c4 = wide_int_to_tree (type, cst: d);
12879
12880 rtx op0 = expand_normal (exp: treeop0);
12881 treeop0 = make_tree (TREE_TYPE (treeop0), op0);
12882
12883 bool speed_p = optimize_insn_for_speed_p ();
12884
12885 do_pending_stack_adjust ();
12886
12887 location_t loc = gimple_location (g: stmt);
12888 struct separate_ops ops;
12889 ops.code = TRUNC_MOD_EXPR;
12890 ops.location = loc;
12891 ops.type = TREE_TYPE (treeop0);
12892 ops.op0 = treeop0;
12893 ops.op1 = treeop1;
12894 ops.op2 = NULL_TREE;
12895 start_sequence ();
12896 rtx mor = expand_expr_real_2 (ops: &ops, NULL_RTX, TYPE_MODE (ops.type),
12897 modifier: EXPAND_NORMAL);
12898 rtx_insn *moinsns = get_insns ();
12899 end_sequence ();
12900
12901 unsigned mocost = seq_cost (moinsns, speed_p);
12902 mocost += rtx_cost (mor, mode, EQ, 0, speed_p);
12903 mocost += rtx_cost (expand_normal (exp: *arg1), mode, EQ, 1, speed_p);
12904
12905 tree t = fold_convert_loc (loc, type, treeop0);
12906 if (!integer_zerop (*arg1))
12907 t = fold_build2_loc (loc, MINUS_EXPR, type, t, fold_convert (type, *arg1));
12908 t = fold_build2_loc (loc, MULT_EXPR, type, t, c3);
12909 if (sgn == SIGNED)
12910 t = fold_build2_loc (loc, PLUS_EXPR, type, t, c5);
12911 if (shift)
12912 {
12913 tree s = build_int_cst (NULL_TREE, shift);
12914 t = fold_build2_loc (loc, RROTATE_EXPR, type, t, s);
12915 }
12916
12917 start_sequence ();
12918 rtx mur = expand_normal (exp: t);
12919 rtx_insn *muinsns = get_insns ();
12920 end_sequence ();
12921
12922 unsigned mucost = seq_cost (muinsns, speed_p);
12923 mucost += rtx_cost (mur, mode, LE, 0, speed_p);
12924 mucost += rtx_cost (expand_normal (exp: c4), mode, LE, 1, speed_p);
12925
12926 if (mocost <= mucost)
12927 {
12928 emit_insn (moinsns);
12929 *arg0 = make_tree (TREE_TYPE (*arg0), mor);
12930 return code;
12931 }
12932
12933 emit_insn (muinsns);
12934 *arg0 = make_tree (type, mur);
12935 *arg1 = c4;
12936 return code == EQ_EXPR ? LE_EXPR : GT_EXPR;
12937}
12938
12939/* Optimize x - y < 0 into x < 0 if x - y has undefined overflow. */
12940
12941void
12942maybe_optimize_sub_cmp_0 (enum tree_code code, tree *arg0, tree *arg1)
12943{
12944 gcc_checking_assert (code == GT_EXPR || code == GE_EXPR
12945 || code == LT_EXPR || code == LE_EXPR);
12946 gcc_checking_assert (integer_zerop (*arg1));
12947
12948 if (!optimize)
12949 return;
12950
12951 gimple *stmt = get_def_for_expr (name: *arg0, code: MINUS_EXPR);
12952 if (stmt == NULL)
12953 return;
12954
12955 tree treeop0 = gimple_assign_rhs1 (gs: stmt);
12956 tree treeop1 = gimple_assign_rhs2 (gs: stmt);
12957 if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (treeop0)))
12958 return;
12959
12960 if (issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_COMPARISON))
12961 warning_at (gimple_location (g: stmt), OPT_Wstrict_overflow,
12962 "assuming signed overflow does not occur when "
12963 "simplifying %<X - Y %s 0%> to %<X %s Y%>",
12964 op_symbol_code (code), op_symbol_code (code));
12965
12966 *arg0 = treeop0;
12967 *arg1 = treeop1;
12968}
12969
12970
12971/* Expand CODE with arguments INNER & (1<<BITNUM) and 0 that represents
12972 a single bit equality/inequality test, returns where the result is located. */
12973
12974static rtx
12975expand_single_bit_test (location_t loc, enum tree_code code,
12976 tree inner, int bitnum,
12977 tree result_type, rtx target,
12978 machine_mode mode)
12979{
12980 gcc_assert (code == NE_EXPR || code == EQ_EXPR);
12981
12982 tree type = TREE_TYPE (inner);
12983 scalar_int_mode operand_mode = SCALAR_INT_TYPE_MODE (type);
12984 int ops_unsigned;
12985 tree signed_type, unsigned_type, intermediate_type;
12986 gimple *inner_def;
12987
12988 /* First, see if we can fold the single bit test into a sign-bit
12989 test. */
12990 if (bitnum == TYPE_PRECISION (type) - 1
12991 && type_has_mode_precision_p (t: type))
12992 {
12993 tree stype = signed_type_for (type);
12994 tree tmp = fold_build2_loc (loc, code == EQ_EXPR ? GE_EXPR : LT_EXPR,
12995 result_type,
12996 fold_convert_loc (loc, stype, inner),
12997 build_int_cst (stype, 0));
12998 return expand_expr (exp: tmp, target, VOIDmode, modifier: EXPAND_NORMAL);
12999 }
13000
13001 /* Otherwise we have (A & C) != 0 where C is a single bit,
13002 convert that into ((A >> C2) & 1). Where C2 = log2(C).
13003 Similarly for (A & C) == 0. */
13004
13005 /* If INNER is a right shift of a constant and it plus BITNUM does
13006 not overflow, adjust BITNUM and INNER. */
13007 if ((inner_def = get_def_for_expr (name: inner, code: RSHIFT_EXPR))
13008 && TREE_CODE (gimple_assign_rhs2 (inner_def)) == INTEGER_CST
13009 && bitnum < TYPE_PRECISION (type)
13010 && wi::ltu_p (x: wi::to_wide (t: gimple_assign_rhs2 (gs: inner_def)),
13011 TYPE_PRECISION (type) - bitnum))
13012 {
13013 bitnum += tree_to_uhwi (gimple_assign_rhs2 (gs: inner_def));
13014 inner = gimple_assign_rhs1 (gs: inner_def);
13015 }
13016
13017 /* If we are going to be able to omit the AND below, we must do our
13018 operations as unsigned. If we must use the AND, we have a choice.
13019 Normally unsigned is faster, but for some machines signed is. */
13020 ops_unsigned = (load_extend_op (mode: operand_mode) == SIGN_EXTEND
13021 && !flag_syntax_only) ? 0 : 1;
13022
13023 signed_type = lang_hooks.types.type_for_mode (operand_mode, 0);
13024 unsigned_type = lang_hooks.types.type_for_mode (operand_mode, 1);
13025 intermediate_type = ops_unsigned ? unsigned_type : signed_type;
13026 inner = fold_convert_loc (loc, intermediate_type, inner);
13027
13028 rtx inner0 = expand_expr (exp: inner, NULL_RTX, VOIDmode, modifier: EXPAND_NORMAL);
13029
13030 if (CONST_SCALAR_INT_P (inner0))
13031 {
13032 wide_int t = rtx_mode_t (inner0, operand_mode);
13033 bool setp = (wi::lrshift (x: t, y: bitnum) & 1) != 0;
13034 return (setp ^ (code == EQ_EXPR)) ? const1_rtx : const0_rtx;
13035 }
13036 int bitpos = bitnum;
13037
13038 if (BYTES_BIG_ENDIAN)
13039 bitpos = GET_MODE_BITSIZE (mode: operand_mode) - 1 - bitpos;
13040
13041 inner0 = extract_bit_field (inner0, 1, bitpos, 1, target,
13042 operand_mode, mode, 0, NULL);
13043
13044 if (code == EQ_EXPR)
13045 inner0 = expand_binop (GET_MODE (inner0), xor_optab, inner0, const1_rtx,
13046 NULL_RTX, 1, OPTAB_LIB_WIDEN);
13047 if (GET_MODE (inner0) != mode)
13048 {
13049 rtx t = gen_reg_rtx (mode);
13050 convert_move (to: t, from: inner0, unsignedp: 0);
13051 return t;
13052 }
13053 return inner0;
13054}
13055
13056/* Generate code to calculate OPS, and exploded expression
13057 using a store-flag instruction and return an rtx for the result.
13058 OPS reflects a comparison.
13059
13060 If TARGET is nonzero, store the result there if convenient.
13061
13062 Return zero if there is no suitable set-flag instruction
13063 available on this machine.
13064
13065 Once expand_expr has been called on the arguments of the comparison,
13066 we are committed to doing the store flag, since it is not safe to
13067 re-evaluate the expression. We emit the store-flag insn by calling
13068 emit_store_flag, but only expand the arguments if we have a reason
13069 to believe that emit_store_flag will be successful. If we think that
13070 it will, but it isn't, we have to simulate the store-flag with a
13071 set/jump/set sequence. */
13072
13073static rtx
13074do_store_flag (sepops ops, rtx target, machine_mode mode)
13075{
13076 enum rtx_code code;
13077 tree arg0, arg1, type;
13078 machine_mode operand_mode;
13079 int unsignedp;
13080 rtx op0, op1;
13081 rtx subtarget = target;
13082 location_t loc = ops->location;
13083
13084 arg0 = ops->op0;
13085 arg1 = ops->op1;
13086
13087 /* Don't crash if the comparison was erroneous. */
13088 if (arg0 == error_mark_node || arg1 == error_mark_node)
13089 return const0_rtx;
13090
13091 type = TREE_TYPE (arg0);
13092 operand_mode = TYPE_MODE (type);
13093 unsignedp = TYPE_UNSIGNED (type);
13094
13095 /* We won't bother with BLKmode store-flag operations because it would mean
13096 passing a lot of information to emit_store_flag. */
13097 if (operand_mode == BLKmode)
13098 return 0;
13099
13100 /* We won't bother with store-flag operations involving function pointers
13101 when function pointers must be canonicalized before comparisons. */
13102 if (targetm.have_canonicalize_funcptr_for_compare ()
13103 && ((POINTER_TYPE_P (TREE_TYPE (arg0))
13104 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg0))))
13105 || (POINTER_TYPE_P (TREE_TYPE (arg1))
13106 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (arg1))))))
13107 return 0;
13108
13109 STRIP_NOPS (arg0);
13110 STRIP_NOPS (arg1);
13111
13112 /* For vector typed comparisons emit code to generate the desired
13113 all-ones or all-zeros mask. */
13114 if (VECTOR_TYPE_P (ops->type))
13115 {
13116 tree ifexp = build2 (ops->code, ops->type, arg0, arg1);
13117 if (VECTOR_BOOLEAN_TYPE_P (ops->type)
13118 && expand_vec_cmp_expr_p (TREE_TYPE (arg0), ops->type, ops->code))
13119 return expand_vec_cmp_expr (ops->type, ifexp, target);
13120 else
13121 gcc_unreachable ();
13122 }
13123
13124 /* Optimize (x % C1) == C2 or (x % C1) != C2 if it is beneficial
13125 into (x - C2) * C3 < C4. */
13126 if ((ops->code == EQ_EXPR || ops->code == NE_EXPR)
13127 && TREE_CODE (arg0) == SSA_NAME
13128 && TREE_CODE (arg1) == INTEGER_CST)
13129 {
13130 enum tree_code new_code = maybe_optimize_mod_cmp (code: ops->code,
13131 arg0: &arg0, arg1: &arg1);
13132 if (new_code != ops->code)
13133 {
13134 struct separate_ops nops = *ops;
13135 nops.code = ops->code = new_code;
13136 nops.op0 = arg0;
13137 nops.op1 = arg1;
13138 nops.type = TREE_TYPE (arg0);
13139 return do_store_flag (ops: &nops, target, mode);
13140 }
13141 }
13142
13143 /* Optimize (x - y) < 0 into x < y if x - y has undefined overflow. */
13144 if (!unsignedp
13145 && (ops->code == LT_EXPR || ops->code == LE_EXPR
13146 || ops->code == GT_EXPR || ops->code == GE_EXPR)
13147 && integer_zerop (arg1)
13148 && TREE_CODE (arg0) == SSA_NAME)
13149 maybe_optimize_sub_cmp_0 (code: ops->code, arg0: &arg0, arg1: &arg1);
13150
13151 /* Get the rtx comparison code to use. We know that EXP is a comparison
13152 operation of some type. Some comparisons against 1 and -1 can be
13153 converted to comparisons with zero. Do so here so that the tests
13154 below will be aware that we have a comparison with zero. These
13155 tests will not catch constants in the first operand, but constants
13156 are rarely passed as the first operand. */
13157
13158 switch (ops->code)
13159 {
13160 case EQ_EXPR:
13161 code = EQ;
13162 break;
13163 case NE_EXPR:
13164 code = NE;
13165 break;
13166 case LT_EXPR:
13167 if (integer_onep (arg1))
13168 arg1 = integer_zero_node, code = unsignedp ? LEU : LE;
13169 else
13170 code = unsignedp ? LTU : LT;
13171 break;
13172 case LE_EXPR:
13173 if (! unsignedp && integer_all_onesp (arg1))
13174 arg1 = integer_zero_node, code = LT;
13175 else
13176 code = unsignedp ? LEU : LE;
13177 break;
13178 case GT_EXPR:
13179 if (! unsignedp && integer_all_onesp (arg1))
13180 arg1 = integer_zero_node, code = GE;
13181 else
13182 code = unsignedp ? GTU : GT;
13183 break;
13184 case GE_EXPR:
13185 if (integer_onep (arg1))
13186 arg1 = integer_zero_node, code = unsignedp ? GTU : GT;
13187 else
13188 code = unsignedp ? GEU : GE;
13189 break;
13190
13191 case UNORDERED_EXPR:
13192 code = UNORDERED;
13193 break;
13194 case ORDERED_EXPR:
13195 code = ORDERED;
13196 break;
13197 case UNLT_EXPR:
13198 code = UNLT;
13199 break;
13200 case UNLE_EXPR:
13201 code = UNLE;
13202 break;
13203 case UNGT_EXPR:
13204 code = UNGT;
13205 break;
13206 case UNGE_EXPR:
13207 code = UNGE;
13208 break;
13209 case UNEQ_EXPR:
13210 code = UNEQ;
13211 break;
13212 case LTGT_EXPR:
13213 code = LTGT;
13214 break;
13215
13216 default:
13217 gcc_unreachable ();
13218 }
13219
13220 /* Put a constant second. */
13221 if (TREE_CODE (arg0) == REAL_CST || TREE_CODE (arg0) == INTEGER_CST
13222 || TREE_CODE (arg0) == FIXED_CST)
13223 {
13224 std::swap (a&: arg0, b&: arg1);
13225 code = swap_condition (code);
13226 }
13227
13228 /* If this is an equality or inequality test of a single bit, we can
13229 do this by shifting the bit being tested to the low-order bit and
13230 masking the result with the constant 1. If the condition was EQ,
13231 we xor it with 1. This does not require an scc insn and is faster
13232 than an scc insn even if we have it. */
13233
13234 if ((code == NE || code == EQ)
13235 && (integer_zerop (arg1)
13236 || integer_pow2p (arg1))
13237 && (TYPE_PRECISION (ops->type) != 1 || TYPE_UNSIGNED (ops->type)))
13238 {
13239 tree narg0 = arg0;
13240 wide_int nz = tree_nonzero_bits (narg0);
13241 gimple *srcstmt = get_def_for_expr (name: narg0, code: BIT_AND_EXPR);
13242 /* If the defining statement was (x & POW2), then use that instead of
13243 the non-zero bits. */
13244 if (srcstmt && integer_pow2p (gimple_assign_rhs2 (gs: srcstmt)))
13245 {
13246 nz = wi::to_wide (t: gimple_assign_rhs2 (gs: srcstmt));
13247 narg0 = gimple_assign_rhs1 (gs: srcstmt);
13248 }
13249
13250 if (wi::popcount (nz) == 1
13251 && (integer_zerop (arg1)
13252 || wi::to_wide (t: arg1) == nz))
13253 {
13254 int bitnum = wi::exact_log2 (nz);
13255 enum tree_code tcode = EQ_EXPR;
13256 if ((code == NE) ^ !integer_zerop (arg1))
13257 tcode = NE_EXPR;
13258
13259 type = lang_hooks.types.type_for_mode (mode, unsignedp);
13260 return expand_single_bit_test (loc, code: tcode,
13261 inner: narg0,
13262 bitnum, result_type: type, target, mode);
13263 }
13264 }
13265
13266
13267 if (! get_subtarget (x: target)
13268 || GET_MODE (subtarget) != operand_mode)
13269 subtarget = 0;
13270
13271 expand_operands (exp0: arg0, exp1: arg1, target: subtarget, op0: &op0, op1: &op1, modifier: EXPAND_NORMAL);
13272
13273 if (target == 0)
13274 target = gen_reg_rtx (mode);
13275
13276 /* Try a cstore if possible. */
13277 return emit_store_flag_force (target, code, op0, op1,
13278 operand_mode, unsignedp,
13279 (TYPE_PRECISION (ops->type) == 1
13280 && !TYPE_UNSIGNED (ops->type)) ? -1 : 1);
13281}
13282
13283/* Attempt to generate a casesi instruction. Returns true if successful,
13284 false otherwise (i.e. if there is no casesi instruction).
13285
13286 DEFAULT_PROBABILITY is the probability of jumping to the default
13287 label. */
13288bool
13289try_casesi (tree index_type, tree index_expr, tree minval, tree range,
13290 rtx table_label, rtx default_label, rtx fallback_label,
13291 profile_probability default_probability)
13292{
13293 class expand_operand ops[5];
13294 scalar_int_mode index_mode = SImode;
13295 rtx op1, op2, index;
13296
13297 if (! targetm.have_casesi ())
13298 return false;
13299
13300 /* The index must be some form of integer. Convert it to SImode. */
13301 scalar_int_mode omode = SCALAR_INT_TYPE_MODE (index_type);
13302 if (GET_MODE_BITSIZE (mode: omode) > GET_MODE_BITSIZE (mode: index_mode))
13303 {
13304 rtx rangertx = expand_normal (exp: range);
13305
13306 /* We must handle the endpoints in the original mode. */
13307 index_expr = build2 (MINUS_EXPR, index_type,
13308 index_expr, minval);
13309 minval = integer_zero_node;
13310 index = expand_normal (exp: index_expr);
13311 if (default_label)
13312 emit_cmp_and_jump_insns (rangertx, index, LTU, NULL_RTX,
13313 omode, 1, default_label,
13314 prob: default_probability);
13315 /* Now we can safely truncate. */
13316 index = convert_to_mode (mode: index_mode, x: index, unsignedp: 0);
13317 }
13318 else
13319 {
13320 if (omode != index_mode)
13321 {
13322 index_type = lang_hooks.types.type_for_mode (index_mode, 0);
13323 index_expr = fold_convert (index_type, index_expr);
13324 }
13325
13326 index = expand_normal (exp: index_expr);
13327 }
13328
13329 do_pending_stack_adjust ();
13330
13331 op1 = expand_normal (exp: minval);
13332 op2 = expand_normal (exp: range);
13333
13334 create_input_operand (op: &ops[0], value: index, mode: index_mode);
13335 create_convert_operand_from_type (op: &ops[1], value: op1, TREE_TYPE (minval));
13336 create_convert_operand_from_type (op: &ops[2], value: op2, TREE_TYPE (range));
13337 create_fixed_operand (op: &ops[3], x: table_label);
13338 create_fixed_operand (op: &ops[4], x: (default_label
13339 ? default_label
13340 : fallback_label));
13341 expand_jump_insn (icode: targetm.code_for_casesi, nops: 5, ops);
13342 return true;
13343}
13344
13345/* Attempt to generate a tablejump instruction; same concept. */
13346/* Subroutine of the next function.
13347
13348 INDEX is the value being switched on, with the lowest value
13349 in the table already subtracted.
13350 MODE is its expected mode (needed if INDEX is constant).
13351 RANGE is the length of the jump table.
13352 TABLE_LABEL is a CODE_LABEL rtx for the table itself.
13353
13354 DEFAULT_LABEL is a CODE_LABEL rtx to jump to if the
13355 index value is out of range.
13356 DEFAULT_PROBABILITY is the probability of jumping to
13357 the default label. */
13358
13359static void
13360do_tablejump (rtx index, machine_mode mode, rtx range, rtx table_label,
13361 rtx default_label, profile_probability default_probability)
13362{
13363 rtx temp, vector;
13364
13365 if (INTVAL (range) > cfun->cfg->max_jumptable_ents)
13366 cfun->cfg->max_jumptable_ents = INTVAL (range);
13367
13368 /* Do an unsigned comparison (in the proper mode) between the index
13369 expression and the value which represents the length of the range.
13370 Since we just finished subtracting the lower bound of the range
13371 from the index expression, this comparison allows us to simultaneously
13372 check that the original index expression value is both greater than
13373 or equal to the minimum value of the range and less than or equal to
13374 the maximum value of the range. */
13375
13376 if (default_label)
13377 emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
13378 default_label, prob: default_probability);
13379
13380 /* If index is in range, it must fit in Pmode.
13381 Convert to Pmode so we can index with it. */
13382 if (mode != Pmode)
13383 {
13384 unsigned int width;
13385
13386 /* We know the value of INDEX is between 0 and RANGE. If we have a
13387 sign-extended subreg, and RANGE does not have the sign bit set, then
13388 we have a value that is valid for both sign and zero extension. In
13389 this case, we get better code if we sign extend. */
13390 if (GET_CODE (index) == SUBREG
13391 && SUBREG_PROMOTED_VAR_P (index)
13392 && SUBREG_PROMOTED_SIGNED_P (index)
13393 && ((width = GET_MODE_PRECISION (mode: as_a <scalar_int_mode> (m: mode)))
13394 <= HOST_BITS_PER_WIDE_INT)
13395 && ! (UINTVAL (range) & (HOST_WIDE_INT_1U << (width - 1))))
13396 index = convert_to_mode (Pmode, x: index, unsignedp: 0);
13397 else
13398 index = convert_to_mode (Pmode, x: index, unsignedp: 1);
13399 }
13400
13401 /* Don't let a MEM slip through, because then INDEX that comes
13402 out of PIC_CASE_VECTOR_ADDRESS won't be a valid address,
13403 and break_out_memory_refs will go to work on it and mess it up. */
13404#ifdef PIC_CASE_VECTOR_ADDRESS
13405 if (flag_pic && !REG_P (index))
13406 index = copy_to_mode_reg (Pmode, index);
13407#endif
13408
13409 /* ??? The only correct use of CASE_VECTOR_MODE is the one inside the
13410 GET_MODE_SIZE, because this indicates how large insns are. The other
13411 uses should all be Pmode, because they are addresses. This code
13412 could fail if addresses and insns are not the same size. */
13413 index = simplify_gen_binary (code: MULT, Pmode, op0: index,
13414 op1: gen_int_mode (GET_MODE_SIZE (CASE_VECTOR_MODE),
13415 Pmode));
13416 index = simplify_gen_binary (code: PLUS, Pmode, op0: index,
13417 gen_rtx_LABEL_REF (Pmode, table_label));
13418
13419#ifdef PIC_CASE_VECTOR_ADDRESS
13420 if (flag_pic)
13421 index = PIC_CASE_VECTOR_ADDRESS (index);
13422 else
13423#endif
13424 index = memory_address (CASE_VECTOR_MODE, index);
13425 temp = gen_reg_rtx (CASE_VECTOR_MODE);
13426 vector = gen_const_mem (CASE_VECTOR_MODE, index);
13427 convert_move (to: temp, from: vector, unsignedp: 0);
13428
13429 emit_jump_insn (targetm.gen_tablejump (temp, table_label));
13430
13431 /* If we are generating PIC code or if the table is PC-relative, the
13432 table and JUMP_INSN must be adjacent, so don't output a BARRIER. */
13433 if (! CASE_VECTOR_PC_RELATIVE && ! flag_pic)
13434 emit_barrier ();
13435}
13436
13437bool
13438try_tablejump (tree index_type, tree index_expr, tree minval, tree range,
13439 rtx table_label, rtx default_label,
13440 profile_probability default_probability)
13441{
13442 rtx index;
13443
13444 if (! targetm.have_tablejump ())
13445 return false;
13446
13447 index_expr = fold_build2 (MINUS_EXPR, index_type,
13448 fold_convert (index_type, index_expr),
13449 fold_convert (index_type, minval));
13450 index = expand_normal (exp: index_expr);
13451 do_pending_stack_adjust ();
13452
13453 do_tablejump (index, TYPE_MODE (index_type),
13454 range: convert_modes (TYPE_MODE (index_type),
13455 TYPE_MODE (TREE_TYPE (range)),
13456 x: expand_normal (exp: range),
13457 TYPE_UNSIGNED (TREE_TYPE (range))),
13458 table_label, default_label, default_probability);
13459 return true;
13460}
13461
13462/* Return a CONST_VECTOR rtx representing vector mask for
13463 a VECTOR_CST of booleans. */
13464static rtx
13465const_vector_mask_from_tree (tree exp)
13466{
13467 machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
13468 machine_mode inner = GET_MODE_INNER (mode);
13469
13470 rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
13471 VECTOR_CST_NELTS_PER_PATTERN (exp));
13472 unsigned int count = builder.encoded_nelts ();
13473 for (unsigned int i = 0; i < count; ++i)
13474 {
13475 tree elt = VECTOR_CST_ELT (exp, i);
13476 gcc_assert (TREE_CODE (elt) == INTEGER_CST);
13477 if (integer_zerop (elt))
13478 builder.quick_push (CONST0_RTX (inner));
13479 else if (integer_onep (elt)
13480 || integer_minus_onep (elt))
13481 builder.quick_push (CONSTM1_RTX (inner));
13482 else
13483 gcc_unreachable ();
13484 }
13485 return builder.build ();
13486}
13487
13488/* Return a CONST_VECTOR rtx for a VECTOR_CST tree. */
13489static rtx
13490const_vector_from_tree (tree exp)
13491{
13492 machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
13493
13494 if (initializer_zerop (exp))
13495 return CONST0_RTX (mode);
13496
13497 if (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (exp)))
13498 return const_vector_mask_from_tree (exp);
13499
13500 machine_mode inner = GET_MODE_INNER (mode);
13501
13502 rtx_vector_builder builder (mode, VECTOR_CST_NPATTERNS (exp),
13503 VECTOR_CST_NELTS_PER_PATTERN (exp));
13504 unsigned int count = builder.encoded_nelts ();
13505 for (unsigned int i = 0; i < count; ++i)
13506 {
13507 tree elt = VECTOR_CST_ELT (exp, i);
13508 if (TREE_CODE (elt) == REAL_CST)
13509 builder.quick_push (obj: const_double_from_real_value (TREE_REAL_CST (elt),
13510 inner));
13511 else if (TREE_CODE (elt) == FIXED_CST)
13512 builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt),
13513 inner));
13514 else
13515 builder.quick_push (obj: immed_wide_int_const (wi::to_poly_wide (t: elt),
13516 inner));
13517 }
13518 return builder.build ();
13519}
13520
13521/* Build a decl for a personality function given a language prefix. */
13522
13523tree
13524build_personality_function (const char *lang)
13525{
13526 const char *unwind_and_version;
13527 tree decl, type;
13528 char *name;
13529
13530 switch (targetm_common.except_unwind_info (&global_options))
13531 {
13532 case UI_NONE:
13533 return NULL;
13534 case UI_SJLJ:
13535 unwind_and_version = "_sj0";
13536 break;
13537 case UI_DWARF2:
13538 case UI_TARGET:
13539 unwind_and_version = "_v0";
13540 break;
13541 case UI_SEH:
13542 unwind_and_version = "_seh0";
13543 break;
13544 default:
13545 gcc_unreachable ();
13546 }
13547
13548 name = ACONCAT (("__", lang, "_personality", unwind_and_version, NULL));
13549
13550 type = build_function_type_list (unsigned_type_node,
13551 integer_type_node, integer_type_node,
13552 long_long_unsigned_type_node,
13553 ptr_type_node, ptr_type_node, NULL_TREE);
13554 decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
13555 get_identifier (name), type);
13556 DECL_ARTIFICIAL (decl) = 1;
13557 DECL_EXTERNAL (decl) = 1;
13558 TREE_PUBLIC (decl) = 1;
13559
13560 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
13561 are the flags assigned by targetm.encode_section_info. */
13562 SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
13563
13564 return decl;
13565}
13566
13567/* Extracts the personality function of DECL and returns the corresponding
13568 libfunc. */
13569
13570rtx
13571get_personality_function (tree decl)
13572{
13573 tree personality = DECL_FUNCTION_PERSONALITY (decl);
13574 enum eh_personality_kind pk;
13575
13576 pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
13577 if (pk == eh_personality_none)
13578 return NULL;
13579
13580 if (!personality
13581 && pk == eh_personality_any)
13582 personality = lang_hooks.eh_personality ();
13583
13584 if (pk == eh_personality_lang)
13585 gcc_assert (personality != NULL_TREE);
13586
13587 return XEXP (DECL_RTL (personality), 0);
13588}
13589
13590/* Returns a tree for the size of EXP in bytes. */
13591
13592static tree
13593tree_expr_size (const_tree exp)
13594{
13595 if (DECL_P (exp)
13596 && DECL_SIZE_UNIT (exp) != 0)
13597 return DECL_SIZE_UNIT (exp);
13598 else
13599 return size_in_bytes (TREE_TYPE (exp));
13600}
13601
13602/* Return an rtx for the size in bytes of the value of EXP. */
13603
13604rtx
13605expr_size (tree exp)
13606{
13607 tree size;
13608
13609 if (TREE_CODE (exp) == WITH_SIZE_EXPR)
13610 size = TREE_OPERAND (exp, 1);
13611 else
13612 {
13613 size = tree_expr_size (exp);
13614 gcc_assert (size);
13615 gcc_assert (size == SUBSTITUTE_PLACEHOLDER_IN_EXPR (size, exp));
13616 }
13617
13618 return expand_expr (exp: size, NULL_RTX, TYPE_MODE (sizetype), modifier: EXPAND_NORMAL);
13619}
13620
13621/* Return a wide integer for the size in bytes of the value of EXP, or -1
13622 if the size can vary or is larger than an integer. */
13623
13624HOST_WIDE_INT
13625int_expr_size (const_tree exp)
13626{
13627 tree size;
13628
13629 if (TREE_CODE (exp) == WITH_SIZE_EXPR)
13630 size = TREE_OPERAND (exp, 1);
13631 else
13632 {
13633 size = tree_expr_size (exp);
13634 gcc_assert (size);
13635 }
13636
13637 if (size == 0 || !tree_fits_shwi_p (size))
13638 return -1;
13639
13640 return tree_to_shwi (size);
13641}
13642

source code of gcc/expr.cc