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