Branch data Line data Source code
1 : : /* Medium-level subroutines: convert bit-field store and extract
2 : : and shifts, multiplies and divides to rtl instructions.
3 : : Copyright (C) 1987-2025 Free Software Foundation, Inc.
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
12 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 : : for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : /* Work around tree-optimization/91825. */
22 : : #pragma GCC diagnostic warning "-Wmaybe-uninitialized"
23 : :
24 : : #include "config.h"
25 : : #include "system.h"
26 : : #include "coretypes.h"
27 : : #include "backend.h"
28 : : #include "target.h"
29 : : #include "rtl.h"
30 : : #include "tree.h"
31 : : #include "predict.h"
32 : : #include "memmodel.h"
33 : : #include "tm_p.h"
34 : : #include "optabs.h"
35 : : #include "expmed.h"
36 : : #include "regs.h"
37 : : #include "emit-rtl.h"
38 : : #include "diagnostic-core.h"
39 : : #include "fold-const.h"
40 : : #include "stor-layout.h"
41 : : #include "dojump.h"
42 : : #include "explow.h"
43 : : #include "expr.h"
44 : : #include "langhooks.h"
45 : : #include "tree-vector-builder.h"
46 : : #include "recog.h"
47 : :
48 : : struct target_expmed default_target_expmed;
49 : : #if SWITCHABLE_TARGET
50 : : struct target_expmed *this_target_expmed = &default_target_expmed;
51 : : #endif
52 : :
53 : : static bool store_integral_bit_field (rtx, opt_scalar_int_mode,
54 : : unsigned HOST_WIDE_INT,
55 : : unsigned HOST_WIDE_INT,
56 : : poly_uint64, poly_uint64,
57 : : machine_mode, rtx, bool, bool);
58 : : static void store_fixed_bit_field (rtx, opt_scalar_int_mode,
59 : : unsigned HOST_WIDE_INT,
60 : : unsigned HOST_WIDE_INT,
61 : : poly_uint64, poly_uint64,
62 : : rtx, scalar_int_mode, bool);
63 : : static void store_fixed_bit_field_1 (rtx, scalar_int_mode,
64 : : unsigned HOST_WIDE_INT,
65 : : unsigned HOST_WIDE_INT,
66 : : rtx, scalar_int_mode, bool);
67 : : static void store_split_bit_field (rtx, opt_scalar_int_mode,
68 : : unsigned HOST_WIDE_INT,
69 : : unsigned HOST_WIDE_INT,
70 : : poly_uint64, poly_uint64,
71 : : rtx, scalar_int_mode, bool);
72 : : static rtx extract_integral_bit_field (rtx, opt_scalar_int_mode,
73 : : unsigned HOST_WIDE_INT,
74 : : unsigned HOST_WIDE_INT, int, rtx,
75 : : machine_mode, machine_mode, bool, bool);
76 : : static rtx extract_fixed_bit_field (machine_mode, rtx, opt_scalar_int_mode,
77 : : unsigned HOST_WIDE_INT,
78 : : unsigned HOST_WIDE_INT, rtx, int, bool);
79 : : static rtx extract_fixed_bit_field_1 (machine_mode, rtx, scalar_int_mode,
80 : : unsigned HOST_WIDE_INT,
81 : : unsigned HOST_WIDE_INT, rtx, int, bool);
82 : : static rtx lshift_value (machine_mode, unsigned HOST_WIDE_INT, int);
83 : : static rtx extract_split_bit_field (rtx, opt_scalar_int_mode,
84 : : unsigned HOST_WIDE_INT,
85 : : unsigned HOST_WIDE_INT, int, bool);
86 : : static void do_cmp_and_jump (rtx, rtx, enum rtx_code, machine_mode, rtx_code_label *);
87 : : static rtx expand_smod_pow2 (scalar_int_mode, rtx, HOST_WIDE_INT);
88 : : static rtx expand_sdiv_pow2 (scalar_int_mode, rtx, HOST_WIDE_INT);
89 : :
90 : : /* Return a constant integer mask value of mode MODE with BITSIZE ones
91 : : followed by BITPOS zeros, or the complement of that if COMPLEMENT.
92 : : The mask is truncated if necessary to the width of mode MODE. The
93 : : mask is zero-extended if BITSIZE+BITPOS is too small for MODE. */
94 : :
95 : : static inline rtx
96 : 227160 : mask_rtx (scalar_int_mode mode, int bitpos, int bitsize, bool complement)
97 : : {
98 : 227160 : return immed_wide_int_const
99 : 227160 : (wi::shifted_mask (bitpos, bitsize, complement,
100 : 227160 : GET_MODE_PRECISION (mode)), mode);
101 : : }
102 : :
103 : : /* Test whether a value is zero of a power of two. */
104 : : #define EXACT_POWER_OF_2_OR_ZERO_P(x) \
105 : : (((x) & ((x) - HOST_WIDE_INT_1U)) == 0)
106 : :
107 : : struct init_expmed_rtl
108 : : {
109 : : rtx reg;
110 : : rtx plus;
111 : : rtx neg;
112 : : rtx mult;
113 : : rtx sdiv;
114 : : rtx udiv;
115 : : rtx sdiv_32;
116 : : rtx smod_32;
117 : : rtx wide_mult;
118 : : rtx wide_lshr;
119 : : rtx wide_trunc;
120 : : rtx shift;
121 : : rtx shift_mult;
122 : : rtx shift_add;
123 : : rtx shift_sub0;
124 : : rtx shift_sub1;
125 : : rtx zext;
126 : : rtx trunc;
127 : :
128 : : rtx pow2[MAX_BITS_PER_WORD];
129 : : rtx cint[MAX_BITS_PER_WORD];
130 : : };
131 : :
132 : : static void
133 : 29247820 : init_expmed_one_conv (struct init_expmed_rtl *all, scalar_int_mode to_mode,
134 : : scalar_int_mode from_mode, bool speed)
135 : : {
136 : 29247820 : int to_size, from_size;
137 : 29247820 : rtx which;
138 : :
139 : 29247820 : to_size = GET_MODE_PRECISION (to_mode);
140 : 29247820 : from_size = GET_MODE_PRECISION (from_mode);
141 : :
142 : : /* Most partial integers have a precision less than the "full"
143 : : integer it requires for storage. In case one doesn't, for
144 : : comparison purposes here, reduce the bit size by one in that
145 : : case. */
146 : 29247820 : if (GET_MODE_CLASS (to_mode) == MODE_PARTIAL_INT
147 : 29247820 : && pow2p_hwi (to_size))
148 : 5849564 : to_size --;
149 : 29247820 : if (GET_MODE_CLASS (from_mode) == MODE_PARTIAL_INT
150 : 29247820 : && pow2p_hwi (from_size))
151 : 0 : from_size --;
152 : :
153 : : /* Assume cost of zero-extend and sign-extend is the same. */
154 : 29247820 : which = (to_size < from_size ? all->trunc : all->zext);
155 : :
156 : 29247820 : PUT_MODE (all->reg, from_mode);
157 : 29247820 : set_convert_cost (to_mode, from_mode, speed,
158 : : set_src_cost (which, to_mode, speed));
159 : : /* Restore all->reg's mode. */
160 : 29247820 : PUT_MODE (all->reg, to_mode);
161 : 29247820 : }
162 : :
163 : : static void
164 : 17548692 : init_expmed_one_mode (struct init_expmed_rtl *all,
165 : : machine_mode mode, int speed)
166 : : {
167 : 17548692 : int m, n, mode_bitsize;
168 : 17548692 : machine_mode mode_from;
169 : :
170 : 17548692 : mode_bitsize = GET_MODE_UNIT_BITSIZE (mode);
171 : :
172 : 17548692 : PUT_MODE (all->reg, mode);
173 : 17548692 : PUT_MODE (all->plus, mode);
174 : 17548692 : PUT_MODE (all->neg, mode);
175 : 17548692 : PUT_MODE (all->mult, mode);
176 : 17548692 : PUT_MODE (all->sdiv, mode);
177 : 17548692 : PUT_MODE (all->udiv, mode);
178 : 17548692 : PUT_MODE (all->sdiv_32, mode);
179 : 17548692 : PUT_MODE (all->smod_32, mode);
180 : 17548692 : PUT_MODE (all->wide_trunc, mode);
181 : 17548692 : PUT_MODE (all->shift, mode);
182 : 17548692 : PUT_MODE (all->shift_mult, mode);
183 : 17548692 : PUT_MODE (all->shift_add, mode);
184 : 17548692 : PUT_MODE (all->shift_sub0, mode);
185 : 17548692 : PUT_MODE (all->shift_sub1, mode);
186 : 17548692 : PUT_MODE (all->zext, mode);
187 : 17548692 : PUT_MODE (all->trunc, mode);
188 : :
189 : 17548692 : set_add_cost (speed, mode, set_src_cost (all->plus, mode, speed));
190 : 17548692 : set_neg_cost (speed, mode, set_src_cost (all->neg, mode, speed));
191 : 17548692 : set_mul_cost (speed, mode, set_src_cost (all->mult, mode, speed));
192 : 17548692 : set_sdiv_cost (speed, mode, set_src_cost (all->sdiv, mode, speed));
193 : 17548692 : set_udiv_cost (speed, mode, set_src_cost (all->udiv, mode, speed));
194 : :
195 : 17548692 : set_sdiv_pow2_cheap (speed, mode, (set_src_cost (all->sdiv_32, mode, speed)
196 : 17548692 : <= 2 * add_cost (speed, mode)));
197 : 17548692 : set_smod_pow2_cheap (speed, mode, (set_src_cost (all->smod_32, mode, speed)
198 : 17548692 : <= 4 * add_cost (speed, mode)));
199 : :
200 : 17548692 : set_shift_cost (speed, mode, 0, 0);
201 : 17548692 : {
202 : 17548692 : int cost = add_cost (speed, mode);
203 : 17548692 : set_shiftadd_cost (speed, mode, 0, cost);
204 : 17548692 : set_shiftsub0_cost (speed, mode, 0, cost);
205 : 17548692 : set_shiftsub1_cost (speed, mode, 0, cost);
206 : : }
207 : :
208 : 17548692 : n = MIN (MAX_BITS_PER_WORD, mode_bitsize);
209 : 588299008 : for (m = 1; m < n; m++)
210 : : {
211 : 570750316 : XEXP (all->shift, 1) = all->cint[m];
212 : 570750316 : XEXP (all->shift_mult, 1) = all->pow2[m];
213 : :
214 : 570750316 : set_shift_cost (speed, mode, m, set_src_cost (all->shift, mode, speed));
215 : 570750316 : set_shiftadd_cost (speed, mode, m, set_src_cost (all->shift_add, mode,
216 : : speed));
217 : 570750316 : set_shiftsub0_cost (speed, mode, m, set_src_cost (all->shift_sub0, mode,
218 : : speed));
219 : 570750316 : set_shiftsub1_cost (speed, mode, m, set_src_cost (all->shift_sub1, mode,
220 : : speed));
221 : : }
222 : :
223 : 17548692 : scalar_int_mode int_mode_to;
224 : 17548692 : if (is_a <scalar_int_mode> (mode, &int_mode_to))
225 : : {
226 : 33426080 : for (mode_from = MIN_MODE_INT; mode_from <= MAX_MODE_INT;
227 : 29247820 : mode_from = (machine_mode)(mode_from + 1))
228 : 29247820 : init_expmed_one_conv (all, int_mode_to,
229 : : as_a <scalar_int_mode> (mode_from), speed);
230 : :
231 : 4178260 : scalar_int_mode wider_mode;
232 : 4178260 : if (GET_MODE_CLASS (int_mode_to) == MODE_INT
233 : 4178260 : && GET_MODE_WIDER_MODE (int_mode_to).exists (&wider_mode))
234 : : {
235 : 2506956 : PUT_MODE (all->reg, mode);
236 : 2506956 : PUT_MODE (all->zext, wider_mode);
237 : 2506956 : PUT_MODE (all->wide_mult, wider_mode);
238 : 2506956 : PUT_MODE (all->wide_lshr, wider_mode);
239 : 2506956 : XEXP (all->wide_lshr, 1)
240 : 2506956 : = gen_int_shift_amount (wider_mode, mode_bitsize);
241 : :
242 : 2506956 : set_mul_widen_cost (speed, wider_mode,
243 : : set_src_cost (all->wide_mult, wider_mode, speed));
244 : 2506956 : set_mul_highpart_cost (speed, int_mode_to,
245 : : set_src_cost (all->wide_trunc,
246 : : int_mode_to, speed));
247 : : }
248 : : }
249 : 17548692 : }
250 : :
251 : : void
252 : 208913 : init_expmed (void)
253 : : {
254 : 208913 : struct init_expmed_rtl all;
255 : 208913 : machine_mode mode = QImode;
256 : 208913 : int m, speed;
257 : :
258 : 208913 : memset (&all, 0, sizeof all);
259 : 13370432 : for (m = 1; m < MAX_BITS_PER_WORD; m++)
260 : : {
261 : 13161519 : all.pow2[m] = GEN_INT (HOST_WIDE_INT_1 << m);
262 : 13161519 : all.cint[m] = GEN_INT (m);
263 : : }
264 : :
265 : : /* Avoid using hard regs in ways which may be unsupported. */
266 : 208913 : all.reg = gen_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1);
267 : 208913 : all.plus = gen_rtx_PLUS (mode, all.reg, all.reg);
268 : 208913 : all.neg = gen_rtx_NEG (mode, all.reg);
269 : 208913 : all.mult = gen_rtx_MULT (mode, all.reg, all.reg);
270 : 208913 : all.sdiv = gen_rtx_DIV (mode, all.reg, all.reg);
271 : 208913 : all.udiv = gen_rtx_UDIV (mode, all.reg, all.reg);
272 : 208913 : all.sdiv_32 = gen_rtx_DIV (mode, all.reg, all.pow2[5]);
273 : 208913 : all.smod_32 = gen_rtx_MOD (mode, all.reg, all.pow2[5]);
274 : 208913 : all.zext = gen_rtx_ZERO_EXTEND (mode, all.reg);
275 : 208913 : all.wide_mult = gen_rtx_MULT (mode, all.zext, all.zext);
276 : 208913 : all.wide_lshr = gen_rtx_LSHIFTRT (mode, all.wide_mult, all.reg);
277 : 208913 : all.wide_trunc = gen_rtx_TRUNCATE (mode, all.wide_lshr);
278 : 208913 : all.shift = gen_rtx_ASHIFT (mode, all.reg, all.reg);
279 : 208913 : all.shift_mult = gen_rtx_MULT (mode, all.reg, all.reg);
280 : 208913 : all.shift_add = gen_rtx_PLUS (mode, all.shift_mult, all.reg);
281 : 208913 : all.shift_sub0 = gen_rtx_MINUS (mode, all.shift_mult, all.reg);
282 : 208913 : all.shift_sub1 = gen_rtx_MINUS (mode, all.reg, all.shift_mult);
283 : 208913 : all.trunc = gen_rtx_TRUNCATE (mode, all.reg);
284 : :
285 : 626739 : for (speed = 0; speed < 2; speed++)
286 : : {
287 : 417826 : crtl->maybe_hot_insn_p = speed;
288 : 417826 : set_zero_cost (speed, set_src_cost (const0_rtx, mode, speed));
289 : :
290 : 3342608 : for (mode = MIN_MODE_INT; mode <= MAX_MODE_INT;
291 : 2924782 : mode = (machine_mode)(mode + 1))
292 : 2924782 : init_expmed_one_mode (&all, mode, speed);
293 : :
294 : : if (MIN_MODE_PARTIAL_INT != VOIDmode)
295 : 1671304 : for (mode = MIN_MODE_PARTIAL_INT; mode <= MAX_MODE_PARTIAL_INT;
296 : 1253478 : mode = (machine_mode)(mode + 1))
297 : 1253478 : init_expmed_one_mode (&all, mode, speed);
298 : :
299 : : if (MIN_MODE_VECTOR_INT != VOIDmode)
300 : 13788258 : for (mode = MIN_MODE_VECTOR_INT; mode <= MAX_MODE_VECTOR_INT;
301 : 13370432 : mode = (machine_mode)(mode + 1))
302 : 13370432 : init_expmed_one_mode (&all, mode, speed);
303 : : }
304 : :
305 : 208913 : if (alg_hash_used_p ())
306 : : {
307 : 1013 : struct alg_hash_entry *p = alg_hash_entry_ptr (0);
308 : 1013 : memset (p, 0, sizeof (*p) * NUM_ALG_HASH_ENTRIES);
309 : : }
310 : : else
311 : 207900 : set_alg_hash_used_p (true);
312 : 208913 : default_rtl_profile ();
313 : :
314 : 208913 : ggc_free (all.trunc);
315 : 208913 : ggc_free (all.shift_sub1);
316 : 208913 : ggc_free (all.shift_sub0);
317 : 208913 : ggc_free (all.shift_add);
318 : 208913 : ggc_free (all.shift_mult);
319 : 208913 : ggc_free (all.shift);
320 : 208913 : ggc_free (all.wide_trunc);
321 : 208913 : ggc_free (all.wide_lshr);
322 : 208913 : ggc_free (all.wide_mult);
323 : 208913 : ggc_free (all.zext);
324 : 208913 : ggc_free (all.smod_32);
325 : 208913 : ggc_free (all.sdiv_32);
326 : 208913 : ggc_free (all.udiv);
327 : 208913 : ggc_free (all.sdiv);
328 : 208913 : ggc_free (all.mult);
329 : 208913 : ggc_free (all.neg);
330 : 208913 : ggc_free (all.plus);
331 : 208913 : ggc_free (all.reg);
332 : 208913 : }
333 : :
334 : : /* Return an rtx representing minus the value of X.
335 : : MODE is the intended mode of the result,
336 : : useful if X is a CONST_INT. */
337 : :
338 : : rtx
339 : 1020475 : negate_rtx (machine_mode mode, rtx x)
340 : : {
341 : 1020475 : rtx result = simplify_unary_operation (NEG, mode, x, mode);
342 : :
343 : 1020475 : if (result == 0)
344 : 2010 : result = expand_unop (mode, neg_optab, x, NULL_RTX, 0);
345 : :
346 : 1020475 : return result;
347 : : }
348 : :
349 : : /* Whether reverse storage order is supported on the target. */
350 : : static int reverse_storage_order_supported = -1;
351 : :
352 : : /* Check whether reverse storage order is supported on the target. */
353 : :
354 : : static void
355 : 286 : check_reverse_storage_order_support (void)
356 : : {
357 : 286 : if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
358 : : {
359 : : reverse_storage_order_supported = 0;
360 : : sorry ("reverse scalar storage order");
361 : : }
362 : : else
363 : 286 : reverse_storage_order_supported = 1;
364 : 286 : }
365 : :
366 : : /* Whether reverse FP storage order is supported on the target. */
367 : : static int reverse_float_storage_order_supported = -1;
368 : :
369 : : /* Check whether reverse FP storage order is supported on the target. */
370 : :
371 : : static void
372 : 55 : check_reverse_float_storage_order_support (void)
373 : : {
374 : 55 : if (FLOAT_WORDS_BIG_ENDIAN != WORDS_BIG_ENDIAN)
375 : : {
376 : : reverse_float_storage_order_supported = 0;
377 : : sorry ("reverse floating-point scalar storage order");
378 : : }
379 : : else
380 : 55 : reverse_float_storage_order_supported = 1;
381 : 55 : }
382 : :
383 : : /* Return an rtx representing value of X with reverse storage order.
384 : : MODE is the intended mode of the result,
385 : : useful if X is a CONST_INT. */
386 : :
387 : : rtx
388 : 3220 : flip_storage_order (machine_mode mode, rtx x)
389 : : {
390 : 3220 : scalar_int_mode int_mode;
391 : 3220 : rtx result;
392 : :
393 : 3220 : if (mode == QImode)
394 : : return x;
395 : :
396 : 2343 : if (COMPLEX_MODE_P (mode))
397 : : {
398 : 42 : rtx real = read_complex_part (x, false);
399 : 42 : rtx imag = read_complex_part (x, true);
400 : :
401 : 84 : real = flip_storage_order (GET_MODE_INNER (mode), real);
402 : 84 : imag = flip_storage_order (GET_MODE_INNER (mode), imag);
403 : :
404 : 42 : return gen_rtx_CONCAT (mode, real, imag);
405 : : }
406 : :
407 : 2301 : if (UNLIKELY (reverse_storage_order_supported < 0))
408 : 286 : check_reverse_storage_order_support ();
409 : :
410 : 2301 : if (!is_a <scalar_int_mode> (mode, &int_mode))
411 : : {
412 : 243 : if (FLOAT_MODE_P (mode)
413 : 243 : && UNLIKELY (reverse_float_storage_order_supported < 0))
414 : 55 : check_reverse_float_storage_order_support ();
415 : :
416 : 243 : if (!int_mode_for_size (GET_MODE_PRECISION (mode), 0).exists (&int_mode)
417 : 243 : || !targetm.scalar_mode_supported_p (int_mode))
418 : : {
419 : 0 : sorry ("reverse storage order for %smode", GET_MODE_NAME (mode));
420 : 0 : return x;
421 : : }
422 : 243 : x = gen_lowpart (int_mode, x);
423 : : }
424 : :
425 : 2301 : result = simplify_unary_operation (BSWAP, int_mode, x, int_mode);
426 : 2301 : if (result == 0)
427 : 982 : result = expand_unop (int_mode, bswap_optab, x, NULL_RTX, 1);
428 : :
429 : 2301 : if (int_mode != mode)
430 : 243 : result = gen_lowpart (mode, result);
431 : :
432 : : return result;
433 : : }
434 : :
435 : : /* If MODE is set, adjust bitfield memory MEM so that it points to the
436 : : first unit of mode MODE that contains a bitfield of size BITSIZE at
437 : : bit position BITNUM. If MODE is not set, return a BLKmode reference
438 : : to every byte in the bitfield. Set *NEW_BITNUM to the bit position
439 : : of the field within the new memory. */
440 : :
441 : : static rtx
442 : 427712 : narrow_bit_field_mem (rtx mem, opt_scalar_int_mode mode,
443 : : unsigned HOST_WIDE_INT bitsize,
444 : : unsigned HOST_WIDE_INT bitnum,
445 : : unsigned HOST_WIDE_INT *new_bitnum)
446 : : {
447 : 427712 : scalar_int_mode imode;
448 : 427712 : if (mode.exists (&imode))
449 : : {
450 : 427712 : unsigned int unit = GET_MODE_BITSIZE (imode);
451 : 427712 : *new_bitnum = bitnum % unit;
452 : 427712 : HOST_WIDE_INT offset = (bitnum - *new_bitnum) / BITS_PER_UNIT;
453 : 427712 : return adjust_bitfield_address (mem, imode, offset);
454 : : }
455 : : else
456 : : {
457 : 0 : *new_bitnum = bitnum % BITS_PER_UNIT;
458 : 0 : HOST_WIDE_INT offset = bitnum / BITS_PER_UNIT;
459 : 0 : HOST_WIDE_INT size = ((*new_bitnum + bitsize + BITS_PER_UNIT - 1)
460 : 0 : / BITS_PER_UNIT);
461 : 0 : return adjust_bitfield_address_size (mem, BLKmode, offset, size);
462 : : }
463 : : }
464 : :
465 : : /* The caller wants to perform insertion or extraction PATTERN on a
466 : : bitfield of size BITSIZE at BITNUM bits into memory operand OP0.
467 : : BITREGION_START and BITREGION_END are as for store_bit_field
468 : : and FIELDMODE is the natural mode of the field.
469 : :
470 : : Search for a mode that is compatible with the memory access
471 : : restrictions and (where applicable) with a register insertion or
472 : : extraction. Return the new memory on success, storing the adjusted
473 : : bit position in *NEW_BITNUM. Return null otherwise. */
474 : :
475 : : static rtx
476 : 206265 : adjust_bit_field_mem_for_reg (enum extraction_pattern pattern,
477 : : rtx op0, HOST_WIDE_INT bitsize,
478 : : HOST_WIDE_INT bitnum,
479 : : poly_uint64 bitregion_start,
480 : : poly_uint64 bitregion_end,
481 : : machine_mode fieldmode,
482 : : unsigned HOST_WIDE_INT *new_bitnum)
483 : : {
484 : 206265 : bit_field_mode_iterator iter (bitsize, bitnum, bitregion_start,
485 : 206265 : bitregion_end, MEM_ALIGN (op0),
486 : 206267 : MEM_VOLATILE_P (op0));
487 : 206265 : scalar_int_mode best_mode;
488 : 206265 : if (iter.next_mode (&best_mode))
489 : : {
490 : : /* We can use a memory in BEST_MODE. See whether this is true for
491 : : any wider modes. All other things being equal, we prefer to
492 : : use the widest mode possible because it tends to expose more
493 : : CSE opportunities. */
494 : 199676 : if (!iter.prefer_smaller_modes ())
495 : : {
496 : : /* Limit the search to the mode required by the corresponding
497 : : register insertion or extraction instruction, if any. */
498 : 276 : scalar_int_mode limit_mode = word_mode;
499 : 276 : extraction_insn insn;
500 : 552 : if (get_best_reg_extraction_insn (&insn, pattern,
501 : 276 : GET_MODE_BITSIZE (best_mode),
502 : : fieldmode))
503 : 276 : limit_mode = insn.field_mode;
504 : :
505 : 276 : scalar_int_mode wider_mode;
506 : 276 : while (iter.next_mode (&wider_mode)
507 : 830 : && GET_MODE_SIZE (wider_mode) <= GET_MODE_SIZE (limit_mode))
508 : 76 : best_mode = wider_mode;
509 : : }
510 : 199676 : return narrow_bit_field_mem (op0, best_mode, bitsize, bitnum,
511 : : new_bitnum);
512 : : }
513 : : return NULL_RTX;
514 : : }
515 : :
516 : : /* Return true if a bitfield of size BITSIZE at bit number BITNUM within
517 : : a structure of mode STRUCT_MODE represents a lowpart subreg. The subreg
518 : : offset is then BITNUM / BITS_PER_UNIT. */
519 : :
520 : : static bool
521 : 795620 : lowpart_bit_field_p (poly_uint64 bitnum, poly_uint64 bitsize,
522 : : machine_mode struct_mode)
523 : : {
524 : 795620 : poly_uint64 regsize = REGMODE_NATURAL_SIZE (struct_mode);
525 : 795620 : if (BYTES_BIG_ENDIAN)
526 : : return (multiple_p (bitnum, BITS_PER_UNIT)
527 : : && (known_eq (bitnum + bitsize, GET_MODE_BITSIZE (struct_mode))
528 : : || multiple_p (bitnum + bitsize,
529 : : regsize * BITS_PER_UNIT)));
530 : : else
531 : 795620 : return multiple_p (bitnum, regsize * BITS_PER_UNIT);
532 : : }
533 : :
534 : : /* Return true if -fstrict-volatile-bitfields applies to an access of OP0
535 : : containing BITSIZE bits starting at BITNUM, with field mode FIELDMODE.
536 : : Return false if the access would touch memory outside the range
537 : : BITREGION_START to BITREGION_END for conformance to the C++ memory
538 : : model. */
539 : :
540 : : static bool
541 : 1593511 : strict_volatile_bitfield_p (rtx op0, unsigned HOST_WIDE_INT bitsize,
542 : : unsigned HOST_WIDE_INT bitnum,
543 : : scalar_int_mode fieldmode,
544 : : poly_uint64 bitregion_start,
545 : : poly_uint64 bitregion_end)
546 : : {
547 : 1593511 : unsigned HOST_WIDE_INT modesize = GET_MODE_BITSIZE (fieldmode);
548 : :
549 : : /* -fstrict-volatile-bitfields must be enabled and we must have a
550 : : volatile MEM. */
551 : 1593511 : if (!MEM_P (op0)
552 : 176217 : || !MEM_VOLATILE_P (op0)
553 : 1593685 : || flag_strict_volatile_bitfields <= 0)
554 : : return false;
555 : :
556 : : /* The bit size must not be larger than the field mode, and
557 : : the field mode must not be larger than a word. */
558 : 14 : if (bitsize > modesize || modesize > BITS_PER_WORD)
559 : : return false;
560 : :
561 : : /* Check for cases of unaligned fields that must be split. */
562 : 14 : if (bitnum % modesize + bitsize > modesize)
563 : : return false;
564 : :
565 : : /* The memory must be sufficiently aligned for a MODESIZE access.
566 : : This condition guarantees, that the memory access will not
567 : : touch anything after the end of the structure. */
568 : 11 : if (MEM_ALIGN (op0) < modesize)
569 : : return false;
570 : :
571 : : /* Check for cases where the C++ memory model applies. */
572 : 11 : if (maybe_ne (bitregion_end, 0U)
573 : 11 : && (maybe_lt (bitnum - bitnum % modesize, bitregion_start)
574 : 4 : || maybe_gt (bitnum - bitnum % modesize + modesize - 1,
575 : : bitregion_end)))
576 : 0 : return false;
577 : :
578 : : return true;
579 : : }
580 : :
581 : : /* Return true if OP is a memory and if a bitfield of size BITSIZE at
582 : : bit number BITNUM can be treated as a simple value of mode MODE.
583 : : Store the byte offset in *BYTENUM if so. */
584 : :
585 : : static bool
586 : 548207 : simple_mem_bitfield_p (rtx op0, poly_uint64 bitsize, poly_uint64 bitnum,
587 : : machine_mode mode, poly_uint64 *bytenum)
588 : : {
589 : 548207 : return (MEM_P (op0)
590 : 272534 : && multiple_p (bitnum, BITS_PER_UNIT, bytenum)
591 : 215789 : && known_eq (bitsize, GET_MODE_BITSIZE (mode))
592 : 611837 : && (!targetm.slow_unaligned_access (mode, MEM_ALIGN (op0))
593 : 0 : || (multiple_p (bitnum, GET_MODE_ALIGNMENT (mode))
594 : 0 : && MEM_ALIGN (op0) >= GET_MODE_ALIGNMENT (mode))));
595 : : }
596 : :
597 : : /* Try to use instruction INSV to store VALUE into a field of OP0.
598 : : If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is a
599 : : BLKmode MEM. VALUE_MODE is the mode of VALUE. BITSIZE and BITNUM
600 : : are as for store_bit_field. */
601 : :
602 : : static bool
603 : 108432 : store_bit_field_using_insv (const extraction_insn *insv, rtx op0,
604 : : opt_scalar_int_mode op0_mode,
605 : : unsigned HOST_WIDE_INT bitsize,
606 : : unsigned HOST_WIDE_INT bitnum,
607 : : rtx value, scalar_int_mode value_mode)
608 : : {
609 : 108432 : class expand_operand ops[4];
610 : 108432 : rtx value1;
611 : 108432 : rtx xop0 = op0;
612 : 108432 : rtx_insn *last = get_last_insn ();
613 : 108432 : bool copy_back = false;
614 : :
615 : 108432 : scalar_int_mode op_mode = insv->field_mode;
616 : 108432 : unsigned int unit = GET_MODE_BITSIZE (op_mode);
617 : 108432 : if (bitsize == 0 || bitsize > unit)
618 : : return false;
619 : :
620 : 108423 : if (MEM_P (xop0))
621 : : /* Get a reference to the first byte of the field. */
622 : 0 : xop0 = narrow_bit_field_mem (xop0, insv->struct_mode, bitsize, bitnum,
623 : : &bitnum);
624 : : else
625 : : {
626 : : /* Convert from counting within OP0 to counting in OP_MODE. */
627 : 108423 : if (BYTES_BIG_ENDIAN)
628 : : bitnum += unit - GET_MODE_BITSIZE (op0_mode.require ());
629 : :
630 : : /* If xop0 is a register, we need it in OP_MODE
631 : : to make it acceptable to the format of insv. */
632 : 108423 : if (GET_CODE (xop0) == SUBREG)
633 : : {
634 : : /* If such a SUBREG can't be created, give up. */
635 : 32514 : if (!validate_subreg (op_mode, GET_MODE (SUBREG_REG (xop0)),
636 : 32514 : SUBREG_REG (xop0), SUBREG_BYTE (xop0)))
637 : : return false;
638 : : /* We can't just change the mode, because this might clobber op0,
639 : : and we will need the original value of op0 if insv fails. */
640 : 32514 : xop0 = gen_rtx_SUBREG (op_mode, SUBREG_REG (xop0),
641 : 32514 : SUBREG_BYTE (xop0));
642 : : }
643 : 108423 : if (REG_P (xop0) && GET_MODE (xop0) != op_mode)
644 : 26734 : xop0 = gen_lowpart_SUBREG (op_mode, xop0);
645 : : }
646 : :
647 : : /* If the destination is a paradoxical subreg such that we need a
648 : : truncate to the inner mode, perform the insertion on a temporary and
649 : : truncate the result to the original destination. Note that we can't
650 : : just truncate the paradoxical subreg as (truncate:N (subreg:W (reg:N
651 : : X) 0)) is (reg:N X). */
652 : 108423 : if (GET_CODE (xop0) == SUBREG
653 : 59248 : && REG_P (SUBREG_REG (xop0))
654 : 167671 : && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (SUBREG_REG (xop0)),
655 : : op_mode))
656 : : {
657 : 0 : rtx tem = gen_reg_rtx (op_mode);
658 : 0 : emit_move_insn (tem, xop0);
659 : 0 : xop0 = tem;
660 : 0 : copy_back = true;
661 : : }
662 : :
663 : : /* There are similar overflow check at the start of store_bit_field_1,
664 : : but that only check the situation where the field lies completely
665 : : outside the register, while there do have situation where the field
666 : : lies partialy in the register, we need to adjust bitsize for this
667 : : partial overflow situation. Without this fix, pr48335-2.c on big-endian
668 : : will broken on those arch support bit insert instruction, like arm, aarch64
669 : : etc. */
670 : 108423 : if (bitsize + bitnum > unit && bitnum < unit)
671 : : {
672 : 2 : warning (OPT_Wextra, "write of %wu-bit data outside the bound of "
673 : : "destination object, data truncated into %wu-bit",
674 : : bitsize, unit - bitnum);
675 : 2 : bitsize = unit - bitnum;
676 : : }
677 : :
678 : : /* If BITS_BIG_ENDIAN is zero on a BYTES_BIG_ENDIAN machine, we count
679 : : "backwards" from the size of the unit we are inserting into.
680 : : Otherwise, we count bits from the most significant on a
681 : : BYTES/BITS_BIG_ENDIAN machine. */
682 : :
683 : 108423 : if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
684 : : bitnum = unit - bitsize - bitnum;
685 : :
686 : : /* Convert VALUE to op_mode (which insv insn wants) in VALUE1. */
687 : 108423 : value1 = value;
688 : 108423 : if (value_mode != op_mode)
689 : : {
690 : 145512 : if (GET_MODE_BITSIZE (value_mode) >= bitsize)
691 : : {
692 : 72756 : rtx tmp;
693 : : /* Optimization: Don't bother really extending VALUE
694 : : if it has all the bits we will actually use. However,
695 : : if we must narrow it, be sure we do it correctly. */
696 : :
697 : 218268 : if (GET_MODE_SIZE (value_mode) < GET_MODE_SIZE (op_mode))
698 : : {
699 : 35261 : tmp = simplify_subreg (op_mode, value1, value_mode, 0);
700 : 35261 : if (! tmp)
701 : 33866 : tmp = simplify_gen_subreg (op_mode,
702 : : force_reg (value_mode, value1),
703 : 33866 : value_mode, 0);
704 : : }
705 : : else
706 : : {
707 : 37495 : if (targetm.mode_rep_extended (op_mode, value_mode) != UNKNOWN)
708 : 0 : tmp = simplify_gen_unary (TRUNCATE, op_mode,
709 : : value1, value_mode);
710 : : else
711 : : {
712 : 37495 : tmp = gen_lowpart_if_possible (op_mode, value1);
713 : 37495 : if (! tmp)
714 : 0 : tmp = gen_lowpart (op_mode, force_reg (value_mode, value1));
715 : : }
716 : : }
717 : : value1 = tmp;
718 : : }
719 : 0 : else if (CONST_INT_P (value))
720 : 0 : value1 = gen_int_mode (INTVAL (value), op_mode);
721 : : else
722 : : /* Parse phase is supposed to make VALUE's data type
723 : : match that of the component reference, which is a type
724 : : at least as wide as the field; so VALUE should have
725 : : a mode that corresponds to that type. */
726 : 0 : gcc_assert (CONSTANT_P (value));
727 : : }
728 : :
729 : 108423 : create_fixed_operand (&ops[0], xop0);
730 : 108423 : create_integer_operand (&ops[1], bitsize);
731 : 108423 : create_integer_operand (&ops[2], bitnum);
732 : 108423 : create_input_operand (&ops[3], value1, op_mode);
733 : 108423 : if (maybe_expand_insn (insv->icode, 4, ops))
734 : : {
735 : 2513 : if (copy_back)
736 : 0 : convert_move (op0, xop0, true);
737 : 2513 : return true;
738 : : }
739 : 105910 : delete_insns_since (last);
740 : 105910 : return false;
741 : : }
742 : :
743 : : /* A subroutine of store_bit_field, with the same arguments. Return true
744 : : if the operation could be implemented.
745 : :
746 : : If FALLBACK_P is true, fall back to store_fixed_bit_field if we have
747 : : no other way of implementing the operation. If FALLBACK_P is false,
748 : : return false instead.
749 : :
750 : : if UNDEFINED_P is true then STR_RTX is undefined and may be set using
751 : : a subreg instead. */
752 : :
753 : : static bool
754 : 882408 : store_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
755 : : poly_uint64 bitregion_start, poly_uint64 bitregion_end,
756 : : machine_mode fieldmode,
757 : : rtx value, bool reverse, bool fallback_p, bool undefined_p)
758 : : {
759 : 882408 : rtx op0 = str_rtx;
760 : :
761 : 882414 : while (GET_CODE (op0) == SUBREG)
762 : : {
763 : 6 : bitnum += subreg_memory_offset (op0) * BITS_PER_UNIT;
764 : 6 : op0 = SUBREG_REG (op0);
765 : : }
766 : :
767 : : /* No action is needed if the target is a register and if the field
768 : : lies completely outside that register. This can occur if the source
769 : : code contains an out-of-bounds access to a small array. */
770 : 1688313 : if (REG_P (op0) && known_ge (bitnum, GET_MODE_BITSIZE (GET_MODE (op0))))
771 : : return true;
772 : :
773 : : /* Use vec_set patterns for inserting parts of vectors whenever
774 : : available. */
775 : 882405 : machine_mode outermode = GET_MODE (op0);
776 : 882405 : scalar_mode innermode = GET_MODE_INNER (outermode);
777 : 882405 : poly_uint64 pos;
778 : 879675 : if (VECTOR_MODE_P (outermode)
779 : 3069 : && !MEM_P (op0)
780 : 3069 : && optab_handler (vec_set_optab, outermode) != CODE_FOR_nothing
781 : 985 : && fieldmode == innermode
782 : 817 : && known_eq (bitsize, GET_MODE_PRECISION (innermode))
783 : 883222 : && multiple_p (bitnum, GET_MODE_PRECISION (innermode), &pos))
784 : : {
785 : 817 : class expand_operand ops[3];
786 : 817 : enum insn_code icode = optab_handler (vec_set_optab, outermode);
787 : :
788 : 817 : create_fixed_operand (&ops[0], op0);
789 : 817 : create_input_operand (&ops[1], value, innermode);
790 : 817 : create_integer_operand (&ops[2], pos);
791 : 817 : if (maybe_expand_insn (icode, 3, ops))
792 : 817 : return true;
793 : : }
794 : :
795 : : /* If the target is a register, overwriting the entire object, or storing
796 : : a full-word or multi-word field can be done with just a SUBREG. */
797 : 881588 : if (!MEM_P (op0)
798 : 1686673 : && known_eq (bitsize, GET_MODE_BITSIZE (fieldmode)))
799 : : {
800 : : /* Use the subreg machinery either to narrow OP0 to the required
801 : : words or to cope with mode punning between equal-sized modes.
802 : : In the latter case, use subreg on the rhs side, not lhs. */
803 : 736230 : rtx sub;
804 : 736230 : poly_uint64 bytenum;
805 : 736230 : poly_uint64 regsize = REGMODE_NATURAL_SIZE (GET_MODE (op0));
806 : 736230 : if (known_eq (bitnum, 0U)
807 : 1108702 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0))))
808 : : {
809 : 60011 : sub = force_subreg (GET_MODE (op0), value, fieldmode, 0);
810 : 60011 : if (sub)
811 : : {
812 : 60011 : if (reverse)
813 : 1 : sub = flip_storage_order (GET_MODE (op0), sub);
814 : 60011 : emit_move_insn (op0, sub);
815 : 60011 : return true;
816 : : }
817 : : }
818 : 866658 : else if (multiple_p (bitnum, BITS_PER_UNIT, &bytenum)
819 : 676214 : && (undefined_p
820 : 672570 : || (multiple_p (bitnum, regsize * BITS_PER_UNIT)
821 : 660452 : && multiple_p (bitsize, regsize * BITS_PER_UNIT)))
822 : 1262294 : && known_ge (GET_MODE_BITSIZE (GET_MODE (op0)), bitsize))
823 : : {
824 : 631135 : sub = simplify_gen_subreg (fieldmode, op0, GET_MODE (op0), bytenum);
825 : 631135 : if (sub)
826 : : {
827 : 631133 : if (reverse)
828 : 0 : value = flip_storage_order (fieldmode, value);
829 : 631133 : emit_move_insn (sub, value);
830 : 631133 : return true;
831 : : }
832 : : }
833 : : }
834 : :
835 : : /* If the target is memory, storing any naturally aligned field can be
836 : : done with a simple store. For targets that support fast unaligned
837 : : memory, any naturally sized, unit aligned field can be done directly. */
838 : 190444 : poly_uint64 bytenum;
839 : 190444 : if (simple_mem_bitfield_p (op0, bitsize, bitnum, fieldmode, &bytenum))
840 : : {
841 : 6541 : op0 = adjust_bitfield_address (op0, fieldmode, bytenum);
842 : 6541 : if (reverse)
843 : 0 : value = flip_storage_order (fieldmode, value);
844 : 6541 : emit_move_insn (op0, value);
845 : 6541 : return true;
846 : : }
847 : :
848 : : /* It's possible we'll need to handle other cases here for
849 : : polynomial bitnum and bitsize. */
850 : :
851 : : /* From here on we need to be looking at a fixed-size insertion. */
852 : 183903 : unsigned HOST_WIDE_INT ibitsize = bitsize.to_constant ();
853 : 183903 : unsigned HOST_WIDE_INT ibitnum = bitnum.to_constant ();
854 : :
855 : : /* Make sure we are playing with integral modes. Pun with subregs
856 : : if we aren't. This must come after the entire register case above,
857 : : since that case is valid for any mode. The following cases are only
858 : : valid for integral modes. */
859 : 183903 : opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (op0));
860 : 183903 : scalar_int_mode imode;
861 : 183903 : if (!op0_mode.exists (&imode) || imode != GET_MODE (op0))
862 : : {
863 : 26333 : if (MEM_P (op0))
864 : 21050 : op0 = adjust_bitfield_address_size (op0, op0_mode.else_blk (),
865 : : 0, MEM_SIZE (op0));
866 : 5283 : else if (!op0_mode.exists ())
867 : : {
868 : 0 : if (ibitnum == 0
869 : 0 : && known_eq (ibitsize, GET_MODE_BITSIZE (GET_MODE (op0)))
870 : 0 : && MEM_P (value)
871 : 0 : && !reverse)
872 : : {
873 : 0 : value = adjust_address (value, GET_MODE (op0), 0);
874 : 0 : emit_move_insn (op0, value);
875 : 0 : return true;
876 : : }
877 : 0 : if (!fallback_p)
878 : : return false;
879 : 0 : rtx temp = assign_stack_temp (GET_MODE (op0),
880 : 0 : GET_MODE_SIZE (GET_MODE (op0)));
881 : 0 : emit_move_insn (temp, op0);
882 : 0 : store_bit_field_1 (temp, bitsize, bitnum, 0, 0, fieldmode, value,
883 : : reverse, fallback_p, undefined_p);
884 : 0 : emit_move_insn (op0, temp);
885 : 0 : return true;
886 : : }
887 : : else
888 : 5283 : op0 = gen_lowpart (op0_mode.require (), op0);
889 : : }
890 : :
891 : 183903 : return store_integral_bit_field (op0, op0_mode, ibitsize, ibitnum,
892 : : bitregion_start, bitregion_end,
893 : 183903 : fieldmode, value, reverse, fallback_p);
894 : : }
895 : :
896 : : /* Subroutine of store_bit_field_1, with the same arguments, except
897 : : that BITSIZE and BITNUM are constant. Handle cases specific to
898 : : integral modes. If OP0_MODE is defined, it is the mode of OP0,
899 : : otherwise OP0 is a BLKmode MEM. */
900 : :
901 : : static bool
902 : 183903 : store_integral_bit_field (rtx op0, opt_scalar_int_mode op0_mode,
903 : : unsigned HOST_WIDE_INT bitsize,
904 : : unsigned HOST_WIDE_INT bitnum,
905 : : poly_uint64 bitregion_start,
906 : : poly_uint64 bitregion_end,
907 : : machine_mode fieldmode,
908 : : rtx value, bool reverse, bool fallback_p)
909 : : {
910 : : /* Storing an lsb-aligned field in a register
911 : : can be done with a movstrict instruction. */
912 : :
913 : 183903 : if (!MEM_P (op0)
914 : 113941 : && !reverse
915 : 371857 : && lowpart_bit_field_p (bitnum, bitsize, op0_mode.require ())
916 : 78727 : && known_eq (bitsize, GET_MODE_BITSIZE (fieldmode))
917 : 216866 : && optab_handler (movstrict_optab, fieldmode) != CODE_FOR_nothing)
918 : : {
919 : 4687 : class expand_operand ops[2];
920 : 4687 : enum insn_code icode = optab_handler (movstrict_optab, fieldmode);
921 : 4687 : rtx arg0 = op0;
922 : 4687 : unsigned HOST_WIDE_INT subreg_off;
923 : :
924 : 4687 : if (GET_CODE (arg0) == SUBREG)
925 : : {
926 : : /* Else we've got some float mode source being extracted into
927 : : a different float mode destination -- this combination of
928 : : subregs results in Severe Tire Damage. */
929 : 782 : gcc_assert (GET_MODE (SUBREG_REG (arg0)) == fieldmode
930 : : || GET_MODE_CLASS (fieldmode) == MODE_INT
931 : : || GET_MODE_CLASS (fieldmode) == MODE_PARTIAL_INT);
932 : : arg0 = SUBREG_REG (arg0);
933 : : }
934 : :
935 : 4687 : subreg_off = bitnum / BITS_PER_UNIT;
936 : 4702 : if (validate_subreg (fieldmode, GET_MODE (arg0), arg0, subreg_off)
937 : : /* STRICT_LOW_PART must have a non-paradoxical subreg as
938 : : operand. */
939 : 4687 : && !paradoxical_subreg_p (fieldmode, GET_MODE (arg0)))
940 : : {
941 : 4672 : arg0 = gen_rtx_SUBREG (fieldmode, arg0, subreg_off);
942 : :
943 : 4672 : create_fixed_operand (&ops[0], arg0);
944 : : /* Shrink the source operand to FIELDMODE. */
945 : 4672 : create_convert_operand_to (&ops[1], value, fieldmode, false);
946 : 4672 : if (maybe_expand_insn (icode, 2, ops))
947 : 4671 : return true;
948 : : }
949 : : }
950 : :
951 : : /* Handle fields bigger than a word. */
952 : :
953 : 180642 : if (bitsize > BITS_PER_WORD)
954 : : {
955 : : /* Here we transfer the words of the field
956 : : in the order least significant first.
957 : : This is because the most significant word is the one which may
958 : : be less than full.
959 : : However, only do that if the value is not BLKmode. */
960 : :
961 : 769 : const bool backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
962 : 769 : const int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
963 : 769 : rtx_insn *last;
964 : :
965 : : /* This is the mode we must force value to, so that there will be enough
966 : : subwords to extract. Note that fieldmode will often (always?) be
967 : : VOIDmode, because that is what store_field uses to indicate that this
968 : : is a bit field, but passing VOIDmode to operand_subword_force
969 : : is not allowed.
970 : :
971 : : The mode must be fixed-size, since insertions into variable-sized
972 : : objects are meant to be handled before calling this function. */
973 : 769 : fixed_size_mode value_mode = as_a <fixed_size_mode> (GET_MODE (value));
974 : 769 : if (value_mode == VOIDmode)
975 : 22 : value_mode
976 : 22 : = smallest_int_mode_for_size (nwords * BITS_PER_WORD).require ();
977 : :
978 : 769 : last = get_last_insn ();
979 : 2302 : for (int i = 0; i < nwords; i++)
980 : : {
981 : : /* Number of bits to be stored in this iteration, i.e. BITS_PER_WORD
982 : : except maybe for the last iteration. */
983 : 3076 : const unsigned HOST_WIDE_INT new_bitsize
984 : 1574 : = MIN (BITS_PER_WORD, bitsize - i * BITS_PER_WORD);
985 : : /* Bit offset from the starting bit number in the target. */
986 : 3076 : const unsigned int bit_offset
987 : : = backwards ^ reverse
988 : 1538 : ? MAX ((int) bitsize - (i + 1) * BITS_PER_WORD, 0)
989 : : : i * BITS_PER_WORD;
990 : :
991 : : /* No further action is needed if the target is a register and if
992 : : this field lies completely outside that register. */
993 : 1792 : if (REG_P (op0) && known_ge (bitnum + bit_offset,
994 : : GET_MODE_BITSIZE (GET_MODE (op0))))
995 : : {
996 : 5 : if (backwards ^ reverse)
997 : 0 : continue;
998 : : /* For forward operation we are finished. */
999 : 183903 : return true;
1000 : : }
1001 : :
1002 : : /* Starting word number in the value. */
1003 : 1533 : const unsigned int wordnum
1004 : : = backwards
1005 : 1533 : ? GET_MODE_SIZE (value_mode) / UNITS_PER_WORD - (i + 1)
1006 : : : i;
1007 : : /* The chunk of the value in word_mode. We use bit-field extraction
1008 : : in BLKmode to handle unaligned memory references and to shift the
1009 : : last chunk right on big-endian machines if need be. */
1010 : 1533 : rtx value_word
1011 : : = fieldmode == BLKmode
1012 : 1569 : ? extract_bit_field (value, new_bitsize, wordnum * BITS_PER_WORD,
1013 : : 1, NULL_RTX, word_mode, word_mode, false,
1014 : : NULL)
1015 : 1302 : : operand_subword_force (value, wordnum, value_mode);
1016 : :
1017 : 1533 : if (!store_bit_field_1 (op0, new_bitsize,
1018 : 1533 : bitnum + bit_offset,
1019 : : bitregion_start, bitregion_end,
1020 : : word_mode,
1021 : : value_word, reverse, fallback_p, false))
1022 : : {
1023 : 0 : delete_insns_since (last);
1024 : 0 : return false;
1025 : : }
1026 : : }
1027 : : return true;
1028 : : }
1029 : :
1030 : : /* If VALUE has a floating-point or complex mode, access it as an
1031 : : integer of the corresponding size. This can occur on a machine
1032 : : with 64 bit registers that uses SFmode for float. It can also
1033 : : occur for unaligned float or complex fields. */
1034 : 178463 : rtx orig_value = value;
1035 : 178463 : scalar_int_mode value_mode;
1036 : 178463 : if (GET_MODE (value) == VOIDmode)
1037 : : /* By this point we've dealt with values that are bigger than a word,
1038 : : so word_mode is a conservatively correct choice. */
1039 : 103275 : value_mode = word_mode;
1040 : 75188 : else if (!is_a <scalar_int_mode> (GET_MODE (value), &value_mode))
1041 : : {
1042 : 1080 : value_mode = int_mode_for_mode (GET_MODE (value)).require ();
1043 : 1080 : value = gen_reg_rtx (value_mode);
1044 : 1080 : emit_move_insn (gen_lowpart (GET_MODE (orig_value), value), orig_value);
1045 : : }
1046 : :
1047 : : /* If OP0 is a multi-word register, narrow it to the affected word.
1048 : : If the region spans two words, defer to store_split_bit_field.
1049 : : Don't do this if op0 is a single hard register wider than word
1050 : : such as a float or vector register. */
1051 : 178463 : if (!MEM_P (op0)
1052 : 219122 : && GET_MODE_SIZE (op0_mode.require ()) > UNITS_PER_WORD
1053 : 210811 : && (!REG_P (op0)
1054 : 32262 : || !HARD_REGISTER_P (op0)
1055 : 146117 : || hard_regno_nregs (REGNO (op0), op0_mode.require ()) != 1))
1056 : : {
1057 : 32418 : if (bitnum % BITS_PER_WORD + bitsize > BITS_PER_WORD)
1058 : : {
1059 : 689 : if (!fallback_p)
1060 : : return false;
1061 : :
1062 : 64 : store_split_bit_field (op0, op0_mode, bitsize, bitnum,
1063 : : bitregion_start, bitregion_end,
1064 : : value, value_mode, reverse);
1065 : 64 : return true;
1066 : : }
1067 : 31657 : op0 = simplify_gen_subreg (word_mode, op0, op0_mode.require (),
1068 : 31729 : bitnum / BITS_PER_WORD * UNITS_PER_WORD);
1069 : 31657 : gcc_assert (op0);
1070 : 31657 : op0_mode = word_mode;
1071 : 31729 : bitnum %= BITS_PER_WORD;
1072 : : }
1073 : :
1074 : : /* From here on we can assume that the field to be stored in fits
1075 : : within a word. If the destination is a register, it too fits
1076 : : in a word. */
1077 : :
1078 : 177774 : extraction_insn insv;
1079 : 177774 : if (!MEM_P (op0)
1080 : 108451 : && !reverse
1081 : 108434 : && get_best_reg_extraction_insn (&insv, EP_insv,
1082 : 216868 : GET_MODE_BITSIZE (op0_mode.require ()),
1083 : : fieldmode)
1084 : 286206 : && store_bit_field_using_insv (&insv, op0, op0_mode,
1085 : : bitsize, bitnum, value, value_mode))
1086 : 2513 : return true;
1087 : :
1088 : : /* If OP0 is a memory, try copying it to a register and seeing if a
1089 : : cheap register alternative is available. */
1090 : 175261 : if (MEM_P (op0) && !reverse)
1091 : : {
1092 : 68922 : if (get_best_mem_extraction_insn (&insv, EP_insv, bitsize, bitnum,
1093 : : fieldmode)
1094 : 68922 : && store_bit_field_using_insv (&insv, op0, op0_mode,
1095 : : bitsize, bitnum, value, value_mode))
1096 : 0 : return true;
1097 : :
1098 : 68922 : rtx_insn *last = get_last_insn ();
1099 : :
1100 : : /* Try loading part of OP0 into a register, inserting the bitfield
1101 : : into that, and then copying the result back to OP0. */
1102 : 68922 : unsigned HOST_WIDE_INT bitpos;
1103 : 68922 : rtx xop0 = adjust_bit_field_mem_for_reg (EP_insv, op0, bitsize, bitnum,
1104 : : bitregion_start, bitregion_end,
1105 : : fieldmode, &bitpos);
1106 : 68922 : if (xop0)
1107 : : {
1108 : 65074 : rtx tempreg = copy_to_reg (xop0);
1109 : 65074 : if (store_bit_field_1 (tempreg, bitsize, bitpos,
1110 : : bitregion_start, bitregion_end,
1111 : : fieldmode, orig_value, reverse, false, false))
1112 : : {
1113 : 0 : emit_move_insn (xop0, tempreg);
1114 : 0 : return true;
1115 : : }
1116 : 65074 : delete_insns_since (last);
1117 : : }
1118 : : }
1119 : :
1120 : 175261 : if (!fallback_p)
1121 : : return false;
1122 : :
1123 : 110812 : store_fixed_bit_field (op0, op0_mode, bitsize, bitnum, bitregion_start,
1124 : : bitregion_end, value, value_mode, reverse);
1125 : 110812 : return true;
1126 : : }
1127 : :
1128 : : /* Generate code to store value from rtx VALUE
1129 : : into a bit-field within structure STR_RTX
1130 : : containing BITSIZE bits starting at bit BITNUM.
1131 : :
1132 : : BITREGION_START is bitpos of the first bitfield in this region.
1133 : : BITREGION_END is the bitpos of the ending bitfield in this region.
1134 : : These two fields are 0, if the C++ memory model does not apply,
1135 : : or we are not interested in keeping track of bitfield regions.
1136 : :
1137 : : FIELDMODE is the machine-mode of the FIELD_DECL node for this field.
1138 : :
1139 : : If REVERSE is true, the store is to be done in reverse order.
1140 : :
1141 : : If UNDEFINED_P is true then STR_RTX is currently undefined. */
1142 : :
1143 : : void
1144 : 815801 : store_bit_field (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
1145 : : poly_uint64 bitregion_start, poly_uint64 bitregion_end,
1146 : : machine_mode fieldmode,
1147 : : rtx value, bool reverse, bool undefined_p)
1148 : : {
1149 : : /* Handle -fstrict-volatile-bitfields in the cases where it applies. */
1150 : 815801 : unsigned HOST_WIDE_INT ibitsize = 0, ibitnum = 0;
1151 : 815801 : scalar_int_mode int_mode;
1152 : 815801 : if (bitsize.is_constant (&ibitsize)
1153 : 815801 : && bitnum.is_constant (&ibitnum)
1154 : 1534052 : && is_a <scalar_int_mode> (fieldmode, &int_mode)
1155 : 718255 : && strict_volatile_bitfield_p (str_rtx, ibitsize, ibitnum, int_mode,
1156 : : bitregion_start, bitregion_end))
1157 : : {
1158 : : /* Storing of a full word can be done with a simple store.
1159 : : We know here that the field can be accessed with one single
1160 : : instruction. For targets that support unaligned memory,
1161 : : an unaligned access may be necessary. */
1162 : 8 : if (ibitsize == GET_MODE_BITSIZE (int_mode))
1163 : : {
1164 : 0 : str_rtx = adjust_bitfield_address (str_rtx, int_mode,
1165 : : ibitnum / BITS_PER_UNIT);
1166 : 0 : if (reverse)
1167 : 0 : value = flip_storage_order (int_mode, value);
1168 : 0 : gcc_assert (ibitnum % BITS_PER_UNIT == 0);
1169 : 0 : emit_move_insn (str_rtx, value);
1170 : : }
1171 : : else
1172 : : {
1173 : 4 : rtx temp;
1174 : :
1175 : 4 : str_rtx = narrow_bit_field_mem (str_rtx, int_mode, ibitsize,
1176 : : ibitnum, &ibitnum);
1177 : 8 : gcc_assert (ibitnum + ibitsize <= GET_MODE_BITSIZE (int_mode));
1178 : 4 : temp = copy_to_reg (str_rtx);
1179 : 4 : if (!store_bit_field_1 (temp, ibitsize, ibitnum, 0, 0,
1180 : : int_mode, value, reverse, true, undefined_p))
1181 : 0 : gcc_unreachable ();
1182 : :
1183 : 4 : emit_move_insn (str_rtx, temp);
1184 : : }
1185 : :
1186 : 4 : return;
1187 : : }
1188 : :
1189 : : /* Under the C++0x memory model, we must not touch bits outside the
1190 : : bit region. Adjust the address to start at the beginning of the
1191 : : bit region. */
1192 : 815797 : if (MEM_P (str_rtx) && maybe_ne (bitregion_start, 0U))
1193 : : {
1194 : 46817 : scalar_int_mode best_mode;
1195 : 46817 : machine_mode addr_mode = VOIDmode;
1196 : :
1197 : 46817 : poly_uint64 offset = exact_div (bitregion_start, BITS_PER_UNIT);
1198 : 93634 : bitnum -= bitregion_start;
1199 : 46817 : poly_int64 size = bits_to_bytes_round_up (bitnum + bitsize);
1200 : 46817 : bitregion_end -= bitregion_start;
1201 : 46817 : bitregion_start = 0;
1202 : 46817 : if (bitsize.is_constant (&ibitsize)
1203 : 46817 : && bitnum.is_constant (&ibitnum)
1204 : 46817 : && get_best_mode (ibitsize, ibitnum,
1205 : : bitregion_start, bitregion_end,
1206 : 46817 : MEM_ALIGN (str_rtx), INT_MAX,
1207 : 46817 : MEM_VOLATILE_P (str_rtx), &best_mode))
1208 : 43390 : addr_mode = best_mode;
1209 : 46817 : str_rtx = adjust_bitfield_address_size (str_rtx, addr_mode,
1210 : : offset, size);
1211 : : }
1212 : :
1213 : 815797 : if (!store_bit_field_1 (str_rtx, bitsize, bitnum,
1214 : : bitregion_start, bitregion_end,
1215 : : fieldmode, value, reverse, true, undefined_p))
1216 : 0 : gcc_unreachable ();
1217 : : }
1218 : :
1219 : : /* Use shifts and boolean operations to store VALUE into a bit field of
1220 : : width BITSIZE in OP0, starting at bit BITNUM. If OP0_MODE is defined,
1221 : : it is the mode of OP0, otherwise OP0 is a BLKmode MEM. VALUE_MODE is
1222 : : the mode of VALUE.
1223 : :
1224 : : If REVERSE is true, the store is to be done in reverse order. */
1225 : :
1226 : : static void
1227 : 128845 : store_fixed_bit_field (rtx op0, opt_scalar_int_mode op0_mode,
1228 : : unsigned HOST_WIDE_INT bitsize,
1229 : : unsigned HOST_WIDE_INT bitnum,
1230 : : poly_uint64 bitregion_start, poly_uint64 bitregion_end,
1231 : : rtx value, scalar_int_mode value_mode, bool reverse)
1232 : : {
1233 : : /* There is a case not handled here:
1234 : : a structure with a known alignment of just a halfword
1235 : : and a field split across two aligned halfwords within the structure.
1236 : : Or likewise a structure with a known alignment of just a byte
1237 : : and a field split across two bytes.
1238 : : Such cases are not supposed to be able to occur. */
1239 : :
1240 : 128845 : scalar_int_mode best_mode;
1241 : 128845 : if (MEM_P (op0))
1242 : : {
1243 : 87228 : unsigned int max_bitsize = BITS_PER_WORD;
1244 : 87228 : scalar_int_mode imode;
1245 : 143150 : if (op0_mode.exists (&imode) && GET_MODE_BITSIZE (imode) < max_bitsize)
1246 : 82390 : max_bitsize = GET_MODE_BITSIZE (imode);
1247 : :
1248 : 87228 : if (!get_best_mode (bitsize, bitnum, bitregion_start, bitregion_end,
1249 : 87228 : MEM_ALIGN (op0), max_bitsize, MEM_VOLATILE_P (op0),
1250 : : &best_mode))
1251 : : {
1252 : : /* The only way this should occur is if the field spans word
1253 : : boundaries. */
1254 : 6608 : store_split_bit_field (op0, op0_mode, bitsize, bitnum,
1255 : : bitregion_start, bitregion_end,
1256 : : value, value_mode, reverse);
1257 : 6608 : return;
1258 : : }
1259 : :
1260 : 80620 : op0 = narrow_bit_field_mem (op0, best_mode, bitsize, bitnum, &bitnum);
1261 : : }
1262 : : else
1263 : 41617 : best_mode = op0_mode.require ();
1264 : :
1265 : 122237 : store_fixed_bit_field_1 (op0, best_mode, bitsize, bitnum,
1266 : : value, value_mode, reverse);
1267 : : }
1268 : :
1269 : : /* Helper function for store_fixed_bit_field, stores
1270 : : the bit field always using MODE, which is the mode of OP0. The other
1271 : : arguments are as for store_fixed_bit_field. */
1272 : :
1273 : : static void
1274 : 122237 : store_fixed_bit_field_1 (rtx op0, scalar_int_mode mode,
1275 : : unsigned HOST_WIDE_INT bitsize,
1276 : : unsigned HOST_WIDE_INT bitnum,
1277 : : rtx value, scalar_int_mode value_mode, bool reverse)
1278 : : {
1279 : 122237 : rtx temp;
1280 : 122237 : int all_zero = 0;
1281 : 122237 : int all_one = 0;
1282 : :
1283 : : /* Note that bitsize + bitnum can be greater than GET_MODE_BITSIZE (mode)
1284 : : for invalid input, such as f5 from gcc.dg/pr48335-2.c. */
1285 : :
1286 : 122237 : if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
1287 : : /* BITNUM is the distance between our msb
1288 : : and that of the containing datum.
1289 : : Convert it to the distance from the lsb. */
1290 : 1062 : bitnum = GET_MODE_BITSIZE (mode) - bitsize - bitnum;
1291 : :
1292 : : /* Now BITNUM is always the distance between our lsb
1293 : : and that of OP0. */
1294 : :
1295 : : /* Shift VALUE left by BITNUM bits. If VALUE is not constant,
1296 : : we must first convert its mode to MODE. */
1297 : :
1298 : 122237 : if (CONST_INT_P (value))
1299 : : {
1300 : 70272 : unsigned HOST_WIDE_INT v = UINTVAL (value);
1301 : :
1302 : 70272 : if (bitsize < HOST_BITS_PER_WIDE_INT)
1303 : 70254 : v &= (HOST_WIDE_INT_1U << bitsize) - 1;
1304 : :
1305 : 70272 : if (v == 0)
1306 : : all_zero = 1;
1307 : 57095 : else if ((bitsize < HOST_BITS_PER_WIDE_INT
1308 : 57087 : && v == (HOST_WIDE_INT_1U << bitsize) - 1)
1309 : 47549 : || (bitsize == HOST_BITS_PER_WIDE_INT
1310 : 47549 : && v == HOST_WIDE_INT_M1U))
1311 : 9546 : all_one = 1;
1312 : :
1313 : 70272 : value = lshift_value (mode, v, bitnum);
1314 : : }
1315 : : else
1316 : : {
1317 : 51965 : int must_and = (GET_MODE_BITSIZE (value_mode) != bitsize
1318 : 81002 : && bitnum + bitsize != GET_MODE_BITSIZE (mode));
1319 : :
1320 : 51965 : if (value_mode != mode)
1321 : 28752 : value = convert_to_mode (mode, value, 1);
1322 : :
1323 : 51965 : if (must_and)
1324 : 21929 : value = expand_binop (mode, and_optab, value,
1325 : : mask_rtx (mode, 0, bitsize, 0),
1326 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
1327 : 51965 : if (bitnum > 0)
1328 : 17415 : value = expand_shift (LSHIFT_EXPR, mode, value,
1329 : : bitnum, NULL_RTX, 1);
1330 : : }
1331 : :
1332 : 122237 : if (reverse)
1333 : 531 : value = flip_storage_order (mode, value);
1334 : :
1335 : : /* Now clear the chosen bits in OP0,
1336 : : except that if VALUE is -1 we need not bother. */
1337 : : /* We keep the intermediates in registers to allow CSE to combine
1338 : : consecutive bitfield assignments. */
1339 : :
1340 : 122237 : temp = force_reg (mode, op0);
1341 : :
1342 : 122237 : if (! all_one)
1343 : : {
1344 : 112691 : rtx mask = mask_rtx (mode, bitnum, bitsize, 1);
1345 : 112691 : if (reverse)
1346 : 519 : mask = flip_storage_order (mode, mask);
1347 : 112691 : temp = expand_binop (mode, and_optab, temp, mask,
1348 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
1349 : 112691 : temp = force_reg (mode, temp);
1350 : : }
1351 : :
1352 : : /* Now logical-or VALUE into OP0, unless it is zero. */
1353 : :
1354 : 122237 : if (! all_zero)
1355 : : {
1356 : 109060 : temp = expand_binop (mode, ior_optab, temp, value,
1357 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
1358 : 109060 : temp = force_reg (mode, temp);
1359 : : }
1360 : :
1361 : 122237 : if (op0 != temp)
1362 : : {
1363 : 122237 : op0 = copy_rtx (op0);
1364 : 122237 : emit_move_insn (op0, temp);
1365 : : }
1366 : 122237 : }
1367 : :
1368 : : /* Store a bit field that is split across multiple accessible memory objects.
1369 : :
1370 : : OP0 is the REG, SUBREG or MEM rtx for the first of the objects.
1371 : : BITSIZE is the field width; BITPOS the position of its first bit
1372 : : (within the word).
1373 : : VALUE is the value to store, which has mode VALUE_MODE.
1374 : : If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is
1375 : : a BLKmode MEM.
1376 : :
1377 : : If REVERSE is true, the store is to be done in reverse order.
1378 : :
1379 : : This does not yet handle fields wider than BITS_PER_WORD. */
1380 : :
1381 : : static void
1382 : 6672 : store_split_bit_field (rtx op0, opt_scalar_int_mode op0_mode,
1383 : : unsigned HOST_WIDE_INT bitsize,
1384 : : unsigned HOST_WIDE_INT bitpos,
1385 : : poly_uint64 bitregion_start, poly_uint64 bitregion_end,
1386 : : rtx value, scalar_int_mode value_mode, bool reverse)
1387 : : {
1388 : 6672 : unsigned int unit, total_bits, bitsdone = 0;
1389 : :
1390 : : /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
1391 : : much at a time. */
1392 : 6672 : if (REG_P (op0) || GET_CODE (op0) == SUBREG)
1393 : 64 : unit = BITS_PER_WORD;
1394 : : else
1395 : 6608 : unit = MIN (MEM_ALIGN (op0), BITS_PER_WORD);
1396 : :
1397 : : /* If OP0 is a memory with a mode, then UNIT must not be larger than
1398 : : OP0's mode as well. Otherwise, store_fixed_bit_field will call us
1399 : : again, and we will mutually recurse forever. */
1400 : 6672 : if (MEM_P (op0) && op0_mode.exists ())
1401 : 5115 : unit = MIN (unit, GET_MODE_BITSIZE (op0_mode.require ()));
1402 : :
1403 : : /* If VALUE is a constant other than a CONST_INT, get it into a register in
1404 : : WORD_MODE. If we can do this using gen_lowpart_common, do so. Note
1405 : : that VALUE might be a floating-point constant. */
1406 : 6672 : if (CONSTANT_P (value) && !CONST_INT_P (value))
1407 : : {
1408 : 0 : rtx word = gen_lowpart_common (word_mode, value);
1409 : :
1410 : 0 : if (word && (value != word))
1411 : : value = word;
1412 : : else
1413 : 0 : value = gen_lowpart_common (word_mode, force_reg (value_mode, value));
1414 : 0 : value_mode = word_mode;
1415 : : }
1416 : :
1417 : 6672 : total_bits = GET_MODE_BITSIZE (value_mode);
1418 : :
1419 : 31091 : while (bitsdone < bitsize)
1420 : : {
1421 : 24419 : unsigned HOST_WIDE_INT thissize;
1422 : 24419 : unsigned HOST_WIDE_INT thispos;
1423 : 24419 : unsigned HOST_WIDE_INT offset;
1424 : 24419 : rtx part;
1425 : :
1426 : 24419 : offset = (bitpos + bitsdone) / unit;
1427 : 24419 : thispos = (bitpos + bitsdone) % unit;
1428 : :
1429 : : /* When region of bytes we can touch is restricted, decrease
1430 : : UNIT close to the end of the region as needed. If op0 is a REG
1431 : : or SUBREG of REG, don't do this, as there can't be data races
1432 : : on a register and we can expand shorter code in some cases. */
1433 : 30805 : if (maybe_ne (bitregion_end, 0U)
1434 : 24419 : && unit > BITS_PER_UNIT
1435 : 13628 : && maybe_gt (bitpos + bitsdone - thispos + unit, bitregion_end + 1)
1436 : 6443 : && !REG_P (op0)
1437 : 30805 : && (GET_CODE (op0) != SUBREG || !REG_P (SUBREG_REG (op0))))
1438 : : {
1439 : 6386 : unit = unit / 2;
1440 : 6386 : continue;
1441 : : }
1442 : :
1443 : : /* THISSIZE must not overrun a word boundary. Otherwise,
1444 : : store_fixed_bit_field will call us again, and we will mutually
1445 : : recurse forever. */
1446 : 18033 : thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
1447 : 18033 : thissize = MIN (thissize, unit - thispos);
1448 : :
1449 : 18033 : if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
1450 : : {
1451 : : /* Fetch successively less significant portions. */
1452 : 216 : if (CONST_INT_P (value))
1453 : 108 : part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
1454 : : >> (bitsize - bitsdone - thissize))
1455 : : & ((HOST_WIDE_INT_1 << thissize) - 1));
1456 : : /* Likewise, but the source is little-endian. */
1457 : 108 : else if (reverse)
1458 : 108 : part = extract_fixed_bit_field (word_mode, value, value_mode,
1459 : : thissize,
1460 : : bitsize - bitsdone - thissize,
1461 : : NULL_RTX, 1, false);
1462 : : else
1463 : : /* The args are chosen so that the last part includes the
1464 : : lsb. Give extract_bit_field the value it needs (with
1465 : : endianness compensation) to fetch the piece we want. */
1466 : : part = extract_fixed_bit_field (word_mode, value, value_mode,
1467 : : thissize,
1468 : : total_bits - bitsize + bitsdone,
1469 : : NULL_RTX, 1, false);
1470 : : }
1471 : : else
1472 : : {
1473 : : /* Fetch successively more significant portions. */
1474 : 17817 : if (CONST_INT_P (value))
1475 : 12912 : part = GEN_INT (((unsigned HOST_WIDE_INT) (INTVAL (value))
1476 : : >> bitsdone)
1477 : : & ((HOST_WIDE_INT_1 << thissize) - 1));
1478 : : /* Likewise, but the source is big-endian. */
1479 : 4905 : else if (reverse)
1480 : : part = extract_fixed_bit_field (word_mode, value, value_mode,
1481 : : thissize,
1482 : : total_bits - bitsdone - thissize,
1483 : : NULL_RTX, 1, false);
1484 : : else
1485 : 4905 : part = extract_fixed_bit_field (word_mode, value, value_mode,
1486 : : thissize, bitsdone, NULL_RTX,
1487 : : 1, false);
1488 : : }
1489 : :
1490 : : /* If OP0 is a register, then handle OFFSET here. */
1491 : 18033 : rtx op0_piece = op0;
1492 : 18033 : opt_scalar_int_mode op0_piece_mode = op0_mode;
1493 : 18033 : if (SUBREG_P (op0) || REG_P (op0))
1494 : : {
1495 : 128 : scalar_int_mode imode;
1496 : 128 : if (op0_mode.exists (&imode)
1497 : 128 : && GET_MODE_SIZE (imode) < UNITS_PER_WORD)
1498 : : {
1499 : 0 : if (offset)
1500 : 0 : op0_piece = const0_rtx;
1501 : : }
1502 : : else
1503 : : {
1504 : 128 : op0_piece = operand_subword_force (op0,
1505 : 128 : offset * unit / BITS_PER_WORD,
1506 : 128 : GET_MODE (op0));
1507 : 128 : op0_piece_mode = word_mode;
1508 : : }
1509 : 128 : offset &= BITS_PER_WORD / unit - 1;
1510 : : }
1511 : :
1512 : : /* OFFSET is in UNITs, and UNIT is in bits. If WORD is const0_rtx,
1513 : : it is just an out-of-bounds access. Ignore it. */
1514 : 18033 : if (op0_piece != const0_rtx)
1515 : 18033 : store_fixed_bit_field (op0_piece, op0_piece_mode, thissize,
1516 : 18033 : offset * unit + thispos, bitregion_start,
1517 : : bitregion_end, part, word_mode, reverse);
1518 : 18033 : bitsdone += thissize;
1519 : : }
1520 : 6672 : }
1521 : :
1522 : : /* A subroutine of extract_bit_field_1 that converts return value X
1523 : : to either MODE or TMODE. MODE, TMODE and UNSIGNEDP are arguments
1524 : : to extract_bit_field. */
1525 : :
1526 : : static rtx
1527 : 882736 : convert_extracted_bit_field (rtx x, machine_mode mode,
1528 : : machine_mode tmode, bool unsignedp)
1529 : : {
1530 : 882736 : if (GET_MODE (x) == tmode || GET_MODE (x) == mode)
1531 : : return x;
1532 : :
1533 : : /* If the x mode is not a scalar integral, first convert to the
1534 : : integer mode of that size and then access it as a floating-point
1535 : : value via a SUBREG. */
1536 : 19946 : if (!SCALAR_INT_MODE_P (tmode))
1537 : : {
1538 : 10126 : scalar_int_mode int_mode = int_mode_for_mode (tmode).require ();
1539 : 10126 : x = convert_to_mode (int_mode, x, unsignedp);
1540 : 10126 : x = force_reg (int_mode, x);
1541 : 10126 : return gen_lowpart (tmode, x);
1542 : : }
1543 : :
1544 : 9820 : return convert_to_mode (tmode, x, unsignedp);
1545 : : }
1546 : :
1547 : : /* Try to use an ext(z)v pattern to extract a field from OP0.
1548 : : Return the extracted value on success, otherwise return null.
1549 : : EXTV describes the extraction instruction to use. If OP0_MODE
1550 : : is defined, it is the mode of OP0, otherwise OP0 is a BLKmode MEM.
1551 : : The other arguments are as for extract_bit_field. */
1552 : :
1553 : : static rtx
1554 : 146881 : extract_bit_field_using_extv (const extraction_insn *extv, rtx op0,
1555 : : opt_scalar_int_mode op0_mode,
1556 : : unsigned HOST_WIDE_INT bitsize,
1557 : : unsigned HOST_WIDE_INT bitnum,
1558 : : int unsignedp, rtx target,
1559 : : machine_mode mode, machine_mode tmode)
1560 : : {
1561 : 146881 : class expand_operand ops[4];
1562 : 146881 : rtx spec_target = target;
1563 : 146881 : rtx spec_target_subreg = 0;
1564 : 146881 : scalar_int_mode ext_mode = extv->field_mode;
1565 : 146881 : unsigned unit = GET_MODE_BITSIZE (ext_mode);
1566 : :
1567 : 146881 : if (bitsize == 0 || unit < bitsize)
1568 : : return NULL_RTX;
1569 : :
1570 : 146881 : if (MEM_P (op0))
1571 : : /* Get a reference to the first byte of the field. */
1572 : 0 : op0 = narrow_bit_field_mem (op0, extv->struct_mode, bitsize, bitnum,
1573 : : &bitnum);
1574 : : else
1575 : : {
1576 : : /* Convert from counting within OP0 to counting in EXT_MODE. */
1577 : 146881 : if (BYTES_BIG_ENDIAN)
1578 : : bitnum += unit - GET_MODE_BITSIZE (op0_mode.require ());
1579 : :
1580 : : /* If op0 is a register, we need it in EXT_MODE to make it
1581 : : acceptable to the format of ext(z)v. */
1582 : 146881 : if (GET_CODE (op0) == SUBREG && op0_mode.require () != ext_mode)
1583 : 0 : return NULL_RTX;
1584 : 146881 : if (REG_P (op0) && op0_mode.require () != ext_mode)
1585 : 49497 : op0 = gen_lowpart_SUBREG (ext_mode, op0);
1586 : : }
1587 : :
1588 : : /* If BITS_BIG_ENDIAN is zero on a BYTES_BIG_ENDIAN machine, we count
1589 : : "backwards" from the size of the unit we are extracting from.
1590 : : Otherwise, we count bits from the most significant on a
1591 : : BYTES/BITS_BIG_ENDIAN machine. */
1592 : :
1593 : 146881 : if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
1594 : : bitnum = unit - bitsize - bitnum;
1595 : :
1596 : 146881 : if (target == 0)
1597 : 28767 : target = spec_target = gen_reg_rtx (tmode);
1598 : :
1599 : 146881 : if (GET_MODE (target) != ext_mode)
1600 : : {
1601 : 79830 : rtx temp;
1602 : : /* Don't use LHS paradoxical subreg if explicit truncation is needed
1603 : : between the mode of the extraction (word_mode) and the target
1604 : : mode. Instead, create a temporary and use convert_move to set
1605 : : the target. */
1606 : 79830 : if (REG_P (target)
1607 : 79021 : && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode)
1608 : 158851 : && (temp = gen_lowpart_if_possible (ext_mode, target)))
1609 : : {
1610 : 78499 : target = temp;
1611 : 78499 : if (partial_subreg_p (GET_MODE (spec_target), ext_mode))
1612 : 77634 : spec_target_subreg = target;
1613 : : }
1614 : : else
1615 : 1331 : target = gen_reg_rtx (ext_mode);
1616 : : }
1617 : :
1618 : 146881 : create_output_operand (&ops[0], target, ext_mode);
1619 : 146881 : create_fixed_operand (&ops[1], op0);
1620 : 146881 : create_integer_operand (&ops[2], bitsize);
1621 : 146881 : create_integer_operand (&ops[3], bitnum);
1622 : 146881 : if (maybe_expand_insn (extv->icode, 4, ops))
1623 : : {
1624 : 1854 : target = ops[0].value;
1625 : 1854 : if (target == spec_target)
1626 : : return target;
1627 : 1854 : if (target == spec_target_subreg)
1628 : : return spec_target;
1629 : 52 : return convert_extracted_bit_field (target, mode, tmode, unsignedp);
1630 : : }
1631 : : return NULL_RTX;
1632 : : }
1633 : :
1634 : : /* See whether it would be valid to extract the part of OP0 with
1635 : : mode OP0_MODE described by BITNUM and BITSIZE into a value of
1636 : : mode MODE using a subreg operation.
1637 : : Return the subreg if so, otherwise return null. */
1638 : :
1639 : : static rtx
1640 : 824559 : extract_bit_field_as_subreg (machine_mode mode, rtx op0,
1641 : : machine_mode op0_mode,
1642 : : poly_uint64 bitsize, poly_uint64 bitnum)
1643 : : {
1644 : 824559 : poly_uint64 bytenum;
1645 : 824559 : if (multiple_p (bitnum, BITS_PER_UNIT, &bytenum)
1646 : 784001 : && known_eq (bitsize, GET_MODE_BITSIZE (mode))
1647 : 824559 : && lowpart_bit_field_p (bitnum, bitsize, op0_mode)
1648 : 1608560 : && TRULY_NOOP_TRUNCATION_MODES_P (mode, op0_mode))
1649 : 668296 : return force_subreg (mode, op0, op0_mode, bytenum);
1650 : : return NULL_RTX;
1651 : : }
1652 : :
1653 : : /* A subroutine of extract_bit_field, with the same arguments.
1654 : : If UNSIGNEDP is -1, the result need not be sign or zero extended.
1655 : : If FALLBACK_P is true, fall back to extract_fixed_bit_field
1656 : : if we can find no other means of implementing the operation.
1657 : : if FALLBACK_P is false, return NULL instead. */
1658 : :
1659 : : static rtx
1660 : 1123485 : extract_bit_field_1 (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
1661 : : int unsignedp, rtx target, machine_mode mode,
1662 : : machine_mode tmode, bool reverse, bool fallback_p,
1663 : : rtx *alt_rtl)
1664 : : {
1665 : 1123485 : rtx op0 = str_rtx;
1666 : 1123485 : machine_mode mode1;
1667 : :
1668 : 1123485 : if (tmode == VOIDmode)
1669 : 0 : tmode = mode;
1670 : :
1671 : 1132435 : while (GET_CODE (op0) == SUBREG)
1672 : : {
1673 : 8950 : bitnum += SUBREG_BYTE (op0) * BITS_PER_UNIT;
1674 : 8950 : op0 = SUBREG_REG (op0);
1675 : : }
1676 : :
1677 : : /* If we have an out-of-bounds access to a register, just return an
1678 : : uninitialized register of the required mode. This can occur if the
1679 : : source code contains an out-of-bounds access to a small array. */
1680 : 2050958 : if (REG_P (op0) && known_ge (bitnum, GET_MODE_BITSIZE (GET_MODE (op0))))
1681 : 0 : return gen_reg_rtx (tmode);
1682 : :
1683 : 1123485 : if (REG_P (op0)
1684 : 927473 : && mode == GET_MODE (op0)
1685 : 154455 : && known_eq (bitnum, 0U)
1686 : 1366761 : && known_eq (bitsize, GET_MODE_BITSIZE (GET_MODE (op0))))
1687 : : {
1688 : 24161 : if (reverse)
1689 : 0 : op0 = flip_storage_order (mode, op0);
1690 : : /* We're trying to extract a full register from itself. */
1691 : 24161 : return op0;
1692 : : }
1693 : :
1694 : : /* First try to check for vector from vector extractions. */
1695 : 1035877 : if (VECTOR_MODE_P (GET_MODE (op0))
1696 : 81516 : && !MEM_P (op0)
1697 : 81179 : && VECTOR_MODE_P (tmode)
1698 : 9258 : && known_eq (bitsize, GET_MODE_PRECISION (tmode))
1699 : 2217164 : && maybe_gt (GET_MODE_SIZE (GET_MODE (op0)), GET_MODE_SIZE (tmode)))
1700 : : {
1701 : 9258 : machine_mode new_mode = GET_MODE (op0);
1702 : 27774 : if (GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode))
1703 : : {
1704 : 99 : scalar_mode inner_mode = GET_MODE_INNER (tmode);
1705 : 99 : poly_uint64 nunits;
1706 : 198 : if (!multiple_p (GET_MODE_BITSIZE (GET_MODE (op0)),
1707 : 99 : GET_MODE_UNIT_BITSIZE (tmode), &nunits)
1708 : 198 : || !related_vector_mode (tmode, inner_mode,
1709 : 99 : nunits).exists (&new_mode)
1710 : 198 : || maybe_ne (GET_MODE_SIZE (new_mode),
1711 : 297 : GET_MODE_SIZE (GET_MODE (op0))))
1712 : 0 : new_mode = VOIDmode;
1713 : : }
1714 : 9258 : poly_uint64 pos;
1715 : 9258 : if (new_mode != VOIDmode
1716 : 9258 : && (convert_optab_handler (vec_extract_optab, new_mode, tmode)
1717 : : != CODE_FOR_nothing)
1718 : 18516 : && multiple_p (bitnum, GET_MODE_BITSIZE (tmode), &pos))
1719 : : {
1720 : 8899 : class expand_operand ops[3];
1721 : 8899 : machine_mode outermode = new_mode;
1722 : 8899 : machine_mode innermode = tmode;
1723 : 8899 : enum insn_code icode
1724 : 8899 : = convert_optab_handler (vec_extract_optab, outermode, innermode);
1725 : :
1726 : 8899 : if (new_mode != GET_MODE (op0))
1727 : 21 : op0 = gen_lowpart (new_mode, op0);
1728 : 8899 : create_output_operand (&ops[0], target, innermode);
1729 : 8899 : ops[0].target = 1;
1730 : 8899 : create_input_operand (&ops[1], op0, outermode);
1731 : 8899 : create_integer_operand (&ops[2], pos);
1732 : 8899 : if (maybe_expand_insn (icode, 3, ops))
1733 : : {
1734 : 8899 : if (alt_rtl && ops[0].target)
1735 : 53 : *alt_rtl = target;
1736 : 8899 : target = ops[0].value;
1737 : 8899 : if (GET_MODE (target) != mode)
1738 : 8899 : return gen_lowpart (tmode, target);
1739 : : return target;
1740 : : }
1741 : : }
1742 : : }
1743 : :
1744 : : /* See if we can get a better vector mode before extracting. */
1745 : 1028715 : if (VECTOR_MODE_P (GET_MODE (op0))
1746 : 72617 : && !MEM_P (op0)
1747 : 1234985 : && GET_MODE_INNER (GET_MODE (op0)) != tmode)
1748 : : {
1749 : 9175 : machine_mode new_mode;
1750 : :
1751 : 9175 : if (GET_MODE_CLASS (tmode) == MODE_FLOAT)
1752 : 541 : new_mode = MIN_MODE_VECTOR_FLOAT;
1753 : : else if (GET_MODE_CLASS (tmode) == MODE_FRACT)
1754 : 0 : new_mode = MIN_MODE_VECTOR_FRACT;
1755 : : else if (GET_MODE_CLASS (tmode) == MODE_UFRACT)
1756 : 0 : new_mode = MIN_MODE_VECTOR_UFRACT;
1757 : : else if (GET_MODE_CLASS (tmode) == MODE_ACCUM)
1758 : 0 : new_mode = MIN_MODE_VECTOR_ACCUM;
1759 : : else if (GET_MODE_CLASS (tmode) == MODE_UACCUM)
1760 : 0 : new_mode = MIN_MODE_VECTOR_UACCUM;
1761 : : else
1762 : 8634 : new_mode = MIN_MODE_VECTOR_INT;
1763 : :
1764 : 147156 : FOR_EACH_MODE_FROM (new_mode, new_mode)
1765 : 293618 : if (known_eq (GET_MODE_SIZE (new_mode), GET_MODE_SIZE (GET_MODE (op0)))
1766 : 59724 : && known_eq (GET_MODE_UNIT_SIZE (new_mode), GET_MODE_SIZE (tmode))
1767 : 165159 : && known_eq (bitsize, GET_MODE_UNIT_PRECISION (new_mode))
1768 : 18350 : && multiple_p (bitnum, GET_MODE_UNIT_PRECISION (new_mode))
1769 : 9161 : && targetm.vector_mode_supported_p (new_mode)
1770 : 155928 : && targetm.modes_tieable_p (GET_MODE (op0), new_mode))
1771 : : break;
1772 : 9175 : if (new_mode != VOIDmode)
1773 : 8828 : op0 = gen_lowpart (new_mode, op0);
1774 : : }
1775 : :
1776 : : /* Use vec_extract patterns for extracting parts of vectors whenever
1777 : : available. If that fails, see whether the current modes and bitregion
1778 : : give a natural subreg. */
1779 : 1090425 : machine_mode outermode = GET_MODE (op0);
1780 : 1090425 : if (VECTOR_MODE_P (outermode) && !MEM_P (op0))
1781 : : {
1782 : 72280 : scalar_mode innermode = GET_MODE_INNER (outermode);
1783 : :
1784 : 72280 : enum insn_code icode
1785 : 72280 : = convert_optab_handler (vec_extract_optab, outermode, innermode);
1786 : :
1787 : 72280 : poly_uint64 pos;
1788 : 72280 : if (icode != CODE_FOR_nothing
1789 : 72283 : && known_eq (bitsize, GET_MODE_PRECISION (innermode))
1790 : 142115 : && multiple_p (bitnum, GET_MODE_PRECISION (innermode), &pos))
1791 : : {
1792 : 69832 : class expand_operand ops[3];
1793 : :
1794 : 69832 : create_output_operand (&ops[0], target,
1795 : 69832 : insn_data[icode].operand[0].mode);
1796 : 69832 : ops[0].target = 1;
1797 : 69832 : create_input_operand (&ops[1], op0, outermode);
1798 : 69832 : create_integer_operand (&ops[2], pos);
1799 : 69832 : if (maybe_expand_insn (icode, 3, ops))
1800 : : {
1801 : 69832 : if (alt_rtl && ops[0].target)
1802 : 17209 : *alt_rtl = target;
1803 : 69832 : target = ops[0].value;
1804 : 69832 : if (GET_MODE (target) != mode)
1805 : 69832 : return gen_lowpart (tmode, target);
1806 : : return target;
1807 : : }
1808 : : }
1809 : : /* Using subregs is useful if we're extracting one register vector
1810 : : from a multi-register vector. extract_bit_field_as_subreg checks
1811 : : for valid bitsize and bitnum, so we don't need to do that here. */
1812 : 2448 : if (VECTOR_MODE_P (mode))
1813 : : {
1814 : 49 : rtx sub = extract_bit_field_as_subreg (mode, op0, outermode,
1815 : : bitsize, bitnum);
1816 : 49 : if (sub)
1817 : : return sub;
1818 : : }
1819 : : }
1820 : :
1821 : : /* Make sure we are playing with integral modes. Pun with subregs
1822 : : if we aren't. */
1823 : 1020549 : opt_scalar_int_mode op0_mode = int_mode_for_mode (GET_MODE (op0));
1824 : 1020549 : scalar_int_mode imode;
1825 : 1020549 : if (!op0_mode.exists (&imode) || imode != GET_MODE (op0))
1826 : : {
1827 : 173622 : if (MEM_P (op0))
1828 : 169515 : op0 = adjust_bitfield_address_size (op0, op0_mode.else_blk (),
1829 : : 0, MEM_SIZE (op0));
1830 : 4107 : else if (op0_mode.exists (&imode))
1831 : : {
1832 : 4076 : op0 = gen_lowpart (imode, op0);
1833 : :
1834 : : /* If we got a SUBREG, force it into a register since we
1835 : : aren't going to be able to do another SUBREG on it. */
1836 : 4076 : if (GET_CODE (op0) == SUBREG)
1837 : 3799 : op0 = force_reg (imode, op0);
1838 : : }
1839 : : else
1840 : : {
1841 : 62 : poly_int64 size = GET_MODE_SIZE (GET_MODE (op0));
1842 : 31 : rtx mem = assign_stack_temp (GET_MODE (op0), size);
1843 : 31 : emit_move_insn (mem, op0);
1844 : 31 : op0 = adjust_bitfield_address_size (mem, BLKmode, 0, size);
1845 : : }
1846 : : }
1847 : :
1848 : : /* ??? We currently assume TARGET is at least as big as BITSIZE.
1849 : : If that's wrong, the solution is to test for it and set TARGET to 0
1850 : : if needed. */
1851 : :
1852 : : /* Get the mode of the field to use for atomic access or subreg
1853 : : conversion. */
1854 : 1020549 : if (!SCALAR_INT_MODE_P (tmode)
1855 : 1020549 : || !mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0).exists (&mode1))
1856 : 307858 : mode1 = mode;
1857 : 1020549 : gcc_assert (mode1 != BLKmode);
1858 : :
1859 : : /* Extraction of a full MODE1 value can be done with a subreg as long
1860 : : as the least significant bit of the value is the least significant
1861 : : bit of either OP0 or a word of OP0. */
1862 : 1020549 : if (!MEM_P (op0) && !reverse && op0_mode.exists (&imode))
1863 : : {
1864 : 824510 : rtx sub = extract_bit_field_as_subreg (mode1, op0, imode,
1865 : : bitsize, bitnum);
1866 : 824510 : if (sub)
1867 : 662786 : return convert_extracted_bit_field (sub, mode, tmode, unsignedp);
1868 : : }
1869 : :
1870 : : /* Extraction of a full MODE1 value can be done with a load as long as
1871 : : the field is on a byte boundary and is sufficiently aligned. */
1872 : 357763 : poly_uint64 bytenum;
1873 : 357763 : if (simple_mem_bitfield_p (op0, bitsize, bitnum, mode1, &bytenum))
1874 : : {
1875 : 57078 : op0 = adjust_bitfield_address (op0, mode1, bytenum);
1876 : 57078 : if (reverse)
1877 : 51 : op0 = flip_storage_order (mode1, op0);
1878 : 57078 : return convert_extracted_bit_field (op0, mode, tmode, unsignedp);
1879 : : }
1880 : :
1881 : : /* If we have a memory source and a non-constant bit offset, restrict
1882 : : the memory to the referenced bytes. This is a worst-case fallback
1883 : : but is useful for things like vector booleans. */
1884 : 300685 : if (MEM_P (op0) && !bitnum.is_constant ())
1885 : : {
1886 : : bytenum = bits_to_bytes_round_down (bitnum);
1887 : : bitnum = num_trailing_bits (bitnum);
1888 : : poly_uint64 bytesize = bits_to_bytes_round_up (bitnum + bitsize);
1889 : : op0 = adjust_bitfield_address_size (op0, BLKmode, bytenum, bytesize);
1890 : : op0_mode = opt_scalar_int_mode ();
1891 : : }
1892 : :
1893 : : /* It's possible we'll need to handle other cases here for
1894 : : polynomial bitnum and bitsize. */
1895 : :
1896 : : /* From here on we need to be looking at a fixed-size insertion. */
1897 : 300685 : return extract_integral_bit_field (op0, op0_mode, bitsize.to_constant (),
1898 : : bitnum.to_constant (), unsignedp,
1899 : 300685 : target, mode, tmode, reverse, fallback_p);
1900 : : }
1901 : :
1902 : : /* Subroutine of extract_bit_field_1, with the same arguments, except
1903 : : that BITSIZE and BITNUM are constant. Handle cases specific to
1904 : : integral modes. If OP0_MODE is defined, it is the mode of OP0,
1905 : : otherwise OP0 is a BLKmode MEM. */
1906 : :
1907 : : static rtx
1908 : 300685 : extract_integral_bit_field (rtx op0, opt_scalar_int_mode op0_mode,
1909 : : unsigned HOST_WIDE_INT bitsize,
1910 : : unsigned HOST_WIDE_INT bitnum, int unsignedp,
1911 : : rtx target, machine_mode mode, machine_mode tmode,
1912 : : bool reverse, bool fallback_p)
1913 : : {
1914 : : /* Handle fields bigger than a word. */
1915 : :
1916 : 303603 : if (bitsize > BITS_PER_WORD)
1917 : : {
1918 : : /* Here we transfer the words of the field
1919 : : in the order least significant first.
1920 : : This is because the most significant word is the one which may
1921 : : be less than full. */
1922 : :
1923 : 1409 : const bool backwards = WORDS_BIG_ENDIAN;
1924 : 1409 : unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
1925 : 1409 : unsigned int i;
1926 : 1409 : rtx_insn *last;
1927 : :
1928 : 1409 : if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1929 : 1387 : target = gen_reg_rtx (mode);
1930 : :
1931 : : /* In case we're about to clobber a base register or something
1932 : : (see gcc.c-torture/execute/20040625-1.c). */
1933 : 1409 : if (reg_mentioned_p (target, op0))
1934 : 0 : target = gen_reg_rtx (mode);
1935 : :
1936 : : /* Indicate for flow that the entire target reg is being set. */
1937 : 1409 : emit_clobber (target);
1938 : :
1939 : : /* The mode must be fixed-size, since extract_bit_field_1 handles
1940 : : extractions from variable-sized objects before calling this
1941 : : function. */
1942 : 1409 : unsigned int target_size
1943 : 1409 : = GET_MODE_SIZE (GET_MODE (target)).to_constant ();
1944 : 1409 : last = get_last_insn ();
1945 : 4227 : for (i = 0; i < nwords; i++)
1946 : : {
1947 : : /* If I is 0, use the low-order word in both field and target;
1948 : : if I is 1, use the next to lowest word; and so on. */
1949 : : /* Word number in TARGET to use. */
1950 : 2818 : unsigned int wordnum
1951 : : = (backwards ? target_size / UNITS_PER_WORD - i - 1 : i);
1952 : : /* Offset from start of field in OP0. */
1953 : 5636 : unsigned int bit_offset = (backwards ^ reverse
1954 : 2818 : ? MAX ((int) bitsize - ((int) i + 1)
1955 : : * BITS_PER_WORD,
1956 : : 0)
1957 : 2818 : : (int) i * BITS_PER_WORD);
1958 : 2818 : rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
1959 : 2818 : rtx result_part
1960 : 2858 : = extract_bit_field_1 (op0, MIN (BITS_PER_WORD,
1961 : : bitsize - i * BITS_PER_WORD),
1962 : 2818 : bitnum + bit_offset,
1963 : : (unsignedp ? 1 : -1), target_part,
1964 : : mode, word_mode, reverse, fallback_p, NULL);
1965 : :
1966 : 2818 : gcc_assert (target_part);
1967 : 2818 : if (!result_part)
1968 : : {
1969 : 0 : delete_insns_since (last);
1970 : 0 : return NULL;
1971 : : }
1972 : :
1973 : 2818 : if (result_part != target_part)
1974 : 2720 : emit_move_insn (target_part, result_part);
1975 : : }
1976 : :
1977 : 1409 : if (unsignedp)
1978 : : {
1979 : : /* Unless we've filled TARGET, the upper regs in a multi-reg value
1980 : : need to be zero'd out. */
1981 : 1389 : if (target_size > nwords * UNITS_PER_WORD)
1982 : : {
1983 : 0 : unsigned int i, total_words;
1984 : :
1985 : 0 : total_words = target_size / UNITS_PER_WORD;
1986 : 0 : for (i = nwords; i < total_words; i++)
1987 : 0 : emit_move_insn
1988 : 0 : (operand_subword (target,
1989 : 0 : backwards ? total_words - i - 1 : i,
1990 : : 1, VOIDmode),
1991 : : const0_rtx);
1992 : : }
1993 : 1389 : return target;
1994 : : }
1995 : :
1996 : : /* Signed bit field: sign-extend with two arithmetic shifts. */
1997 : 40 : target = expand_shift (LSHIFT_EXPR, mode, target,
1998 : 20 : GET_MODE_BITSIZE (mode) - bitsize, NULL_RTX, 0);
1999 : 40 : return expand_shift (RSHIFT_EXPR, mode, target,
2000 : 20 : GET_MODE_BITSIZE (mode) - bitsize, NULL_RTX, 0);
2001 : : }
2002 : :
2003 : : /* If OP0 is a multi-word register, narrow it to the affected word.
2004 : : If the region spans two words, defer to extract_split_bit_field. */
2005 : 463408 : if (!MEM_P (op0) && GET_MODE_SIZE (op0_mode.require ()) > UNITS_PER_WORD)
2006 : : {
2007 : 4038 : if (bitnum % BITS_PER_WORD + bitsize > BITS_PER_WORD)
2008 : : {
2009 : 1080 : if (!fallback_p)
2010 : : return NULL_RTX;
2011 : 40 : target = extract_split_bit_field (op0, op0_mode, bitsize, bitnum,
2012 : : unsignedp, reverse);
2013 : 40 : return convert_extracted_bit_field (target, mode, tmode, unsignedp);
2014 : : }
2015 : : /* If OP0 is a hard register, copy it to a pseudo before calling
2016 : : force_subreg. */
2017 : 2958 : if (REG_P (op0) && HARD_REGISTER_P (op0))
2018 : 1 : op0 = copy_to_reg (op0);
2019 : 2958 : op0 = force_subreg (word_mode, op0, op0_mode.require (),
2020 : 3504 : bitnum / BITS_PER_WORD * UNITS_PER_WORD);
2021 : 2958 : op0_mode = word_mode;
2022 : 3231 : bitnum %= BITS_PER_WORD;
2023 : : }
2024 : :
2025 : : /* From here on we know the desired field is smaller than a word.
2026 : : If OP0 is a register, it too fits within a word. */
2027 : 298196 : enum extraction_pattern pattern = unsignedp ? EP_extzv : EP_extv;
2028 : 298196 : extraction_insn extv;
2029 : 298196 : if (!MEM_P (op0)
2030 : 160651 : && !reverse
2031 : : /* ??? We could limit the structure size to the part of OP0 that
2032 : : contains the field, with appropriate checks for endianness
2033 : : and TARGET_TRULY_NOOP_TRUNCATION. */
2034 : 458839 : && get_best_reg_extraction_insn (&extv, pattern,
2035 : 472601 : GET_MODE_BITSIZE (op0_mode.require ()),
2036 : : tmode))
2037 : : {
2038 : 146881 : rtx result = extract_bit_field_using_extv (&extv, op0, op0_mode,
2039 : : bitsize, bitnum,
2040 : : unsignedp, target, mode,
2041 : : tmode);
2042 : 146881 : if (result)
2043 : : return result;
2044 : : }
2045 : :
2046 : : /* If OP0 is a memory, try copying it to a register and seeing if a
2047 : : cheap register alternative is available. */
2048 : 296342 : if (MEM_P (op0) & !reverse)
2049 : : {
2050 : 137343 : if (get_best_mem_extraction_insn (&extv, pattern, bitsize, bitnum,
2051 : : tmode))
2052 : : {
2053 : 0 : rtx result = extract_bit_field_using_extv (&extv, op0, op0_mode,
2054 : : bitsize, bitnum,
2055 : : unsignedp, target, mode,
2056 : : tmode);
2057 : 0 : if (result)
2058 : 0 : return result;
2059 : : }
2060 : :
2061 : 137343 : rtx_insn *last = get_last_insn ();
2062 : :
2063 : : /* Try loading part of OP0 into a register and extracting the
2064 : : bitfield from that. */
2065 : 137343 : unsigned HOST_WIDE_INT bitpos;
2066 : 274686 : rtx xop0 = adjust_bit_field_mem_for_reg (pattern, op0, bitsize, bitnum,
2067 : 137343 : 0, 0, tmode, &bitpos);
2068 : 137343 : if (xop0)
2069 : : {
2070 : 134602 : xop0 = copy_to_reg (xop0);
2071 : 134602 : rtx result = extract_bit_field_1 (xop0, bitsize, bitpos,
2072 : : unsignedp, target,
2073 : : mode, tmode, reverse, false, NULL);
2074 : 134602 : if (result)
2075 : : return result;
2076 : 134602 : delete_insns_since (last);
2077 : : }
2078 : : }
2079 : :
2080 : 296342 : if (!fallback_p)
2081 : : return NULL;
2082 : :
2083 : : /* Find a correspondingly-sized integer field, so we can apply
2084 : : shifts and masks to it. */
2085 : 162780 : scalar_int_mode int_mode;
2086 : 162780 : if (!int_mode_for_mode (tmode).exists (&int_mode))
2087 : : /* If this fails, we should probably push op0 out to memory and then
2088 : : do a load. */
2089 : 0 : int_mode = int_mode_for_mode (mode).require ();
2090 : :
2091 : 162780 : target = extract_fixed_bit_field (int_mode, op0, op0_mode, bitsize,
2092 : : bitnum, target, unsignedp, reverse);
2093 : :
2094 : : /* Complex values must be reversed piecewise, so we need to undo the global
2095 : : reversal, convert to the complex mode and reverse again. */
2096 : 162780 : if (reverse && COMPLEX_MODE_P (tmode))
2097 : : {
2098 : 0 : target = flip_storage_order (int_mode, target);
2099 : 0 : target = convert_extracted_bit_field (target, mode, tmode, unsignedp);
2100 : 0 : target = flip_storage_order (tmode, target);
2101 : : }
2102 : : else
2103 : 162780 : target = convert_extracted_bit_field (target, mode, tmode, unsignedp);
2104 : :
2105 : : return target;
2106 : : }
2107 : :
2108 : : /* Generate code to extract a byte-field from STR_RTX
2109 : : containing BITSIZE bits, starting at BITNUM,
2110 : : and put it in TARGET if possible (if TARGET is nonzero).
2111 : : Regardless of TARGET, we return the rtx for where the value is placed.
2112 : :
2113 : : STR_RTX is the structure containing the byte (a REG or MEM).
2114 : : UNSIGNEDP is nonzero if this is an unsigned bit field.
2115 : : MODE is the natural mode of the field value once extracted.
2116 : : TMODE is the mode the caller would like the value to have;
2117 : : but the value may be returned with type MODE instead.
2118 : :
2119 : : If REVERSE is true, the extraction is to be done in reverse order.
2120 : :
2121 : : If a TARGET is specified and we can store in it at no extra cost,
2122 : : we do so, and return TARGET.
2123 : : Otherwise, we return a REG of mode TMODE or MODE, with TMODE preferred
2124 : : if they are equally easy.
2125 : :
2126 : : If the result can be stored at TARGET, and ALT_RTL is non-NULL,
2127 : : then *ALT_RTL is set to TARGET (before legitimziation). */
2128 : :
2129 : : rtx
2130 : 986065 : extract_bit_field (rtx str_rtx, poly_uint64 bitsize, poly_uint64 bitnum,
2131 : : int unsignedp, rtx target, machine_mode mode,
2132 : : machine_mode tmode, bool reverse, rtx *alt_rtl)
2133 : : {
2134 : 986065 : machine_mode mode1;
2135 : :
2136 : : /* Handle -fstrict-volatile-bitfields in the cases where it applies. */
2137 : 1972130 : if (maybe_ne (GET_MODE_BITSIZE (GET_MODE (str_rtx)), 0))
2138 : : mode1 = GET_MODE (str_rtx);
2139 : 269555 : else if (target && maybe_ne (GET_MODE_BITSIZE (GET_MODE (target)), 0))
2140 : : mode1 = GET_MODE (target);
2141 : : else
2142 : : mode1 = tmode;
2143 : :
2144 : 986065 : unsigned HOST_WIDE_INT ibitsize, ibitnum;
2145 : 986065 : scalar_int_mode int_mode;
2146 : 986065 : if (bitsize.is_constant (&ibitsize)
2147 : 986065 : && bitnum.is_constant (&ibitnum)
2148 : 1861314 : && is_a <scalar_int_mode> (mode1, &int_mode)
2149 : 875256 : && strict_volatile_bitfield_p (str_rtx, ibitsize, ibitnum,
2150 : 875256 : int_mode, 0, 0))
2151 : : {
2152 : : /* Extraction of a full INT_MODE value can be done with a simple load.
2153 : : We know here that the field can be accessed with one single
2154 : : instruction. For targets that support unaligned memory,
2155 : : an unaligned access may be necessary. */
2156 : 14 : if (ibitsize == GET_MODE_BITSIZE (int_mode))
2157 : : {
2158 : 0 : rtx result = adjust_bitfield_address (str_rtx, int_mode,
2159 : : ibitnum / BITS_PER_UNIT);
2160 : 0 : if (reverse)
2161 : 0 : result = flip_storage_order (int_mode, result);
2162 : 0 : gcc_assert (ibitnum % BITS_PER_UNIT == 0);
2163 : 0 : return convert_extracted_bit_field (result, mode, tmode, unsignedp);
2164 : : }
2165 : :
2166 : 7 : str_rtx = narrow_bit_field_mem (str_rtx, int_mode, ibitsize, ibitnum,
2167 : : &ibitnum);
2168 : 14 : gcc_assert (ibitnum + ibitsize <= GET_MODE_BITSIZE (int_mode));
2169 : 7 : str_rtx = copy_to_reg (str_rtx);
2170 : 7 : return extract_bit_field_1 (str_rtx, ibitsize, ibitnum, unsignedp,
2171 : : target, mode, tmode, reverse, true, alt_rtl);
2172 : : }
2173 : :
2174 : 986058 : return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp,
2175 : 986058 : target, mode, tmode, reverse, true, alt_rtl);
2176 : : }
2177 : :
2178 : : /* Use shifts and boolean operations to extract a field of BITSIZE bits
2179 : : from bit BITNUM of OP0. If OP0_MODE is defined, it is the mode of OP0,
2180 : : otherwise OP0 is a BLKmode MEM.
2181 : :
2182 : : UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value).
2183 : : If REVERSE is true, the extraction is to be done in reverse order.
2184 : :
2185 : : If TARGET is nonzero, attempts to store the value there
2186 : : and return TARGET, but this is not guaranteed.
2187 : : If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */
2188 : :
2189 : : static rtx
2190 : 182075 : extract_fixed_bit_field (machine_mode tmode, rtx op0,
2191 : : opt_scalar_int_mode op0_mode,
2192 : : unsigned HOST_WIDE_INT bitsize,
2193 : : unsigned HOST_WIDE_INT bitnum, rtx target,
2194 : : int unsignedp, bool reverse)
2195 : : {
2196 : 182075 : scalar_int_mode mode;
2197 : 182075 : if (MEM_P (op0))
2198 : : {
2199 : 151771 : if (!get_best_mode (bitsize, bitnum, 0, 0, MEM_ALIGN (op0),
2200 : 151771 : BITS_PER_WORD, MEM_VOLATILE_P (op0), &mode))
2201 : : /* The only way this should occur is if the field spans word
2202 : : boundaries. */
2203 : 4366 : return extract_split_bit_field (op0, op0_mode, bitsize, bitnum,
2204 : 4366 : unsignedp, reverse);
2205 : :
2206 : 147405 : op0 = narrow_bit_field_mem (op0, mode, bitsize, bitnum, &bitnum);
2207 : : }
2208 : : else
2209 : 30304 : mode = op0_mode.require ();
2210 : :
2211 : 177709 : return extract_fixed_bit_field_1 (tmode, op0, mode, bitsize, bitnum,
2212 : 177709 : target, unsignedp, reverse);
2213 : : }
2214 : :
2215 : : /* Helper function for extract_fixed_bit_field, extracts
2216 : : the bit field always using MODE, which is the mode of OP0.
2217 : : If UNSIGNEDP is -1, the result need not be sign or zero extended.
2218 : : The other arguments are as for extract_fixed_bit_field. */
2219 : :
2220 : : static rtx
2221 : 177709 : extract_fixed_bit_field_1 (machine_mode tmode, rtx op0, scalar_int_mode mode,
2222 : : unsigned HOST_WIDE_INT bitsize,
2223 : : unsigned HOST_WIDE_INT bitnum, rtx target,
2224 : : int unsignedp, bool reverse)
2225 : : {
2226 : : /* Note that bitsize + bitnum can be greater than GET_MODE_BITSIZE (mode)
2227 : : for invalid input, such as extract equivalent of f5 from
2228 : : gcc.dg/pr48335-2.c. */
2229 : :
2230 : 177709 : if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
2231 : : /* BITNUM is the distance between our msb and that of OP0.
2232 : : Convert it to the distance from the lsb. */
2233 : 456 : bitnum = GET_MODE_BITSIZE (mode) - bitsize - bitnum;
2234 : :
2235 : : /* Now BITNUM is always the distance between the field's lsb and that of OP0.
2236 : : We have reduced the big-endian case to the little-endian case. */
2237 : 177709 : if (reverse)
2238 : 228 : op0 = flip_storage_order (mode, op0);
2239 : :
2240 : 177709 : if (unsignedp)
2241 : : {
2242 : 118574 : if (bitnum)
2243 : : {
2244 : : /* If the field does not already start at the lsb,
2245 : : shift it so it does. */
2246 : : /* Maybe propagate the target for the shift. */
2247 : 46224 : rtx subtarget = (target != 0 && REG_P (target) ? target : 0);
2248 : 46224 : if (tmode != mode)
2249 : 23211 : subtarget = 0;
2250 : 46224 : op0 = expand_shift (RSHIFT_EXPR, mode, op0, bitnum, subtarget, 1);
2251 : : }
2252 : : /* Convert the value to the desired mode. TMODE must also be a
2253 : : scalar integer for this conversion to make sense, since we
2254 : : shouldn't reinterpret the bits. */
2255 : 118574 : scalar_int_mode new_mode = as_a <scalar_int_mode> (tmode);
2256 : 118574 : if (mode != new_mode)
2257 : 42359 : op0 = convert_to_mode (new_mode, op0, 1);
2258 : :
2259 : : /* Unless the msb of the field used to be the msb when we shifted,
2260 : : mask out the upper bits. */
2261 : :
2262 : 118574 : if (GET_MODE_BITSIZE (mode) != bitnum + bitsize
2263 : 118574 : && unsignedp != -1)
2264 : 92540 : return expand_binop (new_mode, and_optab, op0,
2265 : : mask_rtx (new_mode, 0, bitsize, 0),
2266 : 92540 : target, 1, OPTAB_LIB_WIDEN);
2267 : : return op0;
2268 : : }
2269 : :
2270 : : /* To extract a signed bit-field, first shift its msb to the msb of the word,
2271 : : then arithmetic-shift its lsb to the lsb of the word. */
2272 : 59135 : op0 = force_reg (mode, op0);
2273 : :
2274 : : /* Find the narrowest integer mode that contains the field. */
2275 : :
2276 : 59135 : opt_scalar_int_mode mode_iter;
2277 : 146809 : FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
2278 : 293618 : if (GET_MODE_BITSIZE (mode_iter.require ()) >= bitsize + bitnum)
2279 : : break;
2280 : :
2281 : 59135 : mode = mode_iter.require ();
2282 : 59135 : op0 = convert_to_mode (mode, op0, 0);
2283 : :
2284 : 59135 : if (mode != tmode)
2285 : 4689 : target = 0;
2286 : :
2287 : 118270 : if (GET_MODE_BITSIZE (mode) != (bitsize + bitnum))
2288 : : {
2289 : 54278 : int amount = GET_MODE_BITSIZE (mode) - (bitsize + bitnum);
2290 : : /* Maybe propagate the target for the shift. */
2291 : 54278 : rtx subtarget = (target != 0 && REG_P (target) ? target : 0);
2292 : 54278 : op0 = expand_shift (LSHIFT_EXPR, mode, op0, amount, subtarget, 1);
2293 : : }
2294 : :
2295 : 118270 : return expand_shift (RSHIFT_EXPR, mode, op0,
2296 : 59135 : GET_MODE_BITSIZE (mode) - bitsize, target, 0);
2297 : : }
2298 : :
2299 : : /* Return a constant integer (CONST_INT or CONST_DOUBLE) rtx with the value
2300 : : VALUE << BITPOS. */
2301 : :
2302 : : static rtx
2303 : 70272 : lshift_value (machine_mode mode, unsigned HOST_WIDE_INT value,
2304 : : int bitpos)
2305 : : {
2306 : 70272 : return immed_wide_int_const (wi::lshift (value, bitpos), mode);
2307 : : }
2308 : :
2309 : : /* Extract a bit field that is split across two words
2310 : : and return an RTX for the result.
2311 : :
2312 : : OP0 is the REG, SUBREG or MEM rtx for the first of the two words.
2313 : : BITSIZE is the field width; BITPOS, position of its first bit, in the word.
2314 : : UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.
2315 : : If OP0_MODE is defined, it is the mode of OP0, otherwise OP0 is
2316 : : a BLKmode MEM.
2317 : :
2318 : : If REVERSE is true, the extraction is to be done in reverse order. */
2319 : :
2320 : : static rtx
2321 : 4406 : extract_split_bit_field (rtx op0, opt_scalar_int_mode op0_mode,
2322 : : unsigned HOST_WIDE_INT bitsize,
2323 : : unsigned HOST_WIDE_INT bitpos, int unsignedp,
2324 : : bool reverse)
2325 : : {
2326 : 4406 : unsigned int unit;
2327 : 4406 : unsigned int bitsdone = 0;
2328 : 4406 : rtx result = NULL_RTX;
2329 : 4406 : int first = 1;
2330 : :
2331 : : /* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
2332 : : much at a time. */
2333 : 4406 : if (REG_P (op0) || GET_CODE (op0) == SUBREG)
2334 : 40 : unit = BITS_PER_WORD;
2335 : : else
2336 : 4408 : unit = MIN (MEM_ALIGN (op0), BITS_PER_WORD);
2337 : :
2338 : 18688 : while (bitsdone < bitsize)
2339 : : {
2340 : 14282 : unsigned HOST_WIDE_INT thissize;
2341 : 14282 : rtx part;
2342 : 14282 : unsigned HOST_WIDE_INT thispos;
2343 : 14282 : unsigned HOST_WIDE_INT offset;
2344 : :
2345 : 14282 : offset = (bitpos + bitsdone) / unit;
2346 : 14282 : thispos = (bitpos + bitsdone) % unit;
2347 : :
2348 : : /* THISSIZE must not overrun a word boundary. Otherwise,
2349 : : extract_fixed_bit_field will call us again, and we will mutually
2350 : : recurse forever. */
2351 : 14282 : thissize = MIN (bitsize - bitsdone, BITS_PER_WORD);
2352 : 14282 : thissize = MIN (thissize, unit - thispos);
2353 : :
2354 : : /* If OP0 is a register, then handle OFFSET here. */
2355 : 14282 : rtx op0_piece = op0;
2356 : 14282 : opt_scalar_int_mode op0_piece_mode = op0_mode;
2357 : 14282 : if (SUBREG_P (op0) || REG_P (op0))
2358 : : {
2359 : 80 : op0_piece = operand_subword_force (op0, offset, op0_mode.require ());
2360 : 80 : op0_piece_mode = word_mode;
2361 : 80 : offset = 0;
2362 : : }
2363 : :
2364 : : /* Extract the parts in bit-counting order,
2365 : : whose meaning is determined by BYTES_PER_UNIT.
2366 : : OFFSET is in UNITs, and UNIT is in bits. */
2367 : 28564 : part = extract_fixed_bit_field (word_mode, op0_piece, op0_piece_mode,
2368 : 14282 : thissize, offset * unit + thispos,
2369 : : 0, 1, reverse);
2370 : 14282 : bitsdone += thissize;
2371 : :
2372 : : /* Shift this part into place for the result. */
2373 : 14282 : if (reverse ? !BYTES_BIG_ENDIAN : BYTES_BIG_ENDIAN)
2374 : : {
2375 : 24 : if (bitsize != bitsdone)
2376 : 18 : part = expand_shift (LSHIFT_EXPR, word_mode, part,
2377 : 18 : bitsize - bitsdone, 0, 1);
2378 : : }
2379 : : else
2380 : : {
2381 : 14258 : if (bitsdone != thissize)
2382 : 9858 : part = expand_shift (LSHIFT_EXPR, word_mode, part,
2383 : 9858 : bitsdone - thissize, 0, 1);
2384 : : }
2385 : :
2386 : 14282 : if (first)
2387 : : result = part;
2388 : : else
2389 : : /* Combine the parts with bitwise or. This works
2390 : : because we extracted each part as an unsigned bit field. */
2391 : 9876 : result = expand_binop (word_mode, ior_optab, part, result, NULL_RTX, 1,
2392 : : OPTAB_LIB_WIDEN);
2393 : :
2394 : 14282 : first = 0;
2395 : : }
2396 : :
2397 : : /* Unsigned bit field: we are done. */
2398 : 4406 : if (unsignedp)
2399 : : return result;
2400 : : /* Signed bit field: sign-extend with two arithmetic shifts. */
2401 : 1486 : result = expand_shift (LSHIFT_EXPR, word_mode, result,
2402 : 1486 : BITS_PER_WORD - bitsize, NULL_RTX, 0);
2403 : 1486 : return expand_shift (RSHIFT_EXPR, word_mode, result,
2404 : 1486 : BITS_PER_WORD - bitsize, NULL_RTX, 0);
2405 : : }
2406 : :
2407 : : /* Try to read the low bits of SRC as an rvalue of mode MODE, preserving
2408 : : the bit pattern. SRC_MODE is the mode of SRC; if this is smaller than
2409 : : MODE, fill the upper bits with zeros. Fail if the layout of either
2410 : : mode is unknown (as for CC modes) or if the extraction would involve
2411 : : unprofitable mode punning. Return the value on success, otherwise
2412 : : return null.
2413 : :
2414 : : This is different from gen_lowpart* in these respects:
2415 : :
2416 : : - the returned value must always be considered an rvalue
2417 : :
2418 : : - when MODE is wider than SRC_MODE, the extraction involves
2419 : : a zero extension
2420 : :
2421 : : - when MODE is smaller than SRC_MODE, the extraction involves
2422 : : a truncation (and is thus subject to TARGET_TRULY_NOOP_TRUNCATION).
2423 : :
2424 : : In other words, this routine performs a computation, whereas the
2425 : : gen_lowpart* routines are conceptually lvalue or rvalue subreg
2426 : : operations. */
2427 : :
2428 : : rtx
2429 : 118518 : extract_low_bits (machine_mode mode, machine_mode src_mode, rtx src)
2430 : : {
2431 : 118518 : scalar_int_mode int_mode, src_int_mode;
2432 : :
2433 : 118518 : if (mode == src_mode)
2434 : : return src;
2435 : :
2436 : 77180 : if (CONSTANT_P (src))
2437 : : {
2438 : : /* simplify_gen_subreg can't be used here, as if simplify_subreg
2439 : : fails, it will happily create (subreg (symbol_ref)) or similar
2440 : : invalid SUBREGs. */
2441 : 12022 : poly_uint64 byte = subreg_lowpart_offset (mode, src_mode);
2442 : 12022 : rtx ret = simplify_subreg (mode, src, src_mode, byte);
2443 : 12022 : if (ret)
2444 : : return ret;
2445 : :
2446 : 22 : if (GET_MODE (src) == VOIDmode
2447 : 22 : || !validate_subreg (mode, src_mode, src, byte))
2448 : 5 : return NULL_RTX;
2449 : :
2450 : 17 : src = force_reg (GET_MODE (src), src);
2451 : 17 : return gen_rtx_SUBREG (mode, src, byte);
2452 : : }
2453 : :
2454 : 65158 : if (GET_MODE_CLASS (mode) == MODE_CC || GET_MODE_CLASS (src_mode) == MODE_CC)
2455 : : return NULL_RTX;
2456 : :
2457 : 130316 : if (known_eq (GET_MODE_BITSIZE (mode), GET_MODE_BITSIZE (src_mode))
2458 : 65158 : && targetm.modes_tieable_p (mode, src_mode))
2459 : : {
2460 : 3832 : rtx x = gen_lowpart_common (mode, src);
2461 : 3832 : if (x)
2462 : : return x;
2463 : : }
2464 : :
2465 : 61326 : if (!int_mode_for_mode (src_mode).exists (&src_int_mode)
2466 : 61313 : || !int_mode_for_mode (mode).exists (&int_mode))
2467 : 13 : return NULL_RTX;
2468 : :
2469 : 61313 : if (!targetm.modes_tieable_p (src_int_mode, src_mode))
2470 : : return NULL_RTX;
2471 : 60235 : if (!targetm.modes_tieable_p (int_mode, mode))
2472 : : return NULL_RTX;
2473 : :
2474 : 58150 : src = gen_lowpart (src_int_mode, src);
2475 : 58150 : if (!validate_subreg (int_mode, src_int_mode, src,
2476 : : subreg_lowpart_offset (int_mode, src_int_mode)))
2477 : : return NULL_RTX;
2478 : :
2479 : 58150 : src = convert_modes (int_mode, src_int_mode, src, true);
2480 : 58150 : src = gen_lowpart (mode, src);
2481 : 58150 : return src;
2482 : : }
2483 : :
2484 : : /* Add INC into TARGET. */
2485 : :
2486 : : void
2487 : 923 : expand_inc (rtx target, rtx inc)
2488 : : {
2489 : 923 : rtx value = expand_binop (GET_MODE (target), add_optab,
2490 : : target, inc,
2491 : : target, 0, OPTAB_LIB_WIDEN);
2492 : 923 : if (value != target)
2493 : 61 : emit_move_insn (target, value);
2494 : 923 : }
2495 : :
2496 : : /* Subtract DEC from TARGET. */
2497 : :
2498 : : void
2499 : 958 : expand_dec (rtx target, rtx dec)
2500 : : {
2501 : 958 : rtx value = expand_binop (GET_MODE (target), sub_optab,
2502 : : target, dec,
2503 : : target, 0, OPTAB_LIB_WIDEN);
2504 : 958 : if (value != target)
2505 : 0 : emit_move_insn (target, value);
2506 : 958 : }
2507 : :
2508 : : /* Output a shift instruction for expression code CODE,
2509 : : with SHIFTED being the rtx for the value to shift,
2510 : : and AMOUNT the rtx for the amount to shift by.
2511 : : Store the result in the rtx TARGET, if that is convenient.
2512 : : If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
2513 : : Return the rtx for where the value is.
2514 : : If that cannot be done, abort the compilation unless MAY_FAIL is true,
2515 : : in which case 0 is returned. */
2516 : :
2517 : : static rtx
2518 : 1392147 : expand_shift_1 (enum tree_code code, machine_mode mode, rtx shifted,
2519 : : rtx amount, rtx target, int unsignedp, bool may_fail = false)
2520 : : {
2521 : 1392147 : rtx op1, temp = 0;
2522 : 1392147 : int left = (code == LSHIFT_EXPR || code == LROTATE_EXPR);
2523 : 1392147 : int rotate = (code == LROTATE_EXPR || code == RROTATE_EXPR);
2524 : 1392147 : optab lshift_optab = ashl_optab;
2525 : 1392147 : optab rshift_arith_optab = ashr_optab;
2526 : 1392147 : optab rshift_uns_optab = lshr_optab;
2527 : 1392147 : optab lrotate_optab = rotl_optab;
2528 : 1392147 : optab rrotate_optab = rotr_optab;
2529 : 1392147 : machine_mode op1_mode;
2530 : 1392147 : scalar_mode scalar_mode = GET_MODE_INNER (mode);
2531 : 1392147 : int attempt;
2532 : 1392147 : bool speed = optimize_insn_for_speed_p ();
2533 : :
2534 : 1392147 : op1 = amount;
2535 : 1392147 : op1_mode = GET_MODE (op1);
2536 : :
2537 : : /* Determine whether the shift/rotate amount is a vector, or scalar. If the
2538 : : shift amount is a vector, use the vector/vector shift patterns. */
2539 : 1392147 : if (VECTOR_MODE_P (mode) && VECTOR_MODE_P (op1_mode))
2540 : : {
2541 : 1392147 : lshift_optab = vashl_optab;
2542 : 1392147 : rshift_arith_optab = vashr_optab;
2543 : 1392147 : rshift_uns_optab = vlshr_optab;
2544 : 1392147 : lrotate_optab = vrotl_optab;
2545 : 1392147 : rrotate_optab = vrotr_optab;
2546 : : }
2547 : :
2548 : : /* Previously detected shift-counts computed by NEGATE_EXPR
2549 : : and shifted in the other direction; but that does not work
2550 : : on all machines. */
2551 : :
2552 : 1392147 : if (SHIFT_COUNT_TRUNCATED)
2553 : : {
2554 : : if (CONST_INT_P (op1)
2555 : : && ((unsigned HOST_WIDE_INT) INTVAL (op1) >=
2556 : : (unsigned HOST_WIDE_INT) GET_MODE_BITSIZE (scalar_mode)))
2557 : : op1 = gen_int_shift_amount (mode,
2558 : : (unsigned HOST_WIDE_INT) INTVAL (op1)
2559 : : % GET_MODE_BITSIZE (scalar_mode));
2560 : : else if (GET_CODE (op1) == SUBREG
2561 : : && subreg_lowpart_p (op1)
2562 : : && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (op1)))
2563 : : && SCALAR_INT_MODE_P (GET_MODE (op1)))
2564 : : op1 = SUBREG_REG (op1);
2565 : : }
2566 : :
2567 : : /* Canonicalize rotates by constant amount. We may canonicalize
2568 : : to reduce the immediate or if the ISA can rotate by constants
2569 : : in only on direction. */
2570 : 1392147 : if (rotate && reverse_rotate_by_imm_p (scalar_mode, left, op1))
2571 : : {
2572 : 2638 : op1 = gen_int_shift_amount (mode, (GET_MODE_BITSIZE (scalar_mode)
2573 : 2638 : - INTVAL (op1)));
2574 : 2638 : left = !left;
2575 : 2638 : code = left ? LROTATE_EXPR : RROTATE_EXPR;
2576 : : }
2577 : :
2578 : : /* Rotation of 16bit values by 8 bits is effectively equivalent to a bswaphi.
2579 : : Note that this is not the case for bigger values. For instance a rotation
2580 : : of 0x01020304 by 16 bits gives 0x03040102 which is different from
2581 : : 0x04030201 (bswapsi). */
2582 : 1392147 : if (rotate
2583 : 7207 : && CONST_INT_P (op1)
2584 : 4551 : && INTVAL (op1) == BITS_PER_UNIT
2585 : 854 : && GET_MODE_SIZE (scalar_mode) == 2
2586 : 1392835 : && optab_handler (bswap_optab, mode) != CODE_FOR_nothing)
2587 : 687 : return expand_unop (mode, bswap_optab, shifted, NULL_RTX, unsignedp);
2588 : :
2589 : 1391460 : if (op1 == const0_rtx)
2590 : : return shifted;
2591 : :
2592 : : /* Check whether its cheaper to implement a left shift by a constant
2593 : : bit count by a sequence of additions. */
2594 : 1342869 : if (code == LSHIFT_EXPR
2595 : 799105 : && CONST_INT_P (op1)
2596 : 770722 : && INTVAL (op1) > 0
2597 : 770697 : && INTVAL (op1) < GET_MODE_PRECISION (scalar_mode)
2598 : 770697 : && INTVAL (op1) < MAX_BITS_PER_WORD
2599 : 766087 : && (shift_cost (speed, mode, INTVAL (op1))
2600 : 766087 : > INTVAL (op1) * add_cost (speed, mode))
2601 : 1344835 : && shift_cost (speed, mode, INTVAL (op1)) != MAX_COST)
2602 : : {
2603 : : int i;
2604 : 4083 : for (i = 0; i < INTVAL (op1); i++)
2605 : : {
2606 : 2117 : temp = force_reg (mode, shifted);
2607 : 2117 : shifted = expand_binop (mode, add_optab, temp, temp, NULL_RTX,
2608 : : unsignedp, OPTAB_LIB_WIDEN);
2609 : : }
2610 : : return shifted;
2611 : : }
2612 : :
2613 : 2681840 : for (attempt = 0; temp == 0 && attempt < 3; attempt++)
2614 : : {
2615 : 1340971 : enum optab_methods methods;
2616 : :
2617 : 1340971 : if (attempt == 0)
2618 : : methods = OPTAB_DIRECT;
2619 : 68 : else if (attempt == 1)
2620 : : methods = OPTAB_WIDEN;
2621 : : else
2622 : 34 : methods = OPTAB_LIB_WIDEN;
2623 : :
2624 : 1340971 : if (rotate)
2625 : : {
2626 : : /* Widening does not work for rotation. */
2627 : 6588 : if (methods == OPTAB_WIDEN)
2628 : 34 : continue;
2629 : 6554 : else if (methods == OPTAB_LIB_WIDEN)
2630 : : {
2631 : : /* If we have been unable to open-code this by a rotation,
2632 : : do it as the IOR or PLUS of two shifts. I.e., to rotate
2633 : : A by N bits, compute
2634 : : (A << N) | ((unsigned) A >> ((-N) & (C - 1)))
2635 : : where C is the bitsize of A. If N cannot be zero,
2636 : : use PLUS instead of IOR.
2637 : :
2638 : : It is theoretically possible that the target machine might
2639 : : not be able to perform either shift and hence we would
2640 : : be making two libcalls rather than just the one for the
2641 : : shift (similarly if IOR could not be done). We will allow
2642 : : this extremely unlikely lossage to avoid complicating the
2643 : : code below. */
2644 : :
2645 : 34 : rtx subtarget = target == shifted ? 0 : target;
2646 : 34 : rtx new_amount, other_amount;
2647 : 34 : rtx temp1;
2648 : :
2649 : 34 : new_amount = op1;
2650 : 34 : if (op1 == const0_rtx)
2651 : : return shifted;
2652 : 34 : else if (CONST_INT_P (op1))
2653 : 23 : other_amount = gen_int_shift_amount
2654 : 23 : (mode, GET_MODE_BITSIZE (scalar_mode) - INTVAL (op1));
2655 : : else
2656 : : {
2657 : 11 : other_amount
2658 : 22 : = simplify_gen_unary (NEG, GET_MODE (op1),
2659 : 11 : op1, GET_MODE (op1));
2660 : 11 : HOST_WIDE_INT mask = GET_MODE_PRECISION (scalar_mode) - 1;
2661 : 11 : other_amount
2662 : 11 : = simplify_gen_binary (AND, GET_MODE (op1), other_amount,
2663 : 11 : gen_int_mode (mask, GET_MODE (op1)));
2664 : : }
2665 : :
2666 : 34 : shifted = force_reg (mode, shifted);
2667 : :
2668 : 45 : temp = expand_shift_1 (left ? LSHIFT_EXPR : RSHIFT_EXPR,
2669 : : mode, shifted, new_amount, 0, 1);
2670 : 45 : temp1 = expand_shift_1 (left ? RSHIFT_EXPR : LSHIFT_EXPR,
2671 : : mode, shifted, other_amount,
2672 : : subtarget, 1);
2673 : 34 : return expand_binop (mode,
2674 : 34 : CONST_INT_P (op1) ? add_optab : ior_optab,
2675 : 34 : temp, temp1, target, unsignedp, methods);
2676 : : }
2677 : :
2678 : 9646 : temp = expand_binop (mode,
2679 : : left ? lrotate_optab : rrotate_optab,
2680 : : shifted, op1, target, unsignedp, methods);
2681 : : }
2682 : 1334383 : else if (unsignedp)
2683 : 1104584 : temp = expand_binop (mode,
2684 : : left ? lshift_optab : rshift_uns_optab,
2685 : : shifted, op1, target, unsignedp, methods);
2686 : :
2687 : : /* Do arithmetic shifts.
2688 : : Also, if we are going to widen the operand, we can just as well
2689 : : use an arithmetic right-shift instead of a logical one. */
2690 : 1340903 : if (temp == 0 && ! rotate
2691 : 546695 : && (! unsignedp || (! left && methods == OPTAB_WIDEN)))
2692 : : {
2693 : : enum optab_methods methods1 = methods;
2694 : :
2695 : : /* If trying to widen a log shift to an arithmetic shift,
2696 : : don't accept an arithmetic shift of the same size. */
2697 : : if (unsignedp)
2698 : : methods1 = OPTAB_MUST_WIDEN;
2699 : :
2700 : : /* Arithmetic shift */
2701 : :
2702 : 767043 : temp = expand_binop (mode,
2703 : : left ? lshift_optab : rshift_arith_optab,
2704 : : shifted, op1, target, unsignedp, methods1);
2705 : : }
2706 : :
2707 : : /* We used to try extzv here for logical right shifts, but that was
2708 : : only useful for one machine, the VAX, and caused poor code
2709 : : generation there for lshrdi3, so the code was deleted and a
2710 : : define_expand for lshrsi3 was added to vax.md. */
2711 : : }
2712 : :
2713 : 1340869 : gcc_assert (temp != NULL_RTX || may_fail);
2714 : : return temp;
2715 : : }
2716 : :
2717 : : /* Output a shift instruction for expression code CODE,
2718 : : with SHIFTED being the rtx for the value to shift,
2719 : : and AMOUNT the amount to shift by.
2720 : : Store the result in the rtx TARGET, if that is convenient.
2721 : : If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
2722 : : Return the rtx for where the value is. */
2723 : :
2724 : : rtx
2725 : 1134263 : expand_shift (enum tree_code code, machine_mode mode, rtx shifted,
2726 : : poly_int64 amount, rtx target, int unsignedp)
2727 : : {
2728 : 1134263 : return expand_shift_1 (code, mode, shifted,
2729 : : gen_int_shift_amount (mode, amount),
2730 : 1134263 : target, unsignedp);
2731 : : }
2732 : :
2733 : : /* Likewise, but return 0 if that cannot be done. */
2734 : :
2735 : : rtx
2736 : 308 : maybe_expand_shift (enum tree_code code, machine_mode mode, rtx shifted,
2737 : : int amount, rtx target, int unsignedp)
2738 : : {
2739 : 308 : return expand_shift_1 (code, mode,
2740 : 308 : shifted, GEN_INT (amount), target, unsignedp, true);
2741 : : }
2742 : :
2743 : : /* Output a shift instruction for expression code CODE,
2744 : : with SHIFTED being the rtx for the value to shift,
2745 : : and AMOUNT the tree for the amount to shift by.
2746 : : Store the result in the rtx TARGET, if that is convenient.
2747 : : If UNSIGNEDP is nonzero, do a logical shift; otherwise, arithmetic.
2748 : : Return the rtx for where the value is. */
2749 : :
2750 : : rtx
2751 : 257508 : expand_variable_shift (enum tree_code code, machine_mode mode, rtx shifted,
2752 : : tree amount, rtx target, int unsignedp)
2753 : : {
2754 : 257508 : return expand_shift_1 (code, mode,
2755 : 257508 : shifted, expand_normal (amount), target, unsignedp);
2756 : : }
2757 : :
2758 : :
2759 : : static void synth_mult (struct algorithm *, unsigned HOST_WIDE_INT,
2760 : : const struct mult_cost *, machine_mode mode);
2761 : : static rtx expand_mult_const (machine_mode, rtx, HOST_WIDE_INT, rtx,
2762 : : const struct algorithm *, enum mult_variant);
2763 : : static unsigned HOST_WIDE_INT invert_mod2n (unsigned HOST_WIDE_INT, int);
2764 : : static rtx extract_high_half (scalar_int_mode, rtx);
2765 : : static rtx expmed_mult_highpart (scalar_int_mode, rtx, rtx, rtx, int, int);
2766 : :
2767 : : /* Compute and return the best algorithm for multiplying by T.
2768 : : The algorithm must cost less than cost_limit
2769 : : If retval.cost >= COST_LIMIT, no algorithm was found and all
2770 : : other field of the returned struct are undefined.
2771 : : MODE is the machine mode of the multiplication. */
2772 : :
2773 : : static void
2774 : 32553128 : synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
2775 : : const struct mult_cost *cost_limit, machine_mode mode)
2776 : : {
2777 : 32553128 : int m;
2778 : 32553128 : struct algorithm *alg_in, *best_alg;
2779 : 32553128 : struct mult_cost best_cost;
2780 : 32553128 : struct mult_cost new_limit;
2781 : 32553128 : int op_cost, op_latency;
2782 : 32553128 : unsigned HOST_WIDE_INT orig_t = t;
2783 : 32553128 : unsigned HOST_WIDE_INT q;
2784 : 32553128 : int maxm, hash_index;
2785 : 32553128 : bool cache_hit = false;
2786 : 32553128 : enum alg_code cache_alg = alg_zero;
2787 : 32553128 : bool speed = optimize_insn_for_speed_p ();
2788 : 32553128 : scalar_int_mode imode;
2789 : 32553128 : struct alg_hash_entry *entry_ptr;
2790 : :
2791 : : /* Indicate that no algorithm is yet found. If no algorithm
2792 : : is found, this value will be returned and indicate failure. */
2793 : 32553128 : alg_out->cost.cost = cost_limit->cost + 1;
2794 : 32553128 : alg_out->cost.latency = cost_limit->latency + 1;
2795 : :
2796 : 32553128 : if (cost_limit->cost < 0
2797 : 26666792 : || (cost_limit->cost == 0 && cost_limit->latency <= 0))
2798 : 25765679 : return;
2799 : :
2800 : : /* Be prepared for vector modes. */
2801 : 44217276 : imode = as_a <scalar_int_mode> (GET_MODE_INNER (mode));
2802 : :
2803 : 65757405 : maxm = MIN (BITS_PER_WORD, GET_MODE_BITSIZE (imode));
2804 : :
2805 : : /* Restrict the bits of "t" to the multiplication's mode. */
2806 : 22108638 : t &= GET_MODE_MASK (imode);
2807 : :
2808 : : /* t == 1 can be done in zero cost. */
2809 : 22108638 : if (t == 1)
2810 : : {
2811 : 5488063 : alg_out->ops = 1;
2812 : 5488063 : alg_out->cost.cost = 0;
2813 : 5488063 : alg_out->cost.latency = 0;
2814 : 5488063 : alg_out->op[0] = alg_m;
2815 : 5488063 : return;
2816 : : }
2817 : :
2818 : : /* t == 0 sometimes has a cost. If it does and it exceeds our limit,
2819 : : fail now. */
2820 : 16620575 : if (t == 0)
2821 : : {
2822 : 496453 : if (MULT_COST_LESS (cost_limit, zero_cost (speed)))
2823 : : return;
2824 : : else
2825 : : {
2826 : 496453 : alg_out->ops = 1;
2827 : 496453 : alg_out->cost.cost = zero_cost (speed);
2828 : 496453 : alg_out->cost.latency = zero_cost (speed);
2829 : 496453 : alg_out->op[0] = alg_zero;
2830 : 496453 : return;
2831 : : }
2832 : : }
2833 : :
2834 : : /* We'll be needing a couple extra algorithm structures now. */
2835 : :
2836 : 16124122 : alg_in = XALLOCA (struct algorithm);
2837 : 16124122 : best_alg = XALLOCA (struct algorithm);
2838 : 16124122 : best_cost = *cost_limit;
2839 : :
2840 : : /* Compute the hash index. */
2841 : 16124122 : hash_index = (t ^ (unsigned int) mode ^ (speed * 256)) % NUM_ALG_HASH_ENTRIES;
2842 : :
2843 : : /* See if we already know what to do for T. */
2844 : 16124122 : entry_ptr = alg_hash_entry_ptr (hash_index);
2845 : 16124122 : if (entry_ptr->t == t
2846 : 13238055 : && entry_ptr->mode == mode
2847 : 13238055 : && entry_ptr->speed == speed
2848 : 13238055 : && entry_ptr->alg != alg_unknown)
2849 : : {
2850 : 13238055 : cache_alg = entry_ptr->alg;
2851 : :
2852 : 13238055 : if (cache_alg == alg_impossible)
2853 : : {
2854 : : /* The cache tells us that it's impossible to synthesize
2855 : : multiplication by T within entry_ptr->cost. */
2856 : 6120311 : if (!CHEAPER_MULT_COST (&entry_ptr->cost, cost_limit))
2857 : : /* COST_LIMIT is at least as restrictive as the one
2858 : : recorded in the hash table, in which case we have no
2859 : : hope of synthesizing a multiplication. Just
2860 : : return. */
2861 : : return;
2862 : :
2863 : : /* If we get here, COST_LIMIT is less restrictive than the
2864 : : one recorded in the hash table, so we may be able to
2865 : : synthesize a multiplication. Proceed as if we didn't
2866 : : have the cache entry. */
2867 : : }
2868 : : else
2869 : : {
2870 : 7117744 : if (CHEAPER_MULT_COST (cost_limit, &entry_ptr->cost))
2871 : : /* The cached algorithm shows that this multiplication
2872 : : requires more cost than COST_LIMIT. Just return. This
2873 : : way, we don't clobber this cache entry with
2874 : : alg_impossible but retain useful information. */
2875 : : return;
2876 : :
2877 : 6430544 : cache_hit = true;
2878 : :
2879 : 6430544 : switch (cache_alg)
2880 : : {
2881 : 4208431 : case alg_shift:
2882 : 4208431 : goto do_alg_shift;
2883 : :
2884 : 850542 : case alg_add_t_m2:
2885 : 850542 : case alg_sub_t_m2:
2886 : 850542 : goto do_alg_addsub_t_m2;
2887 : :
2888 : 119458 : case alg_add_factor:
2889 : 119458 : case alg_sub_factor:
2890 : 119458 : goto do_alg_addsub_factor;
2891 : :
2892 : 1252105 : case alg_add_t2_m:
2893 : 1252105 : goto do_alg_add_t2_m;
2894 : :
2895 : 8 : case alg_sub_t2_m:
2896 : 8 : goto do_alg_sub_t2_m;
2897 : :
2898 : 0 : default:
2899 : 0 : gcc_unreachable ();
2900 : : }
2901 : : }
2902 : : }
2903 : :
2904 : : /* If we have a group of zero bits at the low-order part of T, try
2905 : : multiplying by the remaining bits and then doing a shift. */
2906 : :
2907 : 3711419 : if ((t & 1) == 0)
2908 : : {
2909 : 1880935 : do_alg_shift:
2910 : 6089366 : m = ctz_or_zero (t); /* m = number of low zero bits */
2911 : 6089366 : if (m < maxm)
2912 : : {
2913 : 6089288 : q = t >> m;
2914 : : /* The function expand_shift will choose between a shift and
2915 : : a sequence of additions, so the observed cost is given as
2916 : : MIN (m * add_cost(speed, mode), shift_cost(speed, mode, m)). */
2917 : 6089288 : op_cost = m * add_cost (speed, mode);
2918 : 6089288 : if (shift_cost (speed, mode, m) < op_cost)
2919 : : op_cost = shift_cost (speed, mode, m);
2920 : 6089288 : new_limit.cost = best_cost.cost - op_cost;
2921 : 6089288 : new_limit.latency = best_cost.latency - op_cost;
2922 : 6089288 : synth_mult (alg_in, q, &new_limit, mode);
2923 : :
2924 : 6089288 : alg_in->cost.cost += op_cost;
2925 : 6089288 : alg_in->cost.latency += op_cost;
2926 : 6089288 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
2927 : : {
2928 : 3884901 : best_cost = alg_in->cost;
2929 : 3884901 : std::swap (alg_in, best_alg);
2930 : 3884901 : best_alg->log[best_alg->ops] = m;
2931 : 3884901 : best_alg->op[best_alg->ops] = alg_shift;
2932 : : }
2933 : :
2934 : : /* See if treating ORIG_T as a signed number yields a better
2935 : : sequence. Try this sequence only for a negative ORIG_T
2936 : : as it would be useless for a non-negative ORIG_T. */
2937 : 6089288 : if ((HOST_WIDE_INT) orig_t < 0)
2938 : : {
2939 : : /* Shift ORIG_T as follows because a right shift of a
2940 : : negative-valued signed type is implementation
2941 : : defined. */
2942 : 554536 : q = ~(~orig_t >> m);
2943 : : /* The function expand_shift will choose between a shift
2944 : : and a sequence of additions, so the observed cost is
2945 : : given as MIN (m * add_cost(speed, mode),
2946 : : shift_cost(speed, mode, m)). */
2947 : 554536 : op_cost = m * add_cost (speed, mode);
2948 : 554536 : if (shift_cost (speed, mode, m) < op_cost)
2949 : : op_cost = shift_cost (speed, mode, m);
2950 : 554536 : new_limit.cost = best_cost.cost - op_cost;
2951 : 554536 : new_limit.latency = best_cost.latency - op_cost;
2952 : 554536 : synth_mult (alg_in, q, &new_limit, mode);
2953 : :
2954 : 554536 : alg_in->cost.cost += op_cost;
2955 : 554536 : alg_in->cost.latency += op_cost;
2956 : 554536 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
2957 : : {
2958 : 525554 : best_cost = alg_in->cost;
2959 : 525554 : std::swap (alg_in, best_alg);
2960 : 525554 : best_alg->log[best_alg->ops] = m;
2961 : 525554 : best_alg->op[best_alg->ops] = alg_shift;
2962 : : }
2963 : : }
2964 : : }
2965 : 6089366 : if (cache_hit)
2966 : 4208431 : goto done;
2967 : : }
2968 : :
2969 : : /* If we have an odd number, add or subtract one. */
2970 : 1880935 : if ((t & 1) != 0)
2971 : : {
2972 : 2681026 : unsigned HOST_WIDE_INT w;
2973 : :
2974 : 0 : do_alg_addsub_t_m2:
2975 : 37300395 : for (w = 1; (w & t) != 0; w <<= 1)
2976 : : ;
2977 : : /* If T was -1, then W will be zero after the loop. This is another
2978 : : case where T ends with ...111. Handling this with (T + 1) and
2979 : : subtract 1 produces slightly better code and results in algorithm
2980 : : selection much faster than treating it like the ...0111 case
2981 : : below. */
2982 : 2681026 : if (w == 0
2983 : 2303098 : || (w > 2
2984 : : /* Reject the case where t is 3.
2985 : : Thus we prefer addition in that case. */
2986 : 2303098 : && t != 3))
2987 : : {
2988 : : /* T ends with ...111. Multiply by (T + 1) and subtract T. */
2989 : :
2990 : 1523932 : op_cost = add_cost (speed, mode);
2991 : 1523932 : new_limit.cost = best_cost.cost - op_cost;
2992 : 1523932 : new_limit.latency = best_cost.latency - op_cost;
2993 : 1523932 : synth_mult (alg_in, t + 1, &new_limit, mode);
2994 : :
2995 : 1523932 : alg_in->cost.cost += op_cost;
2996 : 1523932 : alg_in->cost.latency += op_cost;
2997 : 1523932 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
2998 : : {
2999 : 671253 : best_cost = alg_in->cost;
3000 : 671253 : std::swap (alg_in, best_alg);
3001 : 671253 : best_alg->log[best_alg->ops] = 0;
3002 : 671253 : best_alg->op[best_alg->ops] = alg_sub_t_m2;
3003 : : }
3004 : : }
3005 : : else
3006 : : {
3007 : : /* T ends with ...01 or ...011. Multiply by (T - 1) and add T. */
3008 : :
3009 : 1157094 : op_cost = add_cost (speed, mode);
3010 : 1157094 : new_limit.cost = best_cost.cost - op_cost;
3011 : 1157094 : new_limit.latency = best_cost.latency - op_cost;
3012 : 1157094 : synth_mult (alg_in, t - 1, &new_limit, mode);
3013 : :
3014 : 1157094 : alg_in->cost.cost += op_cost;
3015 : 1157094 : alg_in->cost.latency += op_cost;
3016 : 1157094 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
3017 : : {
3018 : 174318 : best_cost = alg_in->cost;
3019 : 174318 : std::swap (alg_in, best_alg);
3020 : 174318 : best_alg->log[best_alg->ops] = 0;
3021 : 174318 : best_alg->op[best_alg->ops] = alg_add_t_m2;
3022 : : }
3023 : : }
3024 : :
3025 : : /* We may be able to calculate a * -7, a * -15, a * -31, etc
3026 : : quickly with a - a * n for some appropriate constant n. */
3027 : 2681026 : m = exact_log2 (-orig_t + 1);
3028 : 2681026 : if (m >= 0 && m < maxm)
3029 : : {
3030 : 662189 : op_cost = add_cost (speed, mode) + shift_cost (speed, mode, m);
3031 : : /* If the target has a cheap shift-and-subtract insn use
3032 : : that in preference to a shift insn followed by a sub insn.
3033 : : Assume that the shift-and-sub is "atomic" with a latency
3034 : : equal to it's cost, otherwise assume that on superscalar
3035 : : hardware the shift may be executed concurrently with the
3036 : : earlier steps in the algorithm. */
3037 : 662189 : if (shiftsub1_cost (speed, mode, m) <= op_cost)
3038 : : {
3039 : : op_cost = shiftsub1_cost (speed, mode, m);
3040 : : op_latency = op_cost;
3041 : : }
3042 : : else
3043 : 656647 : op_latency = add_cost (speed, mode);
3044 : :
3045 : 662189 : new_limit.cost = best_cost.cost - op_cost;
3046 : 662189 : new_limit.latency = best_cost.latency - op_latency;
3047 : 662189 : synth_mult (alg_in, (unsigned HOST_WIDE_INT) (-orig_t + 1) >> m,
3048 : : &new_limit, mode);
3049 : :
3050 : 662189 : alg_in->cost.cost += op_cost;
3051 : 662189 : alg_in->cost.latency += op_latency;
3052 : 662189 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
3053 : : {
3054 : 151076 : best_cost = alg_in->cost;
3055 : 151076 : std::swap (alg_in, best_alg);
3056 : 151076 : best_alg->log[best_alg->ops] = m;
3057 : 151076 : best_alg->op[best_alg->ops] = alg_sub_t_m2;
3058 : : }
3059 : : }
3060 : :
3061 : 2681026 : if (cache_hit)
3062 : 850542 : goto done;
3063 : : }
3064 : :
3065 : : /* Look for factors of t of the form
3066 : : t = q(2**m +- 1), 2 <= m <= floor(log2(t - 1)).
3067 : : If we find such a factor, we can multiply by t using an algorithm that
3068 : : multiplies by q, shift the result by m and add/subtract it to itself.
3069 : :
3070 : : We search for large factors first and loop down, even if large factors
3071 : : are less probable than small; if we find a large factor we will find a
3072 : : good sequence quickly, and therefore be able to prune (by decreasing
3073 : : COST_LIMIT) the search. */
3074 : :
3075 : 1880935 : do_alg_addsub_factor:
3076 : 71466367 : for (m = floor_log2 (t - 1); m >= 2; m--)
3077 : : {
3078 : 69614697 : unsigned HOST_WIDE_INT d;
3079 : :
3080 : 69614697 : d = (HOST_WIDE_INT_1U << m) + 1;
3081 : 69614697 : if (t % d == 0 && t > d && m < maxm
3082 : 940427 : && (!cache_hit || cache_alg == alg_add_factor))
3083 : : {
3084 : 940427 : op_cost = add_cost (speed, mode) + shift_cost (speed, mode, m);
3085 : 940427 : if (shiftadd_cost (speed, mode, m) <= op_cost)
3086 : : op_cost = shiftadd_cost (speed, mode, m);
3087 : :
3088 : 940427 : op_latency = op_cost;
3089 : :
3090 : :
3091 : 940427 : new_limit.cost = best_cost.cost - op_cost;
3092 : 940427 : new_limit.latency = best_cost.latency - op_latency;
3093 : 940427 : synth_mult (alg_in, t / d, &new_limit, mode);
3094 : :
3095 : 940427 : alg_in->cost.cost += op_cost;
3096 : 940427 : alg_in->cost.latency += op_latency;
3097 : 940427 : if (alg_in->cost.latency < op_cost)
3098 : 199622 : alg_in->cost.latency = op_cost;
3099 : 940427 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
3100 : : {
3101 : 110268 : best_cost = alg_in->cost;
3102 : 110268 : std::swap (alg_in, best_alg);
3103 : 110268 : best_alg->log[best_alg->ops] = m;
3104 : 110268 : best_alg->op[best_alg->ops] = alg_add_factor;
3105 : : }
3106 : : /* Other factors will have been taken care of in the recursion. */
3107 : : break;
3108 : : }
3109 : :
3110 : 68674270 : d = (HOST_WIDE_INT_1U << m) - 1;
3111 : 68674270 : if (t % d == 0 && t > d && m < maxm
3112 : 1038780 : && (!cache_hit || cache_alg == alg_sub_factor))
3113 : : {
3114 : 1038780 : op_cost = add_cost (speed, mode) + shift_cost (speed, mode, m);
3115 : 1038780 : if (shiftsub0_cost (speed, mode, m) <= op_cost)
3116 : : op_cost = shiftsub0_cost (speed, mode, m);
3117 : :
3118 : 1038780 : op_latency = op_cost;
3119 : :
3120 : 1038780 : new_limit.cost = best_cost.cost - op_cost;
3121 : 1038780 : new_limit.latency = best_cost.latency - op_latency;
3122 : 1038780 : synth_mult (alg_in, t / d, &new_limit, mode);
3123 : :
3124 : 1038780 : alg_in->cost.cost += op_cost;
3125 : 1038780 : alg_in->cost.latency += op_latency;
3126 : 1038780 : if (alg_in->cost.latency < op_cost)
3127 : 280437 : alg_in->cost.latency = op_cost;
3128 : 1038780 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
3129 : : {
3130 : 39025 : best_cost = alg_in->cost;
3131 : 39025 : std::swap (alg_in, best_alg);
3132 : 39025 : best_alg->log[best_alg->ops] = m;
3133 : 39025 : best_alg->op[best_alg->ops] = alg_sub_factor;
3134 : : }
3135 : : break;
3136 : : }
3137 : : }
3138 : 3830877 : if (cache_hit)
3139 : 119458 : goto done;
3140 : :
3141 : : /* Try shift-and-add (load effective address) instructions,
3142 : : i.e. do a*3, a*5, a*9. */
3143 : 3711419 : if ((t & 1) != 0)
3144 : : {
3145 : 1830484 : do_alg_add_t2_m:
3146 : 3082589 : q = t - 1;
3147 : 3082589 : m = ctz_hwi (q);
3148 : 3082589 : if (q && m < maxm)
3149 : : {
3150 : 3082571 : op_cost = shiftadd_cost (speed, mode, m);
3151 : 3082571 : new_limit.cost = best_cost.cost - op_cost;
3152 : 3082571 : new_limit.latency = best_cost.latency - op_cost;
3153 : 3082571 : synth_mult (alg_in, (t - 1) >> m, &new_limit, mode);
3154 : :
3155 : 3082571 : alg_in->cost.cost += op_cost;
3156 : 3082571 : alg_in->cost.latency += op_cost;
3157 : 3082571 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
3158 : : {
3159 : 1307790 : best_cost = alg_in->cost;
3160 : 1307790 : std::swap (alg_in, best_alg);
3161 : 1307790 : best_alg->log[best_alg->ops] = m;
3162 : 1307790 : best_alg->op[best_alg->ops] = alg_add_t2_m;
3163 : : }
3164 : : }
3165 : 3082589 : if (cache_hit)
3166 : 1252105 : goto done;
3167 : :
3168 : 1830484 : do_alg_sub_t2_m:
3169 : 1830492 : q = t + 1;
3170 : 1830492 : m = ctz_hwi (q);
3171 : 1830492 : if (q && m < maxm)
3172 : : {
3173 : 1809392 : op_cost = shiftsub0_cost (speed, mode, m);
3174 : 1809392 : new_limit.cost = best_cost.cost - op_cost;
3175 : 1809392 : new_limit.latency = best_cost.latency - op_cost;
3176 : 1809392 : synth_mult (alg_in, (t + 1) >> m, &new_limit, mode);
3177 : :
3178 : 1809392 : alg_in->cost.cost += op_cost;
3179 : 1809392 : alg_in->cost.latency += op_cost;
3180 : 1809392 : if (CHEAPER_MULT_COST (&alg_in->cost, &best_cost))
3181 : : {
3182 : 61 : best_cost = alg_in->cost;
3183 : 61 : std::swap (alg_in, best_alg);
3184 : 61 : best_alg->log[best_alg->ops] = m;
3185 : 61 : best_alg->op[best_alg->ops] = alg_sub_t2_m;
3186 : : }
3187 : : }
3188 : 1830492 : if (cache_hit)
3189 : : goto done;
3190 : : }
3191 : :
3192 : 1880935 : done:
3193 : : /* If best_cost has not decreased, we have not found any algorithm. */
3194 : 10141963 : if (!CHEAPER_MULT_COST (&best_cost, cost_limit))
3195 : : {
3196 : : /* We failed to find an algorithm. Record alg_impossible for
3197 : : this case (that is, <T, MODE, COST_LIMIT>) so that next time
3198 : : we are asked to find an algorithm for T within the same or
3199 : : lower COST_LIMIT, we can immediately return to the
3200 : : caller. */
3201 : 3354514 : entry_ptr->t = t;
3202 : 3354514 : entry_ptr->mode = mode;
3203 : 3354514 : entry_ptr->speed = speed;
3204 : 3354514 : entry_ptr->alg = alg_impossible;
3205 : 3354514 : entry_ptr->cost = *cost_limit;
3206 : 3354514 : return;
3207 : : }
3208 : :
3209 : : /* Cache the result. */
3210 : 6787449 : if (!cache_hit)
3211 : : {
3212 : 648579 : entry_ptr->t = t;
3213 : 648579 : entry_ptr->mode = mode;
3214 : 648579 : entry_ptr->speed = speed;
3215 : 648579 : entry_ptr->alg = best_alg->op[best_alg->ops];
3216 : 648579 : entry_ptr->cost.cost = best_cost.cost;
3217 : 648579 : entry_ptr->cost.latency = best_cost.latency;
3218 : : }
3219 : :
3220 : : /* If we are getting a too long sequence for `struct algorithm'
3221 : : to record, make this search fail. */
3222 : 6787449 : if (best_alg->ops == MAX_BITS_PER_WORD)
3223 : : return;
3224 : :
3225 : : /* Copy the algorithm from temporary space to the space at alg_out.
3226 : : We avoid using structure assignment because the majority of
3227 : : best_alg is normally undefined, and this is a critical function. */
3228 : 6787449 : alg_out->ops = best_alg->ops + 1;
3229 : 6787449 : alg_out->cost = best_cost;
3230 : 6787449 : memcpy (alg_out->op, best_alg->op,
3231 : 6787449 : alg_out->ops * sizeof *alg_out->op);
3232 : 6787449 : memcpy (alg_out->log, best_alg->log,
3233 : : alg_out->ops * sizeof *alg_out->log);
3234 : : }
3235 : :
3236 : : /* Find the cheapest way of multiplying a value of mode MODE by VAL.
3237 : : Try three variations:
3238 : :
3239 : : - a shift/add sequence based on VAL itself
3240 : : - a shift/add sequence based on -VAL, followed by a negation
3241 : : - a shift/add sequence based on VAL - 1, followed by an addition.
3242 : :
3243 : : Return true if the cheapest of these cost less than MULT_COST,
3244 : : describing the algorithm in *ALG and final fixup in *VARIANT. */
3245 : :
3246 : : bool
3247 : 6624085 : choose_mult_variant (machine_mode mode, HOST_WIDE_INT val,
3248 : : struct algorithm *alg, enum mult_variant *variant,
3249 : : int mult_cost)
3250 : : {
3251 : 6624085 : struct algorithm alg2;
3252 : 6624085 : struct mult_cost limit;
3253 : 6624085 : int op_cost;
3254 : 6624085 : bool speed = optimize_insn_for_speed_p ();
3255 : :
3256 : : /* Fail quickly for impossible bounds. */
3257 : 6624085 : if (mult_cost < 0)
3258 : : return false;
3259 : :
3260 : : /* Ensure that mult_cost provides a reasonable upper bound.
3261 : : Any constant multiplication can be performed with less
3262 : : than 2 * bits additions. */
3263 : 13244768 : op_cost = 2 * GET_MODE_UNIT_BITSIZE (mode) * add_cost (speed, mode);
3264 : 6622384 : if (mult_cost > op_cost)
3265 : : mult_cost = op_cost;
3266 : :
3267 : 6622384 : *variant = basic_variant;
3268 : 6622384 : limit.cost = mult_cost;
3269 : 6622384 : limit.latency = mult_cost;
3270 : 6622384 : synth_mult (alg, val, &limit, mode);
3271 : :
3272 : : /* This works only if the inverted value actually fits in an
3273 : : `unsigned int' */
3274 : 13244768 : if (HOST_BITS_PER_INT >= GET_MODE_UNIT_BITSIZE (mode))
3275 : : {
3276 : 2450151 : op_cost = neg_cost (speed, mode);
3277 : 2450151 : if (MULT_COST_LESS (&alg->cost, mult_cost))
3278 : : {
3279 : 2352690 : limit.cost = alg->cost.cost - op_cost;
3280 : 2352690 : limit.latency = alg->cost.latency - op_cost;
3281 : : }
3282 : : else
3283 : : {
3284 : 97461 : limit.cost = mult_cost - op_cost;
3285 : 97461 : limit.latency = mult_cost - op_cost;
3286 : : }
3287 : :
3288 : 2450151 : synth_mult (&alg2, -val, &limit, mode);
3289 : 2450151 : alg2.cost.cost += op_cost;
3290 : 2450151 : alg2.cost.latency += op_cost;
3291 : 2450151 : if (CHEAPER_MULT_COST (&alg2.cost, &alg->cost))
3292 : 10807 : *alg = alg2, *variant = negate_variant;
3293 : : }
3294 : :
3295 : : /* This proves very useful for division-by-constant. */
3296 : 6622384 : op_cost = add_cost (speed, mode);
3297 : 6622384 : if (MULT_COST_LESS (&alg->cost, mult_cost))
3298 : : {
3299 : 5903943 : limit.cost = alg->cost.cost - op_cost;
3300 : 5903943 : limit.latency = alg->cost.latency - op_cost;
3301 : : }
3302 : : else
3303 : : {
3304 : 718441 : limit.cost = mult_cost - op_cost;
3305 : 718441 : limit.latency = mult_cost - op_cost;
3306 : : }
3307 : :
3308 : 6622384 : if (val != HOST_WIDE_INT_MIN
3309 : 6622394 : || GET_MODE_UNIT_PRECISION (mode) == HOST_BITS_PER_WIDE_INT)
3310 : : {
3311 : 6622384 : synth_mult (&alg2, val - HOST_WIDE_INT_1U, &limit, mode);
3312 : 6622384 : alg2.cost.cost += op_cost;
3313 : 6622384 : alg2.cost.latency += op_cost;
3314 : 6622384 : if (CHEAPER_MULT_COST (&alg2.cost, &alg->cost))
3315 : 2738 : *alg = alg2, *variant = add_variant;
3316 : : }
3317 : :
3318 : 6622384 : return MULT_COST_LESS (&alg->cost, mult_cost);
3319 : : }
3320 : :
3321 : : /* A subroutine of expand_mult, used for constant multiplications.
3322 : : Multiply OP0 by VAL in mode MODE, storing the result in TARGET if
3323 : : convenient. Use the shift/add sequence described by ALG and apply
3324 : : the final fixup specified by VARIANT. */
3325 : :
3326 : : static rtx
3327 : 129402 : expand_mult_const (machine_mode mode, rtx op0, HOST_WIDE_INT val,
3328 : : rtx target, const struct algorithm *alg,
3329 : : enum mult_variant variant)
3330 : : {
3331 : 129402 : unsigned HOST_WIDE_INT val_so_far;
3332 : 129402 : rtx_insn *insn;
3333 : 129402 : rtx accum, tem;
3334 : 129402 : int opno;
3335 : 129402 : machine_mode nmode;
3336 : :
3337 : : /* Avoid referencing memory over and over and invalid sharing
3338 : : on SUBREGs. */
3339 : 129402 : op0 = force_reg (mode, op0);
3340 : :
3341 : : /* ACCUM starts out either as OP0 or as a zero, depending on
3342 : : the first operation. */
3343 : :
3344 : 129402 : if (alg->op[0] == alg_zero)
3345 : : {
3346 : 4833 : accum = copy_to_mode_reg (mode, CONST0_RTX (mode));
3347 : 4833 : val_so_far = 0;
3348 : : }
3349 : 124569 : else if (alg->op[0] == alg_m)
3350 : : {
3351 : 124569 : accum = copy_to_mode_reg (mode, op0);
3352 : 124569 : val_so_far = 1;
3353 : : }
3354 : : else
3355 : 0 : gcc_unreachable ();
3356 : :
3357 : 365465 : for (opno = 1; opno < alg->ops; opno++)
3358 : : {
3359 : 236063 : int log = alg->log[opno];
3360 : 236063 : rtx shift_subtarget = optimize ? 0 : accum;
3361 : 472126 : rtx add_target
3362 : 129402 : = (opno == alg->ops - 1 && target != 0 && variant != add_variant
3363 : 36146 : && !optimize)
3364 : 236063 : ? target : 0;
3365 : 236063 : rtx accum_target = optimize ? 0 : accum;
3366 : 236063 : rtx accum_inner;
3367 : :
3368 : 236063 : switch (alg->op[opno])
3369 : : {
3370 : 102628 : case alg_shift:
3371 : 102628 : tem = expand_shift (LSHIFT_EXPR, mode, accum, log, NULL_RTX, 0);
3372 : : /* REG_EQUAL note will be attached to the following insn. */
3373 : 102628 : emit_move_insn (accum, tem);
3374 : 102628 : val_so_far <<= log;
3375 : 102628 : break;
3376 : :
3377 : 4867 : case alg_add_t_m2:
3378 : 4867 : tem = expand_shift (LSHIFT_EXPR, mode, op0, log, NULL_RTX, 0);
3379 : 9734 : accum = force_operand (gen_rtx_PLUS (mode, accum, tem),
3380 : : add_target ? add_target : accum_target);
3381 : 4867 : val_so_far += HOST_WIDE_INT_1U << log;
3382 : 4867 : break;
3383 : :
3384 : 19210 : case alg_sub_t_m2:
3385 : 19210 : tem = expand_shift (LSHIFT_EXPR, mode, op0, log, NULL_RTX, 0);
3386 : 38420 : accum = force_operand (gen_rtx_MINUS (mode, accum, tem),
3387 : : add_target ? add_target : accum_target);
3388 : 19210 : val_so_far -= HOST_WIDE_INT_1U << log;
3389 : 19210 : break;
3390 : :
3391 : 108299 : case alg_add_t2_m:
3392 : 108299 : accum = expand_shift (LSHIFT_EXPR, mode, accum,
3393 : : log, shift_subtarget, 0);
3394 : 216598 : accum = force_operand (gen_rtx_PLUS (mode, accum, op0),
3395 : : add_target ? add_target : accum_target);
3396 : 108299 : val_so_far = (val_so_far << log) + 1;
3397 : 108299 : break;
3398 : :
3399 : 0 : case alg_sub_t2_m:
3400 : 0 : accum = expand_shift (LSHIFT_EXPR, mode, accum,
3401 : : log, shift_subtarget, 0);
3402 : 0 : accum = force_operand (gen_rtx_MINUS (mode, accum, op0),
3403 : : add_target ? add_target : accum_target);
3404 : 0 : val_so_far = (val_so_far << log) - 1;
3405 : 0 : break;
3406 : :
3407 : 966 : case alg_add_factor:
3408 : 966 : tem = expand_shift (LSHIFT_EXPR, mode, accum, log, NULL_RTX, 0);
3409 : 1932 : accum = force_operand (gen_rtx_PLUS (mode, accum, tem),
3410 : : add_target ? add_target : accum_target);
3411 : 966 : val_so_far += val_so_far << log;
3412 : 966 : break;
3413 : :
3414 : 93 : case alg_sub_factor:
3415 : 93 : tem = expand_shift (LSHIFT_EXPR, mode, accum, log, NULL_RTX, 0);
3416 : 186 : accum = force_operand (gen_rtx_MINUS (mode, tem, accum),
3417 : : (add_target
3418 : 93 : ? add_target : (optimize ? 0 : tem)));
3419 : 93 : val_so_far = (val_so_far << log) - val_so_far;
3420 : 93 : break;
3421 : :
3422 : 0 : default:
3423 : 0 : gcc_unreachable ();
3424 : : }
3425 : :
3426 : 236063 : if (SCALAR_INT_MODE_P (mode))
3427 : : {
3428 : : /* Write a REG_EQUAL note on the last insn so that we can cse
3429 : : multiplication sequences. Note that if ACCUM is a SUBREG,
3430 : : we've set the inner register and must properly indicate that. */
3431 : 229891 : tem = op0, nmode = mode;
3432 : 229891 : accum_inner = accum;
3433 : 229891 : if (GET_CODE (accum) == SUBREG)
3434 : : {
3435 : 0 : accum_inner = SUBREG_REG (accum);
3436 : 0 : nmode = GET_MODE (accum_inner);
3437 : 0 : tem = gen_lowpart (nmode, op0);
3438 : : }
3439 : :
3440 : : /* Don't add a REG_EQUAL note if tem is a paradoxical SUBREG.
3441 : : In that case, only the low bits of accum would be guaranteed to
3442 : : be equal to the content of the REG_EQUAL note, the upper bits
3443 : : can be anything. */
3444 : 229891 : if (!paradoxical_subreg_p (tem))
3445 : : {
3446 : 229891 : insn = get_last_insn ();
3447 : 229891 : wide_int wval_so_far
3448 : 229891 : = wi::uhwi (val_so_far,
3449 : 229891 : GET_MODE_PRECISION (as_a <scalar_mode> (nmode)));
3450 : 229891 : rtx c = immed_wide_int_const (wval_so_far, nmode);
3451 : 229891 : set_dst_reg_note (insn, REG_EQUAL, gen_rtx_MULT (nmode, tem, c),
3452 : : accum_inner);
3453 : 229891 : }
3454 : : }
3455 : : }
3456 : :
3457 : 129402 : if (variant == negate_variant)
3458 : : {
3459 : 488 : val_so_far = -val_so_far;
3460 : 488 : accum = expand_unop (mode, neg_optab, accum, target, 0);
3461 : : }
3462 : 128914 : else if (variant == add_variant)
3463 : : {
3464 : 18 : val_so_far = val_so_far + 1;
3465 : 18 : accum = force_operand (gen_rtx_PLUS (mode, accum, op0), target);
3466 : : }
3467 : :
3468 : : /* Compare only the bits of val and val_so_far that are significant
3469 : : in the result mode, to avoid sign-/zero-extension confusion. */
3470 : 129402 : nmode = GET_MODE_INNER (mode);
3471 : 129402 : val &= GET_MODE_MASK (nmode);
3472 : 129402 : val_so_far &= GET_MODE_MASK (nmode);
3473 : 129402 : gcc_assert (val == (HOST_WIDE_INT) val_so_far);
3474 : :
3475 : 129402 : return accum;
3476 : : }
3477 : :
3478 : : /* Perform a multiplication and return an rtx for the result.
3479 : : MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
3480 : : TARGET is a suggestion for where to store the result (an rtx).
3481 : :
3482 : : We check specially for a constant integer as OP1.
3483 : : If you want this check for OP0 as well, then before calling
3484 : : you should swap the two operands if OP0 would be constant. */
3485 : :
3486 : : rtx
3487 : 968632 : expand_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
3488 : : int unsignedp, bool no_libcall)
3489 : : {
3490 : 968632 : enum mult_variant variant;
3491 : 968632 : struct algorithm algorithm;
3492 : 968632 : rtx scalar_op1;
3493 : 968632 : int max_cost;
3494 : 968632 : bool speed = optimize_insn_for_speed_p ();
3495 : 968632 : bool do_trapv = flag_trapv && SCALAR_INT_MODE_P (mode) && !unsignedp;
3496 : :
3497 : 968632 : if (CONSTANT_P (op0))
3498 : 268 : std::swap (op0, op1);
3499 : :
3500 : : /* For vectors, there are several simplifications that can be made if
3501 : : all elements of the vector constant are identical. */
3502 : 968632 : scalar_op1 = unwrap_const_vec_duplicate (op1);
3503 : :
3504 : 968632 : if (INTEGRAL_MODE_P (mode))
3505 : : {
3506 : 852403 : rtx fake_reg;
3507 : 852403 : HOST_WIDE_INT coeff;
3508 : 852403 : bool is_neg;
3509 : 852403 : int mode_bitsize;
3510 : :
3511 : 852403 : if (op1 == CONST0_RTX (mode))
3512 : : return op1;
3513 : 852403 : if (op1 == CONST1_RTX (mode))
3514 : : return op0;
3515 : 824837 : if (op1 == CONSTM1_RTX (mode))
3516 : 2824 : return expand_unop (mode, do_trapv ? negv_optab : neg_optab,
3517 : 1412 : op0, target, 0);
3518 : :
3519 : 823425 : if (do_trapv)
3520 : 32 : goto skip_synth;
3521 : :
3522 : : /* If mode is integer vector mode, check if the backend supports
3523 : : vector lshift (by scalar or vector) at all. If not, we can't use
3524 : : synthetized multiply. */
3525 : 823393 : if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
3526 : 14326 : && optab_handler (vashl_optab, mode) == CODE_FOR_nothing
3527 : 835456 : && optab_handler (ashl_optab, mode) == CODE_FOR_nothing)
3528 : 0 : goto skip_synth;
3529 : :
3530 : : /* These are the operations that are potentially turned into
3531 : : a sequence of shifts and additions. */
3532 : 823393 : mode_bitsize = GET_MODE_UNIT_BITSIZE (mode);
3533 : :
3534 : : /* synth_mult does an `unsigned int' multiply. As long as the mode is
3535 : : less than or equal in size to `unsigned int' this doesn't matter.
3536 : : If the mode is larger than `unsigned int', then synth_mult works
3537 : : only if the constant value exactly fits in an `unsigned int' without
3538 : : any truncation. This means that multiplying by negative values does
3539 : : not work; results are off by 2^32 on a 32 bit machine. */
3540 : 823393 : if (CONST_INT_P (scalar_op1))
3541 : : {
3542 : 619000 : coeff = INTVAL (scalar_op1);
3543 : 619000 : is_neg = coeff < 0;
3544 : : }
3545 : : #if TARGET_SUPPORTS_WIDE_INT
3546 : 204393 : else if (CONST_WIDE_INT_P (scalar_op1))
3547 : : #else
3548 : : else if (CONST_DOUBLE_AS_INT_P (scalar_op1))
3549 : : #endif
3550 : : {
3551 : 1133 : int shift = wi::exact_log2 (rtx_mode_t (scalar_op1, mode));
3552 : : /* Perfect power of 2 (other than 1, which is handled above). */
3553 : 1133 : if (shift > 0)
3554 : 106 : return expand_shift (LSHIFT_EXPR, mode, op0,
3555 : : shift, target, unsignedp);
3556 : : else
3557 : 1027 : goto skip_synth;
3558 : : }
3559 : : else
3560 : 203260 : goto skip_synth;
3561 : :
3562 : : /* We used to test optimize here, on the grounds that it's better to
3563 : : produce a smaller program when -O is not used. But this causes
3564 : : such a terrible slowdown sometimes that it seems better to always
3565 : : use synth_mult. */
3566 : :
3567 : : /* Special case powers of two. */
3568 : 619000 : if (EXACT_POWER_OF_2_OR_ZERO_P (coeff)
3569 : 399977 : && !(is_neg && mode_bitsize > HOST_BITS_PER_WIDE_INT))
3570 : 399969 : return expand_shift (LSHIFT_EXPR, mode, op0,
3571 : 799938 : floor_log2 (coeff), target, unsignedp);
3572 : :
3573 : 219031 : fake_reg = gen_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1);
3574 : :
3575 : : /* Attempt to handle multiplication of DImode values by negative
3576 : : coefficients, by performing the multiplication by a positive
3577 : : multiplier and then inverting the result. */
3578 : 219031 : if (is_neg && mode_bitsize > HOST_BITS_PER_WIDE_INT)
3579 : : {
3580 : : /* Its safe to use -coeff even for INT_MIN, as the
3581 : : result is interpreted as an unsigned coefficient.
3582 : : Exclude cost of op0 from max_cost to match the cost
3583 : : calculation of the synth_mult. */
3584 : 216 : coeff = -(unsigned HOST_WIDE_INT) coeff;
3585 : 216 : max_cost = (set_src_cost (gen_rtx_MULT (mode, fake_reg, op1),
3586 : : mode, speed)
3587 : 216 : - neg_cost (speed, mode));
3588 : 216 : if (max_cost <= 0)
3589 : 0 : goto skip_synth;
3590 : :
3591 : : /* Special case powers of two. */
3592 : 216 : if (EXACT_POWER_OF_2_OR_ZERO_P (coeff))
3593 : : {
3594 : 342 : rtx temp = expand_shift (LSHIFT_EXPR, mode, op0,
3595 : 171 : floor_log2 (coeff), target, unsignedp);
3596 : 171 : return expand_unop (mode, neg_optab, temp, target, 0);
3597 : : }
3598 : :
3599 : 45 : if (choose_mult_variant (mode, coeff, &algorithm, &variant,
3600 : : max_cost))
3601 : : {
3602 : 44 : rtx temp = expand_mult_const (mode, op0, coeff, NULL_RTX,
3603 : : &algorithm, variant);
3604 : 44 : return expand_unop (mode, neg_optab, temp, target, 0);
3605 : : }
3606 : 1 : goto skip_synth;
3607 : : }
3608 : :
3609 : : /* Exclude cost of op0 from max_cost to match the cost
3610 : : calculation of the synth_mult. */
3611 : 218815 : max_cost = set_src_cost (gen_rtx_MULT (mode, fake_reg, op1), mode, speed);
3612 : 218815 : if (choose_mult_variant (mode, coeff, &algorithm, &variant, max_cost))
3613 : 129309 : return expand_mult_const (mode, op0, coeff, target,
3614 : 129309 : &algorithm, variant);
3615 : : }
3616 : 89506 : skip_synth:
3617 : :
3618 : : /* Expand x*2.0 as x+x. */
3619 : 37301 : if (CONST_DOUBLE_AS_FLOAT_P (scalar_op1)
3620 : 447356 : && real_equal (CONST_DOUBLE_REAL_VALUE (scalar_op1), &dconst2))
3621 : : {
3622 : 5784 : op0 = force_reg (GET_MODE (op0), op0);
3623 : 11568 : return expand_binop (mode, add_optab, op0, op0,
3624 : : target, unsignedp,
3625 : 5784 : no_libcall ? OPTAB_WIDEN : OPTAB_LIB_WIDEN);
3626 : : }
3627 : :
3628 : : /* This used to use umul_optab if unsigned, but for non-widening multiply
3629 : : there is no difference between signed and unsigned. */
3630 : 1212781 : op0 = expand_binop (mode, do_trapv ? smulv_optab : smul_optab,
3631 : : op0, op1, target, unsignedp,
3632 : : no_libcall ? OPTAB_WIDEN : OPTAB_LIB_WIDEN);
3633 : 404271 : gcc_assert (op0 || no_libcall);
3634 : : return op0;
3635 : : }
3636 : :
3637 : : /* Return a cost estimate for multiplying a register by the given
3638 : : COEFFicient in the given MODE and SPEED. */
3639 : :
3640 : : int
3641 : 6140133 : mult_by_coeff_cost (HOST_WIDE_INT coeff, machine_mode mode, bool speed)
3642 : : {
3643 : 6140133 : int max_cost;
3644 : 6140133 : struct algorithm algorithm;
3645 : 6140133 : enum mult_variant variant;
3646 : :
3647 : 6140133 : rtx fake_reg = gen_raw_REG (mode, LAST_VIRTUAL_REGISTER + 1);
3648 : 6140133 : max_cost = set_src_cost (gen_rtx_MULT (mode, fake_reg, fake_reg),
3649 : : mode, speed);
3650 : 6140133 : if (choose_mult_variant (mode, coeff, &algorithm, &variant, max_cost))
3651 : 5515613 : return algorithm.cost.cost;
3652 : : else
3653 : : return max_cost;
3654 : : }
3655 : :
3656 : : /* Perform a widening multiplication and return an rtx for the result.
3657 : : MODE is mode of value; OP0 and OP1 are what to multiply (rtx's);
3658 : : TARGET is a suggestion for where to store the result (an rtx).
3659 : : THIS_OPTAB is the optab we should use, it must be either umul_widen_optab
3660 : : or smul_widen_optab.
3661 : :
3662 : : We check specially for a constant integer as OP1, comparing the
3663 : : cost of a widening multiply against the cost of a sequence of shifts
3664 : : and adds. */
3665 : :
3666 : : rtx
3667 : 18631 : expand_widening_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
3668 : : int unsignedp, optab this_optab)
3669 : : {
3670 : 18631 : bool speed = optimize_insn_for_speed_p ();
3671 : 18631 : rtx cop1;
3672 : :
3673 : 18631 : if (CONST_INT_P (op1)
3674 : 4385 : && GET_MODE (op0) != VOIDmode
3675 : 4385 : && (cop1 = convert_modes (mode, GET_MODE (op0), op1,
3676 : : this_optab == umul_widen_optab))
3677 : 4385 : && CONST_INT_P (cop1)
3678 : 22495 : && (INTVAL (cop1) >= 0
3679 : 21442 : || HWI_COMPUTABLE_MODE_P (mode)))
3680 : : {
3681 : 3631 : HOST_WIDE_INT coeff = INTVAL (cop1);
3682 : 3631 : int max_cost;
3683 : 3631 : enum mult_variant variant;
3684 : 3631 : struct algorithm algorithm;
3685 : :
3686 : 3631 : if (coeff == 0)
3687 : 820 : return CONST0_RTX (mode);
3688 : :
3689 : : /* Special case powers of two. */
3690 : 3523 : if (EXACT_POWER_OF_2_OR_ZERO_P (coeff))
3691 : : {
3692 : 676 : op0 = convert_to_mode (mode, op0, this_optab == umul_widen_optab);
3693 : 676 : return expand_shift (LSHIFT_EXPR, mode, op0,
3694 : 676 : floor_log2 (coeff), target, unsignedp);
3695 : : }
3696 : :
3697 : : /* Exclude cost of op0 from max_cost to match the cost
3698 : : calculation of the synth_mult. */
3699 : 2847 : max_cost = mul_widen_cost (speed, mode);
3700 : 2847 : if (choose_mult_variant (mode, coeff, &algorithm, &variant,
3701 : : max_cost))
3702 : : {
3703 : 36 : op0 = convert_to_mode (mode, op0, this_optab == umul_widen_optab);
3704 : 36 : return expand_mult_const (mode, op0, coeff, target,
3705 : 36 : &algorithm, variant);
3706 : : }
3707 : : }
3708 : 17811 : return expand_binop (mode, this_optab, op0, op1, target,
3709 : 17811 : unsignedp, OPTAB_LIB_WIDEN);
3710 : : }
3711 : :
3712 : : /* Choose a minimal N + 1 bit approximation to 2**K / D that can be used to
3713 : : replace division by D, put the least significant N bits of the result in
3714 : : *MULTIPLIER_PTR, the value K - N in *POST_SHIFT_PTR, and return the most
3715 : : significant bit.
3716 : :
3717 : : The width of operations is N (should be <= HOST_BITS_PER_WIDE_INT), the
3718 : : needed precision is PRECISION (should be <= N).
3719 : :
3720 : : PRECISION should be as small as possible so this function can choose the
3721 : : multiplier more freely. If PRECISION is <= N - 1, the most significant
3722 : : bit returned by the function will be zero.
3723 : :
3724 : : Using this function, x / D is equal to (x*m) / 2**N >> (*POST_SHIFT_PTR),
3725 : : where m is the full N + 1 bit multiplier. */
3726 : :
3727 : : unsigned HOST_WIDE_INT
3728 : 73321 : choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision,
3729 : : unsigned HOST_WIDE_INT *multiplier_ptr,
3730 : : int *post_shift_ptr)
3731 : : {
3732 : 73321 : int lgup, post_shift;
3733 : 73321 : int pow1, pow2;
3734 : :
3735 : : /* lgup = ceil(log2(d)) */
3736 : : /* Assuming d > 1, we have d >= 2^(lgup-1) + 1 */
3737 : 73321 : lgup = ceil_log2 (d);
3738 : :
3739 : 73321 : gcc_assert (lgup <= n);
3740 : 73321 : gcc_assert (lgup <= precision);
3741 : :
3742 : 73321 : pow1 = n + lgup;
3743 : 73321 : pow2 = n + lgup - precision;
3744 : :
3745 : : /* mlow = 2^(n + lgup)/d */
3746 : : /* Trivially from above we have mlow < 2^(n+1) */
3747 : 73321 : wide_int val = wi::set_bit_in_zero (pow1, HOST_BITS_PER_DOUBLE_INT);
3748 : 73321 : wide_int mlow = wi::udiv_trunc (val, d);
3749 : :
3750 : : /* mhigh = (2^(n + lgup) + 2^(n + lgup - precision))/d */
3751 : : /* From above we have mhigh < 2^(n+1) assuming lgup <= precision */
3752 : : /* From precision <= n, the difference between the numerators of mhigh and
3753 : : mlow is >= 2^lgup >= d. Therefore the difference of the quotients in
3754 : : the Euclidean division by d is at least 1, so we have mlow < mhigh and
3755 : : the exact value of 2^(n + lgup)/d lies in the interval [mlow; mhigh). */
3756 : 73321 : val |= wi::set_bit_in_zero (pow2, HOST_BITS_PER_DOUBLE_INT);
3757 : 73321 : wide_int mhigh = wi::udiv_trunc (val, d);
3758 : :
3759 : : /* Reduce to lowest terms. */
3760 : : /* If precision <= n - 1, then the difference between the numerators of
3761 : : mhigh and mlow is >= 2^(lgup + 1) >= 2 * 2^lgup >= 2 * d. Therefore
3762 : : the difference of the quotients in the Euclidean division by d is at
3763 : : least 2, which means that mhigh and mlow differ by at least one bit
3764 : : not in the last place. The conclusion is that the first iteration of
3765 : : the loop below completes and shifts mhigh and mlow by 1 bit, which in
3766 : : particular means that mhigh < 2^n, that is to say, the most significant
3767 : : bit in the n + 1 bit value is zero. */
3768 : 200038 : for (post_shift = lgup; post_shift > 0; post_shift--)
3769 : : {
3770 : 194638 : unsigned HOST_WIDE_INT ml_lo = wi::extract_uhwi (mlow, 1,
3771 : : HOST_BITS_PER_WIDE_INT);
3772 : 194638 : unsigned HOST_WIDE_INT mh_lo = wi::extract_uhwi (mhigh, 1,
3773 : : HOST_BITS_PER_WIDE_INT);
3774 : 194638 : if (ml_lo >= mh_lo)
3775 : : break;
3776 : :
3777 : 126717 : mlow = wi::uhwi (ml_lo, HOST_BITS_PER_DOUBLE_INT);
3778 : 126717 : mhigh = wi::uhwi (mh_lo, HOST_BITS_PER_DOUBLE_INT);
3779 : : }
3780 : :
3781 : 73321 : *post_shift_ptr = post_shift;
3782 : :
3783 : 73321 : if (n < HOST_BITS_PER_WIDE_INT)
3784 : : {
3785 : 45385 : unsigned HOST_WIDE_INT mask = (HOST_WIDE_INT_1U << n) - 1;
3786 : 45385 : *multiplier_ptr = mhigh.to_uhwi () & mask;
3787 : 45385 : return mhigh.to_uhwi () > mask;
3788 : : }
3789 : : else
3790 : : {
3791 : 27936 : *multiplier_ptr = mhigh.to_uhwi ();
3792 : 27936 : return wi::extract_uhwi (mhigh, HOST_BITS_PER_WIDE_INT, 1);
3793 : : }
3794 : 73321 : }
3795 : :
3796 : : /* Compute the inverse of X mod 2**N, i.e., find Y such that X * Y is congruent
3797 : : to 1 modulo 2**N, assuming that X is odd. Bézout's lemma guarantees that Y
3798 : : exists for any given positive N. */
3799 : :
3800 : : static unsigned HOST_WIDE_INT
3801 : 34536 : invert_mod2n (unsigned HOST_WIDE_INT x, int n)
3802 : : {
3803 : 34536 : gcc_assert ((x & 1) == 1);
3804 : :
3805 : : /* The algorithm notes that the choice Y = Z satisfies X*Y == 1 mod 2^3,
3806 : : since X is odd. Then each iteration doubles the number of bits of
3807 : : significance in Y. */
3808 : :
3809 : 69072 : const unsigned HOST_WIDE_INT mask
3810 : : = (n == HOST_BITS_PER_WIDE_INT
3811 : 34536 : ? HOST_WIDE_INT_M1U
3812 : 1189 : : (HOST_WIDE_INT_1U << n) - 1);
3813 : 34536 : unsigned HOST_WIDE_INT y = x;
3814 : 34536 : int nbit = 3;
3815 : :
3816 : 205997 : while (nbit < n)
3817 : : {
3818 : 171461 : y = y * (2 - x*y) & mask; /* Modulo 2^N */
3819 : 171461 : nbit *= 2;
3820 : : }
3821 : :
3822 : 34536 : return y;
3823 : : }
3824 : :
3825 : : /* Emit code to adjust ADJ_OPERAND after multiplication of wrong signedness
3826 : : flavor of OP0 and OP1. ADJ_OPERAND is already the high half of the
3827 : : product OP0 x OP1. If UNSIGNEDP is nonzero, adjust the signed product
3828 : : to become unsigned, if UNSIGNEDP is zero, adjust the unsigned product to
3829 : : become signed.
3830 : :
3831 : : The result is put in TARGET if that is convenient.
3832 : :
3833 : : MODE is the mode of operation. */
3834 : :
3835 : : rtx
3836 : 0 : expand_mult_highpart_adjust (scalar_int_mode mode, rtx adj_operand, rtx op0,
3837 : : rtx op1, rtx target, int unsignedp)
3838 : : {
3839 : 0 : rtx tem;
3840 : 0 : enum rtx_code adj_code = unsignedp ? PLUS : MINUS;
3841 : :
3842 : 0 : tem = expand_shift (RSHIFT_EXPR, mode, op0,
3843 : 0 : GET_MODE_BITSIZE (mode) - 1, NULL_RTX, 0);
3844 : 0 : tem = expand_and (mode, tem, op1, NULL_RTX);
3845 : 0 : adj_operand
3846 : 0 : = force_operand (gen_rtx_fmt_ee (adj_code, mode, adj_operand, tem),
3847 : : adj_operand);
3848 : :
3849 : 0 : tem = expand_shift (RSHIFT_EXPR, mode, op1,
3850 : 0 : GET_MODE_BITSIZE (mode) - 1, NULL_RTX, 0);
3851 : 0 : tem = expand_and (mode, tem, op0, NULL_RTX);
3852 : 0 : target = force_operand (gen_rtx_fmt_ee (adj_code, mode, adj_operand, tem),
3853 : : target);
3854 : :
3855 : 0 : return target;
3856 : : }
3857 : :
3858 : : /* Subroutine of expmed_mult_highpart. Return the MODE high part of OP. */
3859 : :
3860 : : static rtx
3861 : 23323 : extract_high_half (scalar_int_mode mode, rtx op)
3862 : : {
3863 : 23323 : if (mode == word_mode)
3864 : 0 : return gen_highpart (mode, op);
3865 : :
3866 : 23323 : scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (mode).require ();
3867 : :
3868 : 46646 : op = expand_shift (RSHIFT_EXPR, wider_mode, op,
3869 : 23323 : GET_MODE_BITSIZE (mode), 0, 1);
3870 : 23323 : return convert_modes (mode, wider_mode, op, 0);
3871 : : }
3872 : :
3873 : : /* Like expmed_mult_highpart, but only consider using multiplication optab. */
3874 : :
3875 : : rtx
3876 : 52880 : expmed_mult_highpart_optab (scalar_int_mode mode, rtx op0, rtx op1,
3877 : : rtx target, int unsignedp, int max_cost)
3878 : : {
3879 : 52880 : const scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (mode).require ();
3880 : 52880 : const bool speed = optimize_insn_for_speed_p ();
3881 : 52880 : const int size = GET_MODE_BITSIZE (mode);
3882 : 52880 : optab moptab;
3883 : 52880 : rtx tem;
3884 : :
3885 : : /* Firstly, try using a multiplication insn that only generates the needed
3886 : : high part of the product, and in the sign flavor of unsignedp. */
3887 : 52880 : if (mul_highpart_cost (speed, mode) < max_cost)
3888 : : {
3889 : 50862 : moptab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
3890 : 50862 : tem = expand_binop (mode, moptab, op0, op1, target, unsignedp,
3891 : : OPTAB_DIRECT);
3892 : 50862 : if (tem)
3893 : : return tem;
3894 : : }
3895 : :
3896 : : /* Secondly, same as above, but use sign flavor opposite of unsignedp.
3897 : : Need to adjust the result after the multiplication. */
3898 : 25453 : if (size - 1 < BITS_PER_WORD
3899 : 50699 : && (mul_highpart_cost (speed, mode)
3900 : 25246 : + 2 * shift_cost (speed, mode, size-1)
3901 : 25246 : + 4 * add_cost (speed, mode) < max_cost))
3902 : : {
3903 : 9766 : moptab = unsignedp ? smul_highpart_optab : umul_highpart_optab;
3904 : 9766 : tem = expand_binop (mode, moptab, op0, op1, target, !unsignedp,
3905 : : OPTAB_DIRECT);
3906 : 9766 : if (tem)
3907 : : /* We used the wrong signedness. Adjust the result. */
3908 : 0 : return expand_mult_highpart_adjust (mode, tem, op0, op1, tem,
3909 : 0 : unsignedp);
3910 : : }
3911 : :
3912 : : /* Try widening multiplication. */
3913 : 25453 : moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
3914 : 25453 : if (convert_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
3915 : 25453 : && mul_widen_cost (speed, wider_mode) < max_cost)
3916 : : {
3917 : 362 : tem = expand_binop (wider_mode, moptab, op0, op1, NULL_RTX, unsignedp,
3918 : : OPTAB_WIDEN);
3919 : 362 : if (tem)
3920 : 362 : return extract_high_half (mode, tem);
3921 : : }
3922 : :
3923 : : /* Try widening the mode and perform a non-widening multiplication. */
3924 : 25091 : if (optab_handler (smul_optab, wider_mode) != CODE_FOR_nothing
3925 : 24669 : && size - 1 < BITS_PER_WORD
3926 : 49753 : && (mul_cost (speed, wider_mode) + shift_cost (speed, mode, size-1)
3927 : : < max_cost))
3928 : : {
3929 : 22948 : rtx_insn *insns;
3930 : 22948 : rtx wop0, wop1;
3931 : :
3932 : : /* We need to widen the operands, for example to ensure the
3933 : : constant multiplier is correctly sign or zero extended.
3934 : : Use a sequence to clean-up any instructions emitted by
3935 : : the conversions if things don't work out. */
3936 : 22948 : start_sequence ();
3937 : 22948 : wop0 = convert_modes (wider_mode, mode, op0, unsignedp);
3938 : 22948 : wop1 = convert_modes (wider_mode, mode, op1, unsignedp);
3939 : 22948 : tem = expand_binop (wider_mode, smul_optab, wop0, wop1, 0,
3940 : : unsignedp, OPTAB_WIDEN);
3941 : 22948 : insns = get_insns ();
3942 : 22948 : end_sequence ();
3943 : :
3944 : 22948 : if (tem)
3945 : : {
3946 : 22948 : emit_insn (insns);
3947 : 22948 : return extract_high_half (mode, tem);
3948 : : }
3949 : : }
3950 : :
3951 : : /* Try widening multiplication of opposite signedness, and adjust. */
3952 : 2143 : moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
3953 : 2143 : if (convert_optab_handler (moptab, wider_mode, mode) != CODE_FOR_nothing
3954 : 316 : && size - 1 < BITS_PER_WORD
3955 : 2673 : && (mul_widen_cost (speed, wider_mode)
3956 : 265 : + 2 * shift_cost (speed, mode, size-1)
3957 : 265 : + 4 * add_cost (speed, mode) < max_cost))
3958 : : {
3959 : 0 : tem = expand_binop (wider_mode, moptab, op0, op1, NULL_RTX, !unsignedp,
3960 : : OPTAB_WIDEN);
3961 : 0 : if (tem != 0)
3962 : : {
3963 : 0 : tem = extract_high_half (mode, tem);
3964 : : /* We used the wrong signedness. Adjust the result. */
3965 : 0 : return expand_mult_highpart_adjust (mode, tem, op0, op1, target,
3966 : 0 : unsignedp);
3967 : : }
3968 : : }
3969 : :
3970 : : return 0;
3971 : : }
3972 : :
3973 : : /* Emit code to multiply OP0 and OP1 (where OP1 is an integer constant),
3974 : : putting the high half of the result in TARGET if that is convenient,
3975 : : and return where the result is. If the operation cannot be performed,
3976 : : 0 is returned.
3977 : :
3978 : : MODE is the mode of operation and result.
3979 : :
3980 : : UNSIGNEDP nonzero means unsigned multiply.
3981 : :
3982 : : MAX_COST is the total allowed cost for the expanded RTL. */
3983 : :
3984 : : static rtx
3985 : 52880 : expmed_mult_highpart (scalar_int_mode mode, rtx op0, rtx op1,
3986 : : rtx target, int unsignedp, int max_cost)
3987 : : {
3988 : 52880 : const bool speed = optimize_insn_for_speed_p ();
3989 : 52880 : unsigned HOST_WIDE_INT cnst1;
3990 : 52880 : int extra_cost;
3991 : 52880 : bool sign_adjust = false;
3992 : 52880 : enum mult_variant variant;
3993 : 52880 : struct algorithm alg;
3994 : 52880 : rtx narrow_op1, tem;
3995 : :
3996 : : /* We can't support modes wider than HOST_BITS_PER_INT. */
3997 : 52880 : gcc_assert (HWI_COMPUTABLE_MODE_P (mode));
3998 : :
3999 : 52880 : cnst1 = INTVAL (op1) & GET_MODE_MASK (mode);
4000 : 52880 : narrow_op1 = gen_int_mode (INTVAL (op1), mode);
4001 : :
4002 : : /* We can't optimize modes wider than BITS_PER_WORD.
4003 : : ??? We might be able to perform double-word arithmetic if
4004 : : mode == word_mode, however all the cost calculations in
4005 : : synth_mult etc. assume single-word operations. */
4006 : 52880 : scalar_int_mode wider_mode = GET_MODE_WIDER_MODE (mode).require ();
4007 : 108626 : if (GET_MODE_BITSIZE (wider_mode) > BITS_PER_WORD)
4008 : 27856 : return expmed_mult_highpart_optab (mode, op0, narrow_op1, target,
4009 : 27856 : unsignedp, max_cost);
4010 : :
4011 : 50048 : extra_cost = shift_cost (speed, mode, GET_MODE_BITSIZE (mode) - 1);
4012 : :
4013 : : /* Check whether we try to multiply by a negative constant. */
4014 : 35920 : if (!unsignedp && ((cnst1 >> (GET_MODE_BITSIZE (mode) - 1)) & 1))
4015 : : {
4016 : 2125 : sign_adjust = true;
4017 : 2125 : extra_cost += add_cost (speed, mode);
4018 : : }
4019 : :
4020 : : /* See whether shift/add multiplication is cheap enough. */
4021 : 25024 : if (choose_mult_variant (wider_mode, cnst1, &alg, &variant,
4022 : : max_cost - extra_cost))
4023 : : {
4024 : : /* See whether the specialized multiplication optabs are
4025 : : cheaper than the shift/add version. */
4026 : 46478 : tem = expmed_mult_highpart_optab (mode, op0, narrow_op1, target,
4027 : : unsignedp,
4028 : 23239 : alg.cost.cost + extra_cost);
4029 : 23239 : if (tem)
4030 : : return tem;
4031 : :
4032 : 13 : tem = convert_to_mode (wider_mode, op0, unsignedp);
4033 : 13 : tem = expand_mult_const (wider_mode, tem, cnst1, 0, &alg, variant);
4034 : 13 : tem = extract_high_half (mode, tem);
4035 : :
4036 : : /* Adjust result for signedness. */
4037 : 13 : if (sign_adjust)
4038 : 0 : tem = force_operand (gen_rtx_MINUS (mode, tem, op0), tem);
4039 : :
4040 : 13 : return tem;
4041 : : }
4042 : 1785 : return expmed_mult_highpart_optab (mode, op0, narrow_op1, target,
4043 : 1785 : unsignedp, max_cost);
4044 : : }
4045 : :
4046 : :
4047 : : /* Expand signed modulus of OP0 by a power of two D in mode MODE. */
4048 : :
4049 : : static rtx
4050 : 2657 : expand_smod_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d)
4051 : : {
4052 : 2657 : rtx result, temp, shift;
4053 : 2657 : rtx_code_label *label;
4054 : 2657 : int logd;
4055 : 2657 : int prec = GET_MODE_PRECISION (mode);
4056 : :
4057 : 2657 : logd = floor_log2 (d);
4058 : 2657 : result = gen_reg_rtx (mode);
4059 : :
4060 : : /* Avoid conditional branches when they're expensive. */
4061 : 2657 : if (BRANCH_COST (optimize_insn_for_speed_p (), false) >= 2
4062 : 2657 : && optimize_insn_for_speed_p ())
4063 : : {
4064 : 2653 : rtx signmask = emit_store_flag (result, LT, op0, const0_rtx,
4065 : : mode, 0, -1);
4066 : 2653 : if (signmask)
4067 : : {
4068 : 2653 : HOST_WIDE_INT masklow = (HOST_WIDE_INT_1 << logd) - 1;
4069 : 2653 : signmask = force_reg (mode, signmask);
4070 : 5306 : shift = gen_int_shift_amount (mode, GET_MODE_BITSIZE (mode) - logd);
4071 : :
4072 : : /* Use the rtx_cost of a LSHIFTRT instruction to determine
4073 : : which instruction sequence to use. If logical right shifts
4074 : : are expensive the use 2 XORs, 2 SUBs and an AND, otherwise
4075 : : use a LSHIFTRT, 1 ADD, 1 SUB and an AND. */
4076 : :
4077 : 2653 : temp = gen_rtx_LSHIFTRT (mode, result, shift);
4078 : 2653 : if (optab_handler (lshr_optab, mode) == CODE_FOR_nothing
4079 : 2653 : || (set_src_cost (temp, mode, optimize_insn_for_speed_p ())
4080 : : > COSTS_N_INSNS (2)))
4081 : : {
4082 : 88 : temp = expand_binop (mode, xor_optab, op0, signmask,
4083 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4084 : 88 : temp = expand_binop (mode, sub_optab, temp, signmask,
4085 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4086 : 88 : temp = expand_binop (mode, and_optab, temp,
4087 : 88 : gen_int_mode (masklow, mode),
4088 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4089 : 88 : temp = expand_binop (mode, xor_optab, temp, signmask,
4090 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4091 : 88 : temp = expand_binop (mode, sub_optab, temp, signmask,
4092 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4093 : : }
4094 : : else
4095 : : {
4096 : 2565 : signmask = expand_binop (mode, lshr_optab, signmask, shift,
4097 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4098 : 2565 : signmask = force_reg (mode, signmask);
4099 : :
4100 : 2565 : temp = expand_binop (mode, add_optab, op0, signmask,
4101 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4102 : 2565 : temp = expand_binop (mode, and_optab, temp,
4103 : 2565 : gen_int_mode (masklow, mode),
4104 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4105 : 2565 : temp = expand_binop (mode, sub_optab, temp, signmask,
4106 : : NULL_RTX, 1, OPTAB_LIB_WIDEN);
4107 : : }
4108 : 2653 : return temp;
4109 : : }
4110 : : }
4111 : :
4112 : : /* Mask contains the mode's signbit and the significant bits of the
4113 : : modulus. By including the signbit in the operation, many targets
4114 : : can avoid an explicit compare operation in the following comparison
4115 : : against zero. */
4116 : 4 : wide_int mask = wi::mask (logd, false, prec);
4117 : 4 : mask = wi::set_bit (mask, prec - 1);
4118 : :
4119 : 8 : temp = expand_binop (mode, and_optab, op0,
4120 : 4 : immed_wide_int_const (mask, mode),
4121 : : result, 1, OPTAB_LIB_WIDEN);
4122 : 4 : if (temp != result)
4123 : 0 : emit_move_insn (result, temp);
4124 : :
4125 : 4 : label = gen_label_rtx ();
4126 : 4 : do_cmp_and_jump (result, const0_rtx, GE, mode, label);
4127 : :
4128 : 4 : temp = expand_binop (mode, sub_optab, result, const1_rtx, result,
4129 : : 0, OPTAB_LIB_WIDEN);
4130 : :
4131 : 4 : mask = wi::mask (logd, true, prec);
4132 : 8 : temp = expand_binop (mode, ior_optab, temp,
4133 : 4 : immed_wide_int_const (mask, mode),
4134 : : result, 1, OPTAB_LIB_WIDEN);
4135 : 4 : temp = expand_binop (mode, add_optab, temp, const1_rtx, result,
4136 : : 0, OPTAB_LIB_WIDEN);
4137 : 4 : if (temp != result)
4138 : 0 : emit_move_insn (result, temp);
4139 : 4 : emit_label (label);
4140 : 4 : return result;
4141 : 4 : }
4142 : :
4143 : : /* Expand signed division of OP0 by a power of two D in mode MODE.
4144 : : This routine is only called for positive values of D. */
4145 : :
4146 : : static rtx
4147 : 9242 : expand_sdiv_pow2 (scalar_int_mode mode, rtx op0, HOST_WIDE_INT d)
4148 : : {
4149 : 9242 : rtx temp;
4150 : 9242 : rtx_code_label *label;
4151 : 9242 : int logd;
4152 : :
4153 : 9242 : logd = floor_log2 (d);
4154 : :
4155 : 9242 : if (d == 2
4156 : 9242 : && BRANCH_COST (optimize_insn_for_speed_p (),
4157 : : false) >= 1)
4158 : : {
4159 : 5177 : temp = gen_reg_rtx (mode);
4160 : 5177 : temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, 1);
4161 : 5177 : if (temp != NULL_RTX)
4162 : : {
4163 : 5177 : temp = expand_binop (mode, add_optab, temp, op0, NULL_RTX,
4164 : : 0, OPTAB_LIB_WIDEN);
4165 : 5177 : return expand_shift (RSHIFT_EXPR, mode, temp, logd, NULL_RTX, 0);
4166 : : }
4167 : : }
4168 : :
4169 : 8129 : if (HAVE_conditional_move
4170 : 4065 : && BRANCH_COST (optimize_insn_for_speed_p (), false) >= 2)
4171 : : {
4172 : 4065 : rtx temp2;
4173 : :
4174 : 4065 : start_sequence ();
4175 : 4065 : temp2 = copy_to_mode_reg (mode, op0);
4176 : 4065 : temp = expand_binop (mode, add_optab, temp2, gen_int_mode (d - 1, mode),
4177 : : NULL_RTX, 0, OPTAB_LIB_WIDEN);
4178 : 4065 : temp = force_reg (mode, temp);
4179 : :
4180 : : /* Construct "temp2 = (temp2 < 0) ? temp : temp2". */
4181 : 4065 : temp2 = emit_conditional_move (temp2, { LT, temp2, const0_rtx, mode },
4182 : : temp, temp2, mode, 0);
4183 : 4065 : if (temp2)
4184 : : {
4185 : 4018 : rtx_insn *seq = get_insns ();
4186 : 4018 : end_sequence ();
4187 : 4018 : emit_insn (seq);
4188 : 4018 : return expand_shift (RSHIFT_EXPR, mode, temp2, logd, NULL_RTX, 0);
4189 : : }
4190 : 47 : end_sequence ();
4191 : : }
4192 : :
4193 : 47 : if (BRANCH_COST (optimize_insn_for_speed_p (),
4194 : : false) >= 2)
4195 : : {
4196 : 47 : int ushift = GET_MODE_BITSIZE (mode) - logd;
4197 : :
4198 : 47 : temp = gen_reg_rtx (mode);
4199 : 47 : temp = emit_store_flag (temp, LT, op0, const0_rtx, mode, 0, -1);
4200 : 47 : if (temp != NULL_RTX)
4201 : : {
4202 : 94 : if (GET_MODE_BITSIZE (mode) >= BITS_PER_WORD
4203 : 47 : || shift_cost (optimize_insn_for_speed_p (), mode, ushift)
4204 : : > COSTS_N_INSNS (1))
4205 : 47 : temp = expand_binop (mode, and_optab, temp,
4206 : 47 : gen_int_mode (d - 1, mode),
4207 : : NULL_RTX, 0, OPTAB_LIB_WIDEN);
4208 : : else
4209 : 0 : temp = expand_shift (RSHIFT_EXPR, mode, temp,
4210 : : ushift, NULL_RTX, 1);
4211 : 47 : temp = expand_binop (mode, add_optab, temp, op0, NULL_RTX,
4212 : : 0, OPTAB_LIB_WIDEN);
4213 : 47 : return expand_shift (RSHIFT_EXPR, mode, temp, logd, NULL_RTX, 0);
4214 : : }
4215 : : }
4216 : :
4217 : 0 : label = gen_label_rtx ();
4218 : 0 : temp = copy_to_mode_reg (mode, op0);
4219 : 0 : do_cmp_and_jump (temp, const0_rtx, GE, mode, label);
4220 : 0 : expand_inc (temp, gen_int_mode (d - 1, mode));
4221 : 0 : emit_label (label);
4222 : 0 : return expand_shift (RSHIFT_EXPR, mode, temp, logd, NULL_RTX, 0);
4223 : : }
4224 : :
4225 : : /* Emit the code to divide OP0 by OP1, putting the result in TARGET
4226 : : if that is convenient, and returning where the result is.
4227 : : You may request either the quotient or the remainder as the result;
4228 : : specify REM_FLAG nonzero to get the remainder.
4229 : :
4230 : : CODE is the expression code for which kind of division this is;
4231 : : it controls how rounding is done. MODE is the machine mode to use.
4232 : : UNSIGNEDP nonzero means do unsigned division. */
4233 : :
4234 : : /* ??? For CEIL_MOD_EXPR, can compute incorrect remainder with ANDI
4235 : : and then correct it by or'ing in missing high bits
4236 : : if result of ANDI is nonzero.
4237 : : For ROUND_MOD_EXPR, can use ANDI and then sign-extend the result.
4238 : : This could optimize to a bfexts instruction.
4239 : : But C doesn't use these operations, so their optimizations are
4240 : : left for later. */
4241 : : /* ??? For modulo, we don't actually need the highpart of the first product,
4242 : : the low part will do nicely. And for small divisors, the second multiply
4243 : : can also be a low-part only multiply or even be completely left out.
4244 : : E.g. to calculate the remainder of a division by 3 with a 32 bit
4245 : : multiply, multiply with 0x55555556 and extract the upper two bits;
4246 : : the result is exact for inputs up to 0x1fffffff.
4247 : : The input range can be reduced by using cross-sum rules.
4248 : : For odd divisors >= 3, the following table gives right shift counts
4249 : : so that if a number is shifted by an integer multiple of the given
4250 : : amount, the remainder stays the same:
4251 : : 2, 4, 3, 6, 10, 12, 4, 8, 18, 6, 11, 20, 18, 0, 5, 10, 12, 0, 12, 20,
4252 : : 14, 12, 23, 21, 8, 0, 20, 18, 0, 0, 6, 12, 0, 22, 0, 18, 20, 30, 0, 0,
4253 : : 0, 8, 0, 11, 12, 10, 36, 0, 30, 0, 0, 12, 0, 0, 0, 0, 44, 12, 24, 0,
4254 : : 20, 0, 7, 14, 0, 18, 36, 0, 0, 46, 60, 0, 42, 0, 15, 24, 20, 0, 0, 33,
4255 : : 0, 20, 0, 0, 18, 0, 60, 0, 0, 0, 0, 0, 40, 18, 0, 0, 12
4256 : :
4257 : : Cross-sum rules for even numbers can be derived by leaving as many bits
4258 : : to the right alone as the divisor has zeros to the right.
4259 : : E.g. if x is an unsigned 32 bit number:
4260 : : (x mod 12) == (((x & 1023) + ((x >> 8) & ~3)) * 0x15555558 >> 2 * 3) >> 28
4261 : : */
4262 : :
4263 : : rtx
4264 : 208590 : expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
4265 : : rtx op0, rtx op1, rtx target, int unsignedp,
4266 : : enum optab_methods methods)
4267 : : {
4268 : 208590 : machine_mode compute_mode;
4269 : 208590 : rtx tquotient;
4270 : 208590 : rtx quotient = 0, remainder = 0;
4271 : 208590 : rtx_insn *last;
4272 : 208590 : rtx_insn *insn;
4273 : 208590 : optab optab1, optab2;
4274 : 208590 : int op1_is_constant, op1_is_pow2 = 0;
4275 : 208590 : int max_cost, extra_cost;
4276 : 208590 : static HOST_WIDE_INT last_div_const = 0;
4277 : 208590 : bool speed = optimize_insn_for_speed_p ();
4278 : :
4279 : 208590 : op1_is_constant = CONST_INT_P (op1);
4280 : 208590 : if (op1_is_constant)
4281 : : {
4282 : 131395 : wide_int ext_op1 = rtx_mode_t (op1, mode);
4283 : 131395 : op1_is_pow2 = (wi::popcount (ext_op1) == 1
4284 : 262790 : || (! unsignedp
4285 : 163618 : && wi::popcount (wi::neg (ext_op1)) == 1));
4286 : 131395 : }
4287 : :
4288 : : /*
4289 : : This is the structure of expand_divmod:
4290 : :
4291 : : First comes code to fix up the operands so we can perform the operations
4292 : : correctly and efficiently.
4293 : :
4294 : : Second comes a switch statement with code specific for each rounding mode.
4295 : : For some special operands this code emits all RTL for the desired
4296 : : operation, for other cases, it generates only a quotient and stores it in
4297 : : QUOTIENT. The case for trunc division/remainder might leave quotient = 0,
4298 : : to indicate that it has not done anything.
4299 : :
4300 : : Last comes code that finishes the operation. If QUOTIENT is set and
4301 : : REM_FLAG is set, the remainder is computed as OP0 - QUOTIENT * OP1. If
4302 : : QUOTIENT is not set, it is computed using trunc rounding.
4303 : :
4304 : : We try to generate special code for division and remainder when OP1 is a
4305 : : constant. If |OP1| = 2**n we can use shifts and some other fast
4306 : : operations. For other values of OP1, we compute a carefully selected
4307 : : fixed-point approximation m = 1/OP1, and generate code that multiplies OP0
4308 : : by m.
4309 : :
4310 : : In all cases but EXACT_DIV_EXPR, this multiplication requires the upper
4311 : : half of the product. Different strategies for generating the product are
4312 : : implemented in expmed_mult_highpart.
4313 : :
4314 : : If what we actually want is the remainder, we generate that by another
4315 : : by-constant multiplication and a subtraction. */
4316 : :
4317 : : /* We shouldn't be called with OP1 == const1_rtx, but some of the
4318 : : code below will malfunction if we are, so check here and handle
4319 : : the special case if so. */
4320 : 208590 : if (op1 == const1_rtx)
4321 : 0 : return rem_flag ? const0_rtx : op0;
4322 : :
4323 : : /* When dividing by -1, we could get an overflow.
4324 : : negv_optab can handle overflows. */
4325 : 208590 : if (! unsignedp && op1 == constm1_rtx)
4326 : : {
4327 : 0 : if (rem_flag)
4328 : 0 : return const0_rtx;
4329 : 0 : return expand_unop (mode, flag_trapv && GET_MODE_CLASS (mode) == MODE_INT
4330 : 0 : ? negv_optab : neg_optab, op0, target, 0);
4331 : : }
4332 : :
4333 : 208590 : if (target
4334 : : /* Don't use the function value register as a target
4335 : : since we have to read it as well as write it,
4336 : : and function-inlining gets confused by this. */
4337 : 208590 : && ((REG_P (target) && REG_FUNCTION_VALUE_P (target))
4338 : : /* Don't clobber an operand while doing a multi-step calculation. */
4339 : 86944 : || ((rem_flag || op1_is_constant)
4340 : 67962 : && (reg_mentioned_p (target, op0)
4341 : 65715 : || (MEM_P (op0) && MEM_P (target))))
4342 : 83987 : || reg_mentioned_p (target, op1)
4343 : 83946 : || (MEM_P (op1) && MEM_P (target))))
4344 : : target = 0;
4345 : :
4346 : : /* Get the mode in which to perform this computation. Normally it will
4347 : : be MODE, but sometimes we can't do the desired operation in MODE.
4348 : : If so, pick a wider mode in which we can do the operation. Convert
4349 : : to that mode at the start to avoid repeated conversions.
4350 : :
4351 : : First see what operations we need. These depend on the expression
4352 : : we are evaluating. (We assume that divxx3 insns exist under the
4353 : : same conditions that modxx3 insns and that these insns don't normally
4354 : : fail. If these assumptions are not correct, we may generate less
4355 : : efficient code in some cases.)
4356 : :
4357 : : Then see if we find a mode in which we can open-code that operation
4358 : : (either a division, modulus, or shift). Finally, check for the smallest
4359 : : mode for which we can do the operation with a library call. */
4360 : :
4361 : : /* We might want to refine this now that we have division-by-constant
4362 : : optimization. Since expmed_mult_highpart tries so many variants, it is
4363 : : not straightforward to generalize this. Maybe we should make an array
4364 : : of possible modes in init_expmed? Save this for GCC 2.7. */
4365 : :
4366 : 417180 : optab1 = (op1_is_pow2
4367 : 208590 : ? (unsignedp ? lshr_optab : ashr_optab)
4368 : 141230 : : (unsignedp ? udiv_optab : sdiv_optab));
4369 : 208590 : optab2 = (op1_is_pow2 ? optab1
4370 : 141230 : : (unsignedp ? udivmod_optab : sdivmod_optab));
4371 : :
4372 : 208590 : if (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN)
4373 : : {
4374 : 220501 : FOR_EACH_MODE_FROM (compute_mode, mode)
4375 : 216148 : if (optab_handler (optab1, compute_mode) != CODE_FOR_nothing
4376 : 216148 : || optab_handler (optab2, compute_mode) != CODE_FOR_nothing)
4377 : : break;
4378 : :
4379 : 206678 : if (compute_mode == VOIDmode && methods == OPTAB_LIB_WIDEN)
4380 : 4353 : FOR_EACH_MODE_FROM (compute_mode, mode)
4381 : 4353 : if (optab_libfunc (optab1, compute_mode)
4382 : 4353 : || optab_libfunc (optab2, compute_mode))
4383 : : break;
4384 : : }
4385 : : else
4386 : : compute_mode = mode;
4387 : :
4388 : : /* If we still couldn't find a mode, use MODE, but expand_binop will
4389 : : probably die. */
4390 : 6265 : if (compute_mode == VOIDmode)
4391 : 0 : compute_mode = mode;
4392 : :
4393 : 208590 : if (target && GET_MODE (target) == compute_mode)
4394 : : tquotient = target;
4395 : : else
4396 : 124796 : tquotient = gen_reg_rtx (compute_mode);
4397 : :
4398 : : #if 0
4399 : : /* It should be possible to restrict the precision to GET_MODE_BITSIZE
4400 : : (mode), and thereby get better code when OP1 is a constant. Do that
4401 : : later. It will require going over all usages of SIZE below. */
4402 : : size = GET_MODE_BITSIZE (mode);
4403 : : #endif
4404 : :
4405 : : /* Only deduct something for a REM if the last divide done was
4406 : : for a different constant. Then set the constant of the last
4407 : : divide. */
4408 : 417180 : max_cost = (unsignedp
4409 : 312423 : ? udiv_cost (speed, compute_mode)
4410 : 104757 : : sdiv_cost (speed, compute_mode));
4411 : 208590 : if (rem_flag && ! (last_div_const != 0 && op1_is_constant
4412 : 9618 : && INTVAL (op1) == last_div_const))
4413 : 50306 : max_cost -= (mul_cost (speed, compute_mode)
4414 : 50306 : + add_cost (speed, compute_mode));
4415 : :
4416 : 208590 : last_div_const = ! rem_flag && op1_is_constant ? INTVAL (op1) : 0;
4417 : :
4418 : : /* Now convert to the best mode to use. */
4419 : 208590 : if (compute_mode != mode)
4420 : : {
4421 : 0 : op0 = convert_modes (compute_mode, mode, op0, unsignedp);
4422 : 0 : op1 = convert_modes (compute_mode, mode, op1, unsignedp);
4423 : :
4424 : : /* convert_modes may have placed op1 into a register, so we
4425 : : must recompute the following. */
4426 : 0 : op1_is_constant = CONST_INT_P (op1);
4427 : 0 : if (op1_is_constant)
4428 : : {
4429 : 0 : wide_int ext_op1 = rtx_mode_t (op1, compute_mode);
4430 : 0 : op1_is_pow2 = (wi::popcount (ext_op1) == 1
4431 : 0 : || (! unsignedp
4432 : 0 : && wi::popcount (wi::neg (ext_op1)) == 1));
4433 : 0 : }
4434 : : else
4435 : : op1_is_pow2 = 0;
4436 : : }
4437 : :
4438 : : /* If one of the operands is a volatile MEM, copy it into a register. */
4439 : :
4440 : 208590 : if (MEM_P (op0) && MEM_VOLATILE_P (op0))
4441 : 0 : op0 = force_reg (compute_mode, op0);
4442 : 208590 : if (MEM_P (op1) && MEM_VOLATILE_P (op1))
4443 : 0 : op1 = force_reg (compute_mode, op1);
4444 : :
4445 : : /* If we need the remainder or if OP1 is constant, we need to
4446 : : put OP0 in a register in case it has any queued subexpressions. */
4447 : 208590 : if (rem_flag || op1_is_constant)
4448 : 157374 : op0 = force_reg (compute_mode, op0);
4449 : :
4450 : 208590 : last = get_last_insn ();
4451 : :
4452 : : /* Promote floor rounding to trunc rounding for unsigned operations. */
4453 : 208590 : if (unsignedp)
4454 : : {
4455 : 103833 : if (code == FLOOR_DIV_EXPR)
4456 : : code = TRUNC_DIV_EXPR;
4457 : 103817 : if (code == FLOOR_MOD_EXPR)
4458 : 98 : code = TRUNC_MOD_EXPR;
4459 : 103833 : if (code == EXACT_DIV_EXPR && op1_is_pow2)
4460 : 1879 : code = TRUNC_DIV_EXPR;
4461 : : }
4462 : :
4463 : 208590 : if (op1 != const0_rtx)
4464 : 208231 : switch (code)
4465 : : {
4466 : 171893 : case TRUNC_MOD_EXPR:
4467 : 171893 : case TRUNC_DIV_EXPR:
4468 : 171893 : if (op1_is_constant)
4469 : : {
4470 : 95549 : scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
4471 : 95549 : int size = GET_MODE_BITSIZE (int_mode);
4472 : 95549 : if (unsignedp)
4473 : : {
4474 : 56721 : unsigned HOST_WIDE_INT mh, ml;
4475 : 56721 : int pre_shift, post_shift;
4476 : 56721 : wide_int wd = rtx_mode_t (op1, int_mode);
4477 : 56721 : unsigned HOST_WIDE_INT d = wd.to_uhwi ();
4478 : :
4479 : 56721 : if (wi::popcount (wd) == 1)
4480 : : {
4481 : 26809 : pre_shift = floor_log2 (d);
4482 : 26809 : if (rem_flag)
4483 : : {
4484 : 344 : unsigned HOST_WIDE_INT mask
4485 : 344 : = (HOST_WIDE_INT_1U << pre_shift) - 1;
4486 : 344 : remainder
4487 : 344 : = expand_binop (int_mode, and_optab, op0,
4488 : 344 : gen_int_mode (mask, int_mode),
4489 : : remainder, 1, methods);
4490 : 344 : if (remainder)
4491 : 344 : return gen_lowpart (mode, remainder);
4492 : : }
4493 : 26465 : quotient = expand_shift (RSHIFT_EXPR, int_mode, op0,
4494 : : pre_shift, tquotient, 1);
4495 : : }
4496 : 29912 : else if (size <= HOST_BITS_PER_WIDE_INT)
4497 : : {
4498 : 28073 : if (d >= (HOST_WIDE_INT_1U << (size - 1)))
4499 : : {
4500 : : /* Most significant bit of divisor is set; emit an scc
4501 : : insn. */
4502 : 146 : quotient = emit_store_flag_force (tquotient, GEU, op0, op1,
4503 : : int_mode, 1, 1);
4504 : : }
4505 : : else
4506 : : {
4507 : : /* Find a suitable multiplier and right shift count
4508 : : instead of directly dividing by D. */
4509 : 27927 : mh = choose_multiplier (d, size, size,
4510 : : &ml, &post_shift);
4511 : :
4512 : : /* If the suggested multiplier is more than SIZE bits,
4513 : : we can do better for even divisors, using an
4514 : : initial right shift. */
4515 : 27927 : if (mh != 0 && (d & 1) == 0)
4516 : : {
4517 : 2990 : pre_shift = ctz_or_zero (d);
4518 : 2990 : mh = choose_multiplier (d >> pre_shift, size,
4519 : : size - pre_shift,
4520 : : &ml, &post_shift);
4521 : 2990 : gcc_assert (!mh);
4522 : : }
4523 : : else
4524 : : pre_shift = 0;
4525 : :
4526 : 3454 : if (mh != 0)
4527 : : {
4528 : 3454 : rtx t1, t2, t3, t4;
4529 : :
4530 : 3540 : if (post_shift - 1 >= BITS_PER_WORD)
4531 : 0 : goto fail1;
4532 : :
4533 : 3454 : extra_cost
4534 : 3454 : = (shift_cost (speed, int_mode, post_shift - 1)
4535 : 3454 : + shift_cost (speed, int_mode, 1)
4536 : 3454 : + 2 * add_cost (speed, int_mode));
4537 : 3454 : t1 = expmed_mult_highpart
4538 : 3454 : (int_mode, op0, gen_int_mode (ml, int_mode),
4539 : : NULL_RTX, 1, max_cost - extra_cost);
4540 : 3454 : if (t1 == 0)
4541 : 99 : goto fail1;
4542 : 3355 : t2 = force_operand (gen_rtx_MINUS (int_mode,
4543 : : op0, t1),
4544 : : NULL_RTX);
4545 : 6710 : t3 = expand_shift (RSHIFT_EXPR, int_mode,
4546 : 3355 : t2, 1, NULL_RTX, 1);
4547 : 3355 : t4 = force_operand (gen_rtx_PLUS (int_mode,
4548 : : t1, t3),
4549 : : NULL_RTX);
4550 : 3355 : quotient = expand_shift
4551 : 3355 : (RSHIFT_EXPR, int_mode, t4,
4552 : 3355 : post_shift - 1, tquotient, 1);
4553 : : }
4554 : : else
4555 : : {
4556 : 24473 : rtx t1, t2;
4557 : :
4558 : 26082 : if (pre_shift >= BITS_PER_WORD
4559 : 24473 : || post_shift >= BITS_PER_WORD)
4560 : 3 : goto fail1;
4561 : :
4562 : 24470 : t1 = expand_shift
4563 : 24470 : (RSHIFT_EXPR, int_mode, op0,
4564 : : pre_shift, NULL_RTX, 1);
4565 : 24470 : extra_cost
4566 : 24470 : = (shift_cost (speed, int_mode, pre_shift)
4567 : 24470 : + shift_cost (speed, int_mode, post_shift));
4568 : 24470 : t2 = expmed_mult_highpart
4569 : 24470 : (int_mode, t1,
4570 : 24470 : gen_int_mode (ml, int_mode),
4571 : : NULL_RTX, 1, max_cost - extra_cost);
4572 : 24470 : if (t2 == 0)
4573 : 910 : goto fail1;
4574 : 23560 : quotient = expand_shift
4575 : 23560 : (RSHIFT_EXPR, int_mode, t2,
4576 : : post_shift, tquotient, 1);
4577 : : }
4578 : : }
4579 : : }
4580 : : else /* Too wide mode to use tricky code */
4581 : : break;
4582 : :
4583 : 53526 : insn = get_last_insn ();
4584 : 53526 : if (insn != last)
4585 : 53526 : set_dst_reg_note (insn, REG_EQUAL,
4586 : : gen_rtx_UDIV (int_mode, op0, op1),
4587 : : quotient);
4588 : 54882 : }
4589 : : else /* TRUNC_DIV, signed */
4590 : : {
4591 : 38828 : unsigned HOST_WIDE_INT ml;
4592 : 38828 : int post_shift;
4593 : 38828 : rtx mlr;
4594 : 38828 : HOST_WIDE_INT d = INTVAL (op1);
4595 : 38828 : unsigned HOST_WIDE_INT abs_d;
4596 : :
4597 : : /* Not prepared to handle division/remainder by
4598 : : 0xffffffffffffffff8000000000000000 etc. */
4599 : 38828 : if (d == HOST_WIDE_INT_MIN && size > HOST_BITS_PER_WIDE_INT)
4600 : : break;
4601 : :
4602 : : /* Since d might be INT_MIN, we have to cast to
4603 : : unsigned HOST_WIDE_INT before negating to avoid
4604 : : undefined signed overflow. */
4605 : 38828 : abs_d = (d >= 0
4606 : 38828 : ? (unsigned HOST_WIDE_INT) d
4607 : : : - (unsigned HOST_WIDE_INT) d);
4608 : :
4609 : : /* n rem d = n rem -d */
4610 : 38828 : if (rem_flag && d < 0)
4611 : : {
4612 : 141 : d = abs_d;
4613 : 141 : op1 = gen_int_mode (abs_d, int_mode);
4614 : : }
4615 : :
4616 : 38828 : if (d == 1)
4617 : : quotient = op0;
4618 : 38828 : else if (d == -1)
4619 : 0 : quotient = expand_unop (int_mode, neg_optab, op0,
4620 : : tquotient, 0);
4621 : 38828 : else if (size <= HOST_BITS_PER_WIDE_INT
4622 : 37427 : && abs_d == HOST_WIDE_INT_1U << (size - 1))
4623 : : {
4624 : : /* This case is not handled correctly below. */
4625 : 133 : quotient = emit_store_flag (tquotient, EQ, op0, op1,
4626 : : int_mode, 1, 1);
4627 : 133 : if (quotient == 0)
4628 : 1356 : goto fail1;
4629 : : }
4630 : 38695 : else if (EXACT_POWER_OF_2_OR_ZERO_P (d)
4631 : 12043 : && (size <= HOST_BITS_PER_WIDE_INT || d >= 0)
4632 : 2786 : && (rem_flag
4633 : 2786 : ? smod_pow2_cheap (speed, int_mode)
4634 : 9257 : : sdiv_pow2_cheap (speed, int_mode))
4635 : : /* We assume that cheap metric is true if the
4636 : : optab has an expander for this mode. */
4637 : 51793 : && ((optab_handler ((rem_flag ? smod_optab
4638 : : : sdiv_optab),
4639 : : int_mode)
4640 : : != CODE_FOR_nothing)
4641 : 594 : || (optab_handler (sdivmod_optab, int_mode)
4642 : : != CODE_FOR_nothing)))
4643 : : ;
4644 : 38107 : else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d))
4645 : : {
4646 : 11906 : if (rem_flag)
4647 : : {
4648 : 2657 : remainder = expand_smod_pow2 (int_mode, op0, d);
4649 : 2657 : if (remainder)
4650 : 2657 : return gen_lowpart (mode, remainder);
4651 : : }
4652 : :
4653 : 9249 : if (sdiv_pow2_cheap (speed, int_mode)
4654 : 9249 : && ((optab_handler (sdiv_optab, int_mode)
4655 : : != CODE_FOR_nothing)
4656 : 10 : || (optab_handler (sdivmod_optab, int_mode)
4657 : : != CODE_FOR_nothing)))
4658 : 7 : quotient = expand_divmod (0, TRUNC_DIV_EXPR,
4659 : : int_mode, op0,
4660 : 7 : gen_int_mode (abs_d,
4661 : : int_mode),
4662 : : NULL_RTX, 0);
4663 : : else
4664 : 9242 : quotient = expand_sdiv_pow2 (int_mode, op0, abs_d);
4665 : :
4666 : : /* We have computed OP0 / abs(OP1). If OP1 is negative,
4667 : : negate the quotient. */
4668 : 9249 : if (d < 0)
4669 : : {
4670 : 451 : insn = get_last_insn ();
4671 : 451 : if (insn != last
4672 : 451 : && abs_d < (HOST_WIDE_INT_1U
4673 : : << (HOST_BITS_PER_WIDE_INT - 1)))
4674 : 451 : set_dst_reg_note (insn, REG_EQUAL,
4675 : 451 : gen_rtx_DIV (int_mode, op0,
4676 : : gen_int_mode
4677 : : (abs_d,
4678 : : int_mode)),
4679 : : quotient);
4680 : :
4681 : 451 : quotient = expand_unop (int_mode, neg_optab,
4682 : : quotient, quotient, 0);
4683 : : }
4684 : : }
4685 : 26201 : else if (size <= HOST_BITS_PER_WIDE_INT)
4686 : : {
4687 : 24863 : choose_multiplier (abs_d, size, size - 1,
4688 : : &ml, &post_shift);
4689 : 24863 : if (ml < HOST_WIDE_INT_1U << (size - 1))
4690 : : {
4691 : 19037 : rtx t1, t2, t3;
4692 : :
4693 : 20113 : if (post_shift >= BITS_PER_WORD
4694 : 19037 : || size - 1 >= BITS_PER_WORD)
4695 : 242 : goto fail1;
4696 : :
4697 : 18795 : extra_cost = (shift_cost (speed, int_mode, post_shift)
4698 : 18795 : + shift_cost (speed, int_mode, size - 1)
4699 : 18795 : + add_cost (speed, int_mode));
4700 : 18795 : t1 = expmed_mult_highpart
4701 : 18795 : (int_mode, op0, gen_int_mode (ml, int_mode),
4702 : : NULL_RTX, 0, max_cost - extra_cost);
4703 : 18795 : if (t1 == 0)
4704 : 880 : goto fail1;
4705 : 17915 : t2 = expand_shift
4706 : 17915 : (RSHIFT_EXPR, int_mode, t1,
4707 : : post_shift, NULL_RTX, 0);
4708 : 17915 : t3 = expand_shift
4709 : 17915 : (RSHIFT_EXPR, int_mode, op0,
4710 : 17915 : size - 1, NULL_RTX, 0);
4711 : 17915 : if (d < 0)
4712 : 197 : quotient
4713 : 197 : = force_operand (gen_rtx_MINUS (int_mode, t3, t2),
4714 : : tquotient);
4715 : : else
4716 : 17718 : quotient
4717 : 17718 : = force_operand (gen_rtx_MINUS (int_mode, t2, t3),
4718 : : tquotient);
4719 : : }
4720 : : else
4721 : : {
4722 : 5826 : rtx t1, t2, t3, t4;
4723 : :
4724 : 6168 : if (post_shift >= BITS_PER_WORD
4725 : 5821 : || size - 1 >= BITS_PER_WORD)
4726 : 24 : goto fail1;
4727 : :
4728 : 5802 : ml |= HOST_WIDE_INT_M1U << (size - 1);
4729 : 5802 : mlr = gen_int_mode (ml, int_mode);
4730 : 5802 : extra_cost = (shift_cost (speed, int_mode, post_shift)
4731 : 5802 : + shift_cost (speed, int_mode, size - 1)
4732 : 5802 : + 2 * add_cost (speed, int_mode));
4733 : 5802 : t1 = expmed_mult_highpart (int_mode, op0, mlr,
4734 : : NULL_RTX, 0,
4735 : : max_cost - extra_cost);
4736 : 5802 : if (t1 == 0)
4737 : 210 : goto fail1;
4738 : 5592 : t2 = force_operand (gen_rtx_PLUS (int_mode, t1, op0),
4739 : : NULL_RTX);
4740 : 5592 : t3 = expand_shift
4741 : 5592 : (RSHIFT_EXPR, int_mode, t2,
4742 : : post_shift, NULL_RTX, 0);
4743 : 5592 : t4 = expand_shift
4744 : 5592 : (RSHIFT_EXPR, int_mode, op0,
4745 : 5592 : size - 1, NULL_RTX, 0);
4746 : 5592 : if (d < 0)
4747 : 49 : quotient
4748 : 49 : = force_operand (gen_rtx_MINUS (int_mode, t4, t3),
4749 : : tquotient);
4750 : : else
4751 : 5543 : quotient
4752 : 5543 : = force_operand (gen_rtx_MINUS (int_mode, t3, t4),
4753 : : tquotient);
4754 : : }
4755 : : }
4756 : : else /* Too wide mode to use tricky code */
4757 : : break;
4758 : :
4759 : 33477 : insn = get_last_insn ();
4760 : 33477 : if (insn != last)
4761 : 32889 : set_dst_reg_note (insn, REG_EQUAL,
4762 : : gen_rtx_DIV (int_mode, op0, op1),
4763 : : quotient);
4764 : : }
4765 : : break;
4766 : : }
4767 : 76344 : fail1:
4768 : 78712 : delete_insns_since (last);
4769 : 78712 : break;
4770 : :
4771 : 1504 : case FLOOR_DIV_EXPR:
4772 : 1504 : case FLOOR_MOD_EXPR:
4773 : : /* We will come here only for signed operations. */
4774 : 1504 : if (op1_is_constant && HWI_COMPUTABLE_MODE_P (compute_mode))
4775 : : {
4776 : 894 : scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
4777 : 894 : int size = GET_MODE_BITSIZE (int_mode);
4778 : 894 : unsigned HOST_WIDE_INT mh, ml;
4779 : 894 : int pre_shift, post_shift;
4780 : 894 : HOST_WIDE_INT d = INTVAL (op1);
4781 : :
4782 : 894 : if (d > 0)
4783 : : {
4784 : : /* We could just as easily deal with negative constants here,
4785 : : but it does not seem worth the trouble for GCC 2.6. */
4786 : 869 : if (EXACT_POWER_OF_2_OR_ZERO_P (d))
4787 : : {
4788 : 508 : pre_shift = floor_log2 (d);
4789 : 508 : if (rem_flag)
4790 : : {
4791 : 74 : unsigned HOST_WIDE_INT mask
4792 : 74 : = (HOST_WIDE_INT_1U << pre_shift) - 1;
4793 : 74 : remainder = expand_binop
4794 : 74 : (int_mode, and_optab, op0,
4795 : 74 : gen_int_mode (mask, int_mode),
4796 : : remainder, 0, methods);
4797 : 74 : if (remainder)
4798 : 74 : return gen_lowpart (mode, remainder);
4799 : : }
4800 : 434 : quotient = expand_shift
4801 : 434 : (RSHIFT_EXPR, int_mode, op0,
4802 : : pre_shift, tquotient, 0);
4803 : : }
4804 : : else
4805 : : {
4806 : 361 : rtx t1, t2, t3, t4;
4807 : :
4808 : 361 : mh = choose_multiplier (d, size, size - 1,
4809 : : &ml, &post_shift);
4810 : 361 : gcc_assert (!mh);
4811 : :
4812 : 385 : if (post_shift < BITS_PER_WORD
4813 : 361 : && size - 1 < BITS_PER_WORD)
4814 : : {
4815 : 359 : t1 = expand_shift
4816 : 359 : (RSHIFT_EXPR, int_mode, op0,
4817 : 359 : size - 1, NULL_RTX, 0);
4818 : 359 : t2 = expand_binop (int_mode, xor_optab, op0, t1,
4819 : : NULL_RTX, 0, OPTAB_WIDEN);
4820 : 359 : extra_cost = (shift_cost (speed, int_mode, post_shift)
4821 : 359 : + shift_cost (speed, int_mode, size - 1)
4822 : 359 : + 2 * add_cost (speed, int_mode));
4823 : 359 : t3 = expmed_mult_highpart
4824 : 359 : (int_mode, t2, gen_int_mode (ml, int_mode),
4825 : : NULL_RTX, 1, max_cost - extra_cost);
4826 : 359 : if (t3 != 0)
4827 : : {
4828 : 328 : t4 = expand_shift
4829 : 328 : (RSHIFT_EXPR, int_mode, t3,
4830 : : post_shift, NULL_RTX, 1);
4831 : 328 : quotient = expand_binop (int_mode, xor_optab,
4832 : : t4, t1, tquotient, 0,
4833 : : OPTAB_WIDEN);
4834 : : }
4835 : : }
4836 : : }
4837 : : }
4838 : : else
4839 : : {
4840 : 25 : rtx nsign, t1, t2, t3, t4;
4841 : 25 : t1 = force_operand (gen_rtx_PLUS (int_mode,
4842 : : op0, constm1_rtx), NULL_RTX);
4843 : 25 : t2 = expand_binop (int_mode, ior_optab, op0, t1, NULL_RTX,
4844 : : 0, OPTAB_WIDEN);
4845 : 50 : nsign = expand_shift (RSHIFT_EXPR, int_mode, t2,
4846 : 25 : size - 1, NULL_RTX, 0);
4847 : 25 : t3 = force_operand (gen_rtx_MINUS (int_mode, t1, nsign),
4848 : : NULL_RTX);
4849 : 25 : t4 = expand_divmod (0, TRUNC_DIV_EXPR, int_mode, t3, op1,
4850 : : NULL_RTX, 0);
4851 : 25 : if (t4)
4852 : : {
4853 : 25 : rtx t5;
4854 : 25 : t5 = expand_unop (int_mode, one_cmpl_optab, nsign,
4855 : : NULL_RTX, 0);
4856 : 25 : quotient = force_operand (gen_rtx_PLUS (int_mode, t4, t5),
4857 : : tquotient);
4858 : : }
4859 : : }
4860 : : }
4861 : :
4862 : 820 : if (quotient != 0)
4863 : : break;
4864 : 643 : delete_insns_since (last);
4865 : :
4866 : : /* Try using an instruction that produces both the quotient and
4867 : : remainder, using truncation. We can easily compensate the quotient
4868 : : or remainder to get floor rounding, once we have the remainder.
4869 : : Notice that we compute also the final remainder value here,
4870 : : and return the result right away. */
4871 : 643 : if (target == 0 || GET_MODE (target) != compute_mode)
4872 : 78 : target = gen_reg_rtx (compute_mode);
4873 : :
4874 : 643 : if (rem_flag)
4875 : : {
4876 : 229 : remainder
4877 : 229 : = REG_P (target) ? target : gen_reg_rtx (compute_mode);
4878 : 229 : quotient = gen_reg_rtx (compute_mode);
4879 : : }
4880 : : else
4881 : : {
4882 : 414 : quotient
4883 : 414 : = REG_P (target) ? target : gen_reg_rtx (compute_mode);
4884 : 414 : remainder = gen_reg_rtx (compute_mode);
4885 : : }
4886 : :
4887 : 643 : if (expand_twoval_binop (sdivmod_optab, op0, op1,
4888 : : quotient, remainder, 0))
4889 : : {
4890 : : /* This could be computed with a branch-less sequence.
4891 : : Save that for later. */
4892 : 608 : rtx tem;
4893 : 608 : rtx_code_label *label = gen_label_rtx ();
4894 : 608 : do_cmp_and_jump (remainder, const0_rtx, EQ, compute_mode, label);
4895 : 608 : tem = expand_binop (compute_mode, xor_optab, op0, op1,
4896 : : NULL_RTX, 0, OPTAB_WIDEN);
4897 : 608 : do_cmp_and_jump (tem, const0_rtx, GE, compute_mode, label);
4898 : 608 : expand_dec (quotient, const1_rtx);
4899 : 608 : expand_inc (remainder, op1);
4900 : 608 : emit_label (label);
4901 : 1013 : return gen_lowpart (mode, rem_flag ? remainder : quotient);
4902 : : }
4903 : :
4904 : : /* No luck with division elimination or divmod. Have to do it
4905 : : by conditionally adjusting op0 *and* the result. */
4906 : 35 : {
4907 : 35 : rtx_code_label *label1, *label2, *label3, *label4, *label5;
4908 : 35 : rtx adjusted_op0;
4909 : 35 : rtx tem;
4910 : :
4911 : 35 : quotient = gen_reg_rtx (compute_mode);
4912 : 35 : adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
4913 : 35 : label1 = gen_label_rtx ();
4914 : 35 : label2 = gen_label_rtx ();
4915 : 35 : label3 = gen_label_rtx ();
4916 : 35 : label4 = gen_label_rtx ();
4917 : 35 : label5 = gen_label_rtx ();
4918 : 35 : do_cmp_and_jump (op1, const0_rtx, LT, compute_mode, label2);
4919 : 35 : do_cmp_and_jump (adjusted_op0, const0_rtx, LT, compute_mode, label1);
4920 : 35 : tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
4921 : : quotient, 0, methods);
4922 : 35 : if (tem != quotient)
4923 : 35 : emit_move_insn (quotient, tem);
4924 : 35 : emit_jump_insn (targetm.gen_jump (label5));
4925 : 35 : emit_barrier ();
4926 : 35 : emit_label (label1);
4927 : 35 : expand_inc (adjusted_op0, const1_rtx);
4928 : 35 : emit_jump_insn (targetm.gen_jump (label4));
4929 : 35 : emit_barrier ();
4930 : 35 : emit_label (label2);
4931 : 35 : do_cmp_and_jump (adjusted_op0, const0_rtx, GT, compute_mode, label3);
4932 : 35 : tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
4933 : : quotient, 0, methods);
4934 : 35 : if (tem != quotient)
4935 : 35 : emit_move_insn (quotient, tem);
4936 : 35 : emit_jump_insn (targetm.gen_jump (label5));
4937 : 35 : emit_barrier ();
4938 : 35 : emit_label (label3);
4939 : 35 : expand_dec (adjusted_op0, const1_rtx);
4940 : 35 : emit_label (label4);
4941 : 35 : tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
4942 : : quotient, 0, methods);
4943 : 35 : if (tem != quotient)
4944 : 35 : emit_move_insn (quotient, tem);
4945 : 35 : expand_dec (quotient, const1_rtx);
4946 : 35 : emit_label (label5);
4947 : : }
4948 : 35 : break;
4949 : :
4950 : 288 : case CEIL_DIV_EXPR:
4951 : 288 : case CEIL_MOD_EXPR:
4952 : 288 : if (unsignedp)
4953 : : {
4954 : 0 : if (op1_is_constant
4955 : 0 : && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
4956 : 0 : && (HWI_COMPUTABLE_MODE_P (compute_mode)
4957 : 0 : || INTVAL (op1) >= 0))
4958 : : {
4959 : 0 : scalar_int_mode int_mode
4960 : 0 : = as_a <scalar_int_mode> (compute_mode);
4961 : 0 : rtx t1, t2, t3;
4962 : 0 : unsigned HOST_WIDE_INT d = INTVAL (op1);
4963 : 0 : t1 = expand_shift (RSHIFT_EXPR, int_mode, op0,
4964 : 0 : floor_log2 (d), tquotient, 1);
4965 : 0 : t2 = expand_binop (int_mode, and_optab, op0,
4966 : 0 : gen_int_mode (d - 1, int_mode),
4967 : : NULL_RTX, 1, methods);
4968 : 0 : t3 = gen_reg_rtx (int_mode);
4969 : 0 : t3 = emit_store_flag (t3, NE, t2, const0_rtx, int_mode, 1, 1);
4970 : 0 : if (t3 == 0)
4971 : : {
4972 : 0 : rtx_code_label *lab;
4973 : 0 : lab = gen_label_rtx ();
4974 : 0 : do_cmp_and_jump (t2, const0_rtx, EQ, int_mode, lab);
4975 : 0 : expand_inc (t1, const1_rtx);
4976 : 0 : emit_label (lab);
4977 : 0 : quotient = t1;
4978 : : }
4979 : : else
4980 : 0 : quotient = force_operand (gen_rtx_PLUS (int_mode, t1, t3),
4981 : : tquotient);
4982 : : break;
4983 : : }
4984 : :
4985 : : /* Try using an instruction that produces both the quotient and
4986 : : remainder, using truncation. We can easily compensate the
4987 : : quotient or remainder to get ceiling rounding, once we have the
4988 : : remainder. Notice that we compute also the final remainder
4989 : : value here, and return the result right away. */
4990 : 0 : if (target == 0 || GET_MODE (target) != compute_mode)
4991 : 0 : target = gen_reg_rtx (compute_mode);
4992 : :
4993 : 0 : if (rem_flag)
4994 : : {
4995 : 0 : remainder = (REG_P (target)
4996 : 0 : ? target : gen_reg_rtx (compute_mode));
4997 : 0 : quotient = gen_reg_rtx (compute_mode);
4998 : : }
4999 : : else
5000 : : {
5001 : 0 : quotient = (REG_P (target)
5002 : 0 : ? target : gen_reg_rtx (compute_mode));
5003 : 0 : remainder = gen_reg_rtx (compute_mode);
5004 : : }
5005 : :
5006 : 0 : if (expand_twoval_binop (udivmod_optab, op0, op1, quotient,
5007 : : remainder, 1))
5008 : : {
5009 : : /* This could be computed with a branch-less sequence.
5010 : : Save that for later. */
5011 : 0 : rtx_code_label *label = gen_label_rtx ();
5012 : 0 : do_cmp_and_jump (remainder, const0_rtx, EQ,
5013 : : compute_mode, label);
5014 : 0 : expand_inc (quotient, const1_rtx);
5015 : 0 : expand_dec (remainder, op1);
5016 : 0 : emit_label (label);
5017 : 0 : return gen_lowpart (mode, rem_flag ? remainder : quotient);
5018 : : }
5019 : :
5020 : : /* No luck with division elimination or divmod. Have to do it
5021 : : by conditionally adjusting op0 *and* the result. */
5022 : 0 : {
5023 : 0 : rtx_code_label *label1, *label2;
5024 : 0 : rtx adjusted_op0, tem;
5025 : :
5026 : 0 : quotient = gen_reg_rtx (compute_mode);
5027 : 0 : adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
5028 : 0 : label1 = gen_label_rtx ();
5029 : 0 : label2 = gen_label_rtx ();
5030 : 0 : do_cmp_and_jump (adjusted_op0, const0_rtx, NE,
5031 : : compute_mode, label1);
5032 : 0 : emit_move_insn (quotient, const0_rtx);
5033 : 0 : emit_jump_insn (targetm.gen_jump (label2));
5034 : 0 : emit_barrier ();
5035 : 0 : emit_label (label1);
5036 : 0 : expand_dec (adjusted_op0, const1_rtx);
5037 : 0 : tem = expand_binop (compute_mode, udiv_optab, adjusted_op0, op1,
5038 : : quotient, 1, methods);
5039 : 0 : if (tem != quotient)
5040 : 0 : emit_move_insn (quotient, tem);
5041 : 0 : expand_inc (quotient, const1_rtx);
5042 : 0 : emit_label (label2);
5043 : : }
5044 : : }
5045 : : else /* signed */
5046 : : {
5047 : 288 : if (op1_is_constant && EXACT_POWER_OF_2_OR_ZERO_P (INTVAL (op1))
5048 : 10 : && INTVAL (op1) >= 0)
5049 : : {
5050 : : /* This is extremely similar to the code for the unsigned case
5051 : : above. For 2.7 we should merge these variants, but for
5052 : : 2.6.1 I don't want to touch the code for unsigned since that
5053 : : get used in C. The signed case will only be used by other
5054 : : languages (Ada). */
5055 : :
5056 : 10 : rtx t1, t2, t3;
5057 : 10 : unsigned HOST_WIDE_INT d = INTVAL (op1);
5058 : 20 : t1 = expand_shift (RSHIFT_EXPR, compute_mode, op0,
5059 : 10 : floor_log2 (d), tquotient, 0);
5060 : 10 : t2 = expand_binop (compute_mode, and_optab, op0,
5061 : 10 : gen_int_mode (d - 1, compute_mode),
5062 : : NULL_RTX, 1, methods);
5063 : 10 : t3 = gen_reg_rtx (compute_mode);
5064 : 10 : t3 = emit_store_flag (t3, NE, t2, const0_rtx,
5065 : : compute_mode, 1, 1);
5066 : 10 : if (t3 == 0)
5067 : : {
5068 : 0 : rtx_code_label *lab;
5069 : 0 : lab = gen_label_rtx ();
5070 : 0 : do_cmp_and_jump (t2, const0_rtx, EQ, compute_mode, lab);
5071 : 0 : expand_inc (t1, const1_rtx);
5072 : 0 : emit_label (lab);
5073 : 0 : quotient = t1;
5074 : : }
5075 : : else
5076 : 10 : quotient = force_operand (gen_rtx_PLUS (compute_mode,
5077 : : t1, t3),
5078 : : tquotient);
5079 : : break;
5080 : : }
5081 : :
5082 : : /* Try using an instruction that produces both the quotient and
5083 : : remainder, using truncation. We can easily compensate the
5084 : : quotient or remainder to get ceiling rounding, once we have the
5085 : : remainder. Notice that we compute also the final remainder
5086 : : value here, and return the result right away. */
5087 : 278 : if (target == 0 || GET_MODE (target) != compute_mode)
5088 : 15 : target = gen_reg_rtx (compute_mode);
5089 : 278 : if (rem_flag)
5090 : : {
5091 : 170 : remainder= (REG_P (target)
5092 : 85 : ? target : gen_reg_rtx (compute_mode));
5093 : 85 : quotient = gen_reg_rtx (compute_mode);
5094 : : }
5095 : : else
5096 : : {
5097 : 386 : quotient = (REG_P (target)
5098 : 193 : ? target : gen_reg_rtx (compute_mode));
5099 : 193 : remainder = gen_reg_rtx (compute_mode);
5100 : : }
5101 : :
5102 : 278 : if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient,
5103 : : remainder, 0))
5104 : : {
5105 : : /* This could be computed with a branch-less sequence.
5106 : : Save that for later. */
5107 : 278 : rtx tem;
5108 : 278 : rtx_code_label *label = gen_label_rtx ();
5109 : 278 : do_cmp_and_jump (remainder, const0_rtx, EQ,
5110 : : compute_mode, label);
5111 : 278 : tem = expand_binop (compute_mode, xor_optab, op0, op1,
5112 : : NULL_RTX, 0, OPTAB_WIDEN);
5113 : 278 : do_cmp_and_jump (tem, const0_rtx, LT, compute_mode, label);
5114 : 278 : expand_inc (quotient, const1_rtx);
5115 : 278 : expand_dec (remainder, op1);
5116 : 278 : emit_label (label);
5117 : 471 : return gen_lowpart (mode, rem_flag ? remainder : quotient);
5118 : : }
5119 : :
5120 : : /* No luck with division elimination or divmod. Have to do it
5121 : : by conditionally adjusting op0 *and* the result. */
5122 : 0 : {
5123 : 0 : rtx_code_label *label1, *label2, *label3, *label4, *label5;
5124 : 0 : rtx adjusted_op0;
5125 : 0 : rtx tem;
5126 : :
5127 : 0 : quotient = gen_reg_rtx (compute_mode);
5128 : 0 : adjusted_op0 = copy_to_mode_reg (compute_mode, op0);
5129 : 0 : label1 = gen_label_rtx ();
5130 : 0 : label2 = gen_label_rtx ();
5131 : 0 : label3 = gen_label_rtx ();
5132 : 0 : label4 = gen_label_rtx ();
5133 : 0 : label5 = gen_label_rtx ();
5134 : 0 : do_cmp_and_jump (op1, const0_rtx, LT, compute_mode, label2);
5135 : 0 : do_cmp_and_jump (adjusted_op0, const0_rtx, GT,
5136 : : compute_mode, label1);
5137 : 0 : tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
5138 : : quotient, 0, methods);
5139 : 0 : if (tem != quotient)
5140 : 0 : emit_move_insn (quotient, tem);
5141 : 0 : emit_jump_insn (targetm.gen_jump (label5));
5142 : 0 : emit_barrier ();
5143 : 0 : emit_label (label1);
5144 : 0 : expand_dec (adjusted_op0, const1_rtx);
5145 : 0 : emit_jump_insn (targetm.gen_jump (label4));
5146 : 0 : emit_barrier ();
5147 : 0 : emit_label (label2);
5148 : 0 : do_cmp_and_jump (adjusted_op0, const0_rtx, LT,
5149 : : compute_mode, label3);
5150 : 0 : tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
5151 : : quotient, 0, methods);
5152 : 0 : if (tem != quotient)
5153 : 0 : emit_move_insn (quotient, tem);
5154 : 0 : emit_jump_insn (targetm.gen_jump (label5));
5155 : 0 : emit_barrier ();
5156 : 0 : emit_label (label3);
5157 : 0 : expand_inc (adjusted_op0, const1_rtx);
5158 : 0 : emit_label (label4);
5159 : 0 : tem = expand_binop (compute_mode, sdiv_optab, adjusted_op0, op1,
5160 : : quotient, 0, methods);
5161 : 0 : if (tem != quotient)
5162 : 0 : emit_move_insn (quotient, tem);
5163 : 0 : expand_inc (quotient, const1_rtx);
5164 : 0 : emit_label (label5);
5165 : : }
5166 : : }
5167 : : break;
5168 : :
5169 : 34544 : case EXACT_DIV_EXPR:
5170 : 34544 : if (op1_is_constant && HWI_COMPUTABLE_MODE_P (compute_mode))
5171 : : {
5172 : 34536 : scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
5173 : 34536 : int size = GET_MODE_BITSIZE (int_mode);
5174 : 34536 : HOST_WIDE_INT d = INTVAL (op1);
5175 : 34536 : unsigned HOST_WIDE_INT ml;
5176 : 34536 : int pre_shift;
5177 : 34536 : rtx t1;
5178 : :
5179 : 34536 : pre_shift = ctz_or_zero (d);
5180 : 34536 : ml = invert_mod2n (d >> pre_shift, size);
5181 : 34536 : t1 = expand_shift (RSHIFT_EXPR, int_mode, op0,
5182 : : pre_shift, NULL_RTX, unsignedp);
5183 : 34536 : quotient = expand_mult (int_mode, t1, gen_int_mode (ml, int_mode),
5184 : : NULL_RTX, 1);
5185 : :
5186 : 34536 : insn = get_last_insn ();
5187 : 69072 : set_dst_reg_note (insn, REG_EQUAL,
5188 : : gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
5189 : : int_mode, op0, op1),
5190 : : quotient);
5191 : : }
5192 : : break;
5193 : :
5194 : 2 : case ROUND_DIV_EXPR:
5195 : 2 : case ROUND_MOD_EXPR:
5196 : 2 : if (unsignedp)
5197 : : {
5198 : 0 : scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
5199 : 0 : rtx tem;
5200 : 0 : rtx_code_label *label;
5201 : 0 : label = gen_label_rtx ();
5202 : 0 : quotient = gen_reg_rtx (int_mode);
5203 : 0 : remainder = gen_reg_rtx (int_mode);
5204 : 0 : if (expand_twoval_binop (udivmod_optab, op0, op1, quotient, remainder, 1) == 0)
5205 : : {
5206 : 0 : rtx tem;
5207 : 0 : quotient = expand_binop (int_mode, udiv_optab, op0, op1,
5208 : : quotient, 1, methods);
5209 : 0 : tem = expand_mult (int_mode, quotient, op1, NULL_RTX, 1);
5210 : 0 : remainder = expand_binop (int_mode, sub_optab, op0, tem,
5211 : : remainder, 1, methods);
5212 : : }
5213 : 0 : tem = plus_constant (int_mode, op1, -1);
5214 : 0 : tem = expand_shift (RSHIFT_EXPR, int_mode, tem, 1, NULL_RTX, 1);
5215 : 0 : do_cmp_and_jump (remainder, tem, LEU, int_mode, label);
5216 : 0 : expand_inc (quotient, const1_rtx);
5217 : 0 : expand_dec (remainder, op1);
5218 : 0 : emit_label (label);
5219 : : }
5220 : : else
5221 : : {
5222 : 2 : scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
5223 : 2 : int size = GET_MODE_BITSIZE (int_mode);
5224 : 2 : rtx abs_rem, abs_op1, tem, mask;
5225 : 2 : rtx_code_label *label;
5226 : 2 : label = gen_label_rtx ();
5227 : 2 : quotient = gen_reg_rtx (int_mode);
5228 : 2 : remainder = gen_reg_rtx (int_mode);
5229 : 2 : if (expand_twoval_binop (sdivmod_optab, op0, op1, quotient, remainder, 0) == 0)
5230 : : {
5231 : 0 : rtx tem;
5232 : 0 : quotient = expand_binop (int_mode, sdiv_optab, op0, op1,
5233 : : quotient, 0, methods);
5234 : 0 : tem = expand_mult (int_mode, quotient, op1, NULL_RTX, 0);
5235 : 0 : remainder = expand_binop (int_mode, sub_optab, op0, tem,
5236 : : remainder, 0, methods);
5237 : : }
5238 : 2 : abs_rem = expand_abs (int_mode, remainder, NULL_RTX, 1, 0);
5239 : 2 : abs_op1 = expand_abs (int_mode, op1, NULL_RTX, 1, 0);
5240 : 4 : tem = expand_shift (LSHIFT_EXPR, int_mode, abs_rem,
5241 : 2 : 1, NULL_RTX, 1);
5242 : 2 : do_cmp_and_jump (tem, abs_op1, LTU, int_mode, label);
5243 : 2 : tem = expand_binop (int_mode, xor_optab, op0, op1,
5244 : : NULL_RTX, 0, OPTAB_WIDEN);
5245 : 4 : mask = expand_shift (RSHIFT_EXPR, int_mode, tem,
5246 : 2 : size - 1, NULL_RTX, 0);
5247 : 2 : tem = expand_binop (int_mode, xor_optab, mask, const1_rtx,
5248 : : NULL_RTX, 0, OPTAB_WIDEN);
5249 : 2 : tem = expand_binop (int_mode, sub_optab, tem, mask,
5250 : : NULL_RTX, 0, OPTAB_WIDEN);
5251 : 2 : expand_inc (quotient, tem);
5252 : 2 : tem = expand_binop (int_mode, xor_optab, mask, op1,
5253 : : NULL_RTX, 0, OPTAB_WIDEN);
5254 : 2 : tem = expand_binop (int_mode, sub_optab, tem, mask,
5255 : : NULL_RTX, 0, OPTAB_WIDEN);
5256 : 2 : expand_dec (remainder, tem);
5257 : 2 : emit_label (label);
5258 : : }
5259 : 3 : return gen_lowpart (mode, rem_flag ? remainder : quotient);
5260 : :
5261 : 0 : default:
5262 : 0 : gcc_unreachable ();
5263 : : }
5264 : :
5265 : 203473 : if (quotient == 0)
5266 : : {
5267 : 82844 : if (target && GET_MODE (target) != compute_mode)
5268 : 43782 : target = 0;
5269 : :
5270 : 82844 : if (rem_flag)
5271 : : {
5272 : : /* Try to produce the remainder without producing the quotient.
5273 : : If we seem to have a divmod pattern that does not require widening,
5274 : : don't try widening here. We should really have a WIDEN argument
5275 : : to expand_twoval_binop, since what we'd really like to do here is
5276 : : 1) try a mod insn in compute_mode
5277 : : 2) try a divmod insn in compute_mode
5278 : : 3) try a div insn in compute_mode and multiply-subtract to get
5279 : : remainder
5280 : : 4) try the same things with widening allowed. */
5281 : 28311 : remainder
5282 : 29764 : = sign_expand_binop (compute_mode, umod_optab, smod_optab,
5283 : : op0, op1, target,
5284 : : unsignedp,
5285 : 28311 : ((optab_handler (optab2, compute_mode)
5286 : : != CODE_FOR_nothing)
5287 : : ? OPTAB_DIRECT : OPTAB_WIDEN));
5288 : 28311 : if (remainder == 0)
5289 : : {
5290 : : /* No luck there. Can we do remainder and divide at once
5291 : : without a library call? */
5292 : 28104 : remainder = gen_reg_rtx (compute_mode);
5293 : 42092 : if (! expand_twoval_binop ((unsignedp
5294 : : ? udivmod_optab
5295 : : : sdivmod_optab),
5296 : : op0, op1,
5297 : : NULL_RTX, remainder, unsignedp))
5298 : : remainder = 0;
5299 : : }
5300 : :
5301 : 26858 : if (remainder)
5302 : 27065 : return gen_lowpart (mode, remainder);
5303 : : }
5304 : :
5305 : : /* Produce the quotient. Try a quotient insn, but not a library call.
5306 : : If we have a divmod in this mode, use it in preference to widening
5307 : : the div (for this test we assume it will not fail). Note that optab2
5308 : : is set to the one of the two optabs that the call below will use. */
5309 : 55779 : quotient
5310 : 61138 : = sign_expand_binop (compute_mode, udiv_optab, sdiv_optab,
5311 : : op0, op1, rem_flag ? NULL_RTX : target,
5312 : : unsignedp,
5313 : 55779 : ((optab_handler (optab2, compute_mode)
5314 : : != CODE_FOR_nothing)
5315 : : ? OPTAB_DIRECT : OPTAB_WIDEN));
5316 : :
5317 : 55779 : if (quotient == 0)
5318 : : {
5319 : : /* No luck there. Try a quotient-and-remainder insn,
5320 : : keeping the quotient alone. */
5321 : 55396 : quotient = gen_reg_rtx (compute_mode);
5322 : 76958 : if (! expand_twoval_binop (unsignedp ? udivmod_optab : sdivmod_optab,
5323 : : op0, op1,
5324 : : quotient, NULL_RTX, unsignedp))
5325 : : {
5326 : 3731 : quotient = 0;
5327 : 3731 : if (! rem_flag)
5328 : : /* Still no luck. If we are not computing the remainder,
5329 : : use a library call for the quotient. */
5330 : 2507 : quotient = sign_expand_binop (compute_mode,
5331 : : udiv_optab, sdiv_optab,
5332 : : op0, op1, target,
5333 : : unsignedp, methods);
5334 : : }
5335 : : }
5336 : : }
5337 : :
5338 : 176338 : if (rem_flag)
5339 : : {
5340 : 24040 : if (target && GET_MODE (target) != compute_mode)
5341 : 15969 : target = 0;
5342 : :
5343 : 24040 : if (quotient == 0)
5344 : : {
5345 : : /* No divide instruction either. Use library for remainder. */
5346 : 1224 : remainder = sign_expand_binop (compute_mode, umod_optab, smod_optab,
5347 : : op0, op1, target,
5348 : : unsignedp, methods);
5349 : : /* No remainder function. Try a quotient-and-remainder
5350 : : function, keeping the remainder. */
5351 : 1224 : if (!remainder
5352 : 0 : && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
5353 : : {
5354 : 0 : remainder = gen_reg_rtx (compute_mode);
5355 : 0 : if (!expand_twoval_binop_libfunc
5356 : 0 : (unsignedp ? udivmod_optab : sdivmod_optab,
5357 : : op0, op1,
5358 : : NULL_RTX, remainder,
5359 : : unsignedp ? UMOD : MOD))
5360 : 0 : remainder = NULL_RTX;
5361 : : }
5362 : : }
5363 : : else
5364 : : {
5365 : : /* We divided. Now finish doing X - Y * (X / Y). */
5366 : 22816 : remainder = expand_mult (compute_mode, quotient, op1,
5367 : : NULL_RTX, unsignedp);
5368 : 22816 : remainder = expand_binop (compute_mode, sub_optab, op0,
5369 : : remainder, target, unsignedp,
5370 : : methods);
5371 : : }
5372 : : }
5373 : :
5374 : 177562 : if (methods != OPTAB_LIB_WIDEN
5375 : 1912 : && (rem_flag ? remainder : quotient) == NULL_RTX)
5376 : : return NULL_RTX;
5377 : :
5378 : 331084 : return gen_lowpart (mode, rem_flag ? remainder : quotient);
5379 : : }
5380 : :
5381 : : /* Return a tree node with data type TYPE, describing the value of X.
5382 : : Usually this is an VAR_DECL, if there is no obvious better choice.
5383 : : X may be an expression, however we only support those expressions
5384 : : generated by loop.c. */
5385 : :
5386 : : tree
5387 : 616423 : make_tree (tree type, rtx x)
5388 : : {
5389 : 616423 : tree t;
5390 : :
5391 : 616423 : switch (GET_CODE (x))
5392 : : {
5393 : 12268 : case CONST_INT:
5394 : 12268 : case CONST_WIDE_INT:
5395 : 12268 : t = wide_int_to_tree (type, rtx_mode_t (x, TYPE_MODE (type)));
5396 : 12268 : return t;
5397 : :
5398 : 0 : case CONST_DOUBLE:
5399 : 0 : STATIC_ASSERT (HOST_BITS_PER_WIDE_INT * 2 <= MAX_BITSIZE_MODE_ANY_INT);
5400 : 0 : if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (x) == VOIDmode)
5401 : : t = wide_int_to_tree (type,
5402 : : wide_int::from_array (&CONST_DOUBLE_LOW (x), 2,
5403 : : HOST_BITS_PER_WIDE_INT * 2));
5404 : : else
5405 : 0 : t = build_real (type, *CONST_DOUBLE_REAL_VALUE (x));
5406 : :
5407 : 0 : return t;
5408 : :
5409 : 0 : case CONST_VECTOR:
5410 : 0 : {
5411 : 0 : unsigned int npatterns = CONST_VECTOR_NPATTERNS (x);
5412 : 0 : unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
5413 : 0 : tree itype = TREE_TYPE (type);
5414 : :
5415 : : /* Build a tree with vector elements. */
5416 : 0 : tree_vector_builder elts (type, npatterns, nelts_per_pattern);
5417 : 0 : unsigned int count = elts.encoded_nelts ();
5418 : 0 : for (unsigned int i = 0; i < count; ++i)
5419 : : {
5420 : 0 : rtx elt = CONST_VECTOR_ELT (x, i);
5421 : 0 : elts.quick_push (make_tree (itype, elt));
5422 : : }
5423 : :
5424 : 0 : return elts.build ();
5425 : 0 : }
5426 : :
5427 : 0 : case PLUS:
5428 : 0 : return fold_build2 (PLUS_EXPR, type, make_tree (type, XEXP (x, 0)),
5429 : : make_tree (type, XEXP (x, 1)));
5430 : :
5431 : 0 : case MINUS:
5432 : 0 : return fold_build2 (MINUS_EXPR, type, make_tree (type, XEXP (x, 0)),
5433 : : make_tree (type, XEXP (x, 1)));
5434 : :
5435 : 0 : case NEG:
5436 : 0 : return fold_build1 (NEGATE_EXPR, type, make_tree (type, XEXP (x, 0)));
5437 : :
5438 : 0 : case MULT:
5439 : 0 : return fold_build2 (MULT_EXPR, type, make_tree (type, XEXP (x, 0)),
5440 : : make_tree (type, XEXP (x, 1)));
5441 : :
5442 : 0 : case ASHIFT:
5443 : 0 : return fold_build2 (LSHIFT_EXPR, type, make_tree (type, XEXP (x, 0)),
5444 : : make_tree (type, XEXP (x, 1)));
5445 : :
5446 : 0 : case LSHIFTRT:
5447 : 0 : t = unsigned_type_for (type);
5448 : 0 : return fold_convert (type, build2 (RSHIFT_EXPR, t,
5449 : : make_tree (t, XEXP (x, 0)),
5450 : : make_tree (type, XEXP (x, 1))));
5451 : :
5452 : 0 : case ASHIFTRT:
5453 : 0 : t = signed_type_for (type);
5454 : 0 : return fold_convert (type, build2 (RSHIFT_EXPR, t,
5455 : : make_tree (t, XEXP (x, 0)),
5456 : : make_tree (type, XEXP (x, 1))));
5457 : :
5458 : 0 : case DIV:
5459 : 0 : if (TREE_CODE (type) != REAL_TYPE)
5460 : 0 : t = signed_type_for (type);
5461 : : else
5462 : : t = type;
5463 : :
5464 : 0 : return fold_convert (type, build2 (TRUNC_DIV_EXPR, t,
5465 : : make_tree (t, XEXP (x, 0)),
5466 : : make_tree (t, XEXP (x, 1))));
5467 : 0 : case UDIV:
5468 : 0 : t = unsigned_type_for (type);
5469 : 0 : return fold_convert (type, build2 (TRUNC_DIV_EXPR, t,
5470 : : make_tree (t, XEXP (x, 0)),
5471 : : make_tree (t, XEXP (x, 1))));
5472 : :
5473 : 0 : case SIGN_EXTEND:
5474 : 0 : case ZERO_EXTEND:
5475 : 0 : t = lang_hooks.types.type_for_mode (GET_MODE (XEXP (x, 0)),
5476 : : GET_CODE (x) == ZERO_EXTEND);
5477 : 0 : return fold_convert (type, make_tree (t, XEXP (x, 0)));
5478 : :
5479 : 0 : case CONST:
5480 : 0 : return make_tree (type, XEXP (x, 0));
5481 : :
5482 : 0 : case SYMBOL_REF:
5483 : 0 : t = SYMBOL_REF_DECL (x);
5484 : 0 : if (t)
5485 : 0 : return fold_convert (type, build_fold_addr_expr (t));
5486 : : /* fall through. */
5487 : :
5488 : 604155 : default:
5489 : 604155 : if (CONST_POLY_INT_P (x))
5490 : : return wide_int_to_tree (t, const_poly_int_value (x));
5491 : :
5492 : 604155 : t = build_decl (RTL_LOCATION (x), VAR_DECL, NULL_TREE, type);
5493 : :
5494 : : /* If TYPE is a POINTER_TYPE, we might need to convert X from
5495 : : address mode to pointer mode. */
5496 : 604155 : if (POINTER_TYPE_P (type))
5497 : 668306 : x = convert_memory_address_addr_space
5498 : 334153 : (SCALAR_INT_TYPE_MODE (type), x, TYPE_ADDR_SPACE (TREE_TYPE (type)));
5499 : :
5500 : : /* Note that we do *not* use SET_DECL_RTL here, because we do not
5501 : : want set_decl_rtl to go adjusting REG_ATTRS for this temporary. */
5502 : 604155 : t->decl_with_rtl.rtl = x;
5503 : :
5504 : 604155 : return t;
5505 : : }
5506 : : }
5507 : :
5508 : : /* Compute the logical-and of OP0 and OP1, storing it in TARGET
5509 : : and returning TARGET.
5510 : :
5511 : : If TARGET is 0, a pseudo-register or constant is returned. */
5512 : :
5513 : : rtx
5514 : 70841 : expand_and (machine_mode mode, rtx op0, rtx op1, rtx target)
5515 : : {
5516 : 70841 : rtx tem = 0;
5517 : :
5518 : 70841 : if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
5519 : 58 : tem = simplify_binary_operation (AND, mode, op0, op1);
5520 : 58 : if (tem == 0)
5521 : 70783 : tem = expand_binop (mode, and_optab, op0, op1, target, 0, OPTAB_LIB_WIDEN);
5522 : :
5523 : 70841 : if (target == 0)
5524 : : target = tem;
5525 : 43062 : else if (tem != target)
5526 : 13 : emit_move_insn (target, tem);
5527 : 70841 : return target;
5528 : : }
5529 : :
5530 : : /* Helper function for emit_store_flag. */
5531 : : rtx
5532 : 626824 : emit_cstore (rtx target, enum insn_code icode, enum rtx_code code,
5533 : : machine_mode mode, machine_mode compare_mode,
5534 : : int unsignedp, rtx x, rtx y, int normalizep,
5535 : : machine_mode target_mode)
5536 : : {
5537 : 626824 : class expand_operand ops[4];
5538 : 626824 : rtx op0, comparison, subtarget;
5539 : 626824 : rtx_insn *last;
5540 : 626824 : scalar_int_mode result_mode = targetm.cstore_mode (icode);
5541 : 626824 : scalar_int_mode int_target_mode;
5542 : :
5543 : 626824 : last = get_last_insn ();
5544 : 626824 : x = prepare_operand (icode, x, 2, mode, compare_mode, unsignedp);
5545 : 626824 : y = prepare_operand (icode, y, 3, mode, compare_mode, unsignedp);
5546 : 626824 : if (!x || !y)
5547 : : {
5548 : 311 : delete_insns_since (last);
5549 : 311 : return NULL_RTX;
5550 : : }
5551 : :
5552 : 626513 : if (target_mode == VOIDmode)
5553 : : int_target_mode = result_mode;
5554 : : else
5555 : 626513 : int_target_mode = as_a <scalar_int_mode> (target_mode);
5556 : 626513 : if (!target)
5557 : 66418 : target = gen_reg_rtx (int_target_mode);
5558 : :
5559 : 626513 : comparison = gen_rtx_fmt_ee (code, result_mode, x, y);
5560 : :
5561 : 626513 : create_output_operand (&ops[0], optimize ? NULL_RTX : target, result_mode);
5562 : 626513 : create_fixed_operand (&ops[1], comparison);
5563 : 626513 : create_fixed_operand (&ops[2], x);
5564 : 626513 : create_fixed_operand (&ops[3], y);
5565 : 626513 : if (!maybe_expand_insn (icode, 4, ops))
5566 : : {
5567 : 150392 : delete_insns_since (last);
5568 : 150392 : return NULL_RTX;
5569 : : }
5570 : 476121 : subtarget = ops[0].value;
5571 : :
5572 : : /* If we are converting to a wider mode, first convert to
5573 : : INT_TARGET_MODE, then normalize. This produces better combining
5574 : : opportunities on machines that have a SIGN_EXTRACT when we are
5575 : : testing a single bit. This mostly benefits the 68k.
5576 : :
5577 : : If STORE_FLAG_VALUE does not have the sign bit set when
5578 : : interpreted in MODE, we can do this conversion as unsigned, which
5579 : : is usually more efficient. */
5580 : 476121 : if (GET_MODE_PRECISION (int_target_mode) > GET_MODE_PRECISION (result_mode))
5581 : : {
5582 : 92658 : gcc_assert (GET_MODE_PRECISION (result_mode) != 1
5583 : : || STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1);
5584 : :
5585 : 92658 : bool unsignedp = (STORE_FLAG_VALUE >= 0);
5586 : 92658 : convert_move (target, subtarget, unsignedp);
5587 : :
5588 : 92658 : op0 = target;
5589 : 92658 : result_mode = int_target_mode;
5590 : : }
5591 : : else
5592 : : op0 = subtarget;
5593 : :
5594 : : /* If we want to keep subexpressions around, don't reuse our last
5595 : : target. */
5596 : 476121 : if (optimize)
5597 : 372517 : subtarget = 0;
5598 : :
5599 : : /* Now normalize to the proper value in MODE. Sometimes we don't
5600 : : have to do anything. */
5601 : 476121 : if (normalizep == 0 || normalizep == STORE_FLAG_VALUE)
5602 : : ;
5603 : : /* STORE_FLAG_VALUE might be the most negative number, so write
5604 : : the comparison this way to avoid a compiler-time warning. */
5605 : 829 : else if (- normalizep == STORE_FLAG_VALUE)
5606 : 829 : op0 = expand_unop (result_mode, neg_optab, op0, subtarget, 0);
5607 : :
5608 : : /* We don't want to use STORE_FLAG_VALUE < 0 below since this makes
5609 : : it hard to use a value of just the sign bit due to ANSI integer
5610 : : constant typing rules. */
5611 : 0 : else if (val_signbit_known_set_p (result_mode, STORE_FLAG_VALUE))
5612 : 0 : op0 = expand_shift (RSHIFT_EXPR, result_mode, op0,
5613 : 0 : GET_MODE_BITSIZE (result_mode) - 1, subtarget,
5614 : : normalizep == 1);
5615 : : else
5616 : : {
5617 : 0 : gcc_assert (STORE_FLAG_VALUE & 1);
5618 : :
5619 : 0 : op0 = expand_and (result_mode, op0, const1_rtx, subtarget);
5620 : 0 : if (normalizep == -1)
5621 : : op0 = expand_unop (result_mode, neg_optab, op0, op0, 0);
5622 : : }
5623 : :
5624 : : /* If we were converting to a smaller mode, do the conversion now. */
5625 : 476121 : if (int_target_mode != result_mode)
5626 : : {
5627 : 0 : convert_move (target, op0, 0);
5628 : 0 : return target;
5629 : : }
5630 : : else
5631 : : return op0;
5632 : : }
5633 : :
5634 : :
5635 : : /* A subroutine of emit_store_flag only including "tricks" that do not
5636 : : need a recursive call. These are kept separate to avoid infinite
5637 : : loops. */
5638 : :
5639 : : static rtx
5640 : 591454 : emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
5641 : : machine_mode mode, int unsignedp, int normalizep,
5642 : : machine_mode target_mode)
5643 : : {
5644 : 591454 : rtx subtarget;
5645 : 591454 : enum insn_code icode;
5646 : 591454 : machine_mode compare_mode;
5647 : 591454 : enum mode_class mclass;
5648 : :
5649 : 591454 : if (unsignedp)
5650 : 149628 : code = unsigned_condition (code);
5651 : :
5652 : : /* If one operand is constant, make it the second one. Only do this
5653 : : if the other operand is not constant as well. */
5654 : :
5655 : 591454 : if (swap_commutative_operands_p (op0, op1))
5656 : : {
5657 : 6444 : std::swap (op0, op1);
5658 : 6444 : code = swap_condition (code);
5659 : : }
5660 : :
5661 : 591454 : if (mode == VOIDmode)
5662 : 31024 : mode = GET_MODE (op0);
5663 : :
5664 : 591454 : if (CONST_SCALAR_INT_P (op1))
5665 : 256362 : canonicalize_comparison (mode, &code, &op1);
5666 : :
5667 : : /* For some comparisons with 1 and -1, we can convert this to
5668 : : comparisons with zero. This will often produce more opportunities for
5669 : : store-flag insns. */
5670 : :
5671 : 591454 : switch (code)
5672 : : {
5673 : 44442 : case LT:
5674 : 44442 : if (op1 == const1_rtx)
5675 : 42 : op1 = const0_rtx, code = LE;
5676 : : break;
5677 : 23808 : case LE:
5678 : 23808 : if (op1 == constm1_rtx)
5679 : 0 : op1 = const0_rtx, code = LT;
5680 : : break;
5681 : 37235 : case GE:
5682 : 37235 : if (op1 == const1_rtx)
5683 : 0 : op1 = const0_rtx, code = GT;
5684 : : break;
5685 : 35810 : case GT:
5686 : 35810 : if (op1 == constm1_rtx)
5687 : 113 : op1 = const0_rtx, code = GE;
5688 : : break;
5689 : 3568 : case GEU:
5690 : 3568 : if (op1 == const1_rtx)
5691 : 0 : op1 = const0_rtx, code = NE;
5692 : : break;
5693 : 8974 : case LTU:
5694 : 8974 : if (op1 == const1_rtx)
5695 : 10 : op1 = const0_rtx, code = EQ;
5696 : : break;
5697 : : default:
5698 : : break;
5699 : : }
5700 : :
5701 : : /* If this is A < 0 or A >= 0, we can do this by taking the ones
5702 : : complement of A (for GE) and shifting the sign bit to the low bit. */
5703 : 591454 : scalar_int_mode int_mode;
5704 : 150314 : if (op1 == const0_rtx && (code == LT || code == GE)
5705 : 591454 : && is_int_mode (mode, &int_mode)
5706 : 591454 : && (normalizep || STORE_FLAG_VALUE == 1
5707 : : || val_signbit_p (int_mode, STORE_FLAG_VALUE)))
5708 : : {
5709 : 38882 : scalar_int_mode int_target_mode;
5710 : 38882 : subtarget = target;
5711 : :
5712 : 38882 : if (!target)
5713 : : int_target_mode = int_mode;
5714 : : else
5715 : : {
5716 : : /* If the result is to be wider than OP0, it is best to convert it
5717 : : first. If it is to be narrower, it is *incorrect* to convert it
5718 : : first. */
5719 : 38882 : int_target_mode = as_a <scalar_int_mode> (target_mode);
5720 : 116646 : if (GET_MODE_SIZE (int_target_mode) > GET_MODE_SIZE (int_mode))
5721 : : {
5722 : 477 : op0 = convert_modes (int_target_mode, int_mode, op0, 0);
5723 : 477 : int_mode = int_target_mode;
5724 : : }
5725 : : }
5726 : :
5727 : 38882 : if (int_target_mode != int_mode)
5728 : 26896 : subtarget = 0;
5729 : :
5730 : 38882 : if (code == GE)
5731 : 20305 : op0 = expand_unop (int_mode, one_cmpl_optab, op0,
5732 : : ((STORE_FLAG_VALUE == 1 || normalizep)
5733 : : ? 0 : subtarget), 0);
5734 : :
5735 : 38882 : if (STORE_FLAG_VALUE == 1 || normalizep)
5736 : : /* If we are supposed to produce a 0/1 value, we want to do
5737 : : a logical shift from the sign bit to the low-order bit; for
5738 : : a -1/0 value, we do an arithmetic shift. */
5739 : 77764 : op0 = expand_shift (RSHIFT_EXPR, int_mode, op0,
5740 : 38882 : GET_MODE_BITSIZE (int_mode) - 1,
5741 : : subtarget, normalizep != -1);
5742 : :
5743 : 38882 : if (int_mode != int_target_mode)
5744 : 26896 : op0 = convert_modes (int_target_mode, int_mode, op0, 0);
5745 : :
5746 : 38882 : return op0;
5747 : : }
5748 : :
5749 : : /* Next try expanding this via the backend's cstore<mode>4. */
5750 : 552572 : mclass = GET_MODE_CLASS (mode);
5751 : 563718 : FOR_EACH_WIDER_MODE_FROM (compare_mode, mode)
5752 : : {
5753 : 556556 : machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
5754 : 556556 : icode = optab_handler (cstore_optab, optab_mode);
5755 : 556556 : if (icode != CODE_FOR_nothing)
5756 : : {
5757 : 545410 : do_pending_stack_adjust ();
5758 : 545410 : rtx tem = emit_cstore (target, icode, code, mode, compare_mode,
5759 : : unsignedp, op0, op1, normalizep, target_mode);
5760 : 545410 : if (tem)
5761 : : return tem;
5762 : :
5763 : 86267 : if (GET_MODE_CLASS (mode) == MODE_FLOAT)
5764 : : {
5765 : 81396 : enum rtx_code scode = swap_condition (code);
5766 : :
5767 : 81396 : tem = emit_cstore (target, icode, scode, mode, compare_mode,
5768 : : unsignedp, op1, op0, normalizep, target_mode);
5769 : 81396 : if (tem)
5770 : : return tem;
5771 : : }
5772 : : break;
5773 : : }
5774 : : }
5775 : :
5776 : : /* If we are comparing a double-word integer with zero or -1, we can
5777 : : convert the comparison into one involving a single word. */
5778 : 76469 : if (is_int_mode (mode, &int_mode)
5779 : 8219 : && GET_MODE_BITSIZE (int_mode) == BITS_PER_WORD * 2
5780 : 4560 : && (!MEM_P (op0) || ! MEM_VOLATILE_P (op0)))
5781 : : {
5782 : 4560 : rtx tem;
5783 : 4560 : if ((code == EQ || code == NE)
5784 : 0 : && (op1 == const0_rtx || op1 == constm1_rtx))
5785 : : {
5786 : 0 : rtx op00, op01;
5787 : :
5788 : : /* Do a logical OR or AND of the two words and compare the
5789 : : result. */
5790 : 0 : op00 = force_subreg (word_mode, op0, int_mode, 0);
5791 : 0 : op01 = force_subreg (word_mode, op0, int_mode, UNITS_PER_WORD);
5792 : 0 : tem = expand_binop (word_mode,
5793 : 0 : op1 == const0_rtx ? ior_optab : and_optab,
5794 : : op00, op01, NULL_RTX, unsignedp,
5795 : : OPTAB_DIRECT);
5796 : :
5797 : 0 : if (tem != 0)
5798 : 0 : tem = emit_store_flag (NULL_RTX, code, tem, op1, word_mode,
5799 : : unsignedp, normalizep);
5800 : : }
5801 : 4560 : else if ((code == LT || code == GE) && op1 == const0_rtx)
5802 : : {
5803 : 0 : rtx op0h;
5804 : :
5805 : : /* If testing the sign bit, can just test on high word. */
5806 : 0 : op0h = force_highpart_subreg (word_mode, op0, int_mode);
5807 : 0 : tem = emit_store_flag (NULL_RTX, code, op0h, op1, word_mode,
5808 : : unsignedp, normalizep);
5809 : 0 : }
5810 : : else
5811 : : tem = NULL_RTX;
5812 : :
5813 : 0 : if (tem)
5814 : : {
5815 : 0 : if (target_mode == VOIDmode || GET_MODE (tem) == target_mode)
5816 : : return tem;
5817 : 0 : if (!target)
5818 : 0 : target = gen_reg_rtx (target_mode);
5819 : :
5820 : 0 : convert_move (target, tem,
5821 : 0 : !val_signbit_known_set_p (word_mode,
5822 : : (normalizep ? normalizep
5823 : : : STORE_FLAG_VALUE)));
5824 : 0 : return target;
5825 : : }
5826 : : }
5827 : :
5828 : : return 0;
5829 : : }
5830 : :
5831 : : /* Subroutine of emit_store_flag that handles cases in which the operands
5832 : : are scalar integers. SUBTARGET is the target to use for temporary
5833 : : operations and TRUEVAL is the value to store when the condition is
5834 : : true. All other arguments are as for emit_store_flag. */
5835 : :
5836 : : rtx
5837 : 2436 : emit_store_flag_int (rtx target, rtx subtarget, enum rtx_code code, rtx op0,
5838 : : rtx op1, scalar_int_mode mode, int unsignedp,
5839 : : int normalizep, rtx trueval)
5840 : : {
5841 : 2436 : machine_mode target_mode = target ? GET_MODE (target) : VOIDmode;
5842 : 2436 : rtx_insn *last = get_last_insn ();
5843 : :
5844 : : /* If this is an equality comparison of integers, we can try to exclusive-or
5845 : : (or subtract) the two operands and use a recursive call to try the
5846 : : comparison with zero. Don't do any of these cases if branches are
5847 : : very cheap. */
5848 : :
5849 : 2436 : if ((code == EQ || code == NE) && op1 != const0_rtx)
5850 : : {
5851 : 1 : rtx tem = expand_binop (mode, xor_optab, op0, op1, subtarget, 1,
5852 : : OPTAB_WIDEN);
5853 : :
5854 : 1 : if (tem == 0)
5855 : 0 : tem = expand_binop (mode, sub_optab, op0, op1, subtarget, 1,
5856 : : OPTAB_WIDEN);
5857 : 0 : if (tem != 0)
5858 : 1 : tem = emit_store_flag (target, code, tem, const0_rtx,
5859 : : mode, unsignedp, normalizep);
5860 : 1 : if (tem != 0)
5861 : : return tem;
5862 : :
5863 : 0 : delete_insns_since (last);
5864 : : }
5865 : :
5866 : : /* For integer comparisons, try the reverse comparison. However, for
5867 : : small X and if we'd have anyway to extend, implementing "X != 0"
5868 : : as "-(int)X >> 31" is still cheaper than inverting "(int)X == 0". */
5869 : 2435 : rtx_code rcode = reverse_condition (code);
5870 : 2435 : if (can_compare_p (rcode, mode, ccp_store_flag)
5871 : 2435 : && ! (optab_handler (cstore_optab, mode) == CODE_FOR_nothing
5872 : 0 : && code == NE
5873 : 0 : && GET_MODE_SIZE (mode) < UNITS_PER_WORD
5874 : 0 : && op1 == const0_rtx))
5875 : : {
5876 : 2435 : int want_add = ((STORE_FLAG_VALUE == 1 && normalizep == -1)
5877 : : || (STORE_FLAG_VALUE == -1 && normalizep == 1));
5878 : :
5879 : : /* Again, for the reverse comparison, use either an addition or a XOR. */
5880 : 2435 : if (want_add
5881 : 2435 : && rtx_cost (GEN_INT (normalizep), mode, PLUS, 1,
5882 : 0 : optimize_insn_for_speed_p ()) == 0)
5883 : : {
5884 : 0 : rtx tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
5885 : : STORE_FLAG_VALUE, target_mode);
5886 : 0 : if (tem != 0)
5887 : 0 : tem = expand_binop (target_mode, add_optab, tem,
5888 : 0 : gen_int_mode (normalizep, target_mode),
5889 : : target, 0, OPTAB_WIDEN);
5890 : 0 : if (tem != 0)
5891 : : return tem;
5892 : : }
5893 : 2435 : else if (!want_add
5894 : 4870 : && rtx_cost (trueval, mode, XOR, 1,
5895 : 2435 : optimize_insn_for_speed_p ()) == 0)
5896 : : {
5897 : 2435 : rtx tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
5898 : : normalizep, target_mode);
5899 : 2435 : if (tem != 0)
5900 : 0 : tem = expand_binop (target_mode, xor_optab, tem, trueval, target,
5901 : 0 : INTVAL (trueval) >= 0, OPTAB_WIDEN);
5902 : 0 : if (tem != 0)
5903 : : return tem;
5904 : : }
5905 : :
5906 : 2435 : delete_insns_since (last);
5907 : : }
5908 : :
5909 : : /* Some other cases we can do are EQ, NE, LE, and GT comparisons with
5910 : : the constant zero. Reject all other comparisons at this point. Only
5911 : : do LE and GT if branches are expensive since they are expensive on
5912 : : 2-operand machines. */
5913 : :
5914 : 2435 : if (op1 != const0_rtx
5915 : 2435 : || (code != EQ && code != NE
5916 : 85 : && (BRANCH_COST (optimize_insn_for_speed_p (),
5917 : 85 : false) <= 1 || (code != LE && code != GT))))
5918 : 2195 : return 0;
5919 : :
5920 : : /* Try to put the result of the comparison in the sign bit. Assume we can't
5921 : : do the necessary operation below. */
5922 : :
5923 : 240 : rtx tem = 0;
5924 : :
5925 : : /* To see if A <= 0, compute (A | (A - 1)). A <= 0 iff that result has
5926 : : the sign bit set. */
5927 : :
5928 : 240 : if (code == LE)
5929 : : {
5930 : : /* This is destructive, so SUBTARGET can't be OP0. */
5931 : 56 : if (rtx_equal_p (subtarget, op0))
5932 : 0 : subtarget = 0;
5933 : :
5934 : 56 : tem = expand_binop (mode, sub_optab, op0, const1_rtx, subtarget, 0,
5935 : : OPTAB_WIDEN);
5936 : 56 : if (tem)
5937 : 56 : tem = expand_binop (mode, ior_optab, op0, tem, subtarget, 0,
5938 : : OPTAB_WIDEN);
5939 : : }
5940 : :
5941 : : /* To see if A > 0, compute (((signed) A) << BITS) - A, where BITS is the
5942 : : number of bits in the mode of OP0, minus one. */
5943 : :
5944 : 240 : if (code == GT)
5945 : : {
5946 : 29 : if (rtx_equal_p (subtarget, op0))
5947 : 0 : subtarget = 0;
5948 : :
5949 : 29 : tem = maybe_expand_shift (RSHIFT_EXPR, mode, op0,
5950 : 29 : GET_MODE_BITSIZE (mode) - 1,
5951 : : subtarget, 0);
5952 : 29 : if (tem)
5953 : 29 : tem = expand_binop (mode, sub_optab, tem, op0, subtarget, 0,
5954 : : OPTAB_WIDEN);
5955 : : }
5956 : :
5957 : 240 : if (code == EQ || code == NE)
5958 : : {
5959 : : /* For EQ or NE, one way to do the comparison is to apply an operation
5960 : : that converts the operand into a positive number if it is nonzero
5961 : : or zero if it was originally zero. Then, for EQ, we subtract 1 and
5962 : : for NE we negate. This puts the result in the sign bit. Then we
5963 : : normalize with a shift, if needed.
5964 : :
5965 : : Two operations that can do the above actions are ABS and FFS, so try
5966 : : them. If that doesn't work, and MODE is smaller than a full word,
5967 : : we can use zero-extension to the wider mode (an unsigned conversion)
5968 : : as the operation. */
5969 : :
5970 : : /* Note that ABS doesn't yield a positive number for INT_MIN, but
5971 : : that is compensated by the subsequent overflow when subtracting
5972 : : one / negating. */
5973 : :
5974 : 155 : if (optab_handler (abs_optab, mode) != CODE_FOR_nothing)
5975 : 155 : tem = expand_unop (mode, abs_optab, op0, subtarget, 1);
5976 : 0 : else if (optab_handler (ffs_optab, mode) != CODE_FOR_nothing)
5977 : 0 : tem = expand_unop (mode, ffs_optab, op0, subtarget, 1);
5978 : 0 : else if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
5979 : : {
5980 : 0 : tem = convert_modes (word_mode, mode, op0, 1);
5981 : 0 : mode = word_mode;
5982 : : }
5983 : :
5984 : 155 : if (tem != 0)
5985 : : {
5986 : 155 : if (code == EQ)
5987 : 0 : tem = expand_binop (mode, sub_optab, tem, const1_rtx, subtarget,
5988 : : 0, OPTAB_WIDEN);
5989 : : else
5990 : 155 : tem = expand_unop (mode, neg_optab, tem, subtarget, 0);
5991 : : }
5992 : :
5993 : : /* If we couldn't do it that way, for NE we can "or" the two's complement
5994 : : of the value with itself. For EQ, we take the one's complement of
5995 : : that "or", which is an extra insn, so we only handle EQ if branches
5996 : : are expensive. */
5997 : :
5998 : 155 : if (tem == 0
5999 : 155 : && (code == NE
6000 : 0 : || BRANCH_COST (optimize_insn_for_speed_p (),
6001 : : false) > 1))
6002 : : {
6003 : 0 : if (rtx_equal_p (subtarget, op0))
6004 : 0 : subtarget = 0;
6005 : :
6006 : 0 : tem = expand_unop (mode, neg_optab, op0, subtarget, 0);
6007 : 0 : tem = expand_binop (mode, ior_optab, tem, op0, subtarget, 0,
6008 : : OPTAB_WIDEN);
6009 : :
6010 : 0 : if (tem && code == EQ)
6011 : 0 : tem = expand_unop (mode, one_cmpl_optab, tem, subtarget, 0);
6012 : : }
6013 : : }
6014 : :
6015 : 240 : if (tem && normalizep)
6016 : 240 : tem = maybe_expand_shift (RSHIFT_EXPR, mode, tem,
6017 : 240 : GET_MODE_BITSIZE (mode) - 1,
6018 : : subtarget, normalizep == 1);
6019 : :
6020 : 240 : if (tem)
6021 : : {
6022 : 240 : if (!target)
6023 : : ;
6024 : 240 : else if (GET_MODE (tem) != target_mode)
6025 : : {
6026 : 85 : convert_move (target, tem, 0);
6027 : 85 : tem = target;
6028 : : }
6029 : 155 : else if (!subtarget)
6030 : : {
6031 : 86 : emit_move_insn (target, tem);
6032 : 86 : tem = target;
6033 : : }
6034 : : }
6035 : : else
6036 : 0 : delete_insns_since (last);
6037 : :
6038 : : return tem;
6039 : : }
6040 : :
6041 : : /* Emit a store-flags instruction for comparison CODE on OP0 and OP1
6042 : : and storing in TARGET. Normally return TARGET.
6043 : : Return 0 if that cannot be done.
6044 : :
6045 : : MODE is the mode to use for OP0 and OP1 should they be CONST_INTs. If
6046 : : it is VOIDmode, they cannot both be CONST_INT.
6047 : :
6048 : : UNSIGNEDP is for the case where we have to widen the operands
6049 : : to perform the operation. It says to use zero-extension.
6050 : :
6051 : : NORMALIZEP is 1 if we should convert the result to be either zero
6052 : : or one. Normalize is -1 if we should convert the result to be
6053 : : either zero or -1. If NORMALIZEP is zero, the result will be left
6054 : : "raw" out of the scc insn. */
6055 : :
6056 : : rtx
6057 : 524372 : emit_store_flag (rtx target, enum rtx_code code, rtx op0, rtx op1,
6058 : : machine_mode mode, int unsignedp, int normalizep)
6059 : : {
6060 : 524372 : machine_mode target_mode = target ? GET_MODE (target) : VOIDmode;
6061 : 524372 : enum rtx_code rcode;
6062 : 524372 : rtx subtarget;
6063 : 524372 : rtx tem, trueval;
6064 : 524372 : rtx_insn *last;
6065 : :
6066 : : /* If we compare constants, we shouldn't use a store-flag operation,
6067 : : but a constant load. We can get there via the vanilla route that
6068 : : usually generates a compare-branch sequence, but will in this case
6069 : : fold the comparison to a constant, and thus elide the branch. */
6070 : 524372 : if (CONSTANT_P (op0) && CONSTANT_P (op1))
6071 : : return NULL_RTX;
6072 : :
6073 : 524071 : tem = emit_store_flag_1 (target, code, op0, op1, mode, unsignedp, normalizep,
6074 : : target_mode);
6075 : 524071 : if (tem)
6076 : : return tem;
6077 : :
6078 : : /* If we reached here, we can't do this with a scc insn, however there
6079 : : are some comparisons that can be done in other ways. Don't do any
6080 : : of these cases if branches are very cheap. */
6081 : 73522 : if (BRANCH_COST (optimize_insn_for_speed_p (), false) == 0)
6082 : : return 0;
6083 : :
6084 : : /* See what we need to return. We can only return a 1, -1, or the
6085 : : sign bit. */
6086 : :
6087 : 73522 : if (normalizep == 0)
6088 : : {
6089 : 0 : if (STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1)
6090 : 0 : normalizep = STORE_FLAG_VALUE;
6091 : :
6092 : : else if (val_signbit_p (mode, STORE_FLAG_VALUE))
6093 : : ;
6094 : : else
6095 : : return 0;
6096 : : }
6097 : :
6098 : 73522 : last = get_last_insn ();
6099 : :
6100 : : /* If optimizing, use different pseudo registers for each insn, instead
6101 : : of reusing the same pseudo. This leads to better CSE, but slows
6102 : : down the compiler, since there are more pseudos. */
6103 : 147044 : subtarget = (!optimize
6104 : 73522 : && (target_mode == mode)) ? target : NULL_RTX;
6105 : 73522 : trueval = GEN_INT (normalizep ? normalizep : STORE_FLAG_VALUE);
6106 : :
6107 : : /* For floating-point comparisons, try the reverse comparison or try
6108 : : changing the "orderedness" of the comparison. */
6109 : 73522 : if (GET_MODE_CLASS (mode) == MODE_FLOAT)
6110 : : {
6111 : 67599 : enum rtx_code first_code;
6112 : 67599 : bool and_them;
6113 : :
6114 : 67599 : rcode = reverse_condition_maybe_unordered (code);
6115 : 67599 : if (can_compare_p (rcode, mode, ccp_store_flag)
6116 : 67599 : && (code == ORDERED || code == UNORDERED
6117 : 0 : || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
6118 : 0 : || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
6119 : : {
6120 : 0 : int want_add = ((STORE_FLAG_VALUE == 1 && normalizep == -1)
6121 : : || (STORE_FLAG_VALUE == -1 && normalizep == 1));
6122 : :
6123 : : /* For the reverse comparison, use either an addition or a XOR. */
6124 : 0 : if (want_add
6125 : 0 : && rtx_cost (GEN_INT (normalizep), mode, PLUS, 1,
6126 : 0 : optimize_insn_for_speed_p ()) == 0)
6127 : : {
6128 : 0 : tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
6129 : : STORE_FLAG_VALUE, target_mode);
6130 : 0 : if (tem)
6131 : 0 : return expand_binop (target_mode, add_optab, tem,
6132 : 0 : gen_int_mode (normalizep, target_mode),
6133 : : target, 0, OPTAB_WIDEN);
6134 : : }
6135 : 0 : else if (!want_add
6136 : 0 : && rtx_cost (trueval, mode, XOR, 1,
6137 : 0 : optimize_insn_for_speed_p ()) == 0)
6138 : : {
6139 : 0 : tem = emit_store_flag_1 (subtarget, rcode, op0, op1, mode, 0,
6140 : : normalizep, target_mode);
6141 : 0 : if (tem)
6142 : 0 : return expand_binop (target_mode, xor_optab, tem, trueval,
6143 : 0 : target, INTVAL (trueval) >= 0,
6144 : 0 : OPTAB_WIDEN);
6145 : : }
6146 : : }
6147 : :
6148 : 67599 : delete_insns_since (last);
6149 : :
6150 : : /* Cannot split ORDERED and UNORDERED, only try the above trick. */
6151 : 67599 : if (code == ORDERED || code == UNORDERED)
6152 : : return 0;
6153 : :
6154 : 67481 : and_them = split_comparison (code, mode, &first_code, &code);
6155 : :
6156 : : /* If there are no NaNs, the first comparison should always fall through.
6157 : : Effectively change the comparison to the other one. */
6158 : 67481 : if (!HONOR_NANS (mode))
6159 : : {
6160 : 494 : gcc_assert (first_code == (and_them ? ORDERED : UNORDERED));
6161 : 298 : return emit_store_flag_1 (target, code, op0, op1, mode, 0, normalizep,
6162 : 298 : target_mode);
6163 : : }
6164 : :
6165 : 67183 : if (!HAVE_conditional_move)
6166 : : return 0;
6167 : :
6168 : : /* Do not turn a trapping comparison into a non-trapping one. */
6169 : 67183 : if ((code != EQ && code != NE && code != UNEQ && code != LTGT)
6170 : 2533 : && flag_trapping_math)
6171 : : return 0;
6172 : :
6173 : : /* Try using a setcc instruction for ORDERED/UNORDERED, followed by a
6174 : : conditional move. */
6175 : 64650 : tem = emit_store_flag_1 (subtarget, first_code, op0, op1, mode, 0,
6176 : : normalizep, target_mode);
6177 : 64650 : if (tem == 0)
6178 : : return 0;
6179 : :
6180 : 64138 : if (and_them)
6181 : 2126 : tem = emit_conditional_move (target, { code, op0, op1, mode },
6182 : 2126 : tem, const0_rtx, GET_MODE (tem), 0);
6183 : : else
6184 : 62012 : tem = emit_conditional_move (target, { code, op0, op1, mode },
6185 : 62012 : trueval, tem, GET_MODE (tem), 0);
6186 : :
6187 : 64138 : if (tem == 0)
6188 : 493 : delete_insns_since (last);
6189 : 64138 : return tem;
6190 : : }
6191 : :
6192 : : /* The remaining tricks only apply to integer comparisons. */
6193 : :
6194 : 5923 : scalar_int_mode int_mode;
6195 : 5923 : if (is_int_mode (mode, &int_mode))
6196 : 2436 : return emit_store_flag_int (target, subtarget, code, op0, op1, int_mode,
6197 : 2436 : unsignedp, normalizep, trueval);
6198 : :
6199 : : return 0;
6200 : : }
6201 : :
6202 : : /* Like emit_store_flag, but always succeeds. */
6203 : :
6204 : : rtx
6205 : 485327 : emit_store_flag_force (rtx target, enum rtx_code code, rtx op0, rtx op1,
6206 : : machine_mode mode, int unsignedp, int normalizep)
6207 : : {
6208 : 485327 : rtx tem;
6209 : 485327 : rtx_code_label *label;
6210 : 485327 : rtx trueval, falseval;
6211 : :
6212 : : /* First see if emit_store_flag can do the job. */
6213 : 485327 : tem = emit_store_flag (target, code, op0, op1, mode, unsignedp, normalizep);
6214 : 485327 : if (tem != 0)
6215 : : return tem;
6216 : :
6217 : : /* If one operand is constant, make it the second one. Only do this
6218 : : if the other operand is not constant as well. */
6219 : 9639 : if (swap_commutative_operands_p (op0, op1))
6220 : : {
6221 : 8 : std::swap (op0, op1);
6222 : 8 : code = swap_condition (code);
6223 : : }
6224 : :
6225 : 9639 : if (mode == VOIDmode)
6226 : 0 : mode = GET_MODE (op0);
6227 : :
6228 : 9639 : if (!target)
6229 : 0 : target = gen_reg_rtx (word_mode);
6230 : :
6231 : : /* If this failed, we have to do this with set/compare/jump/set code.
6232 : : For foo != 0, if foo is in OP0, just replace it with 1 if nonzero. */
6233 : 9639 : trueval = normalizep ? GEN_INT (normalizep) : const1_rtx;
6234 : 9639 : if (code == NE
6235 : 1614 : && GET_MODE_CLASS (mode) == MODE_INT
6236 : 26 : && REG_P (target)
6237 : 26 : && op0 == target
6238 : 0 : && op1 == const0_rtx)
6239 : : {
6240 : 0 : label = gen_label_rtx ();
6241 : 0 : do_compare_rtx_and_jump (target, const0_rtx, EQ, unsignedp, mode,
6242 : : NULL_RTX, NULL, label,
6243 : : profile_probability::uninitialized ());
6244 : 0 : emit_move_insn (target, trueval);
6245 : 0 : emit_label (label);
6246 : 0 : return target;
6247 : : }
6248 : :
6249 : 9639 : if (!REG_P (target)
6250 : 9639 : || reg_mentioned_p (target, op0) || reg_mentioned_p (target, op1))
6251 : 5 : target = gen_reg_rtx (GET_MODE (target));
6252 : :
6253 : : /* Jump in the right direction if the target cannot implement CODE
6254 : : but can jump on its reverse condition. */
6255 : 9639 : falseval = const0_rtx;
6256 : 9639 : if (! can_compare_p (code, mode, ccp_jump)
6257 : 9639 : && (! FLOAT_MODE_P (mode)
6258 : 7134 : || code == ORDERED || code == UNORDERED
6259 : 6971 : || (! HONOR_NANS (mode) && (code == LTGT || code == UNEQ))
6260 : 6971 : || (! HONOR_SNANS (mode) && (code == EQ || code == NE))))
6261 : : {
6262 : 2519 : enum rtx_code rcode;
6263 : 2519 : if (FLOAT_MODE_P (mode))
6264 : 2519 : rcode = reverse_condition_maybe_unordered (code);
6265 : : else
6266 : 0 : rcode = reverse_condition (code);
6267 : :
6268 : : /* Canonicalize to UNORDERED for the libcall. */
6269 : 2519 : if (can_compare_p (rcode, mode, ccp_jump)
6270 : 2519 : || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump)))
6271 : : {
6272 : 139 : falseval = trueval;
6273 : 139 : trueval = const0_rtx;
6274 : 139 : code = rcode;
6275 : : }
6276 : : }
6277 : :
6278 : 9639 : emit_move_insn (target, trueval);
6279 : 9639 : label = gen_label_rtx ();
6280 : 9639 : do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, NULL_RTX, NULL,
6281 : : label, profile_probability::uninitialized ());
6282 : :
6283 : 9639 : emit_move_insn (target, falseval);
6284 : 9639 : emit_label (label);
6285 : :
6286 : 9639 : return target;
6287 : : }
6288 : :
6289 : : /* Expand a vector (left) rotate of MODE of X by an immediate AMT as a vector
6290 : : permute operation. Emit code to put the result in DST if successfull and
6291 : : return it. Otherwise return NULL. This is intended to implement vector
6292 : : rotates by byte amounts using vector permutes when the target does not offer
6293 : : native vector rotate operations. */
6294 : : rtx
6295 : 0 : expand_rotate_as_vec_perm (machine_mode mode, rtx dst, rtx x, rtx amt)
6296 : : {
6297 : 0 : rtx amt_unwrap = unwrap_const_vec_duplicate (amt);
6298 : : /* For now handle only rotate by the same integer constant in all lanes.
6299 : : In principle rotates by any constant vector are representable through
6300 : : permutes as long as the individual rotate amounts are multiples of
6301 : : BITS_PER_UNIT. */
6302 : 0 : if (!CONST_INT_P (amt_unwrap))
6303 : : return NULL_RTX;
6304 : :
6305 : 0 : int rotamnt = INTVAL (amt_unwrap);
6306 : 0 : if (rotamnt % BITS_PER_UNIT != 0)
6307 : : return NULL_RTX;
6308 : 0 : machine_mode qimode;
6309 : 0 : if (!qimode_for_vec_perm (mode).exists (&qimode))
6310 : 0 : return NULL_RTX;
6311 : :
6312 : 0 : vec_perm_builder builder;
6313 : 0 : unsigned nunits = GET_MODE_SIZE (GET_MODE_INNER (mode));
6314 : 0 : poly_uint64 total_units = GET_MODE_SIZE (mode);
6315 : 0 : builder.new_vector (total_units, nunits, 3);
6316 : 0 : unsigned rot_bytes = rotamnt / BITS_PER_UNIT;
6317 : 0 : unsigned rot_to_perm = BYTES_BIG_ENDIAN ? rot_bytes : nunits - rot_bytes;
6318 : 0 : for (unsigned j = 0; j < 3 * nunits; j += nunits)
6319 : 0 : for (unsigned i = 0; i < nunits; i++)
6320 : 0 : builder.quick_push ((rot_to_perm + i) % nunits + j);
6321 : :
6322 : 0 : rtx perm_src = lowpart_subreg (qimode, x, mode);
6323 : 0 : rtx perm_dst = lowpart_subreg (qimode, dst, mode);
6324 : 0 : rtx res
6325 : 0 : = expand_vec_perm_const (qimode, perm_src, perm_src, builder,
6326 : : qimode, perm_dst);
6327 : 0 : if (!res)
6328 : : return NULL_RTX;
6329 : 0 : emit_move_insn (dst, lowpart_subreg (mode, res, qimode));
6330 : 0 : return dst;
6331 : 0 : }
6332 : :
6333 : : /* Helper function for canonicalize_cmp_for_target. Swap between inclusive
6334 : : and exclusive ranges in order to create an equivalent comparison. See
6335 : : canonicalize_cmp_for_target for the possible cases. */
6336 : :
6337 : : static enum rtx_code
6338 : 89 : equivalent_cmp_code (enum rtx_code code)
6339 : : {
6340 : 89 : switch (code)
6341 : : {
6342 : : case GT:
6343 : : return GE;
6344 : 0 : case GE:
6345 : 0 : return GT;
6346 : 0 : case LT:
6347 : 0 : return LE;
6348 : 0 : case LE:
6349 : 0 : return LT;
6350 : 2 : case GTU:
6351 : 2 : return GEU;
6352 : 0 : case GEU:
6353 : 0 : return GTU;
6354 : 1 : case LTU:
6355 : 1 : return LEU;
6356 : 2 : case LEU:
6357 : 2 : return LTU;
6358 : :
6359 : 0 : default:
6360 : 0 : return code;
6361 : : }
6362 : : }
6363 : :
6364 : : /* Choose the more appropiate immediate in scalar integer comparisons. The
6365 : : purpose of this is to end up with an immediate which can be loaded into a
6366 : : register in fewer moves, if possible.
6367 : :
6368 : : For each integer comparison there exists an equivalent choice:
6369 : : i) a > b or a >= b + 1
6370 : : ii) a <= b or a < b + 1
6371 : : iii) a >= b or a > b - 1
6372 : : iv) a < b or a <= b - 1
6373 : :
6374 : : MODE is the mode of the first operand.
6375 : : CODE points to the comparison code.
6376 : : IMM points to the rtx containing the immediate. *IMM must satisfy
6377 : : CONST_SCALAR_INT_P on entry and continues to satisfy CONST_SCALAR_INT_P
6378 : : on exit. */
6379 : :
6380 : : void
6381 : 4426954 : canonicalize_comparison (machine_mode mode, enum rtx_code *code, rtx *imm)
6382 : : {
6383 : 4426954 : if (!SCALAR_INT_MODE_P (mode))
6384 : 3679100 : return;
6385 : :
6386 : 4423629 : int to_add = 0;
6387 : 4423629 : enum signop sgn = unsigned_condition_p (*code) ? UNSIGNED : SIGNED;
6388 : :
6389 : : /* Extract the immediate value from the rtx. */
6390 : 4423629 : wide_int imm_val = rtx_mode_t (*imm, mode);
6391 : :
6392 : 4423629 : if (*code == GT || *code == GTU || *code == LE || *code == LEU)
6393 : : to_add = 1;
6394 : : else if (*code == GE || *code == GEU || *code == LT || *code == LTU)
6395 : : to_add = -1;
6396 : : else
6397 : : return;
6398 : :
6399 : : /* Check for overflow/underflow in the case of signed values and
6400 : : wrapping around in the case of unsigned values. If any occur
6401 : : cancel the optimization. */
6402 : 747998 : wi::overflow_type overflow = wi::OVF_NONE;
6403 : 747998 : wide_int imm_modif;
6404 : :
6405 : 747998 : if (to_add == 1)
6406 : 538729 : imm_modif = wi::add (imm_val, 1, sgn, &overflow);
6407 : : else
6408 : 209269 : imm_modif = wi::sub (imm_val, 1, sgn, &overflow);
6409 : :
6410 : 747998 : if (overflow)
6411 : : return;
6412 : :
6413 : : /* The following creates a pseudo; if we cannot do that, bail out. */
6414 : 747854 : if (!can_create_pseudo_p ())
6415 : : return;
6416 : :
6417 : 747854 : rtx reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1);
6418 : 747854 : rtx new_imm = immed_wide_int_const (imm_modif, mode);
6419 : :
6420 : 747854 : rtx_insn *old_rtx = gen_move_insn (reg, *imm);
6421 : 747854 : rtx_insn *new_rtx = gen_move_insn (reg, new_imm);
6422 : :
6423 : : /* Update the immediate and the code. */
6424 : 747854 : if (insn_cost (old_rtx, true) > insn_cost (new_rtx, true))
6425 : : {
6426 : 89 : *code = equivalent_cmp_code (*code);
6427 : 89 : *imm = new_imm;
6428 : : }
6429 : 4423773 : }
6430 : :
6431 : :
6432 : :
6433 : : /* Perform possibly multi-word comparison and conditional jump to LABEL
6434 : : if ARG1 OP ARG2 true where ARG1 and ARG2 are of mode MODE. This is
6435 : : now a thin wrapper around do_compare_rtx_and_jump. */
6436 : :
6437 : : static void
6438 : 1883 : do_cmp_and_jump (rtx arg1, rtx arg2, enum rtx_code op, machine_mode mode,
6439 : : rtx_code_label *label)
6440 : : {
6441 : 1883 : int unsignedp = (op == LTU || op == LEU || op == GTU || op == GEU);
6442 : 1883 : do_compare_rtx_and_jump (arg1, arg2, op, unsignedp, mode, NULL_RTX,
6443 : : NULL, label, profile_probability::uninitialized ());
6444 : 1883 : }
|