]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/optabs.cc
PR middle-end/105604 - ICE: in tree_to_shwi with vla in struct and sprintf
[thirdparty/gcc.git] / gcc / optabs.cc
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2022 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
19
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "memmodel.h"
29 #include "predict.h"
30 #include "tm_p.h"
31 #include "optabs.h"
32 #include "expmed.h"
33 #include "emit-rtl.h"
34 #include "recog.h"
35 #include "diagnostic-core.h"
36 #include "rtx-vector-builder.h"
37
38 /* Include insn-config.h before expr.h so that HAVE_conditional_move
39 is properly defined. */
40 #include "stor-layout.h"
41 #include "except.h"
42 #include "dojump.h"
43 #include "explow.h"
44 #include "expr.h"
45 #include "optabs-tree.h"
46 #include "libfuncs.h"
47 #include "internal-fn.h"
48 #include "langhooks.h"
49
50 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
51 machine_mode *);
52 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
53 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
54
55 static rtx emit_conditional_move_1 (rtx, rtx, rtx, rtx, machine_mode);
56
57 /* Debug facility for use in GDB. */
58 void debug_optab_libfuncs (void);
59 \f
60 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
61 the result of operation CODE applied to OP0 (and OP1 if it is a binary
62 operation). OP0_MODE is OP0's mode.
63
64 If the last insn does not set TARGET, don't do anything, but return 1.
65
66 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
67 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
68 try again, ensuring that TARGET is not one of the operands. */
69
70 static int
71 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
72 rtx op1, machine_mode op0_mode)
73 {
74 rtx_insn *last_insn;
75 rtx set;
76 rtx note;
77
78 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
79
80 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
81 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
82 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
83 && GET_RTX_CLASS (code) != RTX_COMPARE
84 && GET_RTX_CLASS (code) != RTX_UNARY)
85 return 1;
86
87 if (GET_CODE (target) == ZERO_EXTRACT)
88 return 1;
89
90 for (last_insn = insns;
91 NEXT_INSN (last_insn) != NULL_RTX;
92 last_insn = NEXT_INSN (last_insn))
93 ;
94
95 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
96 a value changing in the insn, so the note would be invalid for CSE. */
97 if (reg_overlap_mentioned_p (target, op0)
98 || (op1 && reg_overlap_mentioned_p (target, op1)))
99 {
100 if (MEM_P (target)
101 && (rtx_equal_p (target, op0)
102 || (op1 && rtx_equal_p (target, op1))))
103 {
104 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
105 over expanding it as temp = MEM op X, MEM = temp. If the target
106 supports MEM = MEM op X instructions, it is sometimes too hard
107 to reconstruct that form later, especially if X is also a memory,
108 and due to multiple occurrences of addresses the address might
109 be forced into register unnecessarily.
110 Note that not emitting the REG_EQUIV note might inhibit
111 CSE in some cases. */
112 set = single_set (last_insn);
113 if (set
114 && GET_CODE (SET_SRC (set)) == code
115 && MEM_P (SET_DEST (set))
116 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
117 || (op1 && rtx_equal_p (SET_DEST (set),
118 XEXP (SET_SRC (set), 1)))))
119 return 1;
120 }
121 return 0;
122 }
123
124 set = set_for_reg_notes (last_insn);
125 if (set == NULL_RTX)
126 return 1;
127
128 if (! rtx_equal_p (SET_DEST (set), target)
129 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
130 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
131 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
132 return 1;
133
134 if (GET_RTX_CLASS (code) == RTX_UNARY)
135 switch (code)
136 {
137 case FFS:
138 case CLZ:
139 case CTZ:
140 case CLRSB:
141 case POPCOUNT:
142 case PARITY:
143 case BSWAP:
144 if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
145 {
146 note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
147 if (GET_MODE_UNIT_SIZE (op0_mode)
148 > GET_MODE_UNIT_SIZE (GET_MODE (target)))
149 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
150 note, op0_mode);
151 else
152 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
153 note, op0_mode);
154 break;
155 }
156 /* FALLTHRU */
157 default:
158 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
159 break;
160 }
161 else
162 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
163
164 set_unique_reg_note (last_insn, REG_EQUAL, note);
165
166 return 1;
167 }
168 \f
169 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
170 for a widening operation would be. In most cases this would be OP0, but if
171 that's a constant it'll be VOIDmode, which isn't useful. */
172
173 static machine_mode
174 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
175 {
176 machine_mode m0 = GET_MODE (op0);
177 machine_mode m1 = GET_MODE (op1);
178 machine_mode result;
179
180 if (m0 == VOIDmode && m1 == VOIDmode)
181 return to_mode;
182 else if (m0 == VOIDmode || GET_MODE_UNIT_SIZE (m0) < GET_MODE_UNIT_SIZE (m1))
183 result = m1;
184 else
185 result = m0;
186
187 if (GET_MODE_UNIT_SIZE (result) > GET_MODE_UNIT_SIZE (to_mode))
188 return to_mode;
189
190 return result;
191 }
192 \f
193 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
194 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
195 not actually do a sign-extend or zero-extend, but can leave the
196 higher-order bits of the result rtx undefined, for example, in the case
197 of logical operations, but not right shifts. */
198
199 static rtx
200 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
201 int unsignedp, int no_extend)
202 {
203 rtx result;
204 scalar_int_mode int_mode;
205
206 /* If we don't have to extend and this is a constant, return it. */
207 if (no_extend && GET_MODE (op) == VOIDmode)
208 return op;
209
210 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
211 extend since it will be more efficient to do so unless the signedness of
212 a promoted object differs from our extension. */
213 if (! no_extend
214 || !is_a <scalar_int_mode> (mode, &int_mode)
215 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
216 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
217 return convert_modes (mode, oldmode, op, unsignedp);
218
219 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
220 SUBREG. */
221 if (GET_MODE_SIZE (int_mode) <= UNITS_PER_WORD)
222 return gen_lowpart (int_mode, force_reg (GET_MODE (op), op));
223
224 /* Otherwise, get an object of MODE, clobber it, and set the low-order
225 part to OP. */
226
227 result = gen_reg_rtx (int_mode);
228 emit_clobber (result);
229 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
230 return result;
231 }
232 \f
233 /* Expand vector widening operations.
234
235 There are two different classes of operations handled here:
236 1) Operations whose result is wider than all the arguments to the operation.
237 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
238 In this case OP0 and optionally OP1 would be initialized,
239 but WIDE_OP wouldn't (not relevant for this case).
240 2) Operations whose result is of the same size as the last argument to the
241 operation, but wider than all the other arguments to the operation.
242 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
243 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
244
245 E.g, when called to expand the following operations, this is how
246 the arguments will be initialized:
247 nops OP0 OP1 WIDE_OP
248 widening-sum 2 oprnd0 - oprnd1
249 widening-dot-product 3 oprnd0 oprnd1 oprnd2
250 widening-mult 2 oprnd0 oprnd1 -
251 type-promotion (vec-unpack) 1 oprnd0 - - */
252
253 rtx
254 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
255 rtx target, int unsignedp)
256 {
257 class expand_operand eops[4];
258 tree oprnd0, oprnd1, oprnd2;
259 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
260 optab widen_pattern_optab;
261 enum insn_code icode;
262 int nops = TREE_CODE_LENGTH (ops->code);
263 int op;
264 bool sbool = false;
265
266 oprnd0 = ops->op0;
267 if (nops >= 2)
268 oprnd1 = ops->op1;
269 if (nops >= 3)
270 oprnd2 = ops->op2;
271
272 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
273 if (ops->code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
274 || ops->code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
275 /* The sign is from the result type rather than operand's type
276 for these ops. */
277 widen_pattern_optab
278 = optab_for_tree_code (ops->code, ops->type, optab_default);
279 else if ((ops->code == VEC_UNPACK_HI_EXPR
280 || ops->code == VEC_UNPACK_LO_EXPR)
281 && VECTOR_BOOLEAN_TYPE_P (ops->type)
282 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (oprnd0))
283 && TYPE_MODE (ops->type) == TYPE_MODE (TREE_TYPE (oprnd0))
284 && SCALAR_INT_MODE_P (TYPE_MODE (ops->type)))
285 {
286 /* For VEC_UNPACK_{LO,HI}_EXPR if the mode of op0 and result is
287 the same scalar mode for VECTOR_BOOLEAN_TYPE_P vectors, use
288 vec_unpacks_sbool_{lo,hi}_optab, so that we can pass in
289 the pattern number of elements in the wider vector. */
290 widen_pattern_optab
291 = (ops->code == VEC_UNPACK_HI_EXPR
292 ? vec_unpacks_sbool_hi_optab : vec_unpacks_sbool_lo_optab);
293 sbool = true;
294 }
295 else if (ops->code == DOT_PROD_EXPR)
296 {
297 enum optab_subtype subtype = optab_default;
298 signop sign1 = TYPE_SIGN (TREE_TYPE (oprnd0));
299 signop sign2 = TYPE_SIGN (TREE_TYPE (oprnd1));
300 if (sign1 == sign2)
301 ;
302 else if (sign1 == SIGNED && sign2 == UNSIGNED)
303 {
304 subtype = optab_vector_mixed_sign;
305 /* Same as optab_vector_mixed_sign but flip the operands. */
306 std::swap (op0, op1);
307 }
308 else if (sign1 == UNSIGNED && sign2 == SIGNED)
309 subtype = optab_vector_mixed_sign;
310 else
311 gcc_unreachable ();
312
313 widen_pattern_optab
314 = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), subtype);
315 }
316 else
317 widen_pattern_optab
318 = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
319 if (ops->code == WIDEN_MULT_PLUS_EXPR
320 || ops->code == WIDEN_MULT_MINUS_EXPR)
321 icode = find_widening_optab_handler (widen_pattern_optab,
322 TYPE_MODE (TREE_TYPE (ops->op2)),
323 tmode0);
324 else
325 icode = optab_handler (widen_pattern_optab, tmode0);
326 gcc_assert (icode != CODE_FOR_nothing);
327
328 if (nops >= 2)
329 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
330 else if (sbool)
331 {
332 nops = 2;
333 op1 = GEN_INT (TYPE_VECTOR_SUBPARTS (TREE_TYPE (oprnd0)).to_constant ());
334 tmode1 = tmode0;
335 }
336
337 /* The last operand is of a wider mode than the rest of the operands. */
338 if (nops == 2)
339 wmode = tmode1;
340 else if (nops == 3)
341 {
342 gcc_assert (tmode1 == tmode0);
343 gcc_assert (op1);
344 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
345 }
346
347 op = 0;
348 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
349 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
350 if (op1)
351 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
352 if (wide_op)
353 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
354 expand_insn (icode, op, eops);
355 return eops[0].value;
356 }
357
358 /* Generate code to perform an operation specified by TERNARY_OPTAB
359 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
360
361 UNSIGNEDP is for the case where we have to widen the operands
362 to perform the operation. It says to use zero-extension.
363
364 If TARGET is nonzero, the value
365 is generated there, if it is convenient to do so.
366 In all cases an rtx is returned for the locus of the value;
367 this may or may not be TARGET. */
368
369 rtx
370 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
371 rtx op1, rtx op2, rtx target, int unsignedp)
372 {
373 class expand_operand ops[4];
374 enum insn_code icode = optab_handler (ternary_optab, mode);
375
376 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
377
378 create_output_operand (&ops[0], target, mode);
379 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
380 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
381 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
382 expand_insn (icode, 4, ops);
383 return ops[0].value;
384 }
385
386
387 /* Like expand_binop, but return a constant rtx if the result can be
388 calculated at compile time. The arguments and return value are
389 otherwise the same as for expand_binop. */
390
391 rtx
392 simplify_expand_binop (machine_mode mode, optab binoptab,
393 rtx op0, rtx op1, rtx target, int unsignedp,
394 enum optab_methods methods)
395 {
396 if (CONSTANT_P (op0) && CONSTANT_P (op1))
397 {
398 rtx x = simplify_binary_operation (optab_to_code (binoptab),
399 mode, op0, op1);
400 if (x)
401 return x;
402 }
403
404 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
405 }
406
407 /* Like simplify_expand_binop, but always put the result in TARGET.
408 Return true if the expansion succeeded. */
409
410 bool
411 force_expand_binop (machine_mode mode, optab binoptab,
412 rtx op0, rtx op1, rtx target, int unsignedp,
413 enum optab_methods methods)
414 {
415 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
416 target, unsignedp, methods);
417 if (x == 0)
418 return false;
419 if (x != target)
420 emit_move_insn (target, x);
421 return true;
422 }
423
424 /* Create a new vector value in VMODE with all elements set to OP. The
425 mode of OP must be the element mode of VMODE. If OP is a constant,
426 then the return value will be a constant. */
427
428 rtx
429 expand_vector_broadcast (machine_mode vmode, rtx op)
430 {
431 int n;
432 rtvec vec;
433
434 gcc_checking_assert (VECTOR_MODE_P (vmode));
435
436 if (valid_for_const_vector_p (vmode, op))
437 return gen_const_vec_duplicate (vmode, op);
438
439 insn_code icode = optab_handler (vec_duplicate_optab, vmode);
440 if (icode != CODE_FOR_nothing)
441 {
442 class expand_operand ops[2];
443 create_output_operand (&ops[0], NULL_RTX, vmode);
444 create_input_operand (&ops[1], op, GET_MODE (op));
445 expand_insn (icode, 2, ops);
446 return ops[0].value;
447 }
448
449 if (!GET_MODE_NUNITS (vmode).is_constant (&n))
450 return NULL;
451
452 /* ??? If the target doesn't have a vec_init, then we have no easy way
453 of performing this operation. Most of this sort of generic support
454 is hidden away in the vector lowering support in gimple. */
455 icode = convert_optab_handler (vec_init_optab, vmode,
456 GET_MODE_INNER (vmode));
457 if (icode == CODE_FOR_nothing)
458 return NULL;
459
460 vec = rtvec_alloc (n);
461 for (int i = 0; i < n; ++i)
462 RTVEC_ELT (vec, i) = op;
463 rtx ret = gen_reg_rtx (vmode);
464 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
465
466 return ret;
467 }
468
469 /* This subroutine of expand_doubleword_shift handles the cases in which
470 the effective shift value is >= BITS_PER_WORD. The arguments and return
471 value are the same as for the parent routine, except that SUPERWORD_OP1
472 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
473 INTO_TARGET may be null if the caller has decided to calculate it. */
474
475 static bool
476 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
477 rtx outof_target, rtx into_target,
478 int unsignedp, enum optab_methods methods)
479 {
480 if (into_target != 0)
481 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
482 into_target, unsignedp, methods))
483 return false;
484
485 if (outof_target != 0)
486 {
487 /* For a signed right shift, we must fill OUTOF_TARGET with copies
488 of the sign bit, otherwise we must fill it with zeros. */
489 if (binoptab != ashr_optab)
490 emit_move_insn (outof_target, CONST0_RTX (word_mode));
491 else
492 if (!force_expand_binop (word_mode, binoptab, outof_input,
493 gen_int_shift_amount (word_mode,
494 BITS_PER_WORD - 1),
495 outof_target, unsignedp, methods))
496 return false;
497 }
498 return true;
499 }
500
501 /* This subroutine of expand_doubleword_shift handles the cases in which
502 the effective shift value is < BITS_PER_WORD. The arguments and return
503 value are the same as for the parent routine. */
504
505 static bool
506 expand_subword_shift (scalar_int_mode op1_mode, optab binoptab,
507 rtx outof_input, rtx into_input, rtx op1,
508 rtx outof_target, rtx into_target,
509 int unsignedp, enum optab_methods methods,
510 unsigned HOST_WIDE_INT shift_mask)
511 {
512 optab reverse_unsigned_shift, unsigned_shift;
513 rtx tmp, carries;
514
515 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
516 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
517
518 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
519 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
520 the opposite direction to BINOPTAB. */
521 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
522 {
523 carries = outof_input;
524 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
525 op1_mode), op1_mode);
526 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
527 0, true, methods);
528 }
529 else
530 {
531 /* We must avoid shifting by BITS_PER_WORD bits since that is either
532 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
533 has unknown behavior. Do a single shift first, then shift by the
534 remainder. It's OK to use ~OP1 as the remainder if shift counts
535 are truncated to the mode size. */
536 carries = expand_binop (word_mode, reverse_unsigned_shift,
537 outof_input, const1_rtx, 0, unsignedp, methods);
538 if (shift_mask == BITS_PER_WORD - 1)
539 {
540 tmp = immed_wide_int_const
541 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
542 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
543 0, true, methods);
544 }
545 else
546 {
547 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
548 op1_mode), op1_mode);
549 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
550 0, true, methods);
551 }
552 }
553 if (tmp == 0 || carries == 0)
554 return false;
555 carries = expand_binop (word_mode, reverse_unsigned_shift,
556 carries, tmp, 0, unsignedp, methods);
557 if (carries == 0)
558 return false;
559
560 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
561 so the result can go directly into INTO_TARGET if convenient. */
562 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
563 into_target, unsignedp, methods);
564 if (tmp == 0)
565 return false;
566
567 /* Now OR in the bits carried over from OUTOF_INPUT. */
568 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
569 into_target, unsignedp, methods))
570 return false;
571
572 /* Use a standard word_mode shift for the out-of half. */
573 if (outof_target != 0)
574 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
575 outof_target, unsignedp, methods))
576 return false;
577
578 return true;
579 }
580
581
582 /* Try implementing expand_doubleword_shift using conditional moves.
583 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
584 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
585 are the shift counts to use in the former and latter case. All other
586 arguments are the same as the parent routine. */
587
588 static bool
589 expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
590 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
591 rtx outof_input, rtx into_input,
592 rtx subword_op1, rtx superword_op1,
593 rtx outof_target, rtx into_target,
594 int unsignedp, enum optab_methods methods,
595 unsigned HOST_WIDE_INT shift_mask)
596 {
597 rtx outof_superword, into_superword;
598
599 /* Put the superword version of the output into OUTOF_SUPERWORD and
600 INTO_SUPERWORD. */
601 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
602 if (outof_target != 0 && subword_op1 == superword_op1)
603 {
604 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
605 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
606 into_superword = outof_target;
607 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
608 outof_superword, 0, unsignedp, methods))
609 return false;
610 }
611 else
612 {
613 into_superword = gen_reg_rtx (word_mode);
614 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
615 outof_superword, into_superword,
616 unsignedp, methods))
617 return false;
618 }
619
620 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
621 if (!expand_subword_shift (op1_mode, binoptab,
622 outof_input, into_input, subword_op1,
623 outof_target, into_target,
624 unsignedp, methods, shift_mask))
625 return false;
626
627 /* Select between them. Do the INTO half first because INTO_SUPERWORD
628 might be the current value of OUTOF_TARGET. */
629 if (!emit_conditional_move (into_target, { cmp_code, cmp1, cmp2, op1_mode },
630 into_target, into_superword, word_mode, false))
631 return false;
632
633 if (outof_target != 0)
634 if (!emit_conditional_move (outof_target,
635 { cmp_code, cmp1, cmp2, op1_mode },
636 outof_target, outof_superword,
637 word_mode, false))
638 return false;
639
640 return true;
641 }
642
643 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
644 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
645 input operand; the shift moves bits in the direction OUTOF_INPUT->
646 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
647 of the target. OP1 is the shift count and OP1_MODE is its mode.
648 If OP1 is constant, it will have been truncated as appropriate
649 and is known to be nonzero.
650
651 If SHIFT_MASK is zero, the result of word shifts is undefined when the
652 shift count is outside the range [0, BITS_PER_WORD). This routine must
653 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
654
655 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
656 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
657 fill with zeros or sign bits as appropriate.
658
659 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
660 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
661 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
662 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
663 are undefined.
664
665 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
666 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
667 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
668 function wants to calculate it itself.
669
670 Return true if the shift could be successfully synthesized. */
671
672 static bool
673 expand_doubleword_shift (scalar_int_mode op1_mode, optab binoptab,
674 rtx outof_input, rtx into_input, rtx op1,
675 rtx outof_target, rtx into_target,
676 int unsignedp, enum optab_methods methods,
677 unsigned HOST_WIDE_INT shift_mask)
678 {
679 rtx superword_op1, tmp, cmp1, cmp2;
680 enum rtx_code cmp_code;
681
682 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
683 fill the result with sign or zero bits as appropriate. If so, the value
684 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
685 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
686 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
687
688 This isn't worthwhile for constant shifts since the optimizers will
689 cope better with in-range shift counts. */
690 if (shift_mask >= BITS_PER_WORD
691 && outof_target != 0
692 && !CONSTANT_P (op1))
693 {
694 if (!expand_doubleword_shift (op1_mode, binoptab,
695 outof_input, into_input, op1,
696 0, into_target,
697 unsignedp, methods, shift_mask))
698 return false;
699 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
700 outof_target, unsignedp, methods))
701 return false;
702 return true;
703 }
704
705 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
706 is true when the effective shift value is less than BITS_PER_WORD.
707 Set SUPERWORD_OP1 to the shift count that should be used to shift
708 OUTOF_INPUT into INTO_TARGET when the condition is false. */
709 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
710 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
711 {
712 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
713 is a subword shift count. */
714 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
715 0, true, methods);
716 cmp2 = CONST0_RTX (op1_mode);
717 cmp_code = EQ;
718 superword_op1 = op1;
719 }
720 else
721 {
722 /* Set CMP1 to OP1 - BITS_PER_WORD. */
723 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
724 0, true, methods);
725 cmp2 = CONST0_RTX (op1_mode);
726 cmp_code = LT;
727 superword_op1 = cmp1;
728 }
729 if (cmp1 == 0)
730 return false;
731
732 /* If we can compute the condition at compile time, pick the
733 appropriate subroutine. */
734 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
735 if (tmp != 0 && CONST_INT_P (tmp))
736 {
737 if (tmp == const0_rtx)
738 return expand_superword_shift (binoptab, outof_input, superword_op1,
739 outof_target, into_target,
740 unsignedp, methods);
741 else
742 return expand_subword_shift (op1_mode, binoptab,
743 outof_input, into_input, op1,
744 outof_target, into_target,
745 unsignedp, methods, shift_mask);
746 }
747
748 /* Try using conditional moves to generate straight-line code. */
749 if (HAVE_conditional_move)
750 {
751 rtx_insn *start = get_last_insn ();
752 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
753 cmp_code, cmp1, cmp2,
754 outof_input, into_input,
755 op1, superword_op1,
756 outof_target, into_target,
757 unsignedp, methods, shift_mask))
758 return true;
759 delete_insns_since (start);
760 }
761
762 /* As a last resort, use branches to select the correct alternative. */
763 rtx_code_label *subword_label = gen_label_rtx ();
764 rtx_code_label *done_label = gen_label_rtx ();
765
766 NO_DEFER_POP;
767 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
768 0, 0, subword_label,
769 profile_probability::uninitialized ());
770 OK_DEFER_POP;
771
772 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
773 outof_target, into_target,
774 unsignedp, methods))
775 return false;
776
777 emit_jump_insn (targetm.gen_jump (done_label));
778 emit_barrier ();
779 emit_label (subword_label);
780
781 if (!expand_subword_shift (op1_mode, binoptab,
782 outof_input, into_input, op1,
783 outof_target, into_target,
784 unsignedp, methods, shift_mask))
785 return false;
786
787 emit_label (done_label);
788 return true;
789 }
790 \f
791 /* Subroutine of expand_binop. Perform a double word multiplication of
792 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
793 as the target's word_mode. This function return NULL_RTX if anything
794 goes wrong, in which case it may have already emitted instructions
795 which need to be deleted.
796
797 If we want to multiply two two-word values and have normal and widening
798 multiplies of single-word values, we can do this with three smaller
799 multiplications.
800
801 The multiplication proceeds as follows:
802 _______________________
803 [__op0_high_|__op0_low__]
804 _______________________
805 * [__op1_high_|__op1_low__]
806 _______________________________________________
807 _______________________
808 (1) [__op0_low__*__op1_low__]
809 _______________________
810 (2a) [__op0_low__*__op1_high_]
811 _______________________
812 (2b) [__op0_high_*__op1_low__]
813 _______________________
814 (3) [__op0_high_*__op1_high_]
815
816
817 This gives a 4-word result. Since we are only interested in the
818 lower 2 words, partial result (3) and the upper words of (2a) and
819 (2b) don't need to be calculated. Hence (2a) and (2b) can be
820 calculated using non-widening multiplication.
821
822 (1), however, needs to be calculated with an unsigned widening
823 multiplication. If this operation is not directly supported we
824 try using a signed widening multiplication and adjust the result.
825 This adjustment works as follows:
826
827 If both operands are positive then no adjustment is needed.
828
829 If the operands have different signs, for example op0_low < 0 and
830 op1_low >= 0, the instruction treats the most significant bit of
831 op0_low as a sign bit instead of a bit with significance
832 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
833 with 2**BITS_PER_WORD - op0_low, and two's complements the
834 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
835 the result.
836
837 Similarly, if both operands are negative, we need to add
838 (op0_low + op1_low) * 2**BITS_PER_WORD.
839
840 We use a trick to adjust quickly. We logically shift op0_low right
841 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
842 op0_high (op1_high) before it is used to calculate 2b (2a). If no
843 logical shift exists, we do an arithmetic right shift and subtract
844 the 0 or -1. */
845
846 static rtx
847 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
848 bool umulp, enum optab_methods methods)
849 {
850 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
851 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
852 rtx wordm1 = (umulp ? NULL_RTX
853 : gen_int_shift_amount (word_mode, BITS_PER_WORD - 1));
854 rtx product, adjust, product_high, temp;
855
856 rtx op0_high = operand_subword_force (op0, high, mode);
857 rtx op0_low = operand_subword_force (op0, low, mode);
858 rtx op1_high = operand_subword_force (op1, high, mode);
859 rtx op1_low = operand_subword_force (op1, low, mode);
860
861 /* If we're using an unsigned multiply to directly compute the product
862 of the low-order words of the operands and perform any required
863 adjustments of the operands, we begin by trying two more multiplications
864 and then computing the appropriate sum.
865
866 We have checked above that the required addition is provided.
867 Full-word addition will normally always succeed, especially if
868 it is provided at all, so we don't worry about its failure. The
869 multiplication may well fail, however, so we do handle that. */
870
871 if (!umulp)
872 {
873 /* ??? This could be done with emit_store_flag where available. */
874 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
875 NULL_RTX, 1, methods);
876 if (temp)
877 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
878 NULL_RTX, 0, OPTAB_DIRECT);
879 else
880 {
881 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
882 NULL_RTX, 0, methods);
883 if (!temp)
884 return NULL_RTX;
885 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
886 NULL_RTX, 0, OPTAB_DIRECT);
887 }
888
889 if (!op0_high)
890 return NULL_RTX;
891 }
892
893 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
894 NULL_RTX, 0, OPTAB_DIRECT);
895 if (!adjust)
896 return NULL_RTX;
897
898 /* OP0_HIGH should now be dead. */
899
900 if (!umulp)
901 {
902 /* ??? This could be done with emit_store_flag where available. */
903 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
904 NULL_RTX, 1, methods);
905 if (temp)
906 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
907 NULL_RTX, 0, OPTAB_DIRECT);
908 else
909 {
910 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
911 NULL_RTX, 0, methods);
912 if (!temp)
913 return NULL_RTX;
914 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
915 NULL_RTX, 0, OPTAB_DIRECT);
916 }
917
918 if (!op1_high)
919 return NULL_RTX;
920 }
921
922 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
923 NULL_RTX, 0, OPTAB_DIRECT);
924 if (!temp)
925 return NULL_RTX;
926
927 /* OP1_HIGH should now be dead. */
928
929 adjust = expand_binop (word_mode, add_optab, adjust, temp,
930 NULL_RTX, 0, OPTAB_DIRECT);
931
932 if (target && !REG_P (target))
933 target = NULL_RTX;
934
935 /* *_widen_optab needs to determine operand mode, make sure at least
936 one operand has non-VOID mode. */
937 if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
938 op0_low = force_reg (word_mode, op0_low);
939
940 if (umulp)
941 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
942 target, 1, OPTAB_DIRECT);
943 else
944 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
945 target, 1, OPTAB_DIRECT);
946
947 if (!product)
948 return NULL_RTX;
949
950 product_high = operand_subword (product, high, 1, mode);
951 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
952 NULL_RTX, 0, OPTAB_DIRECT);
953 emit_move_insn (product_high, adjust);
954 return product;
955 }
956
957 /* Subroutine of expand_binop. Optimize unsigned double-word OP0 % OP1 for
958 constant OP1. If for some bit in [BITS_PER_WORD / 2, BITS_PER_WORD] range
959 (prefer higher bits) ((1w << bit) % OP1) == 1, then the modulo can be
960 computed in word-mode as ((OP0 & (bit - 1)) + ((OP0 >> bit) & (bit - 1))
961 + (OP0 >> (2 * bit))) % OP1. Whether we need to sum 2, 3 or 4 values
962 depends on the bit value, if 2, then carry from the addition needs to be
963 added too, i.e. like:
964 sum += __builtin_add_overflow (low, high, &sum)
965
966 Optimize signed double-word OP0 % OP1 similarly, just apply some correction
967 factor to the sum before doing unsigned remainder, in the form of
968 sum += (((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & const);
969 then perform unsigned
970 remainder = sum % OP1;
971 and finally
972 remainder += ((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1); */
973
974 static rtx
975 expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
976 {
977 if (INTVAL (op1) <= 1 || (INTVAL (op1) & 1) == 0)
978 return NULL_RTX;
979
980 rtx_insn *last = get_last_insn ();
981 for (int bit = BITS_PER_WORD; bit >= BITS_PER_WORD / 2; bit--)
982 {
983 wide_int w = wi::shifted_mask (bit, 1, false, 2 * BITS_PER_WORD);
984 if (wi::ne_p (wi::umod_trunc (w, INTVAL (op1)), 1))
985 continue;
986 rtx sum = NULL_RTX, mask = NULL_RTX;
987 if (bit == BITS_PER_WORD)
988 {
989 /* For signed modulo we need to add correction to the sum
990 and that might again overflow. */
991 if (!unsignedp)
992 continue;
993 if (optab_handler (uaddv4_optab, word_mode) == CODE_FOR_nothing)
994 continue;
995 tree wtype = lang_hooks.types.type_for_mode (word_mode, 1);
996 if (wtype == NULL_TREE)
997 continue;
998 tree ctype = build_complex_type (wtype);
999 if (TYPE_MODE (ctype) != GET_MODE_COMPLEX_MODE (word_mode))
1000 continue;
1001 machine_mode cmode = TYPE_MODE (ctype);
1002 rtx op00 = operand_subword_force (op0, 0, mode);
1003 rtx op01 = operand_subword_force (op0, 1, mode);
1004 rtx cres = gen_rtx_CONCAT (cmode, gen_reg_rtx (word_mode),
1005 gen_reg_rtx (word_mode));
1006 tree lhs = make_tree (ctype, cres);
1007 tree arg0 = make_tree (wtype, op00);
1008 tree arg1 = make_tree (wtype, op01);
1009 expand_addsub_overflow (UNKNOWN_LOCATION, PLUS_EXPR, lhs, arg0,
1010 arg1, true, true, true, false, NULL);
1011 sum = expand_simple_binop (word_mode, PLUS, XEXP (cres, 0),
1012 XEXP (cres, 1), NULL_RTX, 1,
1013 OPTAB_DIRECT);
1014 if (sum == NULL_RTX)
1015 return NULL_RTX;
1016 }
1017 else
1018 {
1019 /* Code below uses GEN_INT, so we need the masks to be representable
1020 in HOST_WIDE_INTs. */
1021 if (bit >= HOST_BITS_PER_WIDE_INT)
1022 continue;
1023 /* If op0 is e.g. -1 or -2 unsigned, then the 2 additions might
1024 overflow. Consider 64-bit -1ULL for word size 32, if we add
1025 0x7fffffffU + 0x7fffffffU + 3U, it wraps around to 1. */
1026 if (bit == BITS_PER_WORD - 1)
1027 continue;
1028
1029 int count = (2 * BITS_PER_WORD + bit - 1) / bit;
1030 rtx sum_corr = NULL_RTX;
1031
1032 if (!unsignedp)
1033 {
1034 /* For signed modulo, compute it as unsigned modulo of
1035 sum with a correction added to it if OP0 is negative,
1036 such that the result can be computed as unsigned
1037 remainder + ((OP1 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1). */
1038 w = wi::min_value (2 * BITS_PER_WORD, SIGNED);
1039 wide_int wmod1 = wi::umod_trunc (w, INTVAL (op1));
1040 wide_int wmod2 = wi::smod_trunc (w, INTVAL (op1));
1041 /* wmod2 == -wmod1. */
1042 wmod2 = wmod2 + (INTVAL (op1) - 1);
1043 if (wi::ne_p (wmod1, wmod2))
1044 {
1045 wide_int wcorr = wmod2 - wmod1;
1046 if (wi::neg_p (w))
1047 wcorr = wcorr + INTVAL (op1);
1048 /* Now verify if the count sums can't overflow, and punt
1049 if they could. */
1050 w = wi::mask (bit, false, 2 * BITS_PER_WORD);
1051 w = w * (count - 1);
1052 w = w + wi::mask (2 * BITS_PER_WORD - (count - 1) * bit,
1053 false, 2 * BITS_PER_WORD);
1054 w = w + wcorr;
1055 w = wi::lrshift (w, BITS_PER_WORD);
1056 if (wi::ne_p (w, 0))
1057 continue;
1058
1059 mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
1060 mode);
1061 mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
1062 GEN_INT (BITS_PER_WORD - 1),
1063 NULL_RTX, 0, OPTAB_DIRECT);
1064 if (mask == NULL_RTX)
1065 return NULL_RTX;
1066 sum_corr = immed_wide_int_const (wcorr, word_mode);
1067 sum_corr = expand_simple_binop (word_mode, AND, mask,
1068 sum_corr, NULL_RTX, 1,
1069 OPTAB_DIRECT);
1070 if (sum_corr == NULL_RTX)
1071 return NULL_RTX;
1072 }
1073 }
1074
1075 for (int i = 0; i < count; i++)
1076 {
1077 rtx v = op0;
1078 if (i)
1079 v = expand_simple_binop (mode, LSHIFTRT, v, GEN_INT (i * bit),
1080 NULL_RTX, 1, OPTAB_DIRECT);
1081 if (v == NULL_RTX)
1082 return NULL_RTX;
1083 v = lowpart_subreg (word_mode, v, mode);
1084 if (v == NULL_RTX)
1085 return NULL_RTX;
1086 if (i != count - 1)
1087 v = expand_simple_binop (word_mode, AND, v,
1088 GEN_INT ((HOST_WIDE_INT_1U << bit)
1089 - 1), NULL_RTX, 1,
1090 OPTAB_DIRECT);
1091 if (v == NULL_RTX)
1092 return NULL_RTX;
1093 if (sum == NULL_RTX)
1094 sum = v;
1095 else
1096 sum = expand_simple_binop (word_mode, PLUS, sum, v, NULL_RTX,
1097 1, OPTAB_DIRECT);
1098 if (sum == NULL_RTX)
1099 return NULL_RTX;
1100 }
1101 if (sum_corr)
1102 {
1103 sum = expand_simple_binop (word_mode, PLUS, sum, sum_corr,
1104 NULL_RTX, 1, OPTAB_DIRECT);
1105 if (sum == NULL_RTX)
1106 return NULL_RTX;
1107 }
1108 }
1109 rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum,
1110 gen_int_mode (INTVAL (op1), word_mode),
1111 NULL_RTX, 1, OPTAB_DIRECT);
1112 if (remainder == NULL_RTX)
1113 return NULL_RTX;
1114
1115 if (!unsignedp)
1116 {
1117 if (mask == NULL_RTX)
1118 {
1119 mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
1120 mode);
1121 mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
1122 GEN_INT (BITS_PER_WORD - 1),
1123 NULL_RTX, 0, OPTAB_DIRECT);
1124 if (mask == NULL_RTX)
1125 return NULL_RTX;
1126 }
1127 mask = expand_simple_binop (word_mode, AND, mask,
1128 gen_int_mode (1 - INTVAL (op1),
1129 word_mode),
1130 NULL_RTX, 1, OPTAB_DIRECT);
1131 if (mask == NULL_RTX)
1132 return NULL_RTX;
1133 remainder = expand_simple_binop (word_mode, PLUS, remainder,
1134 mask, NULL_RTX, 1, OPTAB_DIRECT);
1135 if (remainder == NULL_RTX)
1136 return NULL_RTX;
1137 }
1138
1139 remainder = convert_modes (mode, word_mode, remainder, unsignedp);
1140 /* Punt if we need any library calls. */
1141 if (last)
1142 last = NEXT_INSN (last);
1143 else
1144 last = get_insns ();
1145 for (; last; last = NEXT_INSN (last))
1146 if (CALL_P (last))
1147 return NULL_RTX;
1148 return remainder;
1149 }
1150 return NULL_RTX;
1151 }
1152
1153 /* Similarly to the above function, but compute both quotient and remainder.
1154 Quotient can be computed from the remainder as:
1155 rem = op0 % op1; // Handled using expand_doubleword_mod
1156 quot = (op0 - rem) * inv; // inv is multiplicative inverse of op1 modulo
1157 // 2 * BITS_PER_WORD
1158
1159 We can also handle cases where op1 is a multiple of power of two constant
1160 and constant handled by expand_doubleword_mod.
1161 op11 = 1 << __builtin_ctz (op1);
1162 op12 = op1 / op11;
1163 rem1 = op0 % op12; // Handled using expand_doubleword_mod
1164 quot1 = (op0 - rem1) * inv; // inv is multiplicative inverse of op12 modulo
1165 // 2 * BITS_PER_WORD
1166 rem = (quot1 % op11) * op12 + rem1;
1167 quot = quot1 / op11; */
1168
1169 rtx
1170 expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem,
1171 bool unsignedp)
1172 {
1173 *rem = NULL_RTX;
1174
1175 /* Negative dividend should have been optimized into positive,
1176 similarly modulo by 1 and modulo by power of two is optimized
1177 differently too. */
1178 if (INTVAL (op1) <= 1 || pow2p_hwi (INTVAL (op1)))
1179 return NULL_RTX;
1180
1181 rtx op11 = const1_rtx;
1182 rtx op12 = op1;
1183 if ((INTVAL (op1) & 1) == 0)
1184 {
1185 int bit = ctz_hwi (INTVAL (op1));
1186 op11 = GEN_INT (HOST_WIDE_INT_1 << bit);
1187 op12 = GEN_INT (INTVAL (op1) >> bit);
1188 }
1189
1190 rtx rem1 = expand_doubleword_mod (mode, op0, op12, unsignedp);
1191 if (rem1 == NULL_RTX)
1192 return NULL_RTX;
1193
1194 int prec = 2 * BITS_PER_WORD;
1195 wide_int a = wide_int::from (INTVAL (op12), prec + 1, UNSIGNED);
1196 wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
1197 wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
1198 rtx inv = immed_wide_int_const (m, mode);
1199
1200 rtx_insn *last = get_last_insn ();
1201 rtx quot1 = expand_simple_binop (mode, MINUS, op0, rem1,
1202 NULL_RTX, unsignedp, OPTAB_DIRECT);
1203 if (quot1 == NULL_RTX)
1204 return NULL_RTX;
1205
1206 quot1 = expand_simple_binop (mode, MULT, quot1, inv,
1207 NULL_RTX, unsignedp, OPTAB_DIRECT);
1208 if (quot1 == NULL_RTX)
1209 return NULL_RTX;
1210
1211 if (op11 != const1_rtx)
1212 {
1213 rtx rem2 = expand_divmod (1, TRUNC_MOD_EXPR, mode, quot1, op11,
1214 NULL_RTX, unsignedp, OPTAB_DIRECT);
1215 if (rem2 == NULL_RTX)
1216 return NULL_RTX;
1217
1218 rem2 = expand_simple_binop (mode, MULT, rem2, op12, NULL_RTX,
1219 unsignedp, OPTAB_DIRECT);
1220 if (rem2 == NULL_RTX)
1221 return NULL_RTX;
1222
1223 rem2 = expand_simple_binop (mode, PLUS, rem2, rem1, NULL_RTX,
1224 unsignedp, OPTAB_DIRECT);
1225 if (rem2 == NULL_RTX)
1226 return NULL_RTX;
1227
1228 rtx quot2 = expand_divmod (0, TRUNC_DIV_EXPR, mode, quot1, op11,
1229 NULL_RTX, unsignedp, OPTAB_DIRECT);
1230 if (quot2 == NULL_RTX)
1231 return NULL_RTX;
1232
1233 rem1 = rem2;
1234 quot1 = quot2;
1235 }
1236
1237 /* Punt if we need any library calls. */
1238 if (last)
1239 last = NEXT_INSN (last);
1240 else
1241 last = get_insns ();
1242 for (; last; last = NEXT_INSN (last))
1243 if (CALL_P (last))
1244 return NULL_RTX;
1245
1246 *rem = rem1;
1247 return quot1;
1248 }
1249 \f
1250 /* Wrapper around expand_binop which takes an rtx code to specify
1251 the operation to perform, not an optab pointer. All other
1252 arguments are the same. */
1253 rtx
1254 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
1255 rtx op1, rtx target, int unsignedp,
1256 enum optab_methods methods)
1257 {
1258 optab binop = code_to_optab (code);
1259 gcc_assert (binop);
1260
1261 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1262 }
1263
1264 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1265 binop. Order them according to commutative_operand_precedence and, if
1266 possible, try to put TARGET or a pseudo first. */
1267 static bool
1268 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1269 {
1270 int op0_prec = commutative_operand_precedence (op0);
1271 int op1_prec = commutative_operand_precedence (op1);
1272
1273 if (op0_prec < op1_prec)
1274 return true;
1275
1276 if (op0_prec > op1_prec)
1277 return false;
1278
1279 /* With equal precedence, both orders are ok, but it is better if the
1280 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1281 if (target == 0 || REG_P (target))
1282 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1283 else
1284 return rtx_equal_p (op1, target);
1285 }
1286
1287 /* Return true if BINOPTAB implements a shift operation. */
1288
1289 static bool
1290 shift_optab_p (optab binoptab)
1291 {
1292 switch (optab_to_code (binoptab))
1293 {
1294 case ASHIFT:
1295 case SS_ASHIFT:
1296 case US_ASHIFT:
1297 case ASHIFTRT:
1298 case LSHIFTRT:
1299 case ROTATE:
1300 case ROTATERT:
1301 return true;
1302
1303 default:
1304 return false;
1305 }
1306 }
1307
1308 /* Return true if BINOPTAB implements a commutative binary operation. */
1309
1310 static bool
1311 commutative_optab_p (optab binoptab)
1312 {
1313 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
1314 || binoptab == smul_widen_optab
1315 || binoptab == umul_widen_optab
1316 || binoptab == smul_highpart_optab
1317 || binoptab == umul_highpart_optab);
1318 }
1319
1320 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1321 optimizing, and if the operand is a constant that costs more than
1322 1 instruction, force the constant into a register and return that
1323 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1324
1325 static rtx
1326 avoid_expensive_constant (machine_mode mode, optab binoptab,
1327 int opn, rtx x, bool unsignedp)
1328 {
1329 bool speed = optimize_insn_for_speed_p ();
1330
1331 if (mode != VOIDmode
1332 && optimize
1333 && CONSTANT_P (x)
1334 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
1335 > set_src_cost (x, mode, speed)))
1336 {
1337 if (CONST_INT_P (x))
1338 {
1339 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1340 if (intval != INTVAL (x))
1341 x = GEN_INT (intval);
1342 }
1343 else
1344 x = convert_modes (mode, VOIDmode, x, unsignedp);
1345 x = force_reg (mode, x);
1346 }
1347 return x;
1348 }
1349
1350 /* Helper function for expand_binop: handle the case where there
1351 is an insn ICODE that directly implements the indicated operation.
1352 Returns null if this is not possible. */
1353 static rtx
1354 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
1355 rtx op0, rtx op1,
1356 rtx target, int unsignedp, enum optab_methods methods,
1357 rtx_insn *last)
1358 {
1359 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1360 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1361 machine_mode mode0, mode1, tmp_mode;
1362 class expand_operand ops[3];
1363 bool commutative_p;
1364 rtx_insn *pat;
1365 rtx xop0 = op0, xop1 = op1;
1366 bool canonicalize_op1 = false;
1367
1368 /* If it is a commutative operator and the modes would match
1369 if we would swap the operands, we can save the conversions. */
1370 commutative_p = commutative_optab_p (binoptab);
1371 if (commutative_p
1372 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1373 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode0)
1374 std::swap (xop0, xop1);
1375
1376 /* If we are optimizing, force expensive constants into a register. */
1377 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1378 if (!shift_optab_p (binoptab))
1379 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1380 else
1381 /* Shifts and rotates often use a different mode for op1 from op0;
1382 for VOIDmode constants we don't know the mode, so force it
1383 to be canonicalized using convert_modes. */
1384 canonicalize_op1 = true;
1385
1386 /* In case the insn wants input operands in modes different from
1387 those of the actual operands, convert the operands. It would
1388 seem that we don't need to convert CONST_INTs, but we do, so
1389 that they're properly zero-extended, sign-extended or truncated
1390 for their mode. */
1391
1392 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1393 if (xmode0 != VOIDmode && xmode0 != mode0)
1394 {
1395 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1396 mode0 = xmode0;
1397 }
1398
1399 mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
1400 ? GET_MODE (xop1) : mode);
1401 if (xmode1 != VOIDmode && xmode1 != mode1)
1402 {
1403 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1404 mode1 = xmode1;
1405 }
1406
1407 /* If operation is commutative,
1408 try to make the first operand a register.
1409 Even better, try to make it the same as the target.
1410 Also try to make the last operand a constant. */
1411 if (commutative_p
1412 && swap_commutative_operands_with_target (target, xop0, xop1))
1413 std::swap (xop0, xop1);
1414
1415 /* Now, if insn's predicates don't allow our operands, put them into
1416 pseudo regs. */
1417
1418 if (binoptab == vec_pack_trunc_optab
1419 || binoptab == vec_pack_usat_optab
1420 || binoptab == vec_pack_ssat_optab
1421 || binoptab == vec_pack_ufix_trunc_optab
1422 || binoptab == vec_pack_sfix_trunc_optab
1423 || binoptab == vec_packu_float_optab
1424 || binoptab == vec_packs_float_optab)
1425 {
1426 /* The mode of the result is different then the mode of the
1427 arguments. */
1428 tmp_mode = insn_data[(int) icode].operand[0].mode;
1429 if (VECTOR_MODE_P (mode)
1430 && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
1431 {
1432 delete_insns_since (last);
1433 return NULL_RTX;
1434 }
1435 }
1436 else
1437 tmp_mode = mode;
1438
1439 create_output_operand (&ops[0], target, tmp_mode);
1440 create_input_operand (&ops[1], xop0, mode0);
1441 create_input_operand (&ops[2], xop1, mode1);
1442 pat = maybe_gen_insn (icode, 3, ops);
1443 if (pat)
1444 {
1445 /* If PAT is composed of more than one insn, try to add an appropriate
1446 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1447 operand, call expand_binop again, this time without a target. */
1448 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1449 && ! add_equal_note (pat, ops[0].value,
1450 optab_to_code (binoptab),
1451 ops[1].value, ops[2].value, mode0))
1452 {
1453 delete_insns_since (last);
1454 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1455 unsignedp, methods);
1456 }
1457
1458 emit_insn (pat);
1459 return ops[0].value;
1460 }
1461 delete_insns_since (last);
1462 return NULL_RTX;
1463 }
1464
1465 /* Generate code to perform an operation specified by BINOPTAB
1466 on operands OP0 and OP1, with result having machine-mode MODE.
1467
1468 UNSIGNEDP is for the case where we have to widen the operands
1469 to perform the operation. It says to use zero-extension.
1470
1471 If TARGET is nonzero, the value
1472 is generated there, if it is convenient to do so.
1473 In all cases an rtx is returned for the locus of the value;
1474 this may or may not be TARGET. */
1475
1476 rtx
1477 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1478 rtx target, int unsignedp, enum optab_methods methods)
1479 {
1480 enum optab_methods next_methods
1481 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1482 ? OPTAB_WIDEN : methods);
1483 enum mode_class mclass;
1484 enum insn_code icode;
1485 machine_mode wider_mode;
1486 scalar_int_mode int_mode;
1487 rtx libfunc;
1488 rtx temp;
1489 rtx_insn *entry_last = get_last_insn ();
1490 rtx_insn *last;
1491
1492 mclass = GET_MODE_CLASS (mode);
1493
1494 /* If subtracting an integer constant, convert this into an addition of
1495 the negated constant. */
1496
1497 if (binoptab == sub_optab && CONST_INT_P (op1))
1498 {
1499 op1 = negate_rtx (mode, op1);
1500 binoptab = add_optab;
1501 }
1502 /* For shifts, constant invalid op1 might be expanded from different
1503 mode than MODE. As those are invalid, force them to a register
1504 to avoid further problems during expansion. */
1505 else if (CONST_INT_P (op1)
1506 && shift_optab_p (binoptab)
1507 && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode)))
1508 {
1509 op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode));
1510 op1 = force_reg (GET_MODE_INNER (mode), op1);
1511 }
1512
1513 /* Record where to delete back to if we backtrack. */
1514 last = get_last_insn ();
1515
1516 /* If we can do it with a three-operand insn, do so. */
1517
1518 if (methods != OPTAB_MUST_WIDEN)
1519 {
1520 if (convert_optab_p (binoptab))
1521 {
1522 machine_mode from_mode = widened_mode (mode, op0, op1);
1523 icode = find_widening_optab_handler (binoptab, mode, from_mode);
1524 }
1525 else
1526 icode = optab_handler (binoptab, mode);
1527 if (icode != CODE_FOR_nothing)
1528 {
1529 temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
1530 target, unsignedp, methods, last);
1531 if (temp)
1532 return temp;
1533 }
1534 }
1535
1536 /* If we were trying to rotate, and that didn't work, try rotating
1537 the other direction before falling back to shifts and bitwise-or. */
1538 if (((binoptab == rotl_optab
1539 && (icode = optab_handler (rotr_optab, mode)) != CODE_FOR_nothing)
1540 || (binoptab == rotr_optab
1541 && (icode = optab_handler (rotl_optab, mode)) != CODE_FOR_nothing))
1542 && is_int_mode (mode, &int_mode))
1543 {
1544 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1545 rtx newop1;
1546 unsigned int bits = GET_MODE_PRECISION (int_mode);
1547
1548 if (CONST_INT_P (op1))
1549 newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
1550 else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
1551 newop1 = negate_rtx (GET_MODE (op1), op1);
1552 else
1553 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1554 gen_int_mode (bits, GET_MODE (op1)), op1,
1555 NULL_RTX, unsignedp, OPTAB_DIRECT);
1556
1557 temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
1558 target, unsignedp, methods, last);
1559 if (temp)
1560 return temp;
1561 }
1562
1563 /* If this is a multiply, see if we can do a widening operation that
1564 takes operands of this mode and makes a wider mode. */
1565
1566 if (binoptab == smul_optab
1567 && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
1568 && (convert_optab_handler ((unsignedp
1569 ? umul_widen_optab
1570 : smul_widen_optab),
1571 wider_mode, mode) != CODE_FOR_nothing))
1572 {
1573 /* *_widen_optab needs to determine operand mode, make sure at least
1574 one operand has non-VOID mode. */
1575 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
1576 op0 = force_reg (mode, op0);
1577 temp = expand_binop (wider_mode,
1578 unsignedp ? umul_widen_optab : smul_widen_optab,
1579 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1580
1581 if (temp != 0)
1582 {
1583 if (GET_MODE_CLASS (mode) == MODE_INT
1584 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1585 return gen_lowpart (mode, temp);
1586 else
1587 return convert_to_mode (mode, temp, unsignedp);
1588 }
1589 }
1590
1591 /* If this is a vector shift by a scalar, see if we can do a vector
1592 shift by a vector. If so, broadcast the scalar into a vector. */
1593 if (mclass == MODE_VECTOR_INT)
1594 {
1595 optab otheroptab = unknown_optab;
1596
1597 if (binoptab == ashl_optab)
1598 otheroptab = vashl_optab;
1599 else if (binoptab == ashr_optab)
1600 otheroptab = vashr_optab;
1601 else if (binoptab == lshr_optab)
1602 otheroptab = vlshr_optab;
1603 else if (binoptab == rotl_optab)
1604 otheroptab = vrotl_optab;
1605 else if (binoptab == rotr_optab)
1606 otheroptab = vrotr_optab;
1607
1608 if (otheroptab
1609 && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
1610 {
1611 /* The scalar may have been extended to be too wide. Truncate
1612 it back to the proper size to fit in the broadcast vector. */
1613 scalar_mode inner_mode = GET_MODE_INNER (mode);
1614 if (!CONST_INT_P (op1)
1615 && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
1616 > GET_MODE_BITSIZE (inner_mode)))
1617 op1 = force_reg (inner_mode,
1618 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1619 GET_MODE (op1)));
1620 rtx vop1 = expand_vector_broadcast (mode, op1);
1621 if (vop1)
1622 {
1623 temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
1624 target, unsignedp, methods, last);
1625 if (temp)
1626 return temp;
1627 }
1628 }
1629 }
1630
1631 /* Look for a wider mode of the same class for which we think we
1632 can open-code the operation. Check for a widening multiply at the
1633 wider mode as well. */
1634
1635 if (CLASS_HAS_WIDER_MODES_P (mclass)
1636 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1637 FOR_EACH_WIDER_MODE (wider_mode, mode)
1638 {
1639 machine_mode next_mode;
1640 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1641 || (binoptab == smul_optab
1642 && GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
1643 && (find_widening_optab_handler ((unsignedp
1644 ? umul_widen_optab
1645 : smul_widen_optab),
1646 next_mode, mode)
1647 != CODE_FOR_nothing)))
1648 {
1649 rtx xop0 = op0, xop1 = op1;
1650 int no_extend = 0;
1651
1652 /* For certain integer operations, we need not actually extend
1653 the narrow operands, as long as we will truncate
1654 the results to the same narrowness. */
1655
1656 if ((binoptab == ior_optab || binoptab == and_optab
1657 || binoptab == xor_optab
1658 || binoptab == add_optab || binoptab == sub_optab
1659 || binoptab == smul_optab || binoptab == ashl_optab)
1660 && mclass == MODE_INT)
1661 {
1662 no_extend = 1;
1663 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1664 xop0, unsignedp);
1665 if (binoptab != ashl_optab)
1666 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1667 xop1, unsignedp);
1668 }
1669
1670 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1671
1672 /* The second operand of a shift must always be extended. */
1673 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1674 no_extend && binoptab != ashl_optab);
1675
1676 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1677 unsignedp, OPTAB_DIRECT);
1678 if (temp)
1679 {
1680 if (mclass != MODE_INT
1681 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1682 {
1683 if (target == 0)
1684 target = gen_reg_rtx (mode);
1685 convert_move (target, temp, 0);
1686 return target;
1687 }
1688 else
1689 return gen_lowpart (mode, temp);
1690 }
1691 else
1692 delete_insns_since (last);
1693 }
1694 }
1695
1696 /* If operation is commutative,
1697 try to make the first operand a register.
1698 Even better, try to make it the same as the target.
1699 Also try to make the last operand a constant. */
1700 if (commutative_optab_p (binoptab)
1701 && swap_commutative_operands_with_target (target, op0, op1))
1702 std::swap (op0, op1);
1703
1704 /* These can be done a word at a time. */
1705 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1706 && is_int_mode (mode, &int_mode)
1707 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
1708 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1709 {
1710 int i;
1711 rtx_insn *insns;
1712
1713 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1714 won't be accurate, so use a new target. */
1715 if (target == 0
1716 || target == op0
1717 || target == op1
1718 || reg_overlap_mentioned_p (target, op0)
1719 || reg_overlap_mentioned_p (target, op1)
1720 || !valid_multiword_target_p (target))
1721 target = gen_reg_rtx (int_mode);
1722
1723 start_sequence ();
1724
1725 /* Do the actual arithmetic. */
1726 machine_mode op0_mode = GET_MODE (op0);
1727 machine_mode op1_mode = GET_MODE (op1);
1728 if (op0_mode == VOIDmode)
1729 op0_mode = int_mode;
1730 if (op1_mode == VOIDmode)
1731 op1_mode = int_mode;
1732 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
1733 {
1734 rtx target_piece = operand_subword (target, i, 1, int_mode);
1735 rtx x = expand_binop (word_mode, binoptab,
1736 operand_subword_force (op0, i, op0_mode),
1737 operand_subword_force (op1, i, op1_mode),
1738 target_piece, unsignedp, next_methods);
1739
1740 if (x == 0)
1741 break;
1742
1743 if (target_piece != x)
1744 emit_move_insn (target_piece, x);
1745 }
1746
1747 insns = get_insns ();
1748 end_sequence ();
1749
1750 if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
1751 {
1752 emit_insn (insns);
1753 return target;
1754 }
1755 }
1756
1757 /* Synthesize double word shifts from single word shifts. */
1758 if ((binoptab == lshr_optab || binoptab == ashl_optab
1759 || binoptab == ashr_optab)
1760 && is_int_mode (mode, &int_mode)
1761 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1762 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1763 && GET_MODE_PRECISION (int_mode) == GET_MODE_BITSIZE (int_mode)
1764 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1765 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1766 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1767 {
1768 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1769 scalar_int_mode op1_mode;
1770
1771 double_shift_mask = targetm.shift_truncation_mask (int_mode);
1772 shift_mask = targetm.shift_truncation_mask (word_mode);
1773 op1_mode = (GET_MODE (op1) != VOIDmode
1774 ? as_a <scalar_int_mode> (GET_MODE (op1))
1775 : word_mode);
1776
1777 /* Apply the truncation to constant shifts. */
1778 if (double_shift_mask > 0 && CONST_INT_P (op1))
1779 op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode);
1780
1781 if (op1 == CONST0_RTX (op1_mode))
1782 return op0;
1783
1784 /* Make sure that this is a combination that expand_doubleword_shift
1785 can handle. See the comments there for details. */
1786 if (double_shift_mask == 0
1787 || (shift_mask == BITS_PER_WORD - 1
1788 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1789 {
1790 rtx_insn *insns;
1791 rtx into_target, outof_target;
1792 rtx into_input, outof_input;
1793 int left_shift, outof_word;
1794
1795 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1796 won't be accurate, so use a new target. */
1797 if (target == 0
1798 || target == op0
1799 || target == op1
1800 || reg_overlap_mentioned_p (target, op0)
1801 || reg_overlap_mentioned_p (target, op1)
1802 || !valid_multiword_target_p (target))
1803 target = gen_reg_rtx (int_mode);
1804
1805 start_sequence ();
1806
1807 /* OUTOF_* is the word we are shifting bits away from, and
1808 INTO_* is the word that we are shifting bits towards, thus
1809 they differ depending on the direction of the shift and
1810 WORDS_BIG_ENDIAN. */
1811
1812 left_shift = binoptab == ashl_optab;
1813 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1814
1815 outof_target = operand_subword (target, outof_word, 1, int_mode);
1816 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1817
1818 outof_input = operand_subword_force (op0, outof_word, int_mode);
1819 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1820
1821 if (expand_doubleword_shift (op1_mode, binoptab,
1822 outof_input, into_input, op1,
1823 outof_target, into_target,
1824 unsignedp, next_methods, shift_mask))
1825 {
1826 insns = get_insns ();
1827 end_sequence ();
1828
1829 emit_insn (insns);
1830 return target;
1831 }
1832 end_sequence ();
1833 }
1834 }
1835
1836 /* Synthesize double word rotates from single word shifts. */
1837 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1838 && is_int_mode (mode, &int_mode)
1839 && CONST_INT_P (op1)
1840 && GET_MODE_PRECISION (int_mode) == 2 * BITS_PER_WORD
1841 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1842 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1843 {
1844 rtx_insn *insns;
1845 rtx into_target, outof_target;
1846 rtx into_input, outof_input;
1847 rtx inter;
1848 int shift_count, left_shift, outof_word;
1849
1850 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1851 won't be accurate, so use a new target. Do this also if target is not
1852 a REG, first because having a register instead may open optimization
1853 opportunities, and second because if target and op0 happen to be MEMs
1854 designating the same location, we would risk clobbering it too early
1855 in the code sequence we generate below. */
1856 if (target == 0
1857 || target == op0
1858 || target == op1
1859 || !REG_P (target)
1860 || reg_overlap_mentioned_p (target, op0)
1861 || reg_overlap_mentioned_p (target, op1)
1862 || !valid_multiword_target_p (target))
1863 target = gen_reg_rtx (int_mode);
1864
1865 start_sequence ();
1866
1867 shift_count = INTVAL (op1);
1868
1869 /* OUTOF_* is the word we are shifting bits away from, and
1870 INTO_* is the word that we are shifting bits towards, thus
1871 they differ depending on the direction of the shift and
1872 WORDS_BIG_ENDIAN. */
1873
1874 left_shift = (binoptab == rotl_optab);
1875 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1876
1877 outof_target = operand_subword (target, outof_word, 1, int_mode);
1878 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1879
1880 outof_input = operand_subword_force (op0, outof_word, int_mode);
1881 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1882
1883 if (shift_count == BITS_PER_WORD)
1884 {
1885 /* This is just a word swap. */
1886 emit_move_insn (outof_target, into_input);
1887 emit_move_insn (into_target, outof_input);
1888 inter = const0_rtx;
1889 }
1890 else
1891 {
1892 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1893 HOST_WIDE_INT first_shift_count, second_shift_count;
1894 optab reverse_unsigned_shift, unsigned_shift;
1895
1896 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1897 ? lshr_optab : ashl_optab);
1898
1899 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1900 ? ashl_optab : lshr_optab);
1901
1902 if (shift_count > BITS_PER_WORD)
1903 {
1904 first_shift_count = shift_count - BITS_PER_WORD;
1905 second_shift_count = 2 * BITS_PER_WORD - shift_count;
1906 }
1907 else
1908 {
1909 first_shift_count = BITS_PER_WORD - shift_count;
1910 second_shift_count = shift_count;
1911 }
1912 rtx first_shift_count_rtx
1913 = gen_int_shift_amount (word_mode, first_shift_count);
1914 rtx second_shift_count_rtx
1915 = gen_int_shift_amount (word_mode, second_shift_count);
1916
1917 into_temp1 = expand_binop (word_mode, unsigned_shift,
1918 outof_input, first_shift_count_rtx,
1919 NULL_RTX, unsignedp, next_methods);
1920 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1921 into_input, second_shift_count_rtx,
1922 NULL_RTX, unsignedp, next_methods);
1923
1924 if (into_temp1 != 0 && into_temp2 != 0)
1925 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1926 into_target, unsignedp, next_methods);
1927 else
1928 inter = 0;
1929
1930 if (inter != 0 && inter != into_target)
1931 emit_move_insn (into_target, inter);
1932
1933 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1934 into_input, first_shift_count_rtx,
1935 NULL_RTX, unsignedp, next_methods);
1936 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1937 outof_input, second_shift_count_rtx,
1938 NULL_RTX, unsignedp, next_methods);
1939
1940 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1941 inter = expand_binop (word_mode, ior_optab,
1942 outof_temp1, outof_temp2,
1943 outof_target, unsignedp, next_methods);
1944
1945 if (inter != 0 && inter != outof_target)
1946 emit_move_insn (outof_target, inter);
1947 }
1948
1949 insns = get_insns ();
1950 end_sequence ();
1951
1952 if (inter != 0)
1953 {
1954 emit_insn (insns);
1955 return target;
1956 }
1957 }
1958
1959 /* These can be done a word at a time by propagating carries. */
1960 if ((binoptab == add_optab || binoptab == sub_optab)
1961 && is_int_mode (mode, &int_mode)
1962 && GET_MODE_SIZE (int_mode) >= 2 * UNITS_PER_WORD
1963 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1964 {
1965 unsigned int i;
1966 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1967 const unsigned int nwords = GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD;
1968 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1969 rtx xop0, xop1, xtarget;
1970
1971 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1972 value is one of those, use it. Otherwise, use 1 since it is the
1973 one easiest to get. */
1974 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1975 int normalizep = STORE_FLAG_VALUE;
1976 #else
1977 int normalizep = 1;
1978 #endif
1979
1980 /* Prepare the operands. */
1981 xop0 = force_reg (int_mode, op0);
1982 xop1 = force_reg (int_mode, op1);
1983
1984 xtarget = gen_reg_rtx (int_mode);
1985
1986 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1987 target = xtarget;
1988
1989 /* Indicate for flow that the entire target reg is being set. */
1990 if (REG_P (target))
1991 emit_clobber (xtarget);
1992
1993 /* Do the actual arithmetic. */
1994 for (i = 0; i < nwords; i++)
1995 {
1996 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1997 rtx target_piece = operand_subword (xtarget, index, 1, int_mode);
1998 rtx op0_piece = operand_subword_force (xop0, index, int_mode);
1999 rtx op1_piece = operand_subword_force (xop1, index, int_mode);
2000 rtx x;
2001
2002 /* Main add/subtract of the input operands. */
2003 x = expand_binop (word_mode, binoptab,
2004 op0_piece, op1_piece,
2005 target_piece, unsignedp, next_methods);
2006 if (x == 0)
2007 break;
2008
2009 if (i + 1 < nwords)
2010 {
2011 /* Store carry from main add/subtract. */
2012 carry_out = gen_reg_rtx (word_mode);
2013 carry_out = emit_store_flag_force (carry_out,
2014 (binoptab == add_optab
2015 ? LT : GT),
2016 x, op0_piece,
2017 word_mode, 1, normalizep);
2018 }
2019
2020 if (i > 0)
2021 {
2022 rtx newx;
2023
2024 /* Add/subtract previous carry to main result. */
2025 newx = expand_binop (word_mode,
2026 normalizep == 1 ? binoptab : otheroptab,
2027 x, carry_in,
2028 NULL_RTX, 1, next_methods);
2029
2030 if (i + 1 < nwords)
2031 {
2032 /* Get out carry from adding/subtracting carry in. */
2033 rtx carry_tmp = gen_reg_rtx (word_mode);
2034 carry_tmp = emit_store_flag_force (carry_tmp,
2035 (binoptab == add_optab
2036 ? LT : GT),
2037 newx, x,
2038 word_mode, 1, normalizep);
2039
2040 /* Logical-ior the two poss. carry together. */
2041 carry_out = expand_binop (word_mode, ior_optab,
2042 carry_out, carry_tmp,
2043 carry_out, 0, next_methods);
2044 if (carry_out == 0)
2045 break;
2046 }
2047 emit_move_insn (target_piece, newx);
2048 }
2049 else
2050 {
2051 if (x != target_piece)
2052 emit_move_insn (target_piece, x);
2053 }
2054
2055 carry_in = carry_out;
2056 }
2057
2058 if (i == GET_MODE_BITSIZE (int_mode) / (unsigned) BITS_PER_WORD)
2059 {
2060 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing
2061 || ! rtx_equal_p (target, xtarget))
2062 {
2063 rtx_insn *temp = emit_move_insn (target, xtarget);
2064
2065 set_dst_reg_note (temp, REG_EQUAL,
2066 gen_rtx_fmt_ee (optab_to_code (binoptab),
2067 int_mode, copy_rtx (xop0),
2068 copy_rtx (xop1)),
2069 target);
2070 }
2071 else
2072 target = xtarget;
2073
2074 return target;
2075 }
2076
2077 else
2078 delete_insns_since (last);
2079 }
2080
2081 /* Attempt to synthesize double word multiplies using a sequence of word
2082 mode multiplications. We first attempt to generate a sequence using a
2083 more efficient unsigned widening multiply, and if that fails we then
2084 try using a signed widening multiply. */
2085
2086 if (binoptab == smul_optab
2087 && is_int_mode (mode, &int_mode)
2088 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2089 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
2090 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
2091 {
2092 rtx product = NULL_RTX;
2093 if (convert_optab_handler (umul_widen_optab, int_mode, word_mode)
2094 != CODE_FOR_nothing)
2095 {
2096 product = expand_doubleword_mult (int_mode, op0, op1, target,
2097 true, methods);
2098 if (!product)
2099 delete_insns_since (last);
2100 }
2101
2102 if (product == NULL_RTX
2103 && (convert_optab_handler (smul_widen_optab, int_mode, word_mode)
2104 != CODE_FOR_nothing))
2105 {
2106 product = expand_doubleword_mult (int_mode, op0, op1, target,
2107 false, methods);
2108 if (!product)
2109 delete_insns_since (last);
2110 }
2111
2112 if (product != NULL_RTX)
2113 {
2114 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
2115 {
2116 rtx_insn *move = emit_move_insn (target ? target : product,
2117 product);
2118 set_dst_reg_note (move,
2119 REG_EQUAL,
2120 gen_rtx_fmt_ee (MULT, int_mode,
2121 copy_rtx (op0),
2122 copy_rtx (op1)),
2123 target ? target : product);
2124 }
2125 return product;
2126 }
2127 }
2128
2129 /* Attempt to synthetize double word modulo by constant divisor. */
2130 if ((binoptab == umod_optab
2131 || binoptab == smod_optab
2132 || binoptab == udiv_optab
2133 || binoptab == sdiv_optab)
2134 && optimize
2135 && CONST_INT_P (op1)
2136 && is_int_mode (mode, &int_mode)
2137 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2138 && optab_handler ((binoptab == umod_optab || binoptab == udiv_optab)
2139 ? udivmod_optab : sdivmod_optab,
2140 int_mode) == CODE_FOR_nothing
2141 && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
2142 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
2143 && optimize_insn_for_speed_p ())
2144 {
2145 rtx res = NULL_RTX;
2146 if ((binoptab == umod_optab || binoptab == smod_optab)
2147 && (INTVAL (op1) & 1) == 0)
2148 res = expand_doubleword_mod (int_mode, op0, op1,
2149 binoptab == umod_optab);
2150 else
2151 {
2152 rtx quot = expand_doubleword_divmod (int_mode, op0, op1, &res,
2153 binoptab == umod_optab
2154 || binoptab == udiv_optab);
2155 if (quot == NULL_RTX)
2156 res = NULL_RTX;
2157 else if (binoptab == udiv_optab || binoptab == sdiv_optab)
2158 res = quot;
2159 }
2160 if (res != NULL_RTX)
2161 {
2162 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
2163 {
2164 rtx_insn *move = emit_move_insn (target ? target : res,
2165 res);
2166 set_dst_reg_note (move, REG_EQUAL,
2167 gen_rtx_fmt_ee (optab_to_code (binoptab),
2168 int_mode, copy_rtx (op0), op1),
2169 target ? target : res);
2170 }
2171 return res;
2172 }
2173 else
2174 delete_insns_since (last);
2175 }
2176
2177 /* It can't be open-coded in this mode.
2178 Use a library call if one is available and caller says that's ok. */
2179
2180 libfunc = optab_libfunc (binoptab, mode);
2181 if (libfunc
2182 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2183 {
2184 rtx_insn *insns;
2185 rtx op1x = op1;
2186 machine_mode op1_mode = mode;
2187 rtx value;
2188
2189 start_sequence ();
2190
2191 if (shift_optab_p (binoptab))
2192 {
2193 op1_mode = targetm.libgcc_shift_count_mode ();
2194 /* Specify unsigned here,
2195 since negative shift counts are meaningless. */
2196 op1x = convert_to_mode (op1_mode, op1, 1);
2197 }
2198
2199 if (GET_MODE (op0) != VOIDmode
2200 && GET_MODE (op0) != mode)
2201 op0 = convert_to_mode (mode, op0, unsignedp);
2202
2203 /* Pass 1 for NO_QUEUE so we don't lose any increments
2204 if the libcall is cse'd or moved. */
2205 value = emit_library_call_value (libfunc,
2206 NULL_RTX, LCT_CONST, mode,
2207 op0, mode, op1x, op1_mode);
2208
2209 insns = get_insns ();
2210 end_sequence ();
2211
2212 bool trapv = trapv_binoptab_p (binoptab);
2213 target = gen_reg_rtx (mode);
2214 emit_libcall_block_1 (insns, target, value,
2215 trapv ? NULL_RTX
2216 : gen_rtx_fmt_ee (optab_to_code (binoptab),
2217 mode, op0, op1), trapv);
2218
2219 return target;
2220 }
2221
2222 delete_insns_since (last);
2223
2224 /* It can't be done in this mode. Can we do it in a wider mode? */
2225
2226 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2227 || methods == OPTAB_MUST_WIDEN))
2228 {
2229 /* Caller says, don't even try. */
2230 delete_insns_since (entry_last);
2231 return 0;
2232 }
2233
2234 /* Compute the value of METHODS to pass to recursive calls.
2235 Don't allow widening to be tried recursively. */
2236
2237 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2238
2239 /* Look for a wider mode of the same class for which it appears we can do
2240 the operation. */
2241
2242 if (CLASS_HAS_WIDER_MODES_P (mclass))
2243 {
2244 /* This code doesn't make sense for conversion optabs, since we
2245 wouldn't then want to extend the operands to be the same size
2246 as the result. */
2247 gcc_assert (!convert_optab_p (binoptab));
2248 FOR_EACH_WIDER_MODE (wider_mode, mode)
2249 {
2250 if (optab_handler (binoptab, wider_mode)
2251 || (methods == OPTAB_LIB
2252 && optab_libfunc (binoptab, wider_mode)))
2253 {
2254 rtx xop0 = op0, xop1 = op1;
2255 int no_extend = 0;
2256
2257 /* For certain integer operations, we need not actually extend
2258 the narrow operands, as long as we will truncate
2259 the results to the same narrowness. */
2260
2261 if ((binoptab == ior_optab || binoptab == and_optab
2262 || binoptab == xor_optab
2263 || binoptab == add_optab || binoptab == sub_optab
2264 || binoptab == smul_optab || binoptab == ashl_optab)
2265 && mclass == MODE_INT)
2266 no_extend = 1;
2267
2268 xop0 = widen_operand (xop0, wider_mode, mode,
2269 unsignedp, no_extend);
2270
2271 /* The second operand of a shift must always be extended. */
2272 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2273 no_extend && binoptab != ashl_optab);
2274
2275 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2276 unsignedp, methods);
2277 if (temp)
2278 {
2279 if (mclass != MODE_INT
2280 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2281 {
2282 if (target == 0)
2283 target = gen_reg_rtx (mode);
2284 convert_move (target, temp, 0);
2285 return target;
2286 }
2287 else
2288 return gen_lowpart (mode, temp);
2289 }
2290 else
2291 delete_insns_since (last);
2292 }
2293 }
2294 }
2295
2296 delete_insns_since (entry_last);
2297 return 0;
2298 }
2299 \f
2300 /* Expand a binary operator which has both signed and unsigned forms.
2301 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2302 signed operations.
2303
2304 If we widen unsigned operands, we may use a signed wider operation instead
2305 of an unsigned wider operation, since the result would be the same. */
2306
2307 rtx
2308 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
2309 rtx op0, rtx op1, rtx target, int unsignedp,
2310 enum optab_methods methods)
2311 {
2312 rtx temp;
2313 optab direct_optab = unsignedp ? uoptab : soptab;
2314 bool save_enable;
2315
2316 /* Do it without widening, if possible. */
2317 temp = expand_binop (mode, direct_optab, op0, op1, target,
2318 unsignedp, OPTAB_DIRECT);
2319 if (temp || methods == OPTAB_DIRECT)
2320 return temp;
2321
2322 /* Try widening to a signed int. Disable any direct use of any
2323 signed insn in the current mode. */
2324 save_enable = swap_optab_enable (soptab, mode, false);
2325
2326 temp = expand_binop (mode, soptab, op0, op1, target,
2327 unsignedp, OPTAB_WIDEN);
2328
2329 /* For unsigned operands, try widening to an unsigned int. */
2330 if (!temp && unsignedp)
2331 temp = expand_binop (mode, uoptab, op0, op1, target,
2332 unsignedp, OPTAB_WIDEN);
2333 if (temp || methods == OPTAB_WIDEN)
2334 goto egress;
2335
2336 /* Use the right width libcall if that exists. */
2337 temp = expand_binop (mode, direct_optab, op0, op1, target,
2338 unsignedp, OPTAB_LIB);
2339 if (temp || methods == OPTAB_LIB)
2340 goto egress;
2341
2342 /* Must widen and use a libcall, use either signed or unsigned. */
2343 temp = expand_binop (mode, soptab, op0, op1, target,
2344 unsignedp, methods);
2345 if (!temp && unsignedp)
2346 temp = expand_binop (mode, uoptab, op0, op1, target,
2347 unsignedp, methods);
2348
2349 egress:
2350 /* Undo the fiddling above. */
2351 if (save_enable)
2352 swap_optab_enable (soptab, mode, true);
2353 return temp;
2354 }
2355 \f
2356 /* Generate code to perform an operation specified by UNOPPTAB
2357 on operand OP0, with two results to TARG0 and TARG1.
2358 We assume that the order of the operands for the instruction
2359 is TARG0, TARG1, OP0.
2360
2361 Either TARG0 or TARG1 may be zero, but what that means is that
2362 the result is not actually wanted. We will generate it into
2363 a dummy pseudo-reg and discard it. They may not both be zero.
2364
2365 Returns 1 if this operation can be performed; 0 if not. */
2366
2367 int
2368 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2369 int unsignedp)
2370 {
2371 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2372 enum mode_class mclass;
2373 machine_mode wider_mode;
2374 rtx_insn *entry_last = get_last_insn ();
2375 rtx_insn *last;
2376
2377 mclass = GET_MODE_CLASS (mode);
2378
2379 if (!targ0)
2380 targ0 = gen_reg_rtx (mode);
2381 if (!targ1)
2382 targ1 = gen_reg_rtx (mode);
2383
2384 /* Record where to go back to if we fail. */
2385 last = get_last_insn ();
2386
2387 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2388 {
2389 class expand_operand ops[3];
2390 enum insn_code icode = optab_handler (unoptab, mode);
2391
2392 create_fixed_operand (&ops[0], targ0);
2393 create_fixed_operand (&ops[1], targ1);
2394 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2395 if (maybe_expand_insn (icode, 3, ops))
2396 return 1;
2397 }
2398
2399 /* It can't be done in this mode. Can we do it in a wider mode? */
2400
2401 if (CLASS_HAS_WIDER_MODES_P (mclass))
2402 {
2403 FOR_EACH_WIDER_MODE (wider_mode, mode)
2404 {
2405 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2406 {
2407 rtx t0 = gen_reg_rtx (wider_mode);
2408 rtx t1 = gen_reg_rtx (wider_mode);
2409 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2410
2411 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2412 {
2413 convert_move (targ0, t0, unsignedp);
2414 convert_move (targ1, t1, unsignedp);
2415 return 1;
2416 }
2417 else
2418 delete_insns_since (last);
2419 }
2420 }
2421 }
2422
2423 delete_insns_since (entry_last);
2424 return 0;
2425 }
2426 \f
2427 /* Generate code to perform an operation specified by BINOPTAB
2428 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2429 We assume that the order of the operands for the instruction
2430 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2431 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2432
2433 Either TARG0 or TARG1 may be zero, but what that means is that
2434 the result is not actually wanted. We will generate it into
2435 a dummy pseudo-reg and discard it. They may not both be zero.
2436
2437 Returns 1 if this operation can be performed; 0 if not. */
2438
2439 int
2440 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2441 int unsignedp)
2442 {
2443 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2444 enum mode_class mclass;
2445 machine_mode wider_mode;
2446 rtx_insn *entry_last = get_last_insn ();
2447 rtx_insn *last;
2448
2449 mclass = GET_MODE_CLASS (mode);
2450
2451 if (!targ0)
2452 targ0 = gen_reg_rtx (mode);
2453 if (!targ1)
2454 targ1 = gen_reg_rtx (mode);
2455
2456 /* Record where to go back to if we fail. */
2457 last = get_last_insn ();
2458
2459 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2460 {
2461 class expand_operand ops[4];
2462 enum insn_code icode = optab_handler (binoptab, mode);
2463 machine_mode mode0 = insn_data[icode].operand[1].mode;
2464 machine_mode mode1 = insn_data[icode].operand[2].mode;
2465 rtx xop0 = op0, xop1 = op1;
2466
2467 /* If we are optimizing, force expensive constants into a register. */
2468 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2469 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2470
2471 create_fixed_operand (&ops[0], targ0);
2472 create_convert_operand_from (&ops[1], xop0, mode, unsignedp);
2473 create_convert_operand_from (&ops[2], xop1, mode, unsignedp);
2474 create_fixed_operand (&ops[3], targ1);
2475 if (maybe_expand_insn (icode, 4, ops))
2476 return 1;
2477 delete_insns_since (last);
2478 }
2479
2480 /* It can't be done in this mode. Can we do it in a wider mode? */
2481
2482 if (CLASS_HAS_WIDER_MODES_P (mclass))
2483 {
2484 FOR_EACH_WIDER_MODE (wider_mode, mode)
2485 {
2486 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2487 {
2488 rtx t0 = gen_reg_rtx (wider_mode);
2489 rtx t1 = gen_reg_rtx (wider_mode);
2490 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2491 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2492
2493 if (expand_twoval_binop (binoptab, cop0, cop1,
2494 t0, t1, unsignedp))
2495 {
2496 convert_move (targ0, t0, unsignedp);
2497 convert_move (targ1, t1, unsignedp);
2498 return 1;
2499 }
2500 else
2501 delete_insns_since (last);
2502 }
2503 }
2504 }
2505
2506 delete_insns_since (entry_last);
2507 return 0;
2508 }
2509
2510 /* Expand the two-valued library call indicated by BINOPTAB, but
2511 preserve only one of the values. If TARG0 is non-NULL, the first
2512 value is placed into TARG0; otherwise the second value is placed
2513 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2514 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2515 This routine assumes that the value returned by the library call is
2516 as if the return value was of an integral mode twice as wide as the
2517 mode of OP0. Returns 1 if the call was successful. */
2518
2519 bool
2520 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2521 rtx targ0, rtx targ1, enum rtx_code code)
2522 {
2523 machine_mode mode;
2524 machine_mode libval_mode;
2525 rtx libval;
2526 rtx_insn *insns;
2527 rtx libfunc;
2528
2529 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2530 gcc_assert (!targ0 != !targ1);
2531
2532 mode = GET_MODE (op0);
2533 libfunc = optab_libfunc (binoptab, mode);
2534 if (!libfunc)
2535 return false;
2536
2537 /* The value returned by the library function will have twice as
2538 many bits as the nominal MODE. */
2539 libval_mode = smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode));
2540 start_sequence ();
2541 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2542 libval_mode,
2543 op0, mode,
2544 op1, mode);
2545 /* Get the part of VAL containing the value that we want. */
2546 libval = simplify_gen_subreg (mode, libval, libval_mode,
2547 targ0 ? 0 : GET_MODE_SIZE (mode));
2548 insns = get_insns ();
2549 end_sequence ();
2550 /* Move the into the desired location. */
2551 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2552 gen_rtx_fmt_ee (code, mode, op0, op1));
2553
2554 return true;
2555 }
2556
2557 \f
2558 /* Wrapper around expand_unop which takes an rtx code to specify
2559 the operation to perform, not an optab pointer. All other
2560 arguments are the same. */
2561 rtx
2562 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2563 rtx target, int unsignedp)
2564 {
2565 optab unop = code_to_optab (code);
2566 gcc_assert (unop);
2567
2568 return expand_unop (mode, unop, op0, target, unsignedp);
2569 }
2570
2571 /* Try calculating
2572 (clz:narrow x)
2573 as
2574 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2575
2576 A similar operation can be used for clrsb. UNOPTAB says which operation
2577 we are trying to expand. */
2578 static rtx
2579 widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
2580 {
2581 opt_scalar_int_mode wider_mode_iter;
2582 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2583 {
2584 scalar_int_mode wider_mode = wider_mode_iter.require ();
2585 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2586 {
2587 rtx xop0, temp;
2588 rtx_insn *last;
2589
2590 last = get_last_insn ();
2591
2592 if (target == 0)
2593 target = gen_reg_rtx (mode);
2594 xop0 = widen_operand (op0, wider_mode, mode,
2595 unoptab != clrsb_optab, false);
2596 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2597 unoptab != clrsb_optab);
2598 if (temp != 0)
2599 temp = expand_binop
2600 (wider_mode, sub_optab, temp,
2601 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2602 - GET_MODE_PRECISION (mode),
2603 wider_mode),
2604 target, true, OPTAB_DIRECT);
2605 if (temp == 0)
2606 delete_insns_since (last);
2607
2608 return temp;
2609 }
2610 }
2611 return 0;
2612 }
2613
2614 /* Attempt to emit (clrsb:mode op0) as
2615 (plus:mode (clz:mode (xor:mode op0 (ashr:mode op0 (const_int prec-1))))
2616 (const_int -1))
2617 if CLZ_DEFINED_VALUE_AT_ZERO (mode, val) is 2 and val is prec,
2618 or as
2619 (clz:mode (ior:mode (xor:mode (ashl:mode op0 (const_int 1))
2620 (ashr:mode op0 (const_int prec-1)))
2621 (const_int 1)))
2622 otherwise. */
2623
2624 static rtx
2625 expand_clrsb_using_clz (scalar_int_mode mode, rtx op0, rtx target)
2626 {
2627 if (optimize_insn_for_size_p ()
2628 || optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2629 return NULL_RTX;
2630
2631 start_sequence ();
2632 HOST_WIDE_INT val = 0;
2633 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) != 2
2634 || val != GET_MODE_PRECISION (mode))
2635 val = 0;
2636 else
2637 val = 1;
2638
2639 rtx temp2 = op0;
2640 if (!val)
2641 {
2642 temp2 = expand_binop (mode, ashl_optab, op0, const1_rtx,
2643 NULL_RTX, 0, OPTAB_DIRECT);
2644 if (!temp2)
2645 {
2646 fail:
2647 end_sequence ();
2648 return NULL_RTX;
2649 }
2650 }
2651
2652 rtx temp = expand_binop (mode, ashr_optab, op0,
2653 GEN_INT (GET_MODE_PRECISION (mode) - 1),
2654 NULL_RTX, 0, OPTAB_DIRECT);
2655 if (!temp)
2656 goto fail;
2657
2658 temp = expand_binop (mode, xor_optab, temp2, temp, NULL_RTX, 0,
2659 OPTAB_DIRECT);
2660 if (!temp)
2661 goto fail;
2662
2663 if (!val)
2664 {
2665 temp = expand_binop (mode, ior_optab, temp, const1_rtx,
2666 NULL_RTX, 0, OPTAB_DIRECT);
2667 if (!temp)
2668 goto fail;
2669 }
2670 temp = expand_unop_direct (mode, clz_optab, temp, val ? NULL_RTX : target,
2671 true);
2672 if (!temp)
2673 goto fail;
2674 if (val)
2675 {
2676 temp = expand_binop (mode, add_optab, temp, constm1_rtx,
2677 target, 0, OPTAB_DIRECT);
2678 if (!temp)
2679 goto fail;
2680 }
2681
2682 rtx_insn *seq = get_insns ();
2683 end_sequence ();
2684
2685 add_equal_note (seq, temp, CLRSB, op0, NULL_RTX, mode);
2686 emit_insn (seq);
2687 return temp;
2688 }
2689
2690 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2691 quantities, choosing which based on whether the high word is nonzero. */
2692 static rtx
2693 expand_doubleword_clz (scalar_int_mode mode, rtx op0, rtx target)
2694 {
2695 rtx xop0 = force_reg (mode, op0);
2696 rtx subhi = gen_highpart (word_mode, xop0);
2697 rtx sublo = gen_lowpart (word_mode, xop0);
2698 rtx_code_label *hi0_label = gen_label_rtx ();
2699 rtx_code_label *after_label = gen_label_rtx ();
2700 rtx_insn *seq;
2701 rtx temp, result;
2702
2703 /* If we were not given a target, use a word_mode register, not a
2704 'mode' register. The result will fit, and nobody is expecting
2705 anything bigger (the return type of __builtin_clz* is int). */
2706 if (!target)
2707 target = gen_reg_rtx (word_mode);
2708
2709 /* In any case, write to a word_mode scratch in both branches of the
2710 conditional, so we can ensure there is a single move insn setting
2711 'target' to tag a REG_EQUAL note on. */
2712 result = gen_reg_rtx (word_mode);
2713
2714 start_sequence ();
2715
2716 /* If the high word is not equal to zero,
2717 then clz of the full value is clz of the high word. */
2718 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2719 word_mode, true, hi0_label);
2720
2721 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2722 if (!temp)
2723 goto fail;
2724
2725 if (temp != result)
2726 convert_move (result, temp, true);
2727
2728 emit_jump_insn (targetm.gen_jump (after_label));
2729 emit_barrier ();
2730
2731 /* Else clz of the full value is clz of the low word plus the number
2732 of bits in the high word. */
2733 emit_label (hi0_label);
2734
2735 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2736 if (!temp)
2737 goto fail;
2738 temp = expand_binop (word_mode, add_optab, temp,
2739 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2740 result, true, OPTAB_DIRECT);
2741 if (!temp)
2742 goto fail;
2743 if (temp != result)
2744 convert_move (result, temp, true);
2745
2746 emit_label (after_label);
2747 convert_move (target, result, true);
2748
2749 seq = get_insns ();
2750 end_sequence ();
2751
2752 add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
2753 emit_insn (seq);
2754 return target;
2755
2756 fail:
2757 end_sequence ();
2758 return 0;
2759 }
2760
2761 /* Try calculating popcount of a double-word quantity as two popcount's of
2762 word-sized quantities and summing up the results. */
2763 static rtx
2764 expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
2765 {
2766 rtx t0, t1, t;
2767 rtx_insn *seq;
2768
2769 start_sequence ();
2770
2771 t0 = expand_unop_direct (word_mode, popcount_optab,
2772 operand_subword_force (op0, 0, mode), NULL_RTX,
2773 true);
2774 t1 = expand_unop_direct (word_mode, popcount_optab,
2775 operand_subword_force (op0, 1, mode), NULL_RTX,
2776 true);
2777 if (!t0 || !t1)
2778 {
2779 end_sequence ();
2780 return NULL_RTX;
2781 }
2782
2783 /* If we were not given a target, use a word_mode register, not a
2784 'mode' register. The result will fit, and nobody is expecting
2785 anything bigger (the return type of __builtin_popcount* is int). */
2786 if (!target)
2787 target = gen_reg_rtx (word_mode);
2788
2789 t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
2790
2791 seq = get_insns ();
2792 end_sequence ();
2793
2794 add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
2795 emit_insn (seq);
2796 return t;
2797 }
2798
2799 /* Try calculating
2800 (parity:wide x)
2801 as
2802 (parity:narrow (low (x) ^ high (x))) */
2803 static rtx
2804 expand_doubleword_parity (scalar_int_mode mode, rtx op0, rtx target)
2805 {
2806 rtx t = expand_binop (word_mode, xor_optab,
2807 operand_subword_force (op0, 0, mode),
2808 operand_subword_force (op0, 1, mode),
2809 NULL_RTX, 0, OPTAB_DIRECT);
2810 return expand_unop (word_mode, parity_optab, t, target, true);
2811 }
2812
2813 /* Try calculating
2814 (bswap:narrow x)
2815 as
2816 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2817 static rtx
2818 widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
2819 {
2820 rtx x;
2821 rtx_insn *last;
2822 opt_scalar_int_mode wider_mode_iter;
2823
2824 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2825 if (optab_handler (bswap_optab, wider_mode_iter.require ())
2826 != CODE_FOR_nothing)
2827 break;
2828
2829 if (!wider_mode_iter.exists ())
2830 return NULL_RTX;
2831
2832 scalar_int_mode wider_mode = wider_mode_iter.require ();
2833 last = get_last_insn ();
2834
2835 x = widen_operand (op0, wider_mode, mode, true, true);
2836 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2837
2838 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2839 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2840 if (x != 0)
2841 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2842 GET_MODE_BITSIZE (wider_mode)
2843 - GET_MODE_BITSIZE (mode),
2844 NULL_RTX, true);
2845
2846 if (x != 0)
2847 {
2848 if (target == 0)
2849 target = gen_reg_rtx (mode);
2850 emit_move_insn (target, gen_lowpart (mode, x));
2851 }
2852 else
2853 delete_insns_since (last);
2854
2855 return target;
2856 }
2857
2858 /* Try calculating bswap as two bswaps of two word-sized operands. */
2859
2860 static rtx
2861 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2862 {
2863 rtx t0, t1;
2864
2865 t1 = expand_unop (word_mode, bswap_optab,
2866 operand_subword_force (op, 0, mode), NULL_RTX, true);
2867 t0 = expand_unop (word_mode, bswap_optab,
2868 operand_subword_force (op, 1, mode), NULL_RTX, true);
2869
2870 if (target == 0 || !valid_multiword_target_p (target))
2871 target = gen_reg_rtx (mode);
2872 if (REG_P (target))
2873 emit_clobber (target);
2874 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2875 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2876
2877 return target;
2878 }
2879
2880 /* Try calculating (parity x) as (and (popcount x) 1), where
2881 popcount can also be done in a wider mode. */
2882 static rtx
2883 expand_parity (scalar_int_mode mode, rtx op0, rtx target)
2884 {
2885 enum mode_class mclass = GET_MODE_CLASS (mode);
2886 opt_scalar_int_mode wider_mode_iter;
2887 FOR_EACH_MODE_FROM (wider_mode_iter, mode)
2888 {
2889 scalar_int_mode wider_mode = wider_mode_iter.require ();
2890 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2891 {
2892 rtx xop0, temp;
2893 rtx_insn *last;
2894
2895 last = get_last_insn ();
2896
2897 if (target == 0 || GET_MODE (target) != wider_mode)
2898 target = gen_reg_rtx (wider_mode);
2899
2900 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2901 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2902 true);
2903 if (temp != 0)
2904 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2905 target, true, OPTAB_DIRECT);
2906
2907 if (temp)
2908 {
2909 if (mclass != MODE_INT
2910 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2911 return convert_to_mode (mode, temp, 0);
2912 else
2913 return gen_lowpart (mode, temp);
2914 }
2915 else
2916 delete_insns_since (last);
2917 }
2918 }
2919 return 0;
2920 }
2921
2922 /* Try calculating ctz(x) as K - clz(x & -x) ,
2923 where K is GET_MODE_PRECISION(mode) - 1.
2924
2925 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2926 don't have to worry about what the hardware does in that case. (If
2927 the clz instruction produces the usual value at 0, which is K, the
2928 result of this code sequence will be -1; expand_ffs, below, relies
2929 on this. It might be nice to have it be K instead, for consistency
2930 with the (very few) processors that provide a ctz with a defined
2931 value, but that would take one more instruction, and it would be
2932 less convenient for expand_ffs anyway. */
2933
2934 static rtx
2935 expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
2936 {
2937 rtx_insn *seq;
2938 rtx temp;
2939
2940 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2941 return 0;
2942
2943 start_sequence ();
2944
2945 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2946 if (temp)
2947 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2948 true, OPTAB_DIRECT);
2949 if (temp)
2950 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2951 if (temp)
2952 temp = expand_binop (mode, sub_optab,
2953 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2954 temp, target,
2955 true, OPTAB_DIRECT);
2956 if (temp == 0)
2957 {
2958 end_sequence ();
2959 return 0;
2960 }
2961
2962 seq = get_insns ();
2963 end_sequence ();
2964
2965 add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
2966 emit_insn (seq);
2967 return temp;
2968 }
2969
2970
2971 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2972 else with the sequence used by expand_clz.
2973
2974 The ffs builtin promises to return zero for a zero value and ctz/clz
2975 may have an undefined value in that case. If they do not give us a
2976 convenient value, we have to generate a test and branch. */
2977 static rtx
2978 expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
2979 {
2980 HOST_WIDE_INT val = 0;
2981 bool defined_at_zero = false;
2982 rtx temp;
2983 rtx_insn *seq;
2984
2985 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2986 {
2987 start_sequence ();
2988
2989 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2990 if (!temp)
2991 goto fail;
2992
2993 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2994 }
2995 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2996 {
2997 start_sequence ();
2998 temp = expand_ctz (mode, op0, 0);
2999 if (!temp)
3000 goto fail;
3001
3002 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
3003 {
3004 defined_at_zero = true;
3005 val = (GET_MODE_PRECISION (mode) - 1) - val;
3006 }
3007 }
3008 else
3009 return 0;
3010
3011 if (defined_at_zero && val == -1)
3012 /* No correction needed at zero. */;
3013 else
3014 {
3015 /* We don't try to do anything clever with the situation found
3016 on some processors (eg Alpha) where ctz(0:mode) ==
3017 bitsize(mode). If someone can think of a way to send N to -1
3018 and leave alone all values in the range 0..N-1 (where N is a
3019 power of two), cheaper than this test-and-branch, please add it.
3020
3021 The test-and-branch is done after the operation itself, in case
3022 the operation sets condition codes that can be recycled for this.
3023 (This is true on i386, for instance.) */
3024
3025 rtx_code_label *nonzero_label = gen_label_rtx ();
3026 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
3027 mode, true, nonzero_label);
3028
3029 convert_move (temp, GEN_INT (-1), false);
3030 emit_label (nonzero_label);
3031 }
3032
3033 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
3034 to produce a value in the range 0..bitsize. */
3035 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
3036 target, false, OPTAB_DIRECT);
3037 if (!temp)
3038 goto fail;
3039
3040 seq = get_insns ();
3041 end_sequence ();
3042
3043 add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
3044 emit_insn (seq);
3045 return temp;
3046
3047 fail:
3048 end_sequence ();
3049 return 0;
3050 }
3051
3052 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
3053 conditions, VAL may already be a SUBREG against which we cannot generate
3054 a further SUBREG. In this case, we expect forcing the value into a
3055 register will work around the situation. */
3056
3057 static rtx
3058 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
3059 machine_mode imode)
3060 {
3061 rtx ret;
3062 ret = lowpart_subreg (omode, val, imode);
3063 if (ret == NULL)
3064 {
3065 val = force_reg (imode, val);
3066 ret = lowpart_subreg (omode, val, imode);
3067 gcc_assert (ret != NULL);
3068 }
3069 return ret;
3070 }
3071
3072 /* Expand a floating point absolute value or negation operation via a
3073 logical operation on the sign bit. */
3074
3075 static rtx
3076 expand_absneg_bit (enum rtx_code code, scalar_float_mode mode,
3077 rtx op0, rtx target)
3078 {
3079 const struct real_format *fmt;
3080 int bitpos, word, nwords, i;
3081 scalar_int_mode imode;
3082 rtx temp;
3083 rtx_insn *insns;
3084
3085 /* The format has to have a simple sign bit. */
3086 fmt = REAL_MODE_FORMAT (mode);
3087 if (fmt == NULL)
3088 return NULL_RTX;
3089
3090 bitpos = fmt->signbit_rw;
3091 if (bitpos < 0)
3092 return NULL_RTX;
3093
3094 /* Don't create negative zeros if the format doesn't support them. */
3095 if (code == NEG && !fmt->has_signed_zero)
3096 return NULL_RTX;
3097
3098 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3099 {
3100 if (!int_mode_for_mode (mode).exists (&imode))
3101 return NULL_RTX;
3102 word = 0;
3103 nwords = 1;
3104 }
3105 else
3106 {
3107 imode = word_mode;
3108
3109 if (FLOAT_WORDS_BIG_ENDIAN)
3110 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3111 else
3112 word = bitpos / BITS_PER_WORD;
3113 bitpos = bitpos % BITS_PER_WORD;
3114 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3115 }
3116
3117 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3118 if (code == ABS)
3119 mask = ~mask;
3120
3121 if (target == 0
3122 || target == op0
3123 || reg_overlap_mentioned_p (target, op0)
3124 || (nwords > 1 && !valid_multiword_target_p (target)))
3125 target = gen_reg_rtx (mode);
3126
3127 if (nwords > 1)
3128 {
3129 start_sequence ();
3130
3131 for (i = 0; i < nwords; ++i)
3132 {
3133 rtx targ_piece = operand_subword (target, i, 1, mode);
3134 rtx op0_piece = operand_subword_force (op0, i, mode);
3135
3136 if (i == word)
3137 {
3138 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3139 op0_piece,
3140 immed_wide_int_const (mask, imode),
3141 targ_piece, 1, OPTAB_LIB_WIDEN);
3142 if (temp != targ_piece)
3143 emit_move_insn (targ_piece, temp);
3144 }
3145 else
3146 emit_move_insn (targ_piece, op0_piece);
3147 }
3148
3149 insns = get_insns ();
3150 end_sequence ();
3151
3152 emit_insn (insns);
3153 }
3154 else
3155 {
3156 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3157 gen_lowpart (imode, op0),
3158 immed_wide_int_const (mask, imode),
3159 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3160 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3161
3162 set_dst_reg_note (get_last_insn (), REG_EQUAL,
3163 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
3164 target);
3165 }
3166
3167 return target;
3168 }
3169
3170 /* As expand_unop, but will fail rather than attempt the operation in a
3171 different mode or with a libcall. */
3172 static rtx
3173 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
3174 int unsignedp)
3175 {
3176 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
3177 {
3178 class expand_operand ops[2];
3179 enum insn_code icode = optab_handler (unoptab, mode);
3180 rtx_insn *last = get_last_insn ();
3181 rtx_insn *pat;
3182
3183 create_output_operand (&ops[0], target, mode);
3184 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
3185 pat = maybe_gen_insn (icode, 2, ops);
3186 if (pat)
3187 {
3188 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3189 && ! add_equal_note (pat, ops[0].value,
3190 optab_to_code (unoptab),
3191 ops[1].value, NULL_RTX, mode))
3192 {
3193 delete_insns_since (last);
3194 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
3195 }
3196
3197 emit_insn (pat);
3198
3199 return ops[0].value;
3200 }
3201 }
3202 return 0;
3203 }
3204
3205 /* Generate code to perform an operation specified by UNOPTAB
3206 on operand OP0, with result having machine-mode MODE.
3207
3208 UNSIGNEDP is for the case where we have to widen the operands
3209 to perform the operation. It says to use zero-extension.
3210
3211 If TARGET is nonzero, the value
3212 is generated there, if it is convenient to do so.
3213 In all cases an rtx is returned for the locus of the value;
3214 this may or may not be TARGET. */
3215
3216 rtx
3217 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
3218 int unsignedp)
3219 {
3220 enum mode_class mclass = GET_MODE_CLASS (mode);
3221 machine_mode wider_mode;
3222 scalar_int_mode int_mode;
3223 scalar_float_mode float_mode;
3224 rtx temp;
3225 rtx libfunc;
3226
3227 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3228 if (temp)
3229 return temp;
3230
3231 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3232
3233 /* Widening (or narrowing) clz needs special treatment. */
3234 if (unoptab == clz_optab)
3235 {
3236 if (is_a <scalar_int_mode> (mode, &int_mode))
3237 {
3238 temp = widen_leading (int_mode, op0, target, unoptab);
3239 if (temp)
3240 return temp;
3241
3242 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3243 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3244 {
3245 temp = expand_doubleword_clz (int_mode, op0, target);
3246 if (temp)
3247 return temp;
3248 }
3249 }
3250
3251 goto try_libcall;
3252 }
3253
3254 if (unoptab == clrsb_optab)
3255 {
3256 if (is_a <scalar_int_mode> (mode, &int_mode))
3257 {
3258 temp = widen_leading (int_mode, op0, target, unoptab);
3259 if (temp)
3260 return temp;
3261 temp = expand_clrsb_using_clz (int_mode, op0, target);
3262 if (temp)
3263 return temp;
3264 }
3265 goto try_libcall;
3266 }
3267
3268 if (unoptab == popcount_optab
3269 && is_a <scalar_int_mode> (mode, &int_mode)
3270 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3271 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
3272 && optimize_insn_for_speed_p ())
3273 {
3274 temp = expand_doubleword_popcount (int_mode, op0, target);
3275 if (temp)
3276 return temp;
3277 }
3278
3279 if (unoptab == parity_optab
3280 && is_a <scalar_int_mode> (mode, &int_mode)
3281 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3282 && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
3283 || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
3284 && optimize_insn_for_speed_p ())
3285 {
3286 temp = expand_doubleword_parity (int_mode, op0, target);
3287 if (temp)
3288 return temp;
3289 }
3290
3291 /* Widening (or narrowing) bswap needs special treatment. */
3292 if (unoptab == bswap_optab)
3293 {
3294 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3295 or ROTATERT. First try these directly; if this fails, then try the
3296 obvious pair of shifts with allowed widening, as this will probably
3297 be always more efficient than the other fallback methods. */
3298 if (mode == HImode)
3299 {
3300 rtx_insn *last;
3301 rtx temp1, temp2;
3302
3303 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
3304 {
3305 temp = expand_binop (mode, rotl_optab, op0,
3306 gen_int_shift_amount (mode, 8),
3307 target, unsignedp, OPTAB_DIRECT);
3308 if (temp)
3309 return temp;
3310 }
3311
3312 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
3313 {
3314 temp = expand_binop (mode, rotr_optab, op0,
3315 gen_int_shift_amount (mode, 8),
3316 target, unsignedp, OPTAB_DIRECT);
3317 if (temp)
3318 return temp;
3319 }
3320
3321 last = get_last_insn ();
3322
3323 temp1 = expand_binop (mode, ashl_optab, op0,
3324 gen_int_shift_amount (mode, 8), NULL_RTX,
3325 unsignedp, OPTAB_WIDEN);
3326 temp2 = expand_binop (mode, lshr_optab, op0,
3327 gen_int_shift_amount (mode, 8), NULL_RTX,
3328 unsignedp, OPTAB_WIDEN);
3329 if (temp1 && temp2)
3330 {
3331 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
3332 unsignedp, OPTAB_WIDEN);
3333 if (temp)
3334 return temp;
3335 }
3336
3337 delete_insns_since (last);
3338 }
3339
3340 if (is_a <scalar_int_mode> (mode, &int_mode))
3341 {
3342 temp = widen_bswap (int_mode, op0, target);
3343 if (temp)
3344 return temp;
3345
3346 /* We do not provide a 128-bit bswap in libgcc so force the use of
3347 a double bswap for 64-bit targets. */
3348 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3349 && (UNITS_PER_WORD == 8
3350 || optab_handler (unoptab, word_mode) != CODE_FOR_nothing))
3351 {
3352 temp = expand_doubleword_bswap (mode, op0, target);
3353 if (temp)
3354 return temp;
3355 }
3356 }
3357
3358 goto try_libcall;
3359 }
3360
3361 if (CLASS_HAS_WIDER_MODES_P (mclass))
3362 FOR_EACH_WIDER_MODE (wider_mode, mode)
3363 {
3364 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
3365 {
3366 rtx xop0 = op0;
3367 rtx_insn *last = get_last_insn ();
3368
3369 /* For certain operations, we need not actually extend
3370 the narrow operand, as long as we will truncate the
3371 results to the same narrowness. */
3372
3373 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3374 (unoptab == neg_optab
3375 || unoptab == one_cmpl_optab)
3376 && mclass == MODE_INT);
3377
3378 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3379 unsignedp);
3380
3381 if (temp)
3382 {
3383 if (mclass != MODE_INT
3384 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
3385 {
3386 if (target == 0)
3387 target = gen_reg_rtx (mode);
3388 convert_move (target, temp, 0);
3389 return target;
3390 }
3391 else
3392 return gen_lowpart (mode, temp);
3393 }
3394 else
3395 delete_insns_since (last);
3396 }
3397 }
3398
3399 /* These can be done a word at a time. */
3400 if (unoptab == one_cmpl_optab
3401 && is_int_mode (mode, &int_mode)
3402 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
3403 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3404 {
3405 int i;
3406 rtx_insn *insns;
3407
3408 if (target == 0
3409 || target == op0
3410 || reg_overlap_mentioned_p (target, op0)
3411 || !valid_multiword_target_p (target))
3412 target = gen_reg_rtx (int_mode);
3413
3414 start_sequence ();
3415
3416 /* Do the actual arithmetic. */
3417 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
3418 {
3419 rtx target_piece = operand_subword (target, i, 1, int_mode);
3420 rtx x = expand_unop (word_mode, unoptab,
3421 operand_subword_force (op0, i, int_mode),
3422 target_piece, unsignedp);
3423
3424 if (target_piece != x)
3425 emit_move_insn (target_piece, x);
3426 }
3427
3428 insns = get_insns ();
3429 end_sequence ();
3430
3431 emit_insn (insns);
3432 return target;
3433 }
3434
3435 /* Emit ~op0 as op0 ^ -1. */
3436 if (unoptab == one_cmpl_optab
3437 && (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3438 && optab_handler (xor_optab, mode) != CODE_FOR_nothing)
3439 {
3440 temp = expand_binop (mode, xor_optab, op0, CONSTM1_RTX (mode),
3441 target, unsignedp, OPTAB_DIRECT);
3442 if (temp)
3443 return temp;
3444 }
3445
3446 if (optab_to_code (unoptab) == NEG)
3447 {
3448 /* Try negating floating point values by flipping the sign bit. */
3449 if (is_a <scalar_float_mode> (mode, &float_mode))
3450 {
3451 temp = expand_absneg_bit (NEG, float_mode, op0, target);
3452 if (temp)
3453 return temp;
3454 }
3455
3456 /* If there is no negation pattern, and we have no negative zero,
3457 try subtracting from zero. */
3458 if (!HONOR_SIGNED_ZEROS (mode))
3459 {
3460 temp = expand_binop (mode, (unoptab == negv_optab
3461 ? subv_optab : sub_optab),
3462 CONST0_RTX (mode), op0, target,
3463 unsignedp, OPTAB_DIRECT);
3464 if (temp)
3465 return temp;
3466 }
3467 }
3468
3469 /* Try calculating parity (x) as popcount (x) % 2. */
3470 if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
3471 {
3472 temp = expand_parity (int_mode, op0, target);
3473 if (temp)
3474 return temp;
3475 }
3476
3477 /* Try implementing ffs (x) in terms of clz (x). */
3478 if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
3479 {
3480 temp = expand_ffs (int_mode, op0, target);
3481 if (temp)
3482 return temp;
3483 }
3484
3485 /* Try implementing ctz (x) in terms of clz (x). */
3486 if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
3487 {
3488 temp = expand_ctz (int_mode, op0, target);
3489 if (temp)
3490 return temp;
3491 }
3492
3493 try_libcall:
3494 /* Now try a library call in this mode. */
3495 libfunc = optab_libfunc (unoptab, mode);
3496 if (libfunc)
3497 {
3498 rtx_insn *insns;
3499 rtx value;
3500 rtx eq_value;
3501 machine_mode outmode = mode;
3502
3503 /* All of these functions return small values. Thus we choose to
3504 have them return something that isn't a double-word. */
3505 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3506 || unoptab == clrsb_optab || unoptab == popcount_optab
3507 || unoptab == parity_optab)
3508 outmode
3509 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3510 optab_libfunc (unoptab, mode)));
3511
3512 start_sequence ();
3513
3514 /* Pass 1 for NO_QUEUE so we don't lose any increments
3515 if the libcall is cse'd or moved. */
3516 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3517 op0, mode);
3518 insns = get_insns ();
3519 end_sequence ();
3520
3521 target = gen_reg_rtx (outmode);
3522 bool trapv = trapv_unoptab_p (unoptab);
3523 if (trapv)
3524 eq_value = NULL_RTX;
3525 else
3526 {
3527 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3528 if (GET_MODE_UNIT_SIZE (outmode) < GET_MODE_UNIT_SIZE (mode))
3529 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3530 else if (GET_MODE_UNIT_SIZE (outmode) > GET_MODE_UNIT_SIZE (mode))
3531 eq_value = simplify_gen_unary (ZERO_EXTEND,
3532 outmode, eq_value, mode);
3533 }
3534 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
3535
3536 return target;
3537 }
3538
3539 /* It can't be done in this mode. Can we do it in a wider mode? */
3540
3541 if (CLASS_HAS_WIDER_MODES_P (mclass))
3542 {
3543 FOR_EACH_WIDER_MODE (wider_mode, mode)
3544 {
3545 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3546 || optab_libfunc (unoptab, wider_mode))
3547 {
3548 rtx xop0 = op0;
3549 rtx_insn *last = get_last_insn ();
3550
3551 /* For certain operations, we need not actually extend
3552 the narrow operand, as long as we will truncate the
3553 results to the same narrowness. */
3554 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3555 (unoptab == neg_optab
3556 || unoptab == one_cmpl_optab
3557 || unoptab == bswap_optab)
3558 && mclass == MODE_INT);
3559
3560 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3561 unsignedp);
3562
3563 /* If we are generating clz using wider mode, adjust the
3564 result. Similarly for clrsb. */
3565 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3566 && temp != 0)
3567 {
3568 scalar_int_mode wider_int_mode
3569 = as_a <scalar_int_mode> (wider_mode);
3570 int_mode = as_a <scalar_int_mode> (mode);
3571 temp = expand_binop
3572 (wider_mode, sub_optab, temp,
3573 gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
3574 - GET_MODE_PRECISION (int_mode),
3575 wider_int_mode),
3576 target, true, OPTAB_DIRECT);
3577 }
3578
3579 /* Likewise for bswap. */
3580 if (unoptab == bswap_optab && temp != 0)
3581 {
3582 scalar_int_mode wider_int_mode
3583 = as_a <scalar_int_mode> (wider_mode);
3584 int_mode = as_a <scalar_int_mode> (mode);
3585 gcc_assert (GET_MODE_PRECISION (wider_int_mode)
3586 == GET_MODE_BITSIZE (wider_int_mode)
3587 && GET_MODE_PRECISION (int_mode)
3588 == GET_MODE_BITSIZE (int_mode));
3589
3590 temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
3591 GET_MODE_BITSIZE (wider_int_mode)
3592 - GET_MODE_BITSIZE (int_mode),
3593 NULL_RTX, true);
3594 }
3595
3596 if (temp)
3597 {
3598 if (mclass != MODE_INT)
3599 {
3600 if (target == 0)
3601 target = gen_reg_rtx (mode);
3602 convert_move (target, temp, 0);
3603 return target;
3604 }
3605 else
3606 return gen_lowpart (mode, temp);
3607 }
3608 else
3609 delete_insns_since (last);
3610 }
3611 }
3612 }
3613
3614 /* One final attempt at implementing negation via subtraction,
3615 this time allowing widening of the operand. */
3616 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3617 {
3618 rtx temp;
3619 temp = expand_binop (mode,
3620 unoptab == negv_optab ? subv_optab : sub_optab,
3621 CONST0_RTX (mode), op0,
3622 target, unsignedp, OPTAB_LIB_WIDEN);
3623 if (temp)
3624 return temp;
3625 }
3626
3627 return 0;
3628 }
3629 \f
3630 /* Emit code to compute the absolute value of OP0, with result to
3631 TARGET if convenient. (TARGET may be 0.) The return value says
3632 where the result actually is to be found.
3633
3634 MODE is the mode of the operand; the mode of the result is
3635 different but can be deduced from MODE.
3636
3637 */
3638
3639 rtx
3640 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3641 int result_unsignedp)
3642 {
3643 rtx temp;
3644
3645 if (GET_MODE_CLASS (mode) != MODE_INT
3646 || ! flag_trapv)
3647 result_unsignedp = 1;
3648
3649 /* First try to do it with a special abs instruction. */
3650 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3651 op0, target, 0);
3652 if (temp != 0)
3653 return temp;
3654
3655 /* For floating point modes, try clearing the sign bit. */
3656 scalar_float_mode float_mode;
3657 if (is_a <scalar_float_mode> (mode, &float_mode))
3658 {
3659 temp = expand_absneg_bit (ABS, float_mode, op0, target);
3660 if (temp)
3661 return temp;
3662 }
3663
3664 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3665 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3666 && !HONOR_SIGNED_ZEROS (mode))
3667 {
3668 rtx_insn *last = get_last_insn ();
3669
3670 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3671 op0, NULL_RTX, 0);
3672 if (temp != 0)
3673 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3674 OPTAB_WIDEN);
3675
3676 if (temp != 0)
3677 return temp;
3678
3679 delete_insns_since (last);
3680 }
3681
3682 /* If this machine has expensive jumps, we can do integer absolute
3683 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3684 where W is the width of MODE. */
3685
3686 scalar_int_mode int_mode;
3687 if (is_int_mode (mode, &int_mode)
3688 && BRANCH_COST (optimize_insn_for_speed_p (),
3689 false) >= 2)
3690 {
3691 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3692 GET_MODE_PRECISION (int_mode) - 1,
3693 NULL_RTX, 0);
3694
3695 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3696 OPTAB_LIB_WIDEN);
3697 if (temp != 0)
3698 temp = expand_binop (int_mode,
3699 result_unsignedp ? sub_optab : subv_optab,
3700 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3701
3702 if (temp != 0)
3703 return temp;
3704 }
3705
3706 return NULL_RTX;
3707 }
3708
3709 rtx
3710 expand_abs (machine_mode mode, rtx op0, rtx target,
3711 int result_unsignedp, int safe)
3712 {
3713 rtx temp;
3714 rtx_code_label *op1;
3715
3716 if (GET_MODE_CLASS (mode) != MODE_INT
3717 || ! flag_trapv)
3718 result_unsignedp = 1;
3719
3720 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3721 if (temp != 0)
3722 return temp;
3723
3724 /* If that does not win, use conditional jump and negate. */
3725
3726 /* It is safe to use the target if it is the same
3727 as the source if this is also a pseudo register */
3728 if (op0 == target && REG_P (op0)
3729 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3730 safe = 1;
3731
3732 op1 = gen_label_rtx ();
3733 if (target == 0 || ! safe
3734 || GET_MODE (target) != mode
3735 || (MEM_P (target) && MEM_VOLATILE_P (target))
3736 || (REG_P (target)
3737 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3738 target = gen_reg_rtx (mode);
3739
3740 emit_move_insn (target, op0);
3741 NO_DEFER_POP;
3742
3743 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3744 NULL_RTX, NULL, op1,
3745 profile_probability::uninitialized ());
3746
3747 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3748 target, target, 0);
3749 if (op0 != target)
3750 emit_move_insn (target, op0);
3751 emit_label (op1);
3752 OK_DEFER_POP;
3753 return target;
3754 }
3755
3756 /* Emit code to compute the one's complement absolute value of OP0
3757 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3758 (TARGET may be NULL_RTX.) The return value says where the result
3759 actually is to be found.
3760
3761 MODE is the mode of the operand; the mode of the result is
3762 different but can be deduced from MODE. */
3763
3764 rtx
3765 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3766 {
3767 rtx temp;
3768
3769 /* Not applicable for floating point modes. */
3770 if (FLOAT_MODE_P (mode))
3771 return NULL_RTX;
3772
3773 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3774 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3775 {
3776 rtx_insn *last = get_last_insn ();
3777
3778 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3779 if (temp != 0)
3780 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3781 OPTAB_WIDEN);
3782
3783 if (temp != 0)
3784 return temp;
3785
3786 delete_insns_since (last);
3787 }
3788
3789 /* If this machine has expensive jumps, we can do one's complement
3790 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3791
3792 scalar_int_mode int_mode;
3793 if (is_int_mode (mode, &int_mode)
3794 && BRANCH_COST (optimize_insn_for_speed_p (),
3795 false) >= 2)
3796 {
3797 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3798 GET_MODE_PRECISION (int_mode) - 1,
3799 NULL_RTX, 0);
3800
3801 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3802 OPTAB_LIB_WIDEN);
3803
3804 if (temp != 0)
3805 return temp;
3806 }
3807
3808 return NULL_RTX;
3809 }
3810
3811 /* A subroutine of expand_copysign, perform the copysign operation using the
3812 abs and neg primitives advertised to exist on the target. The assumption
3813 is that we have a split register file, and leaving op0 in fp registers,
3814 and not playing with subregs so much, will help the register allocator. */
3815
3816 static rtx
3817 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3818 int bitpos, bool op0_is_abs)
3819 {
3820 scalar_int_mode imode;
3821 enum insn_code icode;
3822 rtx sign;
3823 rtx_code_label *label;
3824
3825 if (target == op1)
3826 target = NULL_RTX;
3827
3828 /* Check if the back end provides an insn that handles signbit for the
3829 argument's mode. */
3830 icode = optab_handler (signbit_optab, mode);
3831 if (icode != CODE_FOR_nothing)
3832 {
3833 imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
3834 sign = gen_reg_rtx (imode);
3835 emit_unop_insn (icode, sign, op1, UNKNOWN);
3836 }
3837 else
3838 {
3839 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3840 {
3841 if (!int_mode_for_mode (mode).exists (&imode))
3842 return NULL_RTX;
3843 op1 = gen_lowpart (imode, op1);
3844 }
3845 else
3846 {
3847 int word;
3848
3849 imode = word_mode;
3850 if (FLOAT_WORDS_BIG_ENDIAN)
3851 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3852 else
3853 word = bitpos / BITS_PER_WORD;
3854 bitpos = bitpos % BITS_PER_WORD;
3855 op1 = operand_subword_force (op1, word, mode);
3856 }
3857
3858 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3859 sign = expand_binop (imode, and_optab, op1,
3860 immed_wide_int_const (mask, imode),
3861 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3862 }
3863
3864 if (!op0_is_abs)
3865 {
3866 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3867 if (op0 == NULL)
3868 return NULL_RTX;
3869 target = op0;
3870 }
3871 else
3872 {
3873 if (target == NULL_RTX)
3874 target = copy_to_reg (op0);
3875 else
3876 emit_move_insn (target, op0);
3877 }
3878
3879 label = gen_label_rtx ();
3880 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3881
3882 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3883 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3884 else
3885 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3886 if (op0 != target)
3887 emit_move_insn (target, op0);
3888
3889 emit_label (label);
3890
3891 return target;
3892 }
3893
3894
3895 /* A subroutine of expand_copysign, perform the entire copysign operation
3896 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3897 is true if op0 is known to have its sign bit clear. */
3898
3899 static rtx
3900 expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3901 int bitpos, bool op0_is_abs)
3902 {
3903 scalar_int_mode imode;
3904 int word, nwords, i;
3905 rtx temp;
3906 rtx_insn *insns;
3907
3908 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3909 {
3910 if (!int_mode_for_mode (mode).exists (&imode))
3911 return NULL_RTX;
3912 word = 0;
3913 nwords = 1;
3914 }
3915 else
3916 {
3917 imode = word_mode;
3918
3919 if (FLOAT_WORDS_BIG_ENDIAN)
3920 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3921 else
3922 word = bitpos / BITS_PER_WORD;
3923 bitpos = bitpos % BITS_PER_WORD;
3924 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3925 }
3926
3927 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3928
3929 if (target == 0
3930 || target == op0
3931 || target == op1
3932 || reg_overlap_mentioned_p (target, op0)
3933 || reg_overlap_mentioned_p (target, op1)
3934 || (nwords > 1 && !valid_multiword_target_p (target)))
3935 target = gen_reg_rtx (mode);
3936
3937 if (nwords > 1)
3938 {
3939 start_sequence ();
3940
3941 for (i = 0; i < nwords; ++i)
3942 {
3943 rtx targ_piece = operand_subword (target, i, 1, mode);
3944 rtx op0_piece = operand_subword_force (op0, i, mode);
3945
3946 if (i == word)
3947 {
3948 if (!op0_is_abs)
3949 op0_piece
3950 = expand_binop (imode, and_optab, op0_piece,
3951 immed_wide_int_const (~mask, imode),
3952 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3953 op1 = expand_binop (imode, and_optab,
3954 operand_subword_force (op1, i, mode),
3955 immed_wide_int_const (mask, imode),
3956 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3957
3958 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3959 targ_piece, 1, OPTAB_LIB_WIDEN);
3960 if (temp != targ_piece)
3961 emit_move_insn (targ_piece, temp);
3962 }
3963 else
3964 emit_move_insn (targ_piece, op0_piece);
3965 }
3966
3967 insns = get_insns ();
3968 end_sequence ();
3969
3970 emit_insn (insns);
3971 }
3972 else
3973 {
3974 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3975 immed_wide_int_const (mask, imode),
3976 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3977
3978 op0 = gen_lowpart (imode, op0);
3979 if (!op0_is_abs)
3980 op0 = expand_binop (imode, and_optab, op0,
3981 immed_wide_int_const (~mask, imode),
3982 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3983
3984 temp = expand_binop (imode, ior_optab, op0, op1,
3985 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3986 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3987 }
3988
3989 return target;
3990 }
3991
3992 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3993 scalar floating point mode. Return NULL if we do not know how to
3994 expand the operation inline. */
3995
3996 rtx
3997 expand_copysign (rtx op0, rtx op1, rtx target)
3998 {
3999 scalar_float_mode mode;
4000 const struct real_format *fmt;
4001 bool op0_is_abs;
4002 rtx temp;
4003
4004 mode = as_a <scalar_float_mode> (GET_MODE (op0));
4005 gcc_assert (GET_MODE (op1) == mode);
4006
4007 /* First try to do it with a special instruction. */
4008 temp = expand_binop (mode, copysign_optab, op0, op1,
4009 target, 0, OPTAB_DIRECT);
4010 if (temp)
4011 return temp;
4012
4013 fmt = REAL_MODE_FORMAT (mode);
4014 if (fmt == NULL || !fmt->has_signed_zero)
4015 return NULL_RTX;
4016
4017 op0_is_abs = false;
4018 if (CONST_DOUBLE_AS_FLOAT_P (op0))
4019 {
4020 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
4021 op0 = simplify_unary_operation (ABS, mode, op0, mode);
4022 op0_is_abs = true;
4023 }
4024
4025 if (fmt->signbit_ro >= 0
4026 && (CONST_DOUBLE_AS_FLOAT_P (op0)
4027 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
4028 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
4029 {
4030 temp = expand_copysign_absneg (mode, op0, op1, target,
4031 fmt->signbit_ro, op0_is_abs);
4032 if (temp)
4033 return temp;
4034 }
4035
4036 if (fmt->signbit_rw < 0)
4037 return NULL_RTX;
4038 return expand_copysign_bit (mode, op0, op1, target,
4039 fmt->signbit_rw, op0_is_abs);
4040 }
4041 \f
4042 /* Generate an instruction whose insn-code is INSN_CODE,
4043 with two operands: an output TARGET and an input OP0.
4044 TARGET *must* be nonzero, and the output is always stored there.
4045 CODE is an rtx code such that (CODE OP0) is an rtx that describes
4046 the value that is stored into TARGET.
4047
4048 Return false if expansion failed. */
4049
4050 bool
4051 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
4052 enum rtx_code code)
4053 {
4054 class expand_operand ops[2];
4055 rtx_insn *pat;
4056
4057 create_output_operand (&ops[0], target, GET_MODE (target));
4058 create_input_operand (&ops[1], op0, GET_MODE (op0));
4059 pat = maybe_gen_insn (icode, 2, ops);
4060 if (!pat)
4061 return false;
4062
4063 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
4064 && code != UNKNOWN)
4065 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
4066 GET_MODE (op0));
4067
4068 emit_insn (pat);
4069
4070 if (ops[0].value != target)
4071 emit_move_insn (target, ops[0].value);
4072 return true;
4073 }
4074 /* Generate an instruction whose insn-code is INSN_CODE,
4075 with two operands: an output TARGET and an input OP0.
4076 TARGET *must* be nonzero, and the output is always stored there.
4077 CODE is an rtx code such that (CODE OP0) is an rtx that describes
4078 the value that is stored into TARGET. */
4079
4080 void
4081 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
4082 {
4083 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
4084 gcc_assert (ok);
4085 }
4086 \f
4087 struct no_conflict_data
4088 {
4089 rtx target;
4090 rtx_insn *first, *insn;
4091 bool must_stay;
4092 };
4093
4094 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
4095 the currently examined clobber / store has to stay in the list of
4096 insns that constitute the actual libcall block. */
4097 static void
4098 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
4099 {
4100 struct no_conflict_data *p= (struct no_conflict_data *) p0;
4101
4102 /* If this inns directly contributes to setting the target, it must stay. */
4103 if (reg_overlap_mentioned_p (p->target, dest))
4104 p->must_stay = true;
4105 /* If we haven't committed to keeping any other insns in the list yet,
4106 there is nothing more to check. */
4107 else if (p->insn == p->first)
4108 return;
4109 /* If this insn sets / clobbers a register that feeds one of the insns
4110 already in the list, this insn has to stay too. */
4111 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
4112 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
4113 || reg_used_between_p (dest, p->first, p->insn)
4114 /* Likewise if this insn depends on a register set by a previous
4115 insn in the list, or if it sets a result (presumably a hard
4116 register) that is set or clobbered by a previous insn.
4117 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
4118 SET_DEST perform the former check on the address, and the latter
4119 check on the MEM. */
4120 || (GET_CODE (set) == SET
4121 && (modified_in_p (SET_SRC (set), p->first)
4122 || modified_in_p (SET_DEST (set), p->first)
4123 || modified_between_p (SET_SRC (set), p->first, p->insn)
4124 || modified_between_p (SET_DEST (set), p->first, p->insn))))
4125 p->must_stay = true;
4126 }
4127
4128 \f
4129 /* Emit code to make a call to a constant function or a library call.
4130
4131 INSNS is a list containing all insns emitted in the call.
4132 These insns leave the result in RESULT. Our block is to copy RESULT
4133 to TARGET, which is logically equivalent to EQUIV.
4134
4135 We first emit any insns that set a pseudo on the assumption that these are
4136 loading constants into registers; doing so allows them to be safely cse'ed
4137 between blocks. Then we emit all the other insns in the block, followed by
4138 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
4139 note with an operand of EQUIV. */
4140
4141 static void
4142 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
4143 bool equiv_may_trap)
4144 {
4145 rtx final_dest = target;
4146 rtx_insn *next, *last, *insn;
4147
4148 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
4149 into a MEM later. Protect the libcall block from this change. */
4150 if (! REG_P (target) || REG_USERVAR_P (target))
4151 target = gen_reg_rtx (GET_MODE (target));
4152
4153 /* If we're using non-call exceptions, a libcall corresponding to an
4154 operation that may trap may also trap. */
4155 /* ??? See the comment in front of make_reg_eh_region_note. */
4156 if (cfun->can_throw_non_call_exceptions
4157 && (equiv_may_trap || may_trap_p (equiv)))
4158 {
4159 for (insn = insns; insn; insn = NEXT_INSN (insn))
4160 if (CALL_P (insn))
4161 {
4162 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
4163 if (note)
4164 {
4165 int lp_nr = INTVAL (XEXP (note, 0));
4166 if (lp_nr == 0 || lp_nr == INT_MIN)
4167 remove_note (insn, note);
4168 }
4169 }
4170 }
4171 else
4172 {
4173 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
4174 reg note to indicate that this call cannot throw or execute a nonlocal
4175 goto (unless there is already a REG_EH_REGION note, in which case
4176 we update it). */
4177 for (insn = insns; insn; insn = NEXT_INSN (insn))
4178 if (CALL_P (insn))
4179 make_reg_eh_region_note_nothrow_nononlocal (insn);
4180 }
4181
4182 /* First emit all insns that set pseudos. Remove them from the list as
4183 we go. Avoid insns that set pseudos which were referenced in previous
4184 insns. These can be generated by move_by_pieces, for example,
4185 to update an address. Similarly, avoid insns that reference things
4186 set in previous insns. */
4187
4188 for (insn = insns; insn; insn = next)
4189 {
4190 rtx set = single_set (insn);
4191
4192 next = NEXT_INSN (insn);
4193
4194 if (set != 0 && REG_P (SET_DEST (set))
4195 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
4196 {
4197 struct no_conflict_data data;
4198
4199 data.target = const0_rtx;
4200 data.first = insns;
4201 data.insn = insn;
4202 data.must_stay = 0;
4203 note_stores (insn, no_conflict_move_test, &data);
4204 if (! data.must_stay)
4205 {
4206 if (PREV_INSN (insn))
4207 SET_NEXT_INSN (PREV_INSN (insn)) = next;
4208 else
4209 insns = next;
4210
4211 if (next)
4212 SET_PREV_INSN (next) = PREV_INSN (insn);
4213
4214 add_insn (insn);
4215 }
4216 }
4217
4218 /* Some ports use a loop to copy large arguments onto the stack.
4219 Don't move anything outside such a loop. */
4220 if (LABEL_P (insn))
4221 break;
4222 }
4223
4224 /* Write the remaining insns followed by the final copy. */
4225 for (insn = insns; insn; insn = next)
4226 {
4227 next = NEXT_INSN (insn);
4228
4229 add_insn (insn);
4230 }
4231
4232 last = emit_move_insn (target, result);
4233 if (equiv)
4234 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
4235
4236 if (final_dest != target)
4237 emit_move_insn (final_dest, target);
4238 }
4239
4240 void
4241 emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
4242 {
4243 emit_libcall_block_1 (insns, target, result, equiv, false);
4244 }
4245 \f
4246 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4247 PURPOSE describes how this comparison will be used. CODE is the rtx
4248 comparison code we will be using.
4249
4250 ??? Actually, CODE is slightly weaker than that. A target is still
4251 required to implement all of the normal bcc operations, but not
4252 required to implement all (or any) of the unordered bcc operations. */
4253
4254 int
4255 can_compare_p (enum rtx_code code, machine_mode mode,
4256 enum can_compare_purpose purpose)
4257 {
4258 rtx test;
4259 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
4260 do
4261 {
4262 enum insn_code icode;
4263
4264 if (purpose == ccp_jump
4265 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
4266 && insn_operand_matches (icode, 0, test))
4267 return 1;
4268 if (purpose == ccp_store_flag
4269 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
4270 && insn_operand_matches (icode, 1, test))
4271 return 1;
4272 if (purpose == ccp_cmov
4273 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
4274 return 1;
4275
4276 mode = GET_MODE_WIDER_MODE (mode).else_void ();
4277 PUT_MODE (test, mode);
4278 }
4279 while (mode != VOIDmode);
4280
4281 return 0;
4282 }
4283
4284 /* Return whether RTL code CODE corresponds to an unsigned optab. */
4285
4286 static bool
4287 unsigned_optab_p (enum rtx_code code)
4288 {
4289 return code == LTU || code == LEU || code == GTU || code == GEU;
4290 }
4291
4292 /* Return whether the backend-emitted comparison for code CODE, comparing
4293 operands of mode VALUE_MODE and producing a result with MASK_MODE, matches
4294 operand OPNO of pattern ICODE. */
4295
4296 static bool
4297 insn_predicate_matches_p (enum insn_code icode, unsigned int opno,
4298 enum rtx_code code, machine_mode mask_mode,
4299 machine_mode value_mode)
4300 {
4301 rtx reg1 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 1);
4302 rtx reg2 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 2);
4303 rtx test = alloca_rtx_fmt_ee (code, mask_mode, reg1, reg2);
4304 return insn_operand_matches (icode, opno, test);
4305 }
4306
4307 /* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
4308 for code CODE, comparing operands of mode VALUE_MODE and producing a result
4309 with MASK_MODE. */
4310
4311 bool
4312 can_vec_cmp_compare_p (enum rtx_code code, machine_mode value_mode,
4313 machine_mode mask_mode)
4314 {
4315 enum insn_code icode
4316 = get_vec_cmp_icode (value_mode, mask_mode, unsigned_optab_p (code));
4317 if (icode == CODE_FOR_nothing)
4318 return false;
4319
4320 return insn_predicate_matches_p (icode, 1, code, mask_mode, value_mode);
4321 }
4322
4323 /* Return whether the backend can emit a vector comparison (vcond/vcondu) for
4324 code CODE, comparing operands of mode CMP_OP_MODE and producing a result
4325 with VALUE_MODE. */
4326
4327 bool
4328 can_vcond_compare_p (enum rtx_code code, machine_mode value_mode,
4329 machine_mode cmp_op_mode)
4330 {
4331 enum insn_code icode
4332 = get_vcond_icode (value_mode, cmp_op_mode, unsigned_optab_p (code));
4333 if (icode == CODE_FOR_nothing)
4334 return false;
4335
4336 return insn_predicate_matches_p (icode, 3, code, value_mode, cmp_op_mode);
4337 }
4338
4339 /* Return whether the backend can emit vector set instructions for inserting
4340 element into vector at variable index position. */
4341
4342 bool
4343 can_vec_set_var_idx_p (machine_mode vec_mode)
4344 {
4345 if (!VECTOR_MODE_P (vec_mode))
4346 return false;
4347
4348 machine_mode inner_mode = GET_MODE_INNER (vec_mode);
4349 rtx reg1 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 1);
4350 rtx reg2 = alloca_raw_REG (inner_mode, LAST_VIRTUAL_REGISTER + 2);
4351 rtx reg3 = alloca_raw_REG (VOIDmode, LAST_VIRTUAL_REGISTER + 3);
4352
4353 enum insn_code icode = optab_handler (vec_set_optab, vec_mode);
4354
4355 return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1)
4356 && insn_operand_matches (icode, 1, reg2)
4357 && insn_operand_matches (icode, 2, reg3);
4358 }
4359
4360 /* This function is called when we are going to emit a compare instruction that
4361 compares the values found in X and Y, using the rtl operator COMPARISON.
4362
4363 If they have mode BLKmode, then SIZE specifies the size of both operands.
4364
4365 UNSIGNEDP nonzero says that the operands are unsigned;
4366 this matters if they need to be widened (as given by METHODS).
4367
4368 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
4369 if we failed to produce one.
4370
4371 *PMODE is the mode of the inputs (in case they are const_int).
4372
4373 This function performs all the setup necessary so that the caller only has
4374 to emit a single comparison insn. This setup can involve doing a BLKmode
4375 comparison or emitting a library call to perform the comparison if no insn
4376 is available to handle it.
4377 The values which are passed in through pointers can be modified; the caller
4378 should perform the comparison on the modified values. Constant
4379 comparisons must have already been folded. */
4380
4381 static void
4382 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4383 int unsignedp, enum optab_methods methods,
4384 rtx *ptest, machine_mode *pmode)
4385 {
4386 machine_mode mode = *pmode;
4387 rtx libfunc, test;
4388 machine_mode cmp_mode;
4389 enum mode_class mclass;
4390
4391 /* The other methods are not needed. */
4392 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
4393 || methods == OPTAB_LIB_WIDEN);
4394
4395 if (CONST_SCALAR_INT_P (y))
4396 canonicalize_comparison (mode, &comparison, &y);
4397
4398 /* If we are optimizing, force expensive constants into a register. */
4399 if (CONSTANT_P (x) && optimize
4400 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
4401 > COSTS_N_INSNS (1))
4402 && can_create_pseudo_p ())
4403 x = force_reg (mode, x);
4404
4405 if (CONSTANT_P (y) && optimize
4406 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
4407 > COSTS_N_INSNS (1))
4408 && can_create_pseudo_p ())
4409 y = force_reg (mode, y);
4410
4411 /* Don't let both operands fail to indicate the mode. */
4412 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4413 x = force_reg (mode, x);
4414 if (mode == VOIDmode)
4415 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
4416
4417 /* Handle all BLKmode compares. */
4418
4419 if (mode == BLKmode)
4420 {
4421 machine_mode result_mode;
4422 enum insn_code cmp_code;
4423 rtx result;
4424 rtx opalign
4425 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4426
4427 gcc_assert (size);
4428
4429 /* Try to use a memory block compare insn - either cmpstr
4430 or cmpmem will do. */
4431 opt_scalar_int_mode cmp_mode_iter;
4432 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT)
4433 {
4434 scalar_int_mode cmp_mode = cmp_mode_iter.require ();
4435 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
4436 if (cmp_code == CODE_FOR_nothing)
4437 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
4438 if (cmp_code == CODE_FOR_nothing)
4439 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
4440 if (cmp_code == CODE_FOR_nothing)
4441 continue;
4442
4443 /* Must make sure the size fits the insn's mode. */
4444 if (CONST_INT_P (size)
4445 ? UINTVAL (size) > GET_MODE_MASK (cmp_mode)
4446 : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
4447 > GET_MODE_BITSIZE (cmp_mode)))
4448 continue;
4449
4450 result_mode = insn_data[cmp_code].operand[0].mode;
4451 result = gen_reg_rtx (result_mode);
4452 size = convert_to_mode (cmp_mode, size, 1);
4453 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4454
4455 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4456 *pmode = result_mode;
4457 return;
4458 }
4459
4460 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
4461 goto fail;
4462
4463 /* Otherwise call a library function. */
4464 result = emit_block_comp_via_libcall (x, y, size);
4465
4466 x = result;
4467 y = const0_rtx;
4468 mode = TYPE_MODE (integer_type_node);
4469 methods = OPTAB_LIB_WIDEN;
4470 unsignedp = false;
4471 }
4472
4473 /* Don't allow operands to the compare to trap, as that can put the
4474 compare and branch in different basic blocks. */
4475 if (cfun->can_throw_non_call_exceptions)
4476 {
4477 if (!can_create_pseudo_p () && (may_trap_p (x) || may_trap_p (y)))
4478 goto fail;
4479 if (may_trap_p (x))
4480 x = copy_to_reg (x);
4481 if (may_trap_p (y))
4482 y = copy_to_reg (y);
4483 }
4484
4485 if (GET_MODE_CLASS (mode) == MODE_CC)
4486 {
4487 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
4488 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4489 gcc_assert (icode != CODE_FOR_nothing
4490 && insn_operand_matches (icode, 0, test));
4491 *ptest = test;
4492 return;
4493 }
4494
4495 mclass = GET_MODE_CLASS (mode);
4496 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4497 FOR_EACH_MODE_FROM (cmp_mode, mode)
4498 {
4499 enum insn_code icode;
4500 icode = optab_handler (cbranch_optab, cmp_mode);
4501 if (icode != CODE_FOR_nothing
4502 && insn_operand_matches (icode, 0, test))
4503 {
4504 rtx_insn *last = get_last_insn ();
4505 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
4506 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
4507 if (op0 && op1
4508 && insn_operand_matches (icode, 1, op0)
4509 && insn_operand_matches (icode, 2, op1))
4510 {
4511 XEXP (test, 0) = op0;
4512 XEXP (test, 1) = op1;
4513 *ptest = test;
4514 *pmode = cmp_mode;
4515 return;
4516 }
4517 delete_insns_since (last);
4518 }
4519
4520 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
4521 break;
4522 }
4523
4524 if (methods != OPTAB_LIB_WIDEN)
4525 goto fail;
4526
4527 if (SCALAR_FLOAT_MODE_P (mode))
4528 {
4529 /* Small trick if UNORDERED isn't implemented by the hardware. */
4530 if (comparison == UNORDERED && rtx_equal_p (x, y))
4531 {
4532 prepare_cmp_insn (x, y, UNLT, NULL_RTX, unsignedp, OPTAB_WIDEN,
4533 ptest, pmode);
4534 if (*ptest)
4535 return;
4536 }
4537
4538 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4539 }
4540 else
4541 {
4542 rtx result;
4543 machine_mode ret_mode;
4544
4545 /* Handle a libcall just for the mode we are using. */
4546 libfunc = optab_libfunc (cmp_optab, mode);
4547 gcc_assert (libfunc);
4548
4549 /* If we want unsigned, and this mode has a distinct unsigned
4550 comparison routine, use that. */
4551 if (unsignedp)
4552 {
4553 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4554 if (ulibfunc)
4555 libfunc = ulibfunc;
4556 }
4557
4558 ret_mode = targetm.libgcc_cmp_return_mode ();
4559 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4560 ret_mode, x, mode, y, mode);
4561
4562 /* There are two kinds of comparison routines. Biased routines
4563 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4564 of gcc expect that the comparison operation is equivalent
4565 to the modified comparison. For signed comparisons compare the
4566 result against 1 in the biased case, and zero in the unbiased
4567 case. For unsigned comparisons always compare against 1 after
4568 biasing the unbiased result by adding 1. This gives us a way to
4569 represent LTU.
4570 The comparisons in the fixed-point helper library are always
4571 biased. */
4572 x = result;
4573 y = const1_rtx;
4574
4575 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4576 {
4577 if (unsignedp)
4578 x = plus_constant (ret_mode, result, 1);
4579 else
4580 y = const0_rtx;
4581 }
4582
4583 *pmode = ret_mode;
4584 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4585 ptest, pmode);
4586 }
4587
4588 return;
4589
4590 fail:
4591 *ptest = NULL_RTX;
4592 }
4593
4594 /* Before emitting an insn with code ICODE, make sure that X, which is going
4595 to be used for operand OPNUM of the insn, is converted from mode MODE to
4596 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4597 that it is accepted by the operand predicate. Return the new value. */
4598
4599 rtx
4600 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
4601 machine_mode wider_mode, int unsignedp)
4602 {
4603 if (mode != wider_mode)
4604 x = convert_modes (wider_mode, mode, x, unsignedp);
4605
4606 if (!insn_operand_matches (icode, opnum, x))
4607 {
4608 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
4609 if (reload_completed)
4610 return NULL_RTX;
4611 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
4612 return NULL_RTX;
4613 x = copy_to_mode_reg (op_mode, x);
4614 }
4615
4616 return x;
4617 }
4618
4619 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4620 we can do the branch. */
4621
4622 static void
4623 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
4624 profile_probability prob)
4625 {
4626 machine_mode optab_mode;
4627 enum mode_class mclass;
4628 enum insn_code icode;
4629 rtx_insn *insn;
4630
4631 mclass = GET_MODE_CLASS (mode);
4632 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4633 icode = optab_handler (cbranch_optab, optab_mode);
4634
4635 gcc_assert (icode != CODE_FOR_nothing);
4636 gcc_assert (insn_operand_matches (icode, 0, test));
4637 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4638 XEXP (test, 1), label));
4639 if (prob.initialized_p ()
4640 && profile_status_for_fn (cfun) != PROFILE_ABSENT
4641 && insn
4642 && JUMP_P (insn)
4643 && any_condjump_p (insn)
4644 && !find_reg_note (insn, REG_BR_PROB, 0))
4645 add_reg_br_prob_note (insn, prob);
4646 }
4647
4648 /* Generate code to compare X with Y so that the condition codes are
4649 set and to jump to LABEL if the condition is true. If X is a
4650 constant and Y is not a constant, then the comparison is swapped to
4651 ensure that the comparison RTL has the canonical form.
4652
4653 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4654 need to be widened. UNSIGNEDP is also used to select the proper
4655 branch condition code.
4656
4657 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4658
4659 MODE is the mode of the inputs (in case they are const_int).
4660
4661 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4662 It will be potentially converted into an unsigned variant based on
4663 UNSIGNEDP to select a proper jump instruction.
4664
4665 PROB is the probability of jumping to LABEL. */
4666
4667 void
4668 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4669 machine_mode mode, int unsignedp, rtx label,
4670 profile_probability prob)
4671 {
4672 rtx op0 = x, op1 = y;
4673 rtx test;
4674
4675 /* Swap operands and condition to ensure canonical RTL. */
4676 if (swap_commutative_operands_p (x, y)
4677 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4678 {
4679 op0 = y, op1 = x;
4680 comparison = swap_condition (comparison);
4681 }
4682
4683 /* If OP0 is still a constant, then both X and Y must be constants
4684 or the opposite comparison is not supported. Force X into a register
4685 to create canonical RTL. */
4686 if (CONSTANT_P (op0))
4687 op0 = force_reg (mode, op0);
4688
4689 if (unsignedp)
4690 comparison = unsigned_condition (comparison);
4691
4692 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4693 &test, &mode);
4694 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4695 }
4696
4697 \f
4698 /* Emit a library call comparison between floating point X and Y.
4699 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4700
4701 static void
4702 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4703 rtx *ptest, machine_mode *pmode)
4704 {
4705 enum rtx_code swapped = swap_condition (comparison);
4706 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4707 machine_mode orig_mode = GET_MODE (x);
4708 machine_mode mode;
4709 rtx true_rtx, false_rtx;
4710 rtx value, target, equiv;
4711 rtx_insn *insns;
4712 rtx libfunc = 0;
4713 bool reversed_p = false;
4714 scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
4715
4716 FOR_EACH_MODE_FROM (mode, orig_mode)
4717 {
4718 if (code_to_optab (comparison)
4719 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4720 break;
4721
4722 if (code_to_optab (swapped)
4723 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4724 {
4725 std::swap (x, y);
4726 comparison = swapped;
4727 break;
4728 }
4729
4730 if (code_to_optab (reversed)
4731 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4732 {
4733 comparison = reversed;
4734 reversed_p = true;
4735 break;
4736 }
4737 }
4738
4739 gcc_assert (mode != VOIDmode);
4740
4741 if (mode != orig_mode)
4742 {
4743 x = convert_to_mode (mode, x, 0);
4744 y = convert_to_mode (mode, y, 0);
4745 }
4746
4747 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4748 the RTL. The allows the RTL optimizers to delete the libcall if the
4749 condition can be determined at compile-time. */
4750 if (comparison == UNORDERED
4751 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4752 {
4753 true_rtx = const_true_rtx;
4754 false_rtx = const0_rtx;
4755 }
4756 else
4757 {
4758 switch (comparison)
4759 {
4760 case EQ:
4761 true_rtx = const0_rtx;
4762 false_rtx = const_true_rtx;
4763 break;
4764
4765 case NE:
4766 true_rtx = const_true_rtx;
4767 false_rtx = const0_rtx;
4768 break;
4769
4770 case GT:
4771 true_rtx = const1_rtx;
4772 false_rtx = const0_rtx;
4773 break;
4774
4775 case GE:
4776 true_rtx = const0_rtx;
4777 false_rtx = constm1_rtx;
4778 break;
4779
4780 case LT:
4781 true_rtx = constm1_rtx;
4782 false_rtx = const0_rtx;
4783 break;
4784
4785 case LE:
4786 true_rtx = const0_rtx;
4787 false_rtx = const1_rtx;
4788 break;
4789
4790 default:
4791 gcc_unreachable ();
4792 }
4793 }
4794
4795 if (comparison == UNORDERED)
4796 {
4797 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4798 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4799 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4800 temp, const_true_rtx, equiv);
4801 }
4802 else
4803 {
4804 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4805 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4806 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4807 equiv, true_rtx, false_rtx);
4808 }
4809
4810 start_sequence ();
4811 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4812 cmp_mode, x, mode, y, mode);
4813 insns = get_insns ();
4814 end_sequence ();
4815
4816 target = gen_reg_rtx (cmp_mode);
4817 emit_libcall_block (insns, target, value, equiv);
4818
4819 if (comparison == UNORDERED
4820 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4821 || reversed_p)
4822 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4823 else
4824 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4825
4826 *pmode = cmp_mode;
4827 }
4828 \f
4829 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4830
4831 void
4832 emit_indirect_jump (rtx loc)
4833 {
4834 if (!targetm.have_indirect_jump ())
4835 sorry ("indirect jumps are not available on this target");
4836 else
4837 {
4838 class expand_operand ops[1];
4839 create_address_operand (&ops[0], loc);
4840 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4841 emit_barrier ();
4842 }
4843 }
4844 \f
4845
4846 /* Emit a conditional move instruction if the machine supports one for that
4847 condition and machine mode.
4848
4849 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4850 the mode to use should they be constants. If it is VOIDmode, they cannot
4851 both be constants.
4852
4853 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4854 should be stored there. MODE is the mode to use should they be constants.
4855 If it is VOIDmode, they cannot both be constants.
4856
4857 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4858 is not supported. */
4859
4860 rtx
4861 emit_conditional_move (rtx target, struct rtx_comparison comp,
4862 rtx op2, rtx op3,
4863 machine_mode mode, int unsignedp)
4864 {
4865 rtx comparison;
4866 rtx_insn *last;
4867 enum insn_code icode;
4868 enum rtx_code reversed;
4869
4870 /* If the two source operands are identical, that's just a move. */
4871
4872 if (rtx_equal_p (op2, op3))
4873 {
4874 if (!target)
4875 target = gen_reg_rtx (mode);
4876
4877 emit_move_insn (target, op3);
4878 return target;
4879 }
4880
4881 /* If one operand is constant, make it the second one. Only do this
4882 if the other operand is not constant as well. */
4883
4884 if (swap_commutative_operands_p (comp.op0, comp.op1))
4885 {
4886 std::swap (comp.op0, comp.op1);
4887 comp.code = swap_condition (comp.code);
4888 }
4889
4890 /* get_condition will prefer to generate LT and GT even if the old
4891 comparison was against zero, so undo that canonicalization here since
4892 comparisons against zero are cheaper. */
4893
4894 if (comp.code == LT && comp.op1 == const1_rtx)
4895 comp.code = LE, comp.op1 = const0_rtx;
4896 else if (comp.code == GT && comp.op1 == constm1_rtx)
4897 comp.code = GE, comp.op1 = const0_rtx;
4898
4899 if (comp.mode == VOIDmode)
4900 comp.mode = GET_MODE (comp.op0);
4901
4902 enum rtx_code orig_code = comp.code;
4903 bool swapped = false;
4904 if (swap_commutative_operands_p (op2, op3)
4905 && ((reversed =
4906 reversed_comparison_code_parts (comp.code, comp.op0, comp.op1, NULL))
4907 != UNKNOWN))
4908 {
4909 std::swap (op2, op3);
4910 comp.code = reversed;
4911 swapped = true;
4912 }
4913
4914 if (mode == VOIDmode)
4915 mode = GET_MODE (op2);
4916
4917 icode = direct_optab_handler (movcc_optab, mode);
4918
4919 if (icode == CODE_FOR_nothing)
4920 return NULL_RTX;
4921
4922 if (!target)
4923 target = gen_reg_rtx (mode);
4924
4925 for (int pass = 0; ; pass++)
4926 {
4927 comp.code = unsignedp ? unsigned_condition (comp.code) : comp.code;
4928 comparison =
4929 simplify_gen_relational (comp.code, VOIDmode,
4930 comp.mode, comp.op0, comp.op1);
4931
4932 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4933 punt and let the caller figure out how best to deal with this
4934 situation. */
4935 if (COMPARISON_P (comparison))
4936 {
4937 saved_pending_stack_adjust save;
4938 save_pending_stack_adjust (&save);
4939 last = get_last_insn ();
4940 do_pending_stack_adjust ();
4941 machine_mode cmpmode = comp.mode;
4942 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4943 GET_CODE (comparison), NULL_RTX, unsignedp,
4944 OPTAB_WIDEN, &comparison, &cmpmode);
4945 if (comparison)
4946 {
4947 rtx res = emit_conditional_move_1 (target, comparison,
4948 op2, op3, mode);
4949 if (res != NULL_RTX)
4950 return res;
4951 }
4952 delete_insns_since (last);
4953 restore_pending_stack_adjust (&save);
4954 }
4955
4956 if (pass == 1)
4957 return NULL_RTX;
4958
4959 /* If the preferred op2/op3 order is not usable, retry with other
4960 operand order, perhaps it will expand successfully. */
4961 if (swapped)
4962 comp.code = orig_code;
4963 else if ((reversed =
4964 reversed_comparison_code_parts (orig_code, comp.op0, comp.op1,
4965 NULL))
4966 != UNKNOWN)
4967 comp.code = reversed;
4968 else
4969 return NULL_RTX;
4970 std::swap (op2, op3);
4971 }
4972 }
4973
4974 /* Helper function that, in addition to COMPARISON, also tries
4975 the reversed REV_COMPARISON with swapped OP2 and OP3. As opposed
4976 to when we pass the specific constituents of a comparison, no
4977 additional insns are emitted for it. It might still be necessary
4978 to emit more than one insn for the final conditional move, though. */
4979
4980 rtx
4981 emit_conditional_move (rtx target, rtx comparison, rtx rev_comparison,
4982 rtx op2, rtx op3, machine_mode mode)
4983 {
4984 rtx res = emit_conditional_move_1 (target, comparison, op2, op3, mode);
4985
4986 if (res != NULL_RTX)
4987 return res;
4988
4989 return emit_conditional_move_1 (target, rev_comparison, op3, op2, mode);
4990 }
4991
4992 /* Helper for emitting a conditional move. */
4993
4994 static rtx
4995 emit_conditional_move_1 (rtx target, rtx comparison,
4996 rtx op2, rtx op3, machine_mode mode)
4997 {
4998 enum insn_code icode;
4999
5000 if (comparison == NULL_RTX || !COMPARISON_P (comparison))
5001 return NULL_RTX;
5002
5003 /* If the two source operands are identical, that's just a move.
5004 As the comparison comes in non-canonicalized, we must make
5005 sure not to discard any possible side effects. If there are
5006 side effects, just let the target handle it. */
5007 if (!side_effects_p (comparison) && rtx_equal_p (op2, op3))
5008 {
5009 if (!target)
5010 target = gen_reg_rtx (mode);
5011
5012 emit_move_insn (target, op3);
5013 return target;
5014 }
5015
5016 if (mode == VOIDmode)
5017 mode = GET_MODE (op2);
5018
5019 icode = direct_optab_handler (movcc_optab, mode);
5020
5021 if (icode == CODE_FOR_nothing)
5022 return NULL_RTX;
5023
5024 if (!target)
5025 target = gen_reg_rtx (mode);
5026
5027 class expand_operand ops[4];
5028
5029 create_output_operand (&ops[0], target, mode);
5030 create_fixed_operand (&ops[1], comparison);
5031 create_input_operand (&ops[2], op2, mode);
5032 create_input_operand (&ops[3], op3, mode);
5033
5034 if (maybe_expand_insn (icode, 4, ops))
5035 {
5036 if (ops[0].value != target)
5037 convert_move (target, ops[0].value, false);
5038 return target;
5039 }
5040
5041 return NULL_RTX;
5042 }
5043
5044
5045 /* Emit a conditional negate or bitwise complement using the
5046 negcc or notcc optabs if available. Return NULL_RTX if such operations
5047 are not available. Otherwise return the RTX holding the result.
5048 TARGET is the desired destination of the result. COMP is the comparison
5049 on which to negate. If COND is true move into TARGET the negation
5050 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
5051 CODE is either NEG or NOT. MODE is the machine mode in which the
5052 operation is performed. */
5053
5054 rtx
5055 emit_conditional_neg_or_complement (rtx target, rtx_code code,
5056 machine_mode mode, rtx cond, rtx op1,
5057 rtx op2)
5058 {
5059 optab op = unknown_optab;
5060 if (code == NEG)
5061 op = negcc_optab;
5062 else if (code == NOT)
5063 op = notcc_optab;
5064 else
5065 gcc_unreachable ();
5066
5067 insn_code icode = direct_optab_handler (op, mode);
5068
5069 if (icode == CODE_FOR_nothing)
5070 return NULL_RTX;
5071
5072 if (!target)
5073 target = gen_reg_rtx (mode);
5074
5075 rtx_insn *last = get_last_insn ();
5076 class expand_operand ops[4];
5077
5078 create_output_operand (&ops[0], target, mode);
5079 create_fixed_operand (&ops[1], cond);
5080 create_input_operand (&ops[2], op1, mode);
5081 create_input_operand (&ops[3], op2, mode);
5082
5083 if (maybe_expand_insn (icode, 4, ops))
5084 {
5085 if (ops[0].value != target)
5086 convert_move (target, ops[0].value, false);
5087
5088 return target;
5089 }
5090 delete_insns_since (last);
5091 return NULL_RTX;
5092 }
5093
5094 /* Emit a conditional addition instruction if the machine supports one for that
5095 condition and machine mode.
5096
5097 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
5098 the mode to use should they be constants. If it is VOIDmode, they cannot
5099 both be constants.
5100
5101 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
5102 should be stored there. MODE is the mode to use should they be constants.
5103 If it is VOIDmode, they cannot both be constants.
5104
5105 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
5106 is not supported. */
5107
5108 rtx
5109 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
5110 machine_mode cmode, rtx op2, rtx op3,
5111 machine_mode mode, int unsignedp)
5112 {
5113 rtx comparison;
5114 rtx_insn *last;
5115 enum insn_code icode;
5116
5117 /* If one operand is constant, make it the second one. Only do this
5118 if the other operand is not constant as well. */
5119
5120 if (swap_commutative_operands_p (op0, op1))
5121 {
5122 std::swap (op0, op1);
5123 code = swap_condition (code);
5124 }
5125
5126 /* get_condition will prefer to generate LT and GT even if the old
5127 comparison was against zero, so undo that canonicalization here since
5128 comparisons against zero are cheaper. */
5129 if (code == LT && op1 == const1_rtx)
5130 code = LE, op1 = const0_rtx;
5131 else if (code == GT && op1 == constm1_rtx)
5132 code = GE, op1 = const0_rtx;
5133
5134 if (cmode == VOIDmode)
5135 cmode = GET_MODE (op0);
5136
5137 if (mode == VOIDmode)
5138 mode = GET_MODE (op2);
5139
5140 icode = optab_handler (addcc_optab, mode);
5141
5142 if (icode == CODE_FOR_nothing)
5143 return 0;
5144
5145 if (!target)
5146 target = gen_reg_rtx (mode);
5147
5148 code = unsignedp ? unsigned_condition (code) : code;
5149 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
5150
5151 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
5152 return NULL and let the caller figure out how best to deal with this
5153 situation. */
5154 if (!COMPARISON_P (comparison))
5155 return NULL_RTX;
5156
5157 do_pending_stack_adjust ();
5158 last = get_last_insn ();
5159 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
5160 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
5161 &comparison, &cmode);
5162 if (comparison)
5163 {
5164 class expand_operand ops[4];
5165
5166 create_output_operand (&ops[0], target, mode);
5167 create_fixed_operand (&ops[1], comparison);
5168 create_input_operand (&ops[2], op2, mode);
5169 create_input_operand (&ops[3], op3, mode);
5170 if (maybe_expand_insn (icode, 4, ops))
5171 {
5172 if (ops[0].value != target)
5173 convert_move (target, ops[0].value, false);
5174 return target;
5175 }
5176 }
5177 delete_insns_since (last);
5178 return NULL_RTX;
5179 }
5180 \f
5181 /* These functions attempt to generate an insn body, rather than
5182 emitting the insn, but if the gen function already emits them, we
5183 make no attempt to turn them back into naked patterns. */
5184
5185 /* Generate and return an insn body to add Y to X. */
5186
5187 rtx_insn *
5188 gen_add2_insn (rtx x, rtx y)
5189 {
5190 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
5191
5192 gcc_assert (insn_operand_matches (icode, 0, x));
5193 gcc_assert (insn_operand_matches (icode, 1, x));
5194 gcc_assert (insn_operand_matches (icode, 2, y));
5195
5196 return GEN_FCN (icode) (x, x, y);
5197 }
5198
5199 /* Generate and return an insn body to add r1 and c,
5200 storing the result in r0. */
5201
5202 rtx_insn *
5203 gen_add3_insn (rtx r0, rtx r1, rtx c)
5204 {
5205 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
5206
5207 if (icode == CODE_FOR_nothing
5208 || !insn_operand_matches (icode, 0, r0)
5209 || !insn_operand_matches (icode, 1, r1)
5210 || !insn_operand_matches (icode, 2, c))
5211 return NULL;
5212
5213 return GEN_FCN (icode) (r0, r1, c);
5214 }
5215
5216 int
5217 have_add2_insn (rtx x, rtx y)
5218 {
5219 enum insn_code icode;
5220
5221 gcc_assert (GET_MODE (x) != VOIDmode);
5222
5223 icode = optab_handler (add_optab, GET_MODE (x));
5224
5225 if (icode == CODE_FOR_nothing)
5226 return 0;
5227
5228 if (!insn_operand_matches (icode, 0, x)
5229 || !insn_operand_matches (icode, 1, x)
5230 || !insn_operand_matches (icode, 2, y))
5231 return 0;
5232
5233 return 1;
5234 }
5235
5236 /* Generate and return an insn body to add Y to X. */
5237
5238 rtx_insn *
5239 gen_addptr3_insn (rtx x, rtx y, rtx z)
5240 {
5241 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
5242
5243 gcc_assert (insn_operand_matches (icode, 0, x));
5244 gcc_assert (insn_operand_matches (icode, 1, y));
5245 gcc_assert (insn_operand_matches (icode, 2, z));
5246
5247 return GEN_FCN (icode) (x, y, z);
5248 }
5249
5250 /* Return true if the target implements an addptr pattern and X, Y,
5251 and Z are valid for the pattern predicates. */
5252
5253 int
5254 have_addptr3_insn (rtx x, rtx y, rtx z)
5255 {
5256 enum insn_code icode;
5257
5258 gcc_assert (GET_MODE (x) != VOIDmode);
5259
5260 icode = optab_handler (addptr3_optab, GET_MODE (x));
5261
5262 if (icode == CODE_FOR_nothing)
5263 return 0;
5264
5265 if (!insn_operand_matches (icode, 0, x)
5266 || !insn_operand_matches (icode, 1, y)
5267 || !insn_operand_matches (icode, 2, z))
5268 return 0;
5269
5270 return 1;
5271 }
5272
5273 /* Generate and return an insn body to subtract Y from X. */
5274
5275 rtx_insn *
5276 gen_sub2_insn (rtx x, rtx y)
5277 {
5278 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
5279
5280 gcc_assert (insn_operand_matches (icode, 0, x));
5281 gcc_assert (insn_operand_matches (icode, 1, x));
5282 gcc_assert (insn_operand_matches (icode, 2, y));
5283
5284 return GEN_FCN (icode) (x, x, y);
5285 }
5286
5287 /* Generate and return an insn body to subtract r1 and c,
5288 storing the result in r0. */
5289
5290 rtx_insn *
5291 gen_sub3_insn (rtx r0, rtx r1, rtx c)
5292 {
5293 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
5294
5295 if (icode == CODE_FOR_nothing
5296 || !insn_operand_matches (icode, 0, r0)
5297 || !insn_operand_matches (icode, 1, r1)
5298 || !insn_operand_matches (icode, 2, c))
5299 return NULL;
5300
5301 return GEN_FCN (icode) (r0, r1, c);
5302 }
5303
5304 int
5305 have_sub2_insn (rtx x, rtx y)
5306 {
5307 enum insn_code icode;
5308
5309 gcc_assert (GET_MODE (x) != VOIDmode);
5310
5311 icode = optab_handler (sub_optab, GET_MODE (x));
5312
5313 if (icode == CODE_FOR_nothing)
5314 return 0;
5315
5316 if (!insn_operand_matches (icode, 0, x)
5317 || !insn_operand_matches (icode, 1, x)
5318 || !insn_operand_matches (icode, 2, y))
5319 return 0;
5320
5321 return 1;
5322 }
5323 \f
5324 /* Generate the body of an insn to extend Y (with mode MFROM)
5325 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
5326
5327 rtx_insn *
5328 gen_extend_insn (rtx x, rtx y, machine_mode mto,
5329 machine_mode mfrom, int unsignedp)
5330 {
5331 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
5332 return GEN_FCN (icode) (x, y);
5333 }
5334 \f
5335 /* Generate code to convert FROM to floating point
5336 and store in TO. FROM must be fixed point and not VOIDmode.
5337 UNSIGNEDP nonzero means regard FROM as unsigned.
5338 Normally this is done by correcting the final value
5339 if it is negative. */
5340
5341 void
5342 expand_float (rtx to, rtx from, int unsignedp)
5343 {
5344 enum insn_code icode;
5345 rtx target = to;
5346 scalar_mode from_mode, to_mode;
5347 machine_mode fmode, imode;
5348 bool can_do_signed = false;
5349
5350 /* Crash now, because we won't be able to decide which mode to use. */
5351 gcc_assert (GET_MODE (from) != VOIDmode);
5352
5353 /* Look for an insn to do the conversion. Do it in the specified
5354 modes if possible; otherwise convert either input, output or both to
5355 wider mode. If the integer mode is wider than the mode of FROM,
5356 we can do the conversion signed even if the input is unsigned. */
5357
5358 FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
5359 FOR_EACH_MODE_FROM (imode, GET_MODE (from))
5360 {
5361 int doing_unsigned = unsignedp;
5362
5363 if (fmode != GET_MODE (to)
5364 && (significand_size (fmode)
5365 < GET_MODE_UNIT_PRECISION (GET_MODE (from))))
5366 continue;
5367
5368 icode = can_float_p (fmode, imode, unsignedp);
5369 if (icode == CODE_FOR_nothing && unsignedp)
5370 {
5371 enum insn_code scode = can_float_p (fmode, imode, 0);
5372 if (scode != CODE_FOR_nothing)
5373 can_do_signed = true;
5374 if (imode != GET_MODE (from))
5375 icode = scode, doing_unsigned = 0;
5376 }
5377
5378 if (icode != CODE_FOR_nothing)
5379 {
5380 if (imode != GET_MODE (from))
5381 from = convert_to_mode (imode, from, unsignedp);
5382
5383 if (fmode != GET_MODE (to))
5384 target = gen_reg_rtx (fmode);
5385
5386 emit_unop_insn (icode, target, from,
5387 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5388
5389 if (target != to)
5390 convert_move (to, target, 0);
5391 return;
5392 }
5393 }
5394
5395 /* Unsigned integer, and no way to convert directly. Convert as signed,
5396 then unconditionally adjust the result. */
5397 if (unsignedp
5398 && can_do_signed
5399 && is_a <scalar_mode> (GET_MODE (to), &to_mode)
5400 && is_a <scalar_mode> (GET_MODE (from), &from_mode))
5401 {
5402 opt_scalar_mode fmode_iter;
5403 rtx_code_label *label = gen_label_rtx ();
5404 rtx temp;
5405 REAL_VALUE_TYPE offset;
5406
5407 /* Look for a usable floating mode FMODE wider than the source and at
5408 least as wide as the target. Using FMODE will avoid rounding woes
5409 with unsigned values greater than the signed maximum value. */
5410
5411 FOR_EACH_MODE_FROM (fmode_iter, to_mode)
5412 {
5413 scalar_mode fmode = fmode_iter.require ();
5414 if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
5415 && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
5416 break;
5417 }
5418
5419 if (!fmode_iter.exists (&fmode))
5420 {
5421 /* There is no such mode. Pretend the target is wide enough. */
5422 fmode = to_mode;
5423
5424 /* Avoid double-rounding when TO is narrower than FROM. */
5425 if ((significand_size (fmode) + 1)
5426 < GET_MODE_PRECISION (from_mode))
5427 {
5428 rtx temp1;
5429 rtx_code_label *neglabel = gen_label_rtx ();
5430
5431 /* Don't use TARGET if it isn't a register, is a hard register,
5432 or is the wrong mode. */
5433 if (!REG_P (target)
5434 || REGNO (target) < FIRST_PSEUDO_REGISTER
5435 || GET_MODE (target) != fmode)
5436 target = gen_reg_rtx (fmode);
5437
5438 imode = from_mode;
5439 do_pending_stack_adjust ();
5440
5441 /* Test whether the sign bit is set. */
5442 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5443 0, neglabel);
5444
5445 /* The sign bit is not set. Convert as signed. */
5446 expand_float (target, from, 0);
5447 emit_jump_insn (targetm.gen_jump (label));
5448 emit_barrier ();
5449
5450 /* The sign bit is set.
5451 Convert to a usable (positive signed) value by shifting right
5452 one bit, while remembering if a nonzero bit was shifted
5453 out; i.e., compute (from & 1) | (from >> 1). */
5454
5455 emit_label (neglabel);
5456 temp = expand_binop (imode, and_optab, from, const1_rtx,
5457 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5458 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
5459 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5460 OPTAB_LIB_WIDEN);
5461 expand_float (target, temp, 0);
5462
5463 /* Multiply by 2 to undo the shift above. */
5464 temp = expand_binop (fmode, add_optab, target, target,
5465 target, 0, OPTAB_LIB_WIDEN);
5466 if (temp != target)
5467 emit_move_insn (target, temp);
5468
5469 do_pending_stack_adjust ();
5470 emit_label (label);
5471 goto done;
5472 }
5473 }
5474
5475 /* If we are about to do some arithmetic to correct for an
5476 unsigned operand, do it in a pseudo-register. */
5477
5478 if (to_mode != fmode
5479 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5480 target = gen_reg_rtx (fmode);
5481
5482 /* Convert as signed integer to floating. */
5483 expand_float (target, from, 0);
5484
5485 /* If FROM is negative (and therefore TO is negative),
5486 correct its value by 2**bitwidth. */
5487
5488 do_pending_stack_adjust ();
5489 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
5490 0, label);
5491
5492
5493 real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
5494 temp = expand_binop (fmode, add_optab, target,
5495 const_double_from_real_value (offset, fmode),
5496 target, 0, OPTAB_LIB_WIDEN);
5497 if (temp != target)
5498 emit_move_insn (target, temp);
5499
5500 do_pending_stack_adjust ();
5501 emit_label (label);
5502 goto done;
5503 }
5504
5505 /* No hardware instruction available; call a library routine. */
5506 {
5507 rtx libfunc;
5508 rtx_insn *insns;
5509 rtx value;
5510 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5511
5512 if (is_narrower_int_mode (GET_MODE (from), SImode))
5513 from = convert_to_mode (SImode, from, unsignedp);
5514
5515 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5516 gcc_assert (libfunc);
5517
5518 start_sequence ();
5519
5520 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5521 GET_MODE (to), from, GET_MODE (from));
5522 insns = get_insns ();
5523 end_sequence ();
5524
5525 emit_libcall_block (insns, target, value,
5526 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
5527 GET_MODE (to), from));
5528 }
5529
5530 done:
5531
5532 /* Copy result to requested destination
5533 if we have been computing in a temp location. */
5534
5535 if (target != to)
5536 {
5537 if (GET_MODE (target) == GET_MODE (to))
5538 emit_move_insn (to, target);
5539 else
5540 convert_move (to, target, 0);
5541 }
5542 }
5543 \f
5544 /* Generate code to convert FROM to fixed point and store in TO. FROM
5545 must be floating point. */
5546
5547 void
5548 expand_fix (rtx to, rtx from, int unsignedp)
5549 {
5550 enum insn_code icode;
5551 rtx target = to;
5552 machine_mode fmode, imode;
5553 opt_scalar_mode fmode_iter;
5554 bool must_trunc = false;
5555
5556 /* We first try to find a pair of modes, one real and one integer, at
5557 least as wide as FROM and TO, respectively, in which we can open-code
5558 this conversion. If the integer mode is wider than the mode of TO,
5559 we can do the conversion either signed or unsigned. */
5560
5561 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5562 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5563 {
5564 int doing_unsigned = unsignedp;
5565
5566 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5567 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5568 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5569
5570 if (icode != CODE_FOR_nothing)
5571 {
5572 rtx_insn *last = get_last_insn ();
5573 rtx from1 = from;
5574 if (fmode != GET_MODE (from))
5575 from1 = convert_to_mode (fmode, from, 0);
5576
5577 if (must_trunc)
5578 {
5579 rtx temp = gen_reg_rtx (GET_MODE (from1));
5580 from1 = expand_unop (GET_MODE (from1), ftrunc_optab, from1,
5581 temp, 0);
5582 }
5583
5584 if (imode != GET_MODE (to))
5585 target = gen_reg_rtx (imode);
5586
5587 if (maybe_emit_unop_insn (icode, target, from1,
5588 doing_unsigned ? UNSIGNED_FIX : FIX))
5589 {
5590 if (target != to)
5591 convert_move (to, target, unsignedp);
5592 return;
5593 }
5594 delete_insns_since (last);
5595 }
5596 }
5597
5598 /* For an unsigned conversion, there is one more way to do it.
5599 If we have a signed conversion, we generate code that compares
5600 the real value to the largest representable positive number. If if
5601 is smaller, the conversion is done normally. Otherwise, subtract
5602 one plus the highest signed number, convert, and add it back.
5603
5604 We only need to check all real modes, since we know we didn't find
5605 anything with a wider integer mode.
5606
5607 This code used to extend FP value into mode wider than the destination.
5608 This is needed for decimal float modes which cannot accurately
5609 represent one plus the highest signed number of the same size, but
5610 not for binary modes. Consider, for instance conversion from SFmode
5611 into DImode.
5612
5613 The hot path through the code is dealing with inputs smaller than 2^63
5614 and doing just the conversion, so there is no bits to lose.
5615
5616 In the other path we know the value is positive in the range 2^63..2^64-1
5617 inclusive. (as for other input overflow happens and result is undefined)
5618 So we know that the most important bit set in mantissa corresponds to
5619 2^63. The subtraction of 2^63 should not generate any rounding as it
5620 simply clears out that bit. The rest is trivial. */
5621
5622 scalar_int_mode to_mode;
5623 if (unsignedp
5624 && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
5625 && HWI_COMPUTABLE_MODE_P (to_mode))
5626 FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
5627 {
5628 scalar_mode fmode = fmode_iter.require ();
5629 if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
5630 0, &must_trunc)
5631 && (!DECIMAL_FLOAT_MODE_P (fmode)
5632 || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
5633 {
5634 int bitsize;
5635 REAL_VALUE_TYPE offset;
5636 rtx limit;
5637 rtx_code_label *lab1, *lab2;
5638 rtx_insn *insn;
5639
5640 bitsize = GET_MODE_PRECISION (to_mode);
5641 real_2expN (&offset, bitsize - 1, fmode);
5642 limit = const_double_from_real_value (offset, fmode);
5643 lab1 = gen_label_rtx ();
5644 lab2 = gen_label_rtx ();
5645
5646 if (fmode != GET_MODE (from))
5647 from = convert_to_mode (fmode, from, 0);
5648
5649 /* See if we need to do the subtraction. */
5650 do_pending_stack_adjust ();
5651 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
5652 GET_MODE (from), 0, lab1);
5653
5654 /* If not, do the signed "fix" and branch around fixup code. */
5655 expand_fix (to, from, 0);
5656 emit_jump_insn (targetm.gen_jump (lab2));
5657 emit_barrier ();
5658
5659 /* Otherwise, subtract 2**(N-1), convert to signed number,
5660 then add 2**(N-1). Do the addition using XOR since this
5661 will often generate better code. */
5662 emit_label (lab1);
5663 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5664 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5665 expand_fix (to, target, 0);
5666 target = expand_binop (to_mode, xor_optab, to,
5667 gen_int_mode
5668 (HOST_WIDE_INT_1 << (bitsize - 1),
5669 to_mode),
5670 to, 1, OPTAB_LIB_WIDEN);
5671
5672 if (target != to)
5673 emit_move_insn (to, target);
5674
5675 emit_label (lab2);
5676
5677 if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
5678 {
5679 /* Make a place for a REG_NOTE and add it. */
5680 insn = emit_move_insn (to, to);
5681 set_dst_reg_note (insn, REG_EQUAL,
5682 gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
5683 copy_rtx (from)),
5684 to);
5685 }
5686
5687 return;
5688 }
5689 }
5690
5691 /* We can't do it with an insn, so use a library call. But first ensure
5692 that the mode of TO is at least as wide as SImode, since those are the
5693 only library calls we know about. */
5694
5695 if (is_narrower_int_mode (GET_MODE (to), SImode))
5696 {
5697 target = gen_reg_rtx (SImode);
5698
5699 expand_fix (target, from, unsignedp);
5700 }
5701 else
5702 {
5703 rtx_insn *insns;
5704 rtx value;
5705 rtx libfunc;
5706
5707 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5708 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5709 gcc_assert (libfunc);
5710
5711 start_sequence ();
5712
5713 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5714 GET_MODE (to), from, GET_MODE (from));
5715 insns = get_insns ();
5716 end_sequence ();
5717
5718 emit_libcall_block (insns, target, value,
5719 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5720 GET_MODE (to), from));
5721 }
5722
5723 if (target != to)
5724 {
5725 if (GET_MODE (to) == GET_MODE (target))
5726 emit_move_insn (to, target);
5727 else
5728 convert_move (to, target, 0);
5729 }
5730 }
5731
5732
5733 /* Promote integer arguments for a libcall if necessary.
5734 emit_library_call_value cannot do the promotion because it does not
5735 know if it should do a signed or unsigned promotion. This is because
5736 there are no tree types defined for libcalls. */
5737
5738 static rtx
5739 prepare_libcall_arg (rtx arg, int uintp)
5740 {
5741 scalar_int_mode mode;
5742 machine_mode arg_mode;
5743 if (is_a <scalar_int_mode> (GET_MODE (arg), &mode))
5744 {
5745 /* If we need to promote the integer function argument we need to do
5746 it here instead of inside emit_library_call_value because in
5747 emit_library_call_value we don't know if we should do a signed or
5748 unsigned promotion. */
5749
5750 int unsigned_p = 0;
5751 arg_mode = promote_function_mode (NULL_TREE, mode,
5752 &unsigned_p, NULL_TREE, 0);
5753 if (arg_mode != mode)
5754 return convert_to_mode (arg_mode, arg, uintp);
5755 }
5756 return arg;
5757 }
5758
5759 /* Generate code to convert FROM or TO a fixed-point.
5760 If UINTP is true, either TO or FROM is an unsigned integer.
5761 If SATP is true, we need to saturate the result. */
5762
5763 void
5764 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5765 {
5766 machine_mode to_mode = GET_MODE (to);
5767 machine_mode from_mode = GET_MODE (from);
5768 convert_optab tab;
5769 enum rtx_code this_code;
5770 enum insn_code code;
5771 rtx_insn *insns;
5772 rtx value;
5773 rtx libfunc;
5774
5775 if (to_mode == from_mode)
5776 {
5777 emit_move_insn (to, from);
5778 return;
5779 }
5780
5781 if (uintp)
5782 {
5783 tab = satp ? satfractuns_optab : fractuns_optab;
5784 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5785 }
5786 else
5787 {
5788 tab = satp ? satfract_optab : fract_optab;
5789 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5790 }
5791 code = convert_optab_handler (tab, to_mode, from_mode);
5792 if (code != CODE_FOR_nothing)
5793 {
5794 emit_unop_insn (code, to, from, this_code);
5795 return;
5796 }
5797
5798 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5799 gcc_assert (libfunc);
5800
5801 from = prepare_libcall_arg (from, uintp);
5802 from_mode = GET_MODE (from);
5803
5804 start_sequence ();
5805 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5806 from, from_mode);
5807 insns = get_insns ();
5808 end_sequence ();
5809
5810 emit_libcall_block (insns, to, value,
5811 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5812 }
5813
5814 /* Generate code to convert FROM to fixed point and store in TO. FROM
5815 must be floating point, TO must be signed. Use the conversion optab
5816 TAB to do the conversion. */
5817
5818 bool
5819 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5820 {
5821 enum insn_code icode;
5822 rtx target = to;
5823 machine_mode fmode, imode;
5824
5825 /* We first try to find a pair of modes, one real and one integer, at
5826 least as wide as FROM and TO, respectively, in which we can open-code
5827 this conversion. If the integer mode is wider than the mode of TO,
5828 we can do the conversion either signed or unsigned. */
5829
5830 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5831 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5832 {
5833 icode = convert_optab_handler (tab, imode, fmode);
5834 if (icode != CODE_FOR_nothing)
5835 {
5836 rtx_insn *last = get_last_insn ();
5837 if (fmode != GET_MODE (from))
5838 from = convert_to_mode (fmode, from, 0);
5839
5840 if (imode != GET_MODE (to))
5841 target = gen_reg_rtx (imode);
5842
5843 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5844 {
5845 delete_insns_since (last);
5846 continue;
5847 }
5848 if (target != to)
5849 convert_move (to, target, 0);
5850 return true;
5851 }
5852 }
5853
5854 return false;
5855 }
5856 \f
5857 /* Report whether we have an instruction to perform the operation
5858 specified by CODE on operands of mode MODE. */
5859 int
5860 have_insn_for (enum rtx_code code, machine_mode mode)
5861 {
5862 return (code_to_optab (code)
5863 && (optab_handler (code_to_optab (code), mode)
5864 != CODE_FOR_nothing));
5865 }
5866
5867 /* Print information about the current contents of the optabs on
5868 STDERR. */
5869
5870 DEBUG_FUNCTION void
5871 debug_optab_libfuncs (void)
5872 {
5873 int i, j, k;
5874
5875 /* Dump the arithmetic optabs. */
5876 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5877 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5878 {
5879 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5880 if (l)
5881 {
5882 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5883 fprintf (stderr, "%s\t%s:\t%s\n",
5884 GET_RTX_NAME (optab_to_code ((optab) i)),
5885 GET_MODE_NAME (j),
5886 XSTR (l, 0));
5887 }
5888 }
5889
5890 /* Dump the conversion optabs. */
5891 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5892 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5893 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5894 {
5895 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5896 (machine_mode) k);
5897 if (l)
5898 {
5899 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5900 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5901 GET_RTX_NAME (optab_to_code ((optab) i)),
5902 GET_MODE_NAME (j),
5903 GET_MODE_NAME (k),
5904 XSTR (l, 0));
5905 }
5906 }
5907 }
5908
5909 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5910 CODE. Return 0 on failure. */
5911
5912 rtx_insn *
5913 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5914 {
5915 machine_mode mode = GET_MODE (op1);
5916 enum insn_code icode;
5917 rtx_insn *insn;
5918 rtx trap_rtx;
5919
5920 if (mode == VOIDmode)
5921 return 0;
5922
5923 icode = optab_handler (ctrap_optab, mode);
5924 if (icode == CODE_FOR_nothing)
5925 return 0;
5926
5927 /* Some targets only accept a zero trap code. */
5928 if (!insn_operand_matches (icode, 3, tcode))
5929 return 0;
5930
5931 do_pending_stack_adjust ();
5932 start_sequence ();
5933 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5934 &trap_rtx, &mode);
5935 if (!trap_rtx)
5936 insn = NULL;
5937 else
5938 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5939 tcode);
5940
5941 /* If that failed, then give up. */
5942 if (insn == 0)
5943 {
5944 end_sequence ();
5945 return 0;
5946 }
5947
5948 emit_insn (insn);
5949 insn = get_insns ();
5950 end_sequence ();
5951 return insn;
5952 }
5953
5954 /* Return rtx code for TCODE or UNKNOWN. Use UNSIGNEDP to select signed
5955 or unsigned operation code. */
5956
5957 enum rtx_code
5958 get_rtx_code_1 (enum tree_code tcode, bool unsignedp)
5959 {
5960 enum rtx_code code;
5961 switch (tcode)
5962 {
5963 case EQ_EXPR:
5964 code = EQ;
5965 break;
5966 case NE_EXPR:
5967 code = NE;
5968 break;
5969 case LT_EXPR:
5970 code = unsignedp ? LTU : LT;
5971 break;
5972 case LE_EXPR:
5973 code = unsignedp ? LEU : LE;
5974 break;
5975 case GT_EXPR:
5976 code = unsignedp ? GTU : GT;
5977 break;
5978 case GE_EXPR:
5979 code = unsignedp ? GEU : GE;
5980 break;
5981
5982 case UNORDERED_EXPR:
5983 code = UNORDERED;
5984 break;
5985 case ORDERED_EXPR:
5986 code = ORDERED;
5987 break;
5988 case UNLT_EXPR:
5989 code = UNLT;
5990 break;
5991 case UNLE_EXPR:
5992 code = UNLE;
5993 break;
5994 case UNGT_EXPR:
5995 code = UNGT;
5996 break;
5997 case UNGE_EXPR:
5998 code = UNGE;
5999 break;
6000 case UNEQ_EXPR:
6001 code = UNEQ;
6002 break;
6003 case LTGT_EXPR:
6004 code = LTGT;
6005 break;
6006
6007 case BIT_AND_EXPR:
6008 code = AND;
6009 break;
6010
6011 case BIT_IOR_EXPR:
6012 code = IOR;
6013 break;
6014
6015 default:
6016 code = UNKNOWN;
6017 break;
6018 }
6019 return code;
6020 }
6021
6022 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6023 or unsigned operation code. */
6024
6025 enum rtx_code
6026 get_rtx_code (enum tree_code tcode, bool unsignedp)
6027 {
6028 enum rtx_code code = get_rtx_code_1 (tcode, unsignedp);
6029 gcc_assert (code != UNKNOWN);
6030 return code;
6031 }
6032
6033 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
6034 select signed or unsigned operators. OPNO holds the index of the
6035 first comparison operand for insn ICODE. Do not generate the
6036 compare instruction itself. */
6037
6038 rtx
6039 vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
6040 tree t_op0, tree t_op1, bool unsignedp,
6041 enum insn_code icode, unsigned int opno)
6042 {
6043 class expand_operand ops[2];
6044 rtx rtx_op0, rtx_op1;
6045 machine_mode m0, m1;
6046 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
6047
6048 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
6049
6050 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
6051 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
6052 cases, use the original mode. */
6053 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6054 EXPAND_STACK_PARM);
6055 m0 = GET_MODE (rtx_op0);
6056 if (m0 == VOIDmode)
6057 m0 = TYPE_MODE (TREE_TYPE (t_op0));
6058
6059 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6060 EXPAND_STACK_PARM);
6061 m1 = GET_MODE (rtx_op1);
6062 if (m1 == VOIDmode)
6063 m1 = TYPE_MODE (TREE_TYPE (t_op1));
6064
6065 create_input_operand (&ops[0], rtx_op0, m0);
6066 create_input_operand (&ops[1], rtx_op1, m1);
6067 if (!maybe_legitimize_operands (icode, opno, 2, ops))
6068 gcc_unreachable ();
6069 return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
6070 }
6071
6072 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
6073 the first vec_perm operand, assuming the second operand (for left shift
6074 first operand) is a constant vector of zeros. Return the shift distance
6075 in bits if so, or NULL_RTX if the vec_perm is not a shift. MODE is the
6076 mode of the value being shifted. SHIFT_OPTAB is vec_shr_optab for right
6077 shift or vec_shl_optab for left shift. */
6078 static rtx
6079 shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel,
6080 optab shift_optab)
6081 {
6082 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
6083 poly_int64 first = sel[0];
6084 if (maybe_ge (sel[0], GET_MODE_NUNITS (mode)))
6085 return NULL_RTX;
6086
6087 if (shift_optab == vec_shl_optab)
6088 {
6089 unsigned int nelt;
6090 if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
6091 return NULL_RTX;
6092 unsigned firstidx = 0;
6093 for (unsigned int i = 0; i < nelt; i++)
6094 {
6095 if (known_eq (sel[i], nelt))
6096 {
6097 if (i == 0 || firstidx)
6098 return NULL_RTX;
6099 firstidx = i;
6100 }
6101 else if (firstidx
6102 ? maybe_ne (sel[i], nelt + i - firstidx)
6103 : maybe_ge (sel[i], nelt))
6104 return NULL_RTX;
6105 }
6106
6107 if (firstidx == 0)
6108 return NULL_RTX;
6109 first = firstidx;
6110 }
6111 else if (!sel.series_p (0, 1, first, 1))
6112 {
6113 unsigned int nelt;
6114 if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
6115 return NULL_RTX;
6116 for (unsigned int i = 1; i < nelt; i++)
6117 {
6118 poly_int64 expected = i + first;
6119 /* Indices into the second vector are all equivalent. */
6120 if (maybe_lt (sel[i], nelt)
6121 ? maybe_ne (sel[i], expected)
6122 : maybe_lt (expected, nelt))
6123 return NULL_RTX;
6124 }
6125 }
6126
6127 return gen_int_shift_amount (mode, first * bitsize);
6128 }
6129
6130 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn. */
6131
6132 static rtx
6133 expand_vec_perm_1 (enum insn_code icode, rtx target,
6134 rtx v0, rtx v1, rtx sel)
6135 {
6136 machine_mode tmode = GET_MODE (target);
6137 machine_mode smode = GET_MODE (sel);
6138 class expand_operand ops[4];
6139
6140 gcc_assert (GET_MODE_CLASS (smode) == MODE_VECTOR_INT
6141 || related_int_vector_mode (tmode).require () == smode);
6142 create_output_operand (&ops[0], target, tmode);
6143 create_input_operand (&ops[3], sel, smode);
6144
6145 /* Make an effort to preserve v0 == v1. The target expander is able to
6146 rely on this to determine if we're permuting a single input operand. */
6147 if (rtx_equal_p (v0, v1))
6148 {
6149 if (!insn_operand_matches (icode, 1, v0))
6150 v0 = force_reg (tmode, v0);
6151 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
6152 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
6153
6154 create_fixed_operand (&ops[1], v0);
6155 create_fixed_operand (&ops[2], v0);
6156 }
6157 else
6158 {
6159 create_input_operand (&ops[1], v0, tmode);
6160 create_input_operand (&ops[2], v1, tmode);
6161 }
6162
6163 if (maybe_expand_insn (icode, 4, ops))
6164 return ops[0].value;
6165 return NULL_RTX;
6166 }
6167
6168 /* Implement a permutation of vectors v0 and v1 using the permutation
6169 vector in SEL and return the result. Use TARGET to hold the result
6170 if nonnull and convenient.
6171
6172 MODE is the mode of the vectors being permuted (V0 and V1). SEL_MODE
6173 is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
6174 to have a particular mode. */
6175
6176 rtx
6177 expand_vec_perm_const (machine_mode mode, rtx v0, rtx v1,
6178 const vec_perm_builder &sel, machine_mode sel_mode,
6179 rtx target)
6180 {
6181 if (!target || !register_operand (target, mode))
6182 target = gen_reg_rtx (mode);
6183
6184 /* Set QIMODE to a different vector mode with byte elements.
6185 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6186 machine_mode qimode;
6187 if (!qimode_for_vec_perm (mode).exists (&qimode))
6188 qimode = VOIDmode;
6189
6190 rtx_insn *last = get_last_insn ();
6191
6192 bool single_arg_p = rtx_equal_p (v0, v1);
6193 /* Always specify two input vectors here and leave the target to handle
6194 cases in which the inputs are equal. Not all backends can cope with
6195 the single-input representation when testing for a double-input
6196 target instruction. */
6197 vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode));
6198
6199 /* See if this can be handled with a vec_shr or vec_shl. We only do this
6200 if the second (for vec_shr) or first (for vec_shl) vector is all
6201 zeroes. */
6202 insn_code shift_code = CODE_FOR_nothing;
6203 insn_code shift_code_qi = CODE_FOR_nothing;
6204 optab shift_optab = unknown_optab;
6205 rtx v2 = v0;
6206 if (v1 == CONST0_RTX (GET_MODE (v1)))
6207 shift_optab = vec_shr_optab;
6208 else if (v0 == CONST0_RTX (GET_MODE (v0)))
6209 {
6210 shift_optab = vec_shl_optab;
6211 v2 = v1;
6212 }
6213 if (shift_optab != unknown_optab)
6214 {
6215 shift_code = optab_handler (shift_optab, mode);
6216 shift_code_qi = ((qimode != VOIDmode && qimode != mode)
6217 ? optab_handler (shift_optab, qimode)
6218 : CODE_FOR_nothing);
6219 }
6220 if (shift_code != CODE_FOR_nothing || shift_code_qi != CODE_FOR_nothing)
6221 {
6222 rtx shift_amt = shift_amt_for_vec_perm_mask (mode, indices, shift_optab);
6223 if (shift_amt)
6224 {
6225 class expand_operand ops[3];
6226 if (shift_amt == const0_rtx)
6227 return v2;
6228 if (shift_code != CODE_FOR_nothing)
6229 {
6230 create_output_operand (&ops[0], target, mode);
6231 create_input_operand (&ops[1], v2, mode);
6232 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
6233 if (maybe_expand_insn (shift_code, 3, ops))
6234 return ops[0].value;
6235 }
6236 if (shift_code_qi != CODE_FOR_nothing)
6237 {
6238 rtx tmp = gen_reg_rtx (qimode);
6239 create_output_operand (&ops[0], tmp, qimode);
6240 create_input_operand (&ops[1], gen_lowpart (qimode, v2), qimode);
6241 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
6242 if (maybe_expand_insn (shift_code_qi, 3, ops))
6243 return gen_lowpart (mode, ops[0].value);
6244 }
6245 }
6246 }
6247
6248 if (targetm.vectorize.vec_perm_const != NULL)
6249 {
6250 if (single_arg_p)
6251 v1 = v0;
6252
6253 gcc_checking_assert (GET_MODE (v0) == GET_MODE (v1));
6254 machine_mode op_mode = GET_MODE (v0);
6255 if (targetm.vectorize.vec_perm_const (mode, op_mode, target, v0, v1,
6256 indices))
6257 return target;
6258 }
6259
6260 /* Fall back to a constant byte-based permutation. */
6261 vec_perm_indices qimode_indices;
6262 rtx target_qi = NULL_RTX, v0_qi = NULL_RTX, v1_qi = NULL_RTX;
6263 if (qimode != VOIDmode)
6264 {
6265 qimode_indices.new_expanded_vector (indices, GET_MODE_UNIT_SIZE (mode));
6266 target_qi = gen_reg_rtx (qimode);
6267 v0_qi = gen_lowpart (qimode, v0);
6268 v1_qi = gen_lowpart (qimode, v1);
6269 if (targetm.vectorize.vec_perm_const != NULL
6270 && targetm.vectorize.vec_perm_const (qimode, qimode, target_qi, v0_qi,
6271 v1_qi, qimode_indices))
6272 return gen_lowpart (mode, target_qi);
6273 }
6274
6275 v0 = force_reg (mode, v0);
6276 if (single_arg_p)
6277 v1 = v0;
6278 v1 = force_reg (mode, v1);
6279
6280 /* Otherwise expand as a fully variable permuation. */
6281
6282 /* The optabs are only defined for selectors with the same width
6283 as the values being permuted. */
6284 machine_mode required_sel_mode;
6285 if (!related_int_vector_mode (mode).exists (&required_sel_mode))
6286 {
6287 delete_insns_since (last);
6288 return NULL_RTX;
6289 }
6290
6291 /* We know that it is semantically valid to treat SEL as having SEL_MODE.
6292 If that isn't the mode we want then we need to prove that using
6293 REQUIRED_SEL_MODE is OK. */
6294 if (sel_mode != required_sel_mode)
6295 {
6296 if (!selector_fits_mode_p (required_sel_mode, indices))
6297 {
6298 delete_insns_since (last);
6299 return NULL_RTX;
6300 }
6301 sel_mode = required_sel_mode;
6302 }
6303
6304 insn_code icode = direct_optab_handler (vec_perm_optab, mode);
6305 if (icode != CODE_FOR_nothing)
6306 {
6307 rtx sel_rtx = vec_perm_indices_to_rtx (sel_mode, indices);
6308 rtx tmp = expand_vec_perm_1 (icode, target, v0, v1, sel_rtx);
6309 if (tmp)
6310 return tmp;
6311 }
6312
6313 if (qimode != VOIDmode
6314 && selector_fits_mode_p (qimode, qimode_indices))
6315 {
6316 icode = direct_optab_handler (vec_perm_optab, qimode);
6317 if (icode != CODE_FOR_nothing)
6318 {
6319 rtx sel_qi = vec_perm_indices_to_rtx (qimode, qimode_indices);
6320 rtx tmp = expand_vec_perm_1 (icode, target_qi, v0_qi, v1_qi, sel_qi);
6321 if (tmp)
6322 return gen_lowpart (mode, tmp);
6323 }
6324 }
6325
6326 delete_insns_since (last);
6327 return NULL_RTX;
6328 }
6329
6330 /* Implement a permutation of vectors v0 and v1 using the permutation
6331 vector in SEL and return the result. Use TARGET to hold the result
6332 if nonnull and convenient.
6333
6334 MODE is the mode of the vectors being permuted (V0 and V1).
6335 SEL must have the integer equivalent of MODE and is known to be
6336 unsuitable for permutes with a constant permutation vector. */
6337
6338 rtx
6339 expand_vec_perm_var (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
6340 {
6341 enum insn_code icode;
6342 unsigned int i, u;
6343 rtx tmp, sel_qi;
6344
6345 u = GET_MODE_UNIT_SIZE (mode);
6346
6347 if (!target || GET_MODE (target) != mode)
6348 target = gen_reg_rtx (mode);
6349
6350 icode = direct_optab_handler (vec_perm_optab, mode);
6351 if (icode != CODE_FOR_nothing)
6352 {
6353 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6354 if (tmp)
6355 return tmp;
6356 }
6357
6358 /* As a special case to aid several targets, lower the element-based
6359 permutation to a byte-based permutation and try again. */
6360 machine_mode qimode;
6361 if (!qimode_for_vec_perm (mode).exists (&qimode)
6362 || maybe_gt (GET_MODE_NUNITS (qimode), GET_MODE_MASK (QImode) + 1))
6363 return NULL_RTX;
6364 icode = direct_optab_handler (vec_perm_optab, qimode);
6365 if (icode == CODE_FOR_nothing)
6366 return NULL_RTX;
6367
6368 /* Multiply each element by its byte size. */
6369 machine_mode selmode = GET_MODE (sel);
6370 if (u == 2)
6371 sel = expand_simple_binop (selmode, PLUS, sel, sel,
6372 NULL, 0, OPTAB_DIRECT);
6373 else
6374 sel = expand_simple_binop (selmode, ASHIFT, sel,
6375 gen_int_shift_amount (selmode, exact_log2 (u)),
6376 NULL, 0, OPTAB_DIRECT);
6377 gcc_assert (sel != NULL);
6378
6379 /* Broadcast the low byte each element into each of its bytes.
6380 The encoding has U interleaved stepped patterns, one for each
6381 byte of an element. */
6382 vec_perm_builder const_sel (GET_MODE_SIZE (mode), u, 3);
6383 unsigned int low_byte_in_u = BYTES_BIG_ENDIAN ? u - 1 : 0;
6384 for (i = 0; i < 3; ++i)
6385 for (unsigned int j = 0; j < u; ++j)
6386 const_sel.quick_push (i * u + low_byte_in_u);
6387 sel = gen_lowpart (qimode, sel);
6388 sel = expand_vec_perm_const (qimode, sel, sel, const_sel, qimode, NULL);
6389 gcc_assert (sel != NULL);
6390
6391 /* Add the byte offset to each byte element. */
6392 /* Note that the definition of the indicies here is memory ordering,
6393 so there should be no difference between big and little endian. */
6394 rtx_vector_builder byte_indices (qimode, u, 1);
6395 for (i = 0; i < u; ++i)
6396 byte_indices.quick_push (GEN_INT (i));
6397 tmp = byte_indices.build ();
6398 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
6399 sel, 0, OPTAB_DIRECT);
6400 gcc_assert (sel_qi != NULL);
6401
6402 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
6403 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
6404 gen_lowpart (qimode, v1), sel_qi);
6405 if (tmp)
6406 tmp = gen_lowpart (mode, tmp);
6407 return tmp;
6408 }
6409
6410 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
6411 Use TARGET for the result if nonnull and convenient. */
6412
6413 rtx
6414 expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
6415 {
6416 class expand_operand ops[3];
6417 enum insn_code icode;
6418 machine_mode emode = GET_MODE_INNER (vmode);
6419
6420 icode = direct_optab_handler (vec_series_optab, vmode);
6421 gcc_assert (icode != CODE_FOR_nothing);
6422
6423 create_output_operand (&ops[0], target, vmode);
6424 create_input_operand (&ops[1], op0, emode);
6425 create_input_operand (&ops[2], op1, emode);
6426
6427 expand_insn (icode, 3, ops);
6428 return ops[0].value;
6429 }
6430
6431 /* Generate insns for a vector comparison into a mask. */
6432
6433 rtx
6434 expand_vec_cmp_expr (tree type, tree exp, rtx target)
6435 {
6436 class expand_operand ops[4];
6437 enum insn_code icode;
6438 rtx comparison;
6439 machine_mode mask_mode = TYPE_MODE (type);
6440 machine_mode vmode;
6441 bool unsignedp;
6442 tree op0a, op0b;
6443 enum tree_code tcode;
6444
6445 op0a = TREE_OPERAND (exp, 0);
6446 op0b = TREE_OPERAND (exp, 1);
6447 tcode = TREE_CODE (exp);
6448
6449 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
6450 vmode = TYPE_MODE (TREE_TYPE (op0a));
6451
6452 icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
6453 if (icode == CODE_FOR_nothing)
6454 {
6455 if (tcode == EQ_EXPR || tcode == NE_EXPR)
6456 icode = get_vec_cmp_eq_icode (vmode, mask_mode);
6457 if (icode == CODE_FOR_nothing)
6458 return 0;
6459 }
6460
6461 comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
6462 unsignedp, icode, 2);
6463 create_output_operand (&ops[0], target, mask_mode);
6464 create_fixed_operand (&ops[1], comparison);
6465 create_fixed_operand (&ops[2], XEXP (comparison, 0));
6466 create_fixed_operand (&ops[3], XEXP (comparison, 1));
6467 expand_insn (icode, 4, ops);
6468 return ops[0].value;
6469 }
6470
6471 /* Expand a highpart multiply. */
6472
6473 rtx
6474 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
6475 rtx target, bool uns_p)
6476 {
6477 class expand_operand eops[3];
6478 enum insn_code icode;
6479 int method, i;
6480 machine_mode wmode;
6481 rtx m1, m2;
6482 optab tab1, tab2;
6483
6484 method = can_mult_highpart_p (mode, uns_p);
6485 switch (method)
6486 {
6487 case 0:
6488 return NULL_RTX;
6489 case 1:
6490 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
6491 return expand_binop (mode, tab1, op0, op1, target, uns_p,
6492 OPTAB_LIB_WIDEN);
6493 case 2:
6494 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6495 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6496 break;
6497 case 3:
6498 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6499 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6500 if (BYTES_BIG_ENDIAN)
6501 std::swap (tab1, tab2);
6502 break;
6503 default:
6504 gcc_unreachable ();
6505 }
6506
6507 icode = optab_handler (tab1, mode);
6508 wmode = insn_data[icode].operand[0].mode;
6509 gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode),
6510 GET_MODE_NUNITS (mode)));
6511 gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode), GET_MODE_SIZE (mode)));
6512
6513 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6514 create_input_operand (&eops[1], op0, mode);
6515 create_input_operand (&eops[2], op1, mode);
6516 expand_insn (icode, 3, eops);
6517 m1 = gen_lowpart (mode, eops[0].value);
6518
6519 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6520 create_input_operand (&eops[1], op0, mode);
6521 create_input_operand (&eops[2], op1, mode);
6522 expand_insn (optab_handler (tab2, mode), 3, eops);
6523 m2 = gen_lowpart (mode, eops[0].value);
6524
6525 vec_perm_builder sel;
6526 if (method == 2)
6527 {
6528 /* The encoding has 2 interleaved stepped patterns. */
6529 sel.new_vector (GET_MODE_NUNITS (mode), 2, 3);
6530 for (i = 0; i < 6; ++i)
6531 sel.quick_push (!BYTES_BIG_ENDIAN + (i & ~1)
6532 + ((i & 1) ? GET_MODE_NUNITS (mode) : 0));
6533 }
6534 else
6535 {
6536 /* The encoding has a single interleaved stepped pattern. */
6537 sel.new_vector (GET_MODE_NUNITS (mode), 1, 3);
6538 for (i = 0; i < 3; ++i)
6539 sel.quick_push (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
6540 }
6541
6542 return expand_vec_perm_const (mode, m1, m2, sel, BLKmode, target);
6543 }
6544 \f
6545 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6546 pattern. */
6547
6548 static void
6549 find_cc_set (rtx x, const_rtx pat, void *data)
6550 {
6551 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
6552 && GET_CODE (pat) == SET)
6553 {
6554 rtx *p_cc_reg = (rtx *) data;
6555 gcc_assert (!*p_cc_reg);
6556 *p_cc_reg = x;
6557 }
6558 }
6559
6560 /* This is a helper function for the other atomic operations. This function
6561 emits a loop that contains SEQ that iterates until a compare-and-swap
6562 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6563 a set of instructions that takes a value from OLD_REG as an input and
6564 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6565 set to the current contents of MEM. After SEQ, a compare-and-swap will
6566 attempt to update MEM with NEW_REG. The function returns true when the
6567 loop was generated successfully. */
6568
6569 static bool
6570 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6571 {
6572 machine_mode mode = GET_MODE (mem);
6573 rtx_code_label *label;
6574 rtx cmp_reg, success, oldval;
6575
6576 /* The loop we want to generate looks like
6577
6578 cmp_reg = mem;
6579 label:
6580 old_reg = cmp_reg;
6581 seq;
6582 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6583 if (success)
6584 goto label;
6585
6586 Note that we only do the plain load from memory once. Subsequent
6587 iterations use the value loaded by the compare-and-swap pattern. */
6588
6589 label = gen_label_rtx ();
6590 cmp_reg = gen_reg_rtx (mode);
6591
6592 emit_move_insn (cmp_reg, mem);
6593 emit_label (label);
6594 emit_move_insn (old_reg, cmp_reg);
6595 if (seq)
6596 emit_insn (seq);
6597
6598 success = NULL_RTX;
6599 oldval = cmp_reg;
6600 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
6601 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
6602 MEMMODEL_RELAXED))
6603 return false;
6604
6605 if (oldval != cmp_reg)
6606 emit_move_insn (cmp_reg, oldval);
6607
6608 /* Mark this jump predicted not taken. */
6609 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
6610 GET_MODE (success), 1, label,
6611 profile_probability::guessed_never ());
6612 return true;
6613 }
6614
6615
6616 /* This function tries to emit an atomic_exchange intruction. VAL is written
6617 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6618 using TARGET if possible. */
6619
6620 static rtx
6621 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6622 {
6623 machine_mode mode = GET_MODE (mem);
6624 enum insn_code icode;
6625
6626 /* If the target supports the exchange directly, great. */
6627 icode = direct_optab_handler (atomic_exchange_optab, mode);
6628 if (icode != CODE_FOR_nothing)
6629 {
6630 class expand_operand ops[4];
6631
6632 create_output_operand (&ops[0], target, mode);
6633 create_fixed_operand (&ops[1], mem);
6634 create_input_operand (&ops[2], val, mode);
6635 create_integer_operand (&ops[3], model);
6636 if (maybe_expand_insn (icode, 4, ops))
6637 return ops[0].value;
6638 }
6639
6640 return NULL_RTX;
6641 }
6642
6643 /* This function tries to implement an atomic exchange operation using
6644 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6645 The previous contents of *MEM are returned, using TARGET if possible.
6646 Since this instructionn is an acquire barrier only, stronger memory
6647 models may require additional barriers to be emitted. */
6648
6649 static rtx
6650 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
6651 enum memmodel model)
6652 {
6653 machine_mode mode = GET_MODE (mem);
6654 enum insn_code icode;
6655 rtx_insn *last_insn = get_last_insn ();
6656
6657 icode = optab_handler (sync_lock_test_and_set_optab, mode);
6658
6659 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
6660 exists, and the memory model is stronger than acquire, add a release
6661 barrier before the instruction. */
6662
6663 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
6664 expand_mem_thread_fence (model);
6665
6666 if (icode != CODE_FOR_nothing)
6667 {
6668 class expand_operand ops[3];
6669 create_output_operand (&ops[0], target, mode);
6670 create_fixed_operand (&ops[1], mem);
6671 create_input_operand (&ops[2], val, mode);
6672 if (maybe_expand_insn (icode, 3, ops))
6673 return ops[0].value;
6674 }
6675
6676 /* If an external test-and-set libcall is provided, use that instead of
6677 any external compare-and-swap that we might get from the compare-and-
6678 swap-loop expansion later. */
6679 if (!can_compare_and_swap_p (mode, false))
6680 {
6681 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
6682 if (libfunc != NULL)
6683 {
6684 rtx addr;
6685
6686 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6687 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6688 mode, addr, ptr_mode,
6689 val, mode);
6690 }
6691 }
6692
6693 /* If the test_and_set can't be emitted, eliminate any barrier that might
6694 have been emitted. */
6695 delete_insns_since (last_insn);
6696 return NULL_RTX;
6697 }
6698
6699 /* This function tries to implement an atomic exchange operation using a
6700 compare_and_swap loop. VAL is written to *MEM. The previous contents of
6701 *MEM are returned, using TARGET if possible. No memory model is required
6702 since a compare_and_swap loop is seq-cst. */
6703
6704 static rtx
6705 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
6706 {
6707 machine_mode mode = GET_MODE (mem);
6708
6709 if (can_compare_and_swap_p (mode, true))
6710 {
6711 if (!target || !register_operand (target, mode))
6712 target = gen_reg_rtx (mode);
6713 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6714 return target;
6715 }
6716
6717 return NULL_RTX;
6718 }
6719
6720 /* This function tries to implement an atomic test-and-set operation
6721 using the atomic_test_and_set instruction pattern. A boolean value
6722 is returned from the operation, using TARGET if possible. */
6723
6724 static rtx
6725 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6726 {
6727 machine_mode pat_bool_mode;
6728 class expand_operand ops[3];
6729
6730 if (!targetm.have_atomic_test_and_set ())
6731 return NULL_RTX;
6732
6733 /* While we always get QImode from __atomic_test_and_set, we get
6734 other memory modes from __sync_lock_test_and_set. Note that we
6735 use no endian adjustment here. This matches the 4.6 behavior
6736 in the Sparc backend. */
6737 enum insn_code icode = targetm.code_for_atomic_test_and_set;
6738 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
6739 if (GET_MODE (mem) != QImode)
6740 mem = adjust_address_nv (mem, QImode, 0);
6741
6742 pat_bool_mode = insn_data[icode].operand[0].mode;
6743 create_output_operand (&ops[0], target, pat_bool_mode);
6744 create_fixed_operand (&ops[1], mem);
6745 create_integer_operand (&ops[2], model);
6746
6747 if (maybe_expand_insn (icode, 3, ops))
6748 return ops[0].value;
6749 return NULL_RTX;
6750 }
6751
6752 /* This function expands the legacy _sync_lock test_and_set operation which is
6753 generally an atomic exchange. Some limited targets only allow the
6754 constant 1 to be stored. This is an ACQUIRE operation.
6755
6756 TARGET is an optional place to stick the return value.
6757 MEM is where VAL is stored. */
6758
6759 rtx
6760 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
6761 {
6762 rtx ret;
6763
6764 /* Try an atomic_exchange first. */
6765 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
6766 if (ret)
6767 return ret;
6768
6769 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
6770 MEMMODEL_SYNC_ACQUIRE);
6771 if (ret)
6772 return ret;
6773
6774 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6775 if (ret)
6776 return ret;
6777
6778 /* If there are no other options, try atomic_test_and_set if the value
6779 being stored is 1. */
6780 if (val == const1_rtx)
6781 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
6782
6783 return ret;
6784 }
6785
6786 /* This function expands the atomic test_and_set operation:
6787 atomically store a boolean TRUE into MEM and return the previous value.
6788
6789 MEMMODEL is the memory model variant to use.
6790 TARGET is an optional place to stick the return value. */
6791
6792 rtx
6793 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6794 {
6795 machine_mode mode = GET_MODE (mem);
6796 rtx ret, trueval, subtarget;
6797
6798 ret = maybe_emit_atomic_test_and_set (target, mem, model);
6799 if (ret)
6800 return ret;
6801
6802 /* Be binary compatible with non-default settings of trueval, and different
6803 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6804 another only has atomic-exchange. */
6805 if (targetm.atomic_test_and_set_trueval == 1)
6806 {
6807 trueval = const1_rtx;
6808 subtarget = target ? target : gen_reg_rtx (mode);
6809 }
6810 else
6811 {
6812 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
6813 subtarget = gen_reg_rtx (mode);
6814 }
6815
6816 /* Try the atomic-exchange optab... */
6817 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
6818
6819 /* ... then an atomic-compare-and-swap loop ... */
6820 if (!ret)
6821 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
6822
6823 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6824 if (!ret)
6825 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
6826
6827 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6828 things with the value 1. Thus we try again without trueval. */
6829 if (!ret && targetm.atomic_test_and_set_trueval != 1)
6830 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
6831
6832 /* Failing all else, assume a single threaded environment and simply
6833 perform the operation. */
6834 if (!ret)
6835 {
6836 /* If the result is ignored skip the move to target. */
6837 if (subtarget != const0_rtx)
6838 emit_move_insn (subtarget, mem);
6839
6840 emit_move_insn (mem, trueval);
6841 ret = subtarget;
6842 }
6843
6844 /* Recall that have to return a boolean value; rectify if trueval
6845 is not exactly one. */
6846 if (targetm.atomic_test_and_set_trueval != 1)
6847 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
6848
6849 return ret;
6850 }
6851
6852 /* This function expands the atomic exchange operation:
6853 atomically store VAL in MEM and return the previous value in MEM.
6854
6855 MEMMODEL is the memory model variant to use.
6856 TARGET is an optional place to stick the return value. */
6857
6858 rtx
6859 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6860 {
6861 machine_mode mode = GET_MODE (mem);
6862 rtx ret;
6863
6864 /* If loads are not atomic for the required size and we are not called to
6865 provide a __sync builtin, do not do anything so that we stay consistent
6866 with atomic loads of the same size. */
6867 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6868 return NULL_RTX;
6869
6870 ret = maybe_emit_atomic_exchange (target, mem, val, model);
6871
6872 /* Next try a compare-and-swap loop for the exchange. */
6873 if (!ret)
6874 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6875
6876 return ret;
6877 }
6878
6879 /* This function expands the atomic compare exchange operation:
6880
6881 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6882 *PTARGET_OVAL is an optional place to store the old value from memory.
6883 Both target parameters may be NULL or const0_rtx to indicate that we do
6884 not care about that return value. Both target parameters are updated on
6885 success to the actual location of the corresponding result.
6886
6887 MEMMODEL is the memory model variant to use.
6888
6889 The return value of the function is true for success. */
6890
6891 bool
6892 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
6893 rtx mem, rtx expected, rtx desired,
6894 bool is_weak, enum memmodel succ_model,
6895 enum memmodel fail_model)
6896 {
6897 machine_mode mode = GET_MODE (mem);
6898 class expand_operand ops[8];
6899 enum insn_code icode;
6900 rtx target_oval, target_bool = NULL_RTX;
6901 rtx libfunc;
6902
6903 /* If loads are not atomic for the required size and we are not called to
6904 provide a __sync builtin, do not do anything so that we stay consistent
6905 with atomic loads of the same size. */
6906 if (!can_atomic_load_p (mode) && !is_mm_sync (succ_model))
6907 return false;
6908
6909 /* Load expected into a register for the compare and swap. */
6910 if (MEM_P (expected))
6911 expected = copy_to_reg (expected);
6912
6913 /* Make sure we always have some place to put the return oldval.
6914 Further, make sure that place is distinct from the input expected,
6915 just in case we need that path down below. */
6916 if (ptarget_oval && *ptarget_oval == const0_rtx)
6917 ptarget_oval = NULL;
6918
6919 if (ptarget_oval == NULL
6920 || (target_oval = *ptarget_oval) == NULL
6921 || reg_overlap_mentioned_p (expected, target_oval))
6922 target_oval = gen_reg_rtx (mode);
6923
6924 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6925 if (icode != CODE_FOR_nothing)
6926 {
6927 machine_mode bool_mode = insn_data[icode].operand[0].mode;
6928
6929 if (ptarget_bool && *ptarget_bool == const0_rtx)
6930 ptarget_bool = NULL;
6931
6932 /* Make sure we always have a place for the bool operand. */
6933 if (ptarget_bool == NULL
6934 || (target_bool = *ptarget_bool) == NULL
6935 || GET_MODE (target_bool) != bool_mode)
6936 target_bool = gen_reg_rtx (bool_mode);
6937
6938 /* Emit the compare_and_swap. */
6939 create_output_operand (&ops[0], target_bool, bool_mode);
6940 create_output_operand (&ops[1], target_oval, mode);
6941 create_fixed_operand (&ops[2], mem);
6942 create_input_operand (&ops[3], expected, mode);
6943 create_input_operand (&ops[4], desired, mode);
6944 create_integer_operand (&ops[5], is_weak);
6945 create_integer_operand (&ops[6], succ_model);
6946 create_integer_operand (&ops[7], fail_model);
6947 if (maybe_expand_insn (icode, 8, ops))
6948 {
6949 /* Return success/failure. */
6950 target_bool = ops[0].value;
6951 target_oval = ops[1].value;
6952 goto success;
6953 }
6954 }
6955
6956 /* Otherwise fall back to the original __sync_val_compare_and_swap
6957 which is always seq-cst. */
6958 icode = optab_handler (sync_compare_and_swap_optab, mode);
6959 if (icode != CODE_FOR_nothing)
6960 {
6961 rtx cc_reg;
6962
6963 create_output_operand (&ops[0], target_oval, mode);
6964 create_fixed_operand (&ops[1], mem);
6965 create_input_operand (&ops[2], expected, mode);
6966 create_input_operand (&ops[3], desired, mode);
6967 if (!maybe_expand_insn (icode, 4, ops))
6968 return false;
6969
6970 target_oval = ops[0].value;
6971
6972 /* If the caller isn't interested in the boolean return value,
6973 skip the computation of it. */
6974 if (ptarget_bool == NULL)
6975 goto success;
6976
6977 /* Otherwise, work out if the compare-and-swap succeeded. */
6978 cc_reg = NULL_RTX;
6979 if (have_insn_for (COMPARE, CCmode))
6980 note_stores (get_last_insn (), find_cc_set, &cc_reg);
6981 if (cc_reg)
6982 {
6983 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6984 const0_rtx, VOIDmode, 0, 1);
6985 goto success;
6986 }
6987 goto success_bool_from_val;
6988 }
6989
6990 /* Also check for library support for __sync_val_compare_and_swap. */
6991 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6992 if (libfunc != NULL)
6993 {
6994 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6995 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6996 mode, addr, ptr_mode,
6997 expected, mode, desired, mode);
6998 emit_move_insn (target_oval, target);
6999
7000 /* Compute the boolean return value only if requested. */
7001 if (ptarget_bool)
7002 goto success_bool_from_val;
7003 else
7004 goto success;
7005 }
7006
7007 /* Failure. */
7008 return false;
7009
7010 success_bool_from_val:
7011 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
7012 expected, VOIDmode, 1, 1);
7013 success:
7014 /* Make sure that the oval output winds up where the caller asked. */
7015 if (ptarget_oval)
7016 *ptarget_oval = target_oval;
7017 if (ptarget_bool)
7018 *ptarget_bool = target_bool;
7019 return true;
7020 }
7021
7022 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
7023
7024 static void
7025 expand_asm_memory_blockage (void)
7026 {
7027 rtx asm_op, clob;
7028
7029 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
7030 rtvec_alloc (0), rtvec_alloc (0),
7031 rtvec_alloc (0), UNKNOWN_LOCATION);
7032 MEM_VOLATILE_P (asm_op) = 1;
7033
7034 clob = gen_rtx_SCRATCH (VOIDmode);
7035 clob = gen_rtx_MEM (BLKmode, clob);
7036 clob = gen_rtx_CLOBBER (VOIDmode, clob);
7037
7038 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
7039 }
7040
7041 /* Do not propagate memory accesses across this point. */
7042
7043 static void
7044 expand_memory_blockage (void)
7045 {
7046 if (targetm.have_memory_blockage ())
7047 emit_insn (targetm.gen_memory_blockage ());
7048 else
7049 expand_asm_memory_blockage ();
7050 }
7051
7052 /* Generate asm volatile("" : : : "memory") as a memory blockage, at the
7053 same time clobbering the register set specified by REGS. */
7054
7055 void
7056 expand_asm_reg_clobber_mem_blockage (HARD_REG_SET regs)
7057 {
7058 rtx asm_op, clob_mem;
7059
7060 unsigned int num_of_regs = 0;
7061 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7062 if (TEST_HARD_REG_BIT (regs, i))
7063 num_of_regs++;
7064
7065 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
7066 rtvec_alloc (0), rtvec_alloc (0),
7067 rtvec_alloc (0), UNKNOWN_LOCATION);
7068 MEM_VOLATILE_P (asm_op) = 1;
7069
7070 rtvec v = rtvec_alloc (num_of_regs + 2);
7071
7072 clob_mem = gen_rtx_SCRATCH (VOIDmode);
7073 clob_mem = gen_rtx_MEM (BLKmode, clob_mem);
7074 clob_mem = gen_rtx_CLOBBER (VOIDmode, clob_mem);
7075
7076 RTVEC_ELT (v, 0) = asm_op;
7077 RTVEC_ELT (v, 1) = clob_mem;
7078
7079 if (num_of_regs > 0)
7080 {
7081 unsigned int j = 2;
7082 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7083 if (TEST_HARD_REG_BIT (regs, i))
7084 {
7085 RTVEC_ELT (v, j) = gen_rtx_CLOBBER (VOIDmode, regno_reg_rtx[i]);
7086 j++;
7087 }
7088 gcc_assert (j == (num_of_regs + 2));
7089 }
7090
7091 emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
7092 }
7093
7094 /* This routine will either emit the mem_thread_fence pattern or issue a
7095 sync_synchronize to generate a fence for memory model MEMMODEL. */
7096
7097 void
7098 expand_mem_thread_fence (enum memmodel model)
7099 {
7100 if (is_mm_relaxed (model))
7101 return;
7102 if (targetm.have_mem_thread_fence ())
7103 {
7104 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
7105 expand_memory_blockage ();
7106 }
7107 else if (targetm.have_memory_barrier ())
7108 emit_insn (targetm.gen_memory_barrier ());
7109 else if (synchronize_libfunc != NULL_RTX)
7110 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode);
7111 else
7112 expand_memory_blockage ();
7113 }
7114
7115 /* Emit a signal fence with given memory model. */
7116
7117 void
7118 expand_mem_signal_fence (enum memmodel model)
7119 {
7120 /* No machine barrier is required to implement a signal fence, but
7121 a compiler memory barrier must be issued, except for relaxed MM. */
7122 if (!is_mm_relaxed (model))
7123 expand_memory_blockage ();
7124 }
7125
7126 /* This function expands the atomic load operation:
7127 return the atomically loaded value in MEM.
7128
7129 MEMMODEL is the memory model variant to use.
7130 TARGET is an option place to stick the return value. */
7131
7132 rtx
7133 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
7134 {
7135 machine_mode mode = GET_MODE (mem);
7136 enum insn_code icode;
7137
7138 /* If the target supports the load directly, great. */
7139 icode = direct_optab_handler (atomic_load_optab, mode);
7140 if (icode != CODE_FOR_nothing)
7141 {
7142 class expand_operand ops[3];
7143 rtx_insn *last = get_last_insn ();
7144 if (is_mm_seq_cst (model))
7145 expand_memory_blockage ();
7146
7147 create_output_operand (&ops[0], target, mode);
7148 create_fixed_operand (&ops[1], mem);
7149 create_integer_operand (&ops[2], model);
7150 if (maybe_expand_insn (icode, 3, ops))
7151 {
7152 if (!is_mm_relaxed (model))
7153 expand_memory_blockage ();
7154 return ops[0].value;
7155 }
7156 delete_insns_since (last);
7157 }
7158
7159 /* If the size of the object is greater than word size on this target,
7160 then we assume that a load will not be atomic. We could try to
7161 emulate a load with a compare-and-swap operation, but the store that
7162 doing this could result in would be incorrect if this is a volatile
7163 atomic load or targetting read-only-mapped memory. */
7164 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
7165 /* If there is no atomic load, leave the library call. */
7166 return NULL_RTX;
7167
7168 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7169 if (!target || target == const0_rtx)
7170 target = gen_reg_rtx (mode);
7171
7172 /* For SEQ_CST, emit a barrier before the load. */
7173 if (is_mm_seq_cst (model))
7174 expand_mem_thread_fence (model);
7175
7176 emit_move_insn (target, mem);
7177
7178 /* Emit the appropriate barrier after the load. */
7179 expand_mem_thread_fence (model);
7180
7181 return target;
7182 }
7183
7184 /* This function expands the atomic store operation:
7185 Atomically store VAL in MEM.
7186 MEMMODEL is the memory model variant to use.
7187 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7188 function returns const0_rtx if a pattern was emitted. */
7189
7190 rtx
7191 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
7192 {
7193 machine_mode mode = GET_MODE (mem);
7194 enum insn_code icode;
7195 class expand_operand ops[3];
7196
7197 /* If the target supports the store directly, great. */
7198 icode = direct_optab_handler (atomic_store_optab, mode);
7199 if (icode != CODE_FOR_nothing)
7200 {
7201 rtx_insn *last = get_last_insn ();
7202 if (!is_mm_relaxed (model))
7203 expand_memory_blockage ();
7204 create_fixed_operand (&ops[0], mem);
7205 create_input_operand (&ops[1], val, mode);
7206 create_integer_operand (&ops[2], model);
7207 if (maybe_expand_insn (icode, 3, ops))
7208 {
7209 if (is_mm_seq_cst (model))
7210 expand_memory_blockage ();
7211 return const0_rtx;
7212 }
7213 delete_insns_since (last);
7214 }
7215
7216 /* If using __sync_lock_release is a viable alternative, try it.
7217 Note that this will not be set to true if we are expanding a generic
7218 __atomic_store_n. */
7219 if (use_release)
7220 {
7221 icode = direct_optab_handler (sync_lock_release_optab, mode);
7222 if (icode != CODE_FOR_nothing)
7223 {
7224 create_fixed_operand (&ops[0], mem);
7225 create_input_operand (&ops[1], const0_rtx, mode);
7226 if (maybe_expand_insn (icode, 2, ops))
7227 {
7228 /* lock_release is only a release barrier. */
7229 if (is_mm_seq_cst (model))
7230 expand_mem_thread_fence (model);
7231 return const0_rtx;
7232 }
7233 }
7234 }
7235
7236 /* If the size of the object is greater than word size on this target,
7237 a default store will not be atomic. */
7238 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
7239 {
7240 /* If loads are atomic or we are called to provide a __sync builtin,
7241 we can try a atomic_exchange and throw away the result. Otherwise,
7242 don't do anything so that we do not create an inconsistency between
7243 loads and stores. */
7244 if (can_atomic_load_p (mode) || is_mm_sync (model))
7245 {
7246 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
7247 if (!target)
7248 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem,
7249 val);
7250 if (target)
7251 return const0_rtx;
7252 }
7253 return NULL_RTX;
7254 }
7255
7256 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7257 expand_mem_thread_fence (model);
7258
7259 emit_move_insn (mem, val);
7260
7261 /* For SEQ_CST, also emit a barrier after the store. */
7262 if (is_mm_seq_cst (model))
7263 expand_mem_thread_fence (model);
7264
7265 return const0_rtx;
7266 }
7267
7268
7269 /* Structure containing the pointers and values required to process the
7270 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7271
7272 struct atomic_op_functions
7273 {
7274 direct_optab mem_fetch_before;
7275 direct_optab mem_fetch_after;
7276 direct_optab mem_no_result;
7277 optab fetch_before;
7278 optab fetch_after;
7279 direct_optab no_result;
7280 enum rtx_code reverse_code;
7281 };
7282
7283
7284 /* Fill in structure pointed to by OP with the various optab entries for an
7285 operation of type CODE. */
7286
7287 static void
7288 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
7289 {
7290 gcc_assert (op!= NULL);
7291
7292 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7293 in the source code during compilation, and the optab entries are not
7294 computable until runtime. Fill in the values at runtime. */
7295 switch (code)
7296 {
7297 case PLUS:
7298 op->mem_fetch_before = atomic_fetch_add_optab;
7299 op->mem_fetch_after = atomic_add_fetch_optab;
7300 op->mem_no_result = atomic_add_optab;
7301 op->fetch_before = sync_old_add_optab;
7302 op->fetch_after = sync_new_add_optab;
7303 op->no_result = sync_add_optab;
7304 op->reverse_code = MINUS;
7305 break;
7306 case MINUS:
7307 op->mem_fetch_before = atomic_fetch_sub_optab;
7308 op->mem_fetch_after = atomic_sub_fetch_optab;
7309 op->mem_no_result = atomic_sub_optab;
7310 op->fetch_before = sync_old_sub_optab;
7311 op->fetch_after = sync_new_sub_optab;
7312 op->no_result = sync_sub_optab;
7313 op->reverse_code = PLUS;
7314 break;
7315 case XOR:
7316 op->mem_fetch_before = atomic_fetch_xor_optab;
7317 op->mem_fetch_after = atomic_xor_fetch_optab;
7318 op->mem_no_result = atomic_xor_optab;
7319 op->fetch_before = sync_old_xor_optab;
7320 op->fetch_after = sync_new_xor_optab;
7321 op->no_result = sync_xor_optab;
7322 op->reverse_code = XOR;
7323 break;
7324 case AND:
7325 op->mem_fetch_before = atomic_fetch_and_optab;
7326 op->mem_fetch_after = atomic_and_fetch_optab;
7327 op->mem_no_result = atomic_and_optab;
7328 op->fetch_before = sync_old_and_optab;
7329 op->fetch_after = sync_new_and_optab;
7330 op->no_result = sync_and_optab;
7331 op->reverse_code = UNKNOWN;
7332 break;
7333 case IOR:
7334 op->mem_fetch_before = atomic_fetch_or_optab;
7335 op->mem_fetch_after = atomic_or_fetch_optab;
7336 op->mem_no_result = atomic_or_optab;
7337 op->fetch_before = sync_old_ior_optab;
7338 op->fetch_after = sync_new_ior_optab;
7339 op->no_result = sync_ior_optab;
7340 op->reverse_code = UNKNOWN;
7341 break;
7342 case NOT:
7343 op->mem_fetch_before = atomic_fetch_nand_optab;
7344 op->mem_fetch_after = atomic_nand_fetch_optab;
7345 op->mem_no_result = atomic_nand_optab;
7346 op->fetch_before = sync_old_nand_optab;
7347 op->fetch_after = sync_new_nand_optab;
7348 op->no_result = sync_nand_optab;
7349 op->reverse_code = UNKNOWN;
7350 break;
7351 default:
7352 gcc_unreachable ();
7353 }
7354 }
7355
7356 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7357 using memory order MODEL. If AFTER is true the operation needs to return
7358 the value of *MEM after the operation, otherwise the previous value.
7359 TARGET is an optional place to place the result. The result is unused if
7360 it is const0_rtx.
7361 Return the result if there is a better sequence, otherwise NULL_RTX. */
7362
7363 static rtx
7364 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7365 enum memmodel model, bool after)
7366 {
7367 /* If the value is prefetched, or not used, it may be possible to replace
7368 the sequence with a native exchange operation. */
7369 if (!after || target == const0_rtx)
7370 {
7371 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7372 if (code == AND && val == const0_rtx)
7373 {
7374 if (target == const0_rtx)
7375 target = gen_reg_rtx (GET_MODE (mem));
7376 return maybe_emit_atomic_exchange (target, mem, val, model);
7377 }
7378
7379 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7380 if (code == IOR && val == constm1_rtx)
7381 {
7382 if (target == const0_rtx)
7383 target = gen_reg_rtx (GET_MODE (mem));
7384 return maybe_emit_atomic_exchange (target, mem, val, model);
7385 }
7386 }
7387
7388 return NULL_RTX;
7389 }
7390
7391 /* Try to emit an instruction for a specific operation varaition.
7392 OPTAB contains the OP functions.
7393 TARGET is an optional place to return the result. const0_rtx means unused.
7394 MEM is the memory location to operate on.
7395 VAL is the value to use in the operation.
7396 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7397 MODEL is the memory model, if used.
7398 AFTER is true if the returned result is the value after the operation. */
7399
7400 static rtx
7401 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
7402 rtx val, bool use_memmodel, enum memmodel model, bool after)
7403 {
7404 machine_mode mode = GET_MODE (mem);
7405 class expand_operand ops[4];
7406 enum insn_code icode;
7407 int op_counter = 0;
7408 int num_ops;
7409
7410 /* Check to see if there is a result returned. */
7411 if (target == const0_rtx)
7412 {
7413 if (use_memmodel)
7414 {
7415 icode = direct_optab_handler (optab->mem_no_result, mode);
7416 create_integer_operand (&ops[2], model);
7417 num_ops = 3;
7418 }
7419 else
7420 {
7421 icode = direct_optab_handler (optab->no_result, mode);
7422 num_ops = 2;
7423 }
7424 }
7425 /* Otherwise, we need to generate a result. */
7426 else
7427 {
7428 if (use_memmodel)
7429 {
7430 icode = direct_optab_handler (after ? optab->mem_fetch_after
7431 : optab->mem_fetch_before, mode);
7432 create_integer_operand (&ops[3], model);
7433 num_ops = 4;
7434 }
7435 else
7436 {
7437 icode = optab_handler (after ? optab->fetch_after
7438 : optab->fetch_before, mode);
7439 num_ops = 3;
7440 }
7441 create_output_operand (&ops[op_counter++], target, mode);
7442 }
7443 if (icode == CODE_FOR_nothing)
7444 return NULL_RTX;
7445
7446 create_fixed_operand (&ops[op_counter++], mem);
7447 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7448 create_convert_operand_to (&ops[op_counter++], val, mode, true);
7449
7450 if (maybe_expand_insn (icode, num_ops, ops))
7451 return (target == const0_rtx ? const0_rtx : ops[0].value);
7452
7453 return NULL_RTX;
7454 }
7455
7456
7457 /* This function expands an atomic fetch_OP or OP_fetch operation:
7458 TARGET is an option place to stick the return value. const0_rtx indicates
7459 the result is unused.
7460 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7461 CODE is the operation being performed (OP)
7462 MEMMODEL is the memory model variant to use.
7463 AFTER is true to return the result of the operation (OP_fetch).
7464 AFTER is false to return the value before the operation (fetch_OP).
7465
7466 This function will *only* generate instructions if there is a direct
7467 optab. No compare and swap loops or libcalls will be generated. */
7468
7469 static rtx
7470 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
7471 enum rtx_code code, enum memmodel model,
7472 bool after)
7473 {
7474 machine_mode mode = GET_MODE (mem);
7475 struct atomic_op_functions optab;
7476 rtx result;
7477 bool unused_result = (target == const0_rtx);
7478
7479 get_atomic_op_for_code (&optab, code);
7480
7481 /* Check to see if there are any better instructions. */
7482 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
7483 if (result)
7484 return result;
7485
7486 /* Check for the case where the result isn't used and try those patterns. */
7487 if (unused_result)
7488 {
7489 /* Try the memory model variant first. */
7490 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
7491 if (result)
7492 return result;
7493
7494 /* Next try the old style withuot a memory model. */
7495 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
7496 if (result)
7497 return result;
7498
7499 /* There is no no-result pattern, so try patterns with a result. */
7500 target = NULL_RTX;
7501 }
7502
7503 /* Try the __atomic version. */
7504 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
7505 if (result)
7506 return result;
7507
7508 /* Try the older __sync version. */
7509 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
7510 if (result)
7511 return result;
7512
7513 /* If the fetch value can be calculated from the other variation of fetch,
7514 try that operation. */
7515 if (after || unused_result || optab.reverse_code != UNKNOWN)
7516 {
7517 /* Try the __atomic version, then the older __sync version. */
7518 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
7519 if (!result)
7520 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
7521
7522 if (result)
7523 {
7524 /* If the result isn't used, no need to do compensation code. */
7525 if (unused_result)
7526 return result;
7527
7528 /* Issue compensation code. Fetch_after == fetch_before OP val.
7529 Fetch_before == after REVERSE_OP val. */
7530 if (!after)
7531 code = optab.reverse_code;
7532 if (code == NOT)
7533 {
7534 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
7535 true, OPTAB_LIB_WIDEN);
7536 result = expand_simple_unop (mode, NOT, result, target, true);
7537 }
7538 else
7539 result = expand_simple_binop (mode, code, result, val, target,
7540 true, OPTAB_LIB_WIDEN);
7541 return result;
7542 }
7543 }
7544
7545 /* No direct opcode can be generated. */
7546 return NULL_RTX;
7547 }
7548
7549
7550
7551 /* This function expands an atomic fetch_OP or OP_fetch operation:
7552 TARGET is an option place to stick the return value. const0_rtx indicates
7553 the result is unused.
7554 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7555 CODE is the operation being performed (OP)
7556 MEMMODEL is the memory model variant to use.
7557 AFTER is true to return the result of the operation (OP_fetch).
7558 AFTER is false to return the value before the operation (fetch_OP). */
7559 rtx
7560 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7561 enum memmodel model, bool after)
7562 {
7563 machine_mode mode = GET_MODE (mem);
7564 rtx result;
7565 bool unused_result = (target == const0_rtx);
7566
7567 /* If loads are not atomic for the required size and we are not called to
7568 provide a __sync builtin, do not do anything so that we stay consistent
7569 with atomic loads of the same size. */
7570 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
7571 return NULL_RTX;
7572
7573 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
7574 after);
7575
7576 if (result)
7577 return result;
7578
7579 /* Add/sub can be implemented by doing the reverse operation with -(val). */
7580 if (code == PLUS || code == MINUS)
7581 {
7582 rtx tmp;
7583 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
7584
7585 start_sequence ();
7586 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
7587 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
7588 model, after);
7589 if (result)
7590 {
7591 /* PLUS worked so emit the insns and return. */
7592 tmp = get_insns ();
7593 end_sequence ();
7594 emit_insn (tmp);
7595 return result;
7596 }
7597
7598 /* PLUS did not work, so throw away the negation code and continue. */
7599 end_sequence ();
7600 }
7601
7602 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
7603 if (!can_compare_and_swap_p (mode, false))
7604 {
7605 rtx libfunc;
7606 bool fixup = false;
7607 enum rtx_code orig_code = code;
7608 struct atomic_op_functions optab;
7609
7610 get_atomic_op_for_code (&optab, code);
7611 libfunc = optab_libfunc (after ? optab.fetch_after
7612 : optab.fetch_before, mode);
7613 if (libfunc == NULL
7614 && (after || unused_result || optab.reverse_code != UNKNOWN))
7615 {
7616 fixup = true;
7617 if (!after)
7618 code = optab.reverse_code;
7619 libfunc = optab_libfunc (after ? optab.fetch_before
7620 : optab.fetch_after, mode);
7621 }
7622 if (libfunc != NULL)
7623 {
7624 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7625 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
7626 addr, ptr_mode, val, mode);
7627
7628 if (!unused_result && fixup)
7629 result = expand_simple_binop (mode, code, result, val, target,
7630 true, OPTAB_LIB_WIDEN);
7631 return result;
7632 }
7633
7634 /* We need the original code for any further attempts. */
7635 code = orig_code;
7636 }
7637
7638 /* If nothing else has succeeded, default to a compare and swap loop. */
7639 if (can_compare_and_swap_p (mode, true))
7640 {
7641 rtx_insn *insn;
7642 rtx t0 = gen_reg_rtx (mode), t1;
7643
7644 start_sequence ();
7645
7646 /* If the result is used, get a register for it. */
7647 if (!unused_result)
7648 {
7649 if (!target || !register_operand (target, mode))
7650 target = gen_reg_rtx (mode);
7651 /* If fetch_before, copy the value now. */
7652 if (!after)
7653 emit_move_insn (target, t0);
7654 }
7655 else
7656 target = const0_rtx;
7657
7658 t1 = t0;
7659 if (code == NOT)
7660 {
7661 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7662 true, OPTAB_LIB_WIDEN);
7663 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7664 }
7665 else
7666 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
7667 OPTAB_LIB_WIDEN);
7668
7669 /* For after, copy the value now. */
7670 if (!unused_result && after)
7671 emit_move_insn (target, t1);
7672 insn = get_insns ();
7673 end_sequence ();
7674
7675 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7676 return target;
7677 }
7678
7679 return NULL_RTX;
7680 }
7681 \f
7682 /* Return true if OPERAND is suitable for operand number OPNO of
7683 instruction ICODE. */
7684
7685 bool
7686 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
7687 {
7688 return (!insn_data[(int) icode].operand[opno].predicate
7689 || (insn_data[(int) icode].operand[opno].predicate
7690 (operand, insn_data[(int) icode].operand[opno].mode)));
7691 }
7692 \f
7693 /* TARGET is a target of a multiword operation that we are going to
7694 implement as a series of word-mode operations. Return true if
7695 TARGET is suitable for this purpose. */
7696
7697 bool
7698 valid_multiword_target_p (rtx target)
7699 {
7700 machine_mode mode;
7701 int i, size;
7702
7703 mode = GET_MODE (target);
7704 if (!GET_MODE_SIZE (mode).is_constant (&size))
7705 return false;
7706 for (i = 0; i < size; i += UNITS_PER_WORD)
7707 if (!validate_subreg (word_mode, mode, target, i))
7708 return false;
7709 return true;
7710 }
7711
7712 /* Make OP describe an input operand that has value INTVAL and that has
7713 no inherent mode. This function should only be used for operands that
7714 are always expand-time constants. The backend may request that INTVAL
7715 be copied into a different kind of rtx, but it must specify the mode
7716 of that rtx if so. */
7717
7718 void
7719 create_integer_operand (class expand_operand *op, poly_int64 intval)
7720 {
7721 create_expand_operand (op, EXPAND_INTEGER,
7722 gen_int_mode (intval, MAX_MODE_INT),
7723 VOIDmode, false, intval);
7724 }
7725
7726 /* Like maybe_legitimize_operand, but do not change the code of the
7727 current rtx value. */
7728
7729 static bool
7730 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
7731 class expand_operand *op)
7732 {
7733 /* See if the operand matches in its current form. */
7734 if (insn_operand_matches (icode, opno, op->value))
7735 return true;
7736
7737 /* If the operand is a memory whose address has no side effects,
7738 try forcing the address into a non-virtual pseudo register.
7739 The check for side effects is important because copy_to_mode_reg
7740 cannot handle things like auto-modified addresses. */
7741 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
7742 {
7743 rtx addr, mem;
7744
7745 mem = op->value;
7746 addr = XEXP (mem, 0);
7747 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
7748 && !side_effects_p (addr))
7749 {
7750 rtx_insn *last;
7751 machine_mode mode;
7752
7753 last = get_last_insn ();
7754 mode = get_address_mode (mem);
7755 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
7756 if (insn_operand_matches (icode, opno, mem))
7757 {
7758 op->value = mem;
7759 return true;
7760 }
7761 delete_insns_since (last);
7762 }
7763 }
7764
7765 return false;
7766 }
7767
7768 /* Try to make OP match operand OPNO of instruction ICODE. Return true
7769 on success, storing the new operand value back in OP. */
7770
7771 static bool
7772 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
7773 class expand_operand *op)
7774 {
7775 machine_mode mode, imode, tmode;
7776
7777 mode = op->mode;
7778 switch (op->type)
7779 {
7780 case EXPAND_FIXED:
7781 {
7782 temporary_volatile_ok v (true);
7783 return maybe_legitimize_operand_same_code (icode, opno, op);
7784 }
7785
7786 case EXPAND_OUTPUT:
7787 gcc_assert (mode != VOIDmode);
7788 if (op->value
7789 && op->value != const0_rtx
7790 && GET_MODE (op->value) == mode
7791 && maybe_legitimize_operand_same_code (icode, opno, op))
7792 return true;
7793
7794 op->value = gen_reg_rtx (mode);
7795 op->target = 0;
7796 break;
7797
7798 case EXPAND_INPUT:
7799 input:
7800 gcc_assert (mode != VOIDmode);
7801 gcc_assert (GET_MODE (op->value) == VOIDmode
7802 || GET_MODE (op->value) == mode);
7803 if (maybe_legitimize_operand_same_code (icode, opno, op))
7804 return true;
7805
7806 op->value = copy_to_mode_reg (mode, op->value);
7807 break;
7808
7809 case EXPAND_CONVERT_TO:
7810 gcc_assert (mode != VOIDmode);
7811 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
7812 goto input;
7813
7814 case EXPAND_CONVERT_FROM:
7815 if (GET_MODE (op->value) != VOIDmode)
7816 mode = GET_MODE (op->value);
7817 else
7818 /* The caller must tell us what mode this value has. */
7819 gcc_assert (mode != VOIDmode);
7820
7821 imode = insn_data[(int) icode].operand[opno].mode;
7822 tmode = (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode)
7823 ? GET_MODE_INNER (imode) : imode);
7824 if (tmode != VOIDmode && tmode != mode)
7825 {
7826 op->value = convert_modes (tmode, mode, op->value, op->unsigned_p);
7827 mode = tmode;
7828 }
7829 if (imode != VOIDmode && imode != mode)
7830 {
7831 gcc_assert (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode));
7832 op->value = expand_vector_broadcast (imode, op->value);
7833 mode = imode;
7834 }
7835 goto input;
7836
7837 case EXPAND_ADDRESS:
7838 op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
7839 op->value);
7840 goto input;
7841
7842 case EXPAND_INTEGER:
7843 mode = insn_data[(int) icode].operand[opno].mode;
7844 if (mode != VOIDmode
7845 && known_eq (trunc_int_for_mode (op->int_value, mode),
7846 op->int_value))
7847 {
7848 op->value = gen_int_mode (op->int_value, mode);
7849 goto input;
7850 }
7851 break;
7852 }
7853 return insn_operand_matches (icode, opno, op->value);
7854 }
7855
7856 /* Make OP describe an input operand that should have the same value
7857 as VALUE, after any mode conversion that the target might request.
7858 TYPE is the type of VALUE. */
7859
7860 void
7861 create_convert_operand_from_type (class expand_operand *op,
7862 rtx value, tree type)
7863 {
7864 create_convert_operand_from (op, value, TYPE_MODE (type),
7865 TYPE_UNSIGNED (type));
7866 }
7867
7868 /* Return true if the requirements on operands OP1 and OP2 of instruction
7869 ICODE are similar enough for the result of legitimizing OP1 to be
7870 reusable for OP2. OPNO1 and OPNO2 are the operand numbers associated
7871 with OP1 and OP2 respectively. */
7872
7873 static inline bool
7874 can_reuse_operands_p (enum insn_code icode,
7875 unsigned int opno1, unsigned int opno2,
7876 const class expand_operand *op1,
7877 const class expand_operand *op2)
7878 {
7879 /* Check requirements that are common to all types. */
7880 if (op1->type != op2->type
7881 || op1->mode != op2->mode
7882 || (insn_data[(int) icode].operand[opno1].mode
7883 != insn_data[(int) icode].operand[opno2].mode))
7884 return false;
7885
7886 /* Check the requirements for specific types. */
7887 switch (op1->type)
7888 {
7889 case EXPAND_OUTPUT:
7890 /* Outputs must remain distinct. */
7891 return false;
7892
7893 case EXPAND_FIXED:
7894 case EXPAND_INPUT:
7895 case EXPAND_ADDRESS:
7896 case EXPAND_INTEGER:
7897 return true;
7898
7899 case EXPAND_CONVERT_TO:
7900 case EXPAND_CONVERT_FROM:
7901 return op1->unsigned_p == op2->unsigned_p;
7902 }
7903 gcc_unreachable ();
7904 }
7905
7906 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7907 of instruction ICODE. Return true on success, leaving the new operand
7908 values in the OPS themselves. Emit no code on failure. */
7909
7910 bool
7911 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
7912 unsigned int nops, class expand_operand *ops)
7913 {
7914 rtx_insn *last = get_last_insn ();
7915 rtx *orig_values = XALLOCAVEC (rtx, nops);
7916 for (unsigned int i = 0; i < nops; i++)
7917 {
7918 orig_values[i] = ops[i].value;
7919
7920 /* First try reusing the result of an earlier legitimization.
7921 This avoids duplicate rtl and ensures that tied operands
7922 remain tied.
7923
7924 This search is linear, but NOPS is bounded at compile time
7925 to a small number (current a single digit). */
7926 unsigned int j = 0;
7927 for (; j < i; ++j)
7928 if (can_reuse_operands_p (icode, opno + j, opno + i, &ops[j], &ops[i])
7929 && rtx_equal_p (orig_values[j], orig_values[i])
7930 && ops[j].value
7931 && insn_operand_matches (icode, opno + i, ops[j].value))
7932 {
7933 ops[i].value = copy_rtx (ops[j].value);
7934 break;
7935 }
7936
7937 /* Otherwise try legitimizing the operand on its own. */
7938 if (j == i && !maybe_legitimize_operand (icode, opno + i, &ops[i]))
7939 {
7940 delete_insns_since (last);
7941 return false;
7942 }
7943 }
7944 return true;
7945 }
7946
7947 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7948 as its operands. Return the instruction pattern on success,
7949 and emit any necessary set-up code. Return null and emit no
7950 code on failure. */
7951
7952 rtx_insn *
7953 maybe_gen_insn (enum insn_code icode, unsigned int nops,
7954 class expand_operand *ops)
7955 {
7956 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
7957 if (!maybe_legitimize_operands (icode, 0, nops, ops))
7958 return NULL;
7959
7960 switch (nops)
7961 {
7962 case 1:
7963 return GEN_FCN (icode) (ops[0].value);
7964 case 2:
7965 return GEN_FCN (icode) (ops[0].value, ops[1].value);
7966 case 3:
7967 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
7968 case 4:
7969 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7970 ops[3].value);
7971 case 5:
7972 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7973 ops[3].value, ops[4].value);
7974 case 6:
7975 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7976 ops[3].value, ops[4].value, ops[5].value);
7977 case 7:
7978 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7979 ops[3].value, ops[4].value, ops[5].value,
7980 ops[6].value);
7981 case 8:
7982 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7983 ops[3].value, ops[4].value, ops[5].value,
7984 ops[6].value, ops[7].value);
7985 case 9:
7986 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7987 ops[3].value, ops[4].value, ops[5].value,
7988 ops[6].value, ops[7].value, ops[8].value);
7989 }
7990 gcc_unreachable ();
7991 }
7992
7993 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7994 as its operands. Return true on success and emit no code on failure. */
7995
7996 bool
7997 maybe_expand_insn (enum insn_code icode, unsigned int nops,
7998 class expand_operand *ops)
7999 {
8000 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
8001 if (pat)
8002 {
8003 emit_insn (pat);
8004 return true;
8005 }
8006 return false;
8007 }
8008
8009 /* Like maybe_expand_insn, but for jumps. */
8010
8011 bool
8012 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
8013 class expand_operand *ops)
8014 {
8015 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
8016 if (pat)
8017 {
8018 emit_jump_insn (pat);
8019 return true;
8020 }
8021 return false;
8022 }
8023
8024 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8025 as its operands. */
8026
8027 void
8028 expand_insn (enum insn_code icode, unsigned int nops,
8029 class expand_operand *ops)
8030 {
8031 if (!maybe_expand_insn (icode, nops, ops))
8032 gcc_unreachable ();
8033 }
8034
8035 /* Like expand_insn, but for jumps. */
8036
8037 void
8038 expand_jump_insn (enum insn_code icode, unsigned int nops,
8039 class expand_operand *ops)
8040 {
8041 if (!maybe_expand_jump_insn (icode, nops, ops))
8042 gcc_unreachable ();
8043 }