usr.sbin/makefs/hammer2: Remove redundant hammer2_inode_modify()
[dragonfly.git] / contrib / gcc-8.0 / gcc / optabs.c
blobb31016c05ebab56af51e48ffcf45833744e717e5
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2018 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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"
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"
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);
53 /* Debug facility for use in GDB. */
54 void debug_optab_libfuncs (void);
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). OP0_MODE is OP0's mode.
60 If the last insn does not set TARGET, don't do anything, but return 1.
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. */
66 static int
67 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
68 rtx op1, machine_mode op0_mode)
70 rtx_insn *last_insn;
71 rtx set;
72 rtx note;
74 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
76 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
77 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
78 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
79 && GET_RTX_CLASS (code) != RTX_COMPARE
80 && GET_RTX_CLASS (code) != RTX_UNARY)
81 return 1;
83 if (GET_CODE (target) == ZERO_EXTRACT)
84 return 1;
86 for (last_insn = insns;
87 NEXT_INSN (last_insn) != NULL_RTX;
88 last_insn = NEXT_INSN (last_insn))
91 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
92 a value changing in the insn, so the note would be invalid for CSE. */
93 if (reg_overlap_mentioned_p (target, op0)
94 || (op1 && reg_overlap_mentioned_p (target, op1)))
96 if (MEM_P (target)
97 && (rtx_equal_p (target, op0)
98 || (op1 && rtx_equal_p (target, op1))))
100 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
101 over expanding it as temp = MEM op X, MEM = temp. If the target
102 supports MEM = MEM op X instructions, it is sometimes too hard
103 to reconstruct that form later, especially if X is also a memory,
104 and due to multiple occurrences of addresses the address might
105 be forced into register unnecessarily.
106 Note that not emitting the REG_EQUIV note might inhibit
107 CSE in some cases. */
108 set = single_set (last_insn);
109 if (set
110 && GET_CODE (SET_SRC (set)) == code
111 && MEM_P (SET_DEST (set))
112 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
113 || (op1 && rtx_equal_p (SET_DEST (set),
114 XEXP (SET_SRC (set), 1)))))
115 return 1;
117 return 0;
120 set = set_for_reg_notes (last_insn);
121 if (set == NULL_RTX)
122 return 1;
124 if (! rtx_equal_p (SET_DEST (set), target)
125 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
126 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
127 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
128 return 1;
130 if (GET_RTX_CLASS (code) == RTX_UNARY)
131 switch (code)
133 case FFS:
134 case CLZ:
135 case CTZ:
136 case CLRSB:
137 case POPCOUNT:
138 case PARITY:
139 case BSWAP:
140 if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
142 note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
143 if (GET_MODE_UNIT_SIZE (op0_mode)
144 > GET_MODE_UNIT_SIZE (GET_MODE (target)))
145 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
146 note, op0_mode);
147 else
148 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
149 note, op0_mode);
150 break;
152 /* FALLTHRU */
153 default:
154 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
155 break;
157 else
158 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
160 set_unique_reg_note (last_insn, REG_EQUAL, note);
162 return 1;
165 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
166 for a widening operation would be. In most cases this would be OP0, but if
167 that's a constant it'll be VOIDmode, which isn't useful. */
169 static machine_mode
170 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
172 machine_mode m0 = GET_MODE (op0);
173 machine_mode m1 = GET_MODE (op1);
174 machine_mode result;
176 if (m0 == VOIDmode && m1 == VOIDmode)
177 return to_mode;
178 else if (m0 == VOIDmode || GET_MODE_UNIT_SIZE (m0) < GET_MODE_UNIT_SIZE (m1))
179 result = m1;
180 else
181 result = m0;
183 if (GET_MODE_UNIT_SIZE (result) > GET_MODE_UNIT_SIZE (to_mode))
184 return to_mode;
186 return result;
189 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
190 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
191 not actually do a sign-extend or zero-extend, but can leave the
192 higher-order bits of the result rtx undefined, for example, in the case
193 of logical operations, but not right shifts. */
195 static rtx
196 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
197 int unsignedp, int no_extend)
199 rtx result;
200 scalar_int_mode int_mode;
202 /* If we don't have to extend and this is a constant, return it. */
203 if (no_extend && GET_MODE (op) == VOIDmode)
204 return op;
206 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
207 extend since it will be more efficient to do so unless the signedness of
208 a promoted object differs from our extension. */
209 if (! no_extend
210 || !is_a <scalar_int_mode> (mode, &int_mode)
211 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
212 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
213 return convert_modes (mode, oldmode, op, unsignedp);
215 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
216 SUBREG. */
217 if (GET_MODE_SIZE (int_mode) <= UNITS_PER_WORD)
218 return gen_lowpart (int_mode, force_reg (GET_MODE (op), op));
220 /* Otherwise, get an object of MODE, clobber it, and set the low-order
221 part to OP. */
223 result = gen_reg_rtx (int_mode);
224 emit_clobber (result);
225 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
226 return result;
229 /* Expand vector widening operations.
231 There are two different classes of operations handled here:
232 1) Operations whose result is wider than all the arguments to the operation.
233 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
234 In this case OP0 and optionally OP1 would be initialized,
235 but WIDE_OP wouldn't (not relevant for this case).
236 2) Operations whose result is of the same size as the last argument to the
237 operation, but wider than all the other arguments to the operation.
238 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
239 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
241 E.g, when called to expand the following operations, this is how
242 the arguments will be initialized:
243 nops OP0 OP1 WIDE_OP
244 widening-sum 2 oprnd0 - oprnd1
245 widening-dot-product 3 oprnd0 oprnd1 oprnd2
246 widening-mult 2 oprnd0 oprnd1 -
247 type-promotion (vec-unpack) 1 oprnd0 - - */
250 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
251 rtx target, int unsignedp)
253 struct expand_operand eops[4];
254 tree oprnd0, oprnd1, oprnd2;
255 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
256 optab widen_pattern_optab;
257 enum insn_code icode;
258 int nops = TREE_CODE_LENGTH (ops->code);
259 int op;
261 oprnd0 = ops->op0;
262 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
263 widen_pattern_optab =
264 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
265 if (ops->code == WIDEN_MULT_PLUS_EXPR
266 || ops->code == WIDEN_MULT_MINUS_EXPR)
267 icode = find_widening_optab_handler (widen_pattern_optab,
268 TYPE_MODE (TREE_TYPE (ops->op2)),
269 tmode0);
270 else
271 icode = optab_handler (widen_pattern_optab, tmode0);
272 gcc_assert (icode != CODE_FOR_nothing);
274 if (nops >= 2)
276 oprnd1 = ops->op1;
277 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
280 /* The last operand is of a wider mode than the rest of the operands. */
281 if (nops == 2)
282 wmode = tmode1;
283 else if (nops == 3)
285 gcc_assert (tmode1 == tmode0);
286 gcc_assert (op1);
287 oprnd2 = ops->op2;
288 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
291 op = 0;
292 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
293 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
294 if (op1)
295 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
296 if (wide_op)
297 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
298 expand_insn (icode, op, eops);
299 return eops[0].value;
302 /* Generate code to perform an operation specified by TERNARY_OPTAB
303 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
305 UNSIGNEDP is for the case where we have to widen the operands
306 to perform the operation. It says to use zero-extension.
308 If TARGET is nonzero, the value
309 is generated there, if it is convenient to do so.
310 In all cases an rtx is returned for the locus of the value;
311 this may or may not be TARGET. */
314 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
315 rtx op1, rtx op2, rtx target, int unsignedp)
317 struct expand_operand ops[4];
318 enum insn_code icode = optab_handler (ternary_optab, mode);
320 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
322 create_output_operand (&ops[0], target, mode);
323 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
324 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
325 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
326 expand_insn (icode, 4, ops);
327 return ops[0].value;
331 /* Like expand_binop, but return a constant rtx if the result can be
332 calculated at compile time. The arguments and return value are
333 otherwise the same as for expand_binop. */
336 simplify_expand_binop (machine_mode mode, optab binoptab,
337 rtx op0, rtx op1, rtx target, int unsignedp,
338 enum optab_methods methods)
340 if (CONSTANT_P (op0) && CONSTANT_P (op1))
342 rtx x = simplify_binary_operation (optab_to_code (binoptab),
343 mode, op0, op1);
344 if (x)
345 return x;
348 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
351 /* Like simplify_expand_binop, but always put the result in TARGET.
352 Return true if the expansion succeeded. */
354 bool
355 force_expand_binop (machine_mode mode, optab binoptab,
356 rtx op0, rtx op1, rtx target, int unsignedp,
357 enum optab_methods methods)
359 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
360 target, unsignedp, methods);
361 if (x == 0)
362 return false;
363 if (x != target)
364 emit_move_insn (target, x);
365 return true;
368 /* Create a new vector value in VMODE with all elements set to OP. The
369 mode of OP must be the element mode of VMODE. If OP is a constant,
370 then the return value will be a constant. */
373 expand_vector_broadcast (machine_mode vmode, rtx op)
375 int n;
376 rtvec vec;
378 gcc_checking_assert (VECTOR_MODE_P (vmode));
380 if (valid_for_const_vector_p (vmode, op))
381 return gen_const_vec_duplicate (vmode, op);
383 insn_code icode = optab_handler (vec_duplicate_optab, vmode);
384 if (icode != CODE_FOR_nothing)
386 struct expand_operand ops[2];
387 create_output_operand (&ops[0], NULL_RTX, vmode);
388 create_input_operand (&ops[1], op, GET_MODE (op));
389 expand_insn (icode, 2, ops);
390 return ops[0].value;
393 if (!GET_MODE_NUNITS (vmode).is_constant (&n))
394 return NULL;
396 /* ??? If the target doesn't have a vec_init, then we have no easy way
397 of performing this operation. Most of this sort of generic support
398 is hidden away in the vector lowering support in gimple. */
399 icode = convert_optab_handler (vec_init_optab, vmode,
400 GET_MODE_INNER (vmode));
401 if (icode == CODE_FOR_nothing)
402 return NULL;
404 vec = rtvec_alloc (n);
405 for (int i = 0; i < n; ++i)
406 RTVEC_ELT (vec, i) = op;
407 rtx ret = gen_reg_rtx (vmode);
408 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
410 return ret;
413 /* This subroutine of expand_doubleword_shift handles the cases in which
414 the effective shift value is >= BITS_PER_WORD. The arguments and return
415 value are the same as for the parent routine, except that SUPERWORD_OP1
416 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
417 INTO_TARGET may be null if the caller has decided to calculate it. */
419 static bool
420 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
421 rtx outof_target, rtx into_target,
422 int unsignedp, enum optab_methods methods)
424 if (into_target != 0)
425 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
426 into_target, unsignedp, methods))
427 return false;
429 if (outof_target != 0)
431 /* For a signed right shift, we must fill OUTOF_TARGET with copies
432 of the sign bit, otherwise we must fill it with zeros. */
433 if (binoptab != ashr_optab)
434 emit_move_insn (outof_target, CONST0_RTX (word_mode));
435 else
436 if (!force_expand_binop (word_mode, binoptab, outof_input,
437 gen_int_shift_amount (word_mode,
438 BITS_PER_WORD - 1),
439 outof_target, unsignedp, methods))
440 return false;
442 return true;
445 /* This subroutine of expand_doubleword_shift handles the cases in which
446 the effective shift value is < BITS_PER_WORD. The arguments and return
447 value are the same as for the parent routine. */
449 static bool
450 expand_subword_shift (scalar_int_mode op1_mode, optab binoptab,
451 rtx outof_input, rtx into_input, rtx op1,
452 rtx outof_target, rtx into_target,
453 int unsignedp, enum optab_methods methods,
454 unsigned HOST_WIDE_INT shift_mask)
456 optab reverse_unsigned_shift, unsigned_shift;
457 rtx tmp, carries;
459 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
460 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
462 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
463 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
464 the opposite direction to BINOPTAB. */
465 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
467 carries = outof_input;
468 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
469 op1_mode), op1_mode);
470 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
471 0, true, methods);
473 else
475 /* We must avoid shifting by BITS_PER_WORD bits since that is either
476 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
477 has unknown behavior. Do a single shift first, then shift by the
478 remainder. It's OK to use ~OP1 as the remainder if shift counts
479 are truncated to the mode size. */
480 carries = expand_binop (word_mode, reverse_unsigned_shift,
481 outof_input, const1_rtx, 0, unsignedp, methods);
482 if (shift_mask == BITS_PER_WORD - 1)
484 tmp = immed_wide_int_const
485 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
486 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
487 0, true, methods);
489 else
491 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
492 op1_mode), op1_mode);
493 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
494 0, true, methods);
497 if (tmp == 0 || carries == 0)
498 return false;
499 carries = expand_binop (word_mode, reverse_unsigned_shift,
500 carries, tmp, 0, unsignedp, methods);
501 if (carries == 0)
502 return false;
504 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
505 so the result can go directly into INTO_TARGET if convenient. */
506 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
507 into_target, unsignedp, methods);
508 if (tmp == 0)
509 return false;
511 /* Now OR in the bits carried over from OUTOF_INPUT. */
512 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
513 into_target, unsignedp, methods))
514 return false;
516 /* Use a standard word_mode shift for the out-of half. */
517 if (outof_target != 0)
518 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
519 outof_target, unsignedp, methods))
520 return false;
522 return true;
526 /* Try implementing expand_doubleword_shift using conditional moves.
527 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
528 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
529 are the shift counts to use in the former and latter case. All other
530 arguments are the same as the parent routine. */
532 static bool
533 expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
534 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
535 rtx outof_input, rtx into_input,
536 rtx subword_op1, rtx superword_op1,
537 rtx outof_target, rtx into_target,
538 int unsignedp, enum optab_methods methods,
539 unsigned HOST_WIDE_INT shift_mask)
541 rtx outof_superword, into_superword;
543 /* Put the superword version of the output into OUTOF_SUPERWORD and
544 INTO_SUPERWORD. */
545 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
546 if (outof_target != 0 && subword_op1 == superword_op1)
548 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
549 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
550 into_superword = outof_target;
551 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
552 outof_superword, 0, unsignedp, methods))
553 return false;
555 else
557 into_superword = gen_reg_rtx (word_mode);
558 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
559 outof_superword, into_superword,
560 unsignedp, methods))
561 return false;
564 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
565 if (!expand_subword_shift (op1_mode, binoptab,
566 outof_input, into_input, subword_op1,
567 outof_target, into_target,
568 unsignedp, methods, shift_mask))
569 return false;
571 /* Select between them. Do the INTO half first because INTO_SUPERWORD
572 might be the current value of OUTOF_TARGET. */
573 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
574 into_target, into_superword, word_mode, false))
575 return false;
577 if (outof_target != 0)
578 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
579 outof_target, outof_superword,
580 word_mode, false))
581 return false;
583 return true;
586 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
587 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
588 input operand; the shift moves bits in the direction OUTOF_INPUT->
589 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
590 of the target. OP1 is the shift count and OP1_MODE is its mode.
591 If OP1 is constant, it will have been truncated as appropriate
592 and is known to be nonzero.
594 If SHIFT_MASK is zero, the result of word shifts is undefined when the
595 shift count is outside the range [0, BITS_PER_WORD). This routine must
596 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
598 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
599 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
600 fill with zeros or sign bits as appropriate.
602 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
603 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
604 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
605 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
606 are undefined.
608 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
609 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
610 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
611 function wants to calculate it itself.
613 Return true if the shift could be successfully synthesized. */
615 static bool
616 expand_doubleword_shift (scalar_int_mode op1_mode, optab binoptab,
617 rtx outof_input, rtx into_input, rtx op1,
618 rtx outof_target, rtx into_target,
619 int unsignedp, enum optab_methods methods,
620 unsigned HOST_WIDE_INT shift_mask)
622 rtx superword_op1, tmp, cmp1, cmp2;
623 enum rtx_code cmp_code;
625 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
626 fill the result with sign or zero bits as appropriate. If so, the value
627 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
628 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
629 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
631 This isn't worthwhile for constant shifts since the optimizers will
632 cope better with in-range shift counts. */
633 if (shift_mask >= BITS_PER_WORD
634 && outof_target != 0
635 && !CONSTANT_P (op1))
637 if (!expand_doubleword_shift (op1_mode, binoptab,
638 outof_input, into_input, op1,
639 0, into_target,
640 unsignedp, methods, shift_mask))
641 return false;
642 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
643 outof_target, unsignedp, methods))
644 return false;
645 return true;
648 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
649 is true when the effective shift value is less than BITS_PER_WORD.
650 Set SUPERWORD_OP1 to the shift count that should be used to shift
651 OUTOF_INPUT into INTO_TARGET when the condition is false. */
652 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
653 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
655 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
656 is a subword shift count. */
657 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
658 0, true, methods);
659 cmp2 = CONST0_RTX (op1_mode);
660 cmp_code = EQ;
661 superword_op1 = op1;
663 else
665 /* Set CMP1 to OP1 - BITS_PER_WORD. */
666 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
667 0, true, methods);
668 cmp2 = CONST0_RTX (op1_mode);
669 cmp_code = LT;
670 superword_op1 = cmp1;
672 if (cmp1 == 0)
673 return false;
675 /* If we can compute the condition at compile time, pick the
676 appropriate subroutine. */
677 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
678 if (tmp != 0 && CONST_INT_P (tmp))
680 if (tmp == const0_rtx)
681 return expand_superword_shift (binoptab, outof_input, superword_op1,
682 outof_target, into_target,
683 unsignedp, methods);
684 else
685 return expand_subword_shift (op1_mode, binoptab,
686 outof_input, into_input, op1,
687 outof_target, into_target,
688 unsignedp, methods, shift_mask);
691 /* Try using conditional moves to generate straight-line code. */
692 if (HAVE_conditional_move)
694 rtx_insn *start = get_last_insn ();
695 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
696 cmp_code, cmp1, cmp2,
697 outof_input, into_input,
698 op1, superword_op1,
699 outof_target, into_target,
700 unsignedp, methods, shift_mask))
701 return true;
702 delete_insns_since (start);
705 /* As a last resort, use branches to select the correct alternative. */
706 rtx_code_label *subword_label = gen_label_rtx ();
707 rtx_code_label *done_label = gen_label_rtx ();
709 NO_DEFER_POP;
710 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
711 0, 0, subword_label,
712 profile_probability::uninitialized ());
713 OK_DEFER_POP;
715 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
716 outof_target, into_target,
717 unsignedp, methods))
718 return false;
720 emit_jump_insn (targetm.gen_jump (done_label));
721 emit_barrier ();
722 emit_label (subword_label);
724 if (!expand_subword_shift (op1_mode, binoptab,
725 outof_input, into_input, op1,
726 outof_target, into_target,
727 unsignedp, methods, shift_mask))
728 return false;
730 emit_label (done_label);
731 return true;
734 /* Subroutine of expand_binop. Perform a double word multiplication of
735 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
736 as the target's word_mode. This function return NULL_RTX if anything
737 goes wrong, in which case it may have already emitted instructions
738 which need to be deleted.
740 If we want to multiply two two-word values and have normal and widening
741 multiplies of single-word values, we can do this with three smaller
742 multiplications.
744 The multiplication proceeds as follows:
745 _______________________
746 [__op0_high_|__op0_low__]
747 _______________________
748 * [__op1_high_|__op1_low__]
749 _______________________________________________
750 _______________________
751 (1) [__op0_low__*__op1_low__]
752 _______________________
753 (2a) [__op0_low__*__op1_high_]
754 _______________________
755 (2b) [__op0_high_*__op1_low__]
756 _______________________
757 (3) [__op0_high_*__op1_high_]
760 This gives a 4-word result. Since we are only interested in the
761 lower 2 words, partial result (3) and the upper words of (2a) and
762 (2b) don't need to be calculated. Hence (2a) and (2b) can be
763 calculated using non-widening multiplication.
765 (1), however, needs to be calculated with an unsigned widening
766 multiplication. If this operation is not directly supported we
767 try using a signed widening multiplication and adjust the result.
768 This adjustment works as follows:
770 If both operands are positive then no adjustment is needed.
772 If the operands have different signs, for example op0_low < 0 and
773 op1_low >= 0, the instruction treats the most significant bit of
774 op0_low as a sign bit instead of a bit with significance
775 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
776 with 2**BITS_PER_WORD - op0_low, and two's complements the
777 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
778 the result.
780 Similarly, if both operands are negative, we need to add
781 (op0_low + op1_low) * 2**BITS_PER_WORD.
783 We use a trick to adjust quickly. We logically shift op0_low right
784 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
785 op0_high (op1_high) before it is used to calculate 2b (2a). If no
786 logical shift exists, we do an arithmetic right shift and subtract
787 the 0 or -1. */
789 static rtx
790 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
791 bool umulp, enum optab_methods methods)
793 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
794 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
795 rtx wordm1 = (umulp ? NULL_RTX
796 : gen_int_shift_amount (word_mode, BITS_PER_WORD - 1));
797 rtx product, adjust, product_high, temp;
799 rtx op0_high = operand_subword_force (op0, high, mode);
800 rtx op0_low = operand_subword_force (op0, low, mode);
801 rtx op1_high = operand_subword_force (op1, high, mode);
802 rtx op1_low = operand_subword_force (op1, low, mode);
804 /* If we're using an unsigned multiply to directly compute the product
805 of the low-order words of the operands and perform any required
806 adjustments of the operands, we begin by trying two more multiplications
807 and then computing the appropriate sum.
809 We have checked above that the required addition is provided.
810 Full-word addition will normally always succeed, especially if
811 it is provided at all, so we don't worry about its failure. The
812 multiplication may well fail, however, so we do handle that. */
814 if (!umulp)
816 /* ??? This could be done with emit_store_flag where available. */
817 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
818 NULL_RTX, 1, methods);
819 if (temp)
820 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
821 NULL_RTX, 0, OPTAB_DIRECT);
822 else
824 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
825 NULL_RTX, 0, methods);
826 if (!temp)
827 return NULL_RTX;
828 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
829 NULL_RTX, 0, OPTAB_DIRECT);
832 if (!op0_high)
833 return NULL_RTX;
836 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
837 NULL_RTX, 0, OPTAB_DIRECT);
838 if (!adjust)
839 return NULL_RTX;
841 /* OP0_HIGH should now be dead. */
843 if (!umulp)
845 /* ??? This could be done with emit_store_flag where available. */
846 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
847 NULL_RTX, 1, methods);
848 if (temp)
849 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
850 NULL_RTX, 0, OPTAB_DIRECT);
851 else
853 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
854 NULL_RTX, 0, methods);
855 if (!temp)
856 return NULL_RTX;
857 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
858 NULL_RTX, 0, OPTAB_DIRECT);
861 if (!op1_high)
862 return NULL_RTX;
865 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
866 NULL_RTX, 0, OPTAB_DIRECT);
867 if (!temp)
868 return NULL_RTX;
870 /* OP1_HIGH should now be dead. */
872 adjust = expand_binop (word_mode, add_optab, adjust, temp,
873 NULL_RTX, 0, OPTAB_DIRECT);
875 if (target && !REG_P (target))
876 target = NULL_RTX;
878 /* *_widen_optab needs to determine operand mode, make sure at least
879 one operand has non-VOID mode. */
880 if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
881 op0_low = force_reg (word_mode, op0_low);
883 if (umulp)
884 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
885 target, 1, OPTAB_DIRECT);
886 else
887 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
888 target, 1, OPTAB_DIRECT);
890 if (!product)
891 return NULL_RTX;
893 product_high = operand_subword (product, high, 1, mode);
894 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
895 NULL_RTX, 0, OPTAB_DIRECT);
896 emit_move_insn (product_high, adjust);
897 return product;
900 /* Wrapper around expand_binop which takes an rtx code to specify
901 the operation to perform, not an optab pointer. All other
902 arguments are the same. */
904 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
905 rtx op1, rtx target, int unsignedp,
906 enum optab_methods methods)
908 optab binop = code_to_optab (code);
909 gcc_assert (binop);
911 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
914 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
915 binop. Order them according to commutative_operand_precedence and, if
916 possible, try to put TARGET or a pseudo first. */
917 static bool
918 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
920 int op0_prec = commutative_operand_precedence (op0);
921 int op1_prec = commutative_operand_precedence (op1);
923 if (op0_prec < op1_prec)
924 return true;
926 if (op0_prec > op1_prec)
927 return false;
929 /* With equal precedence, both orders are ok, but it is better if the
930 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
931 if (target == 0 || REG_P (target))
932 return (REG_P (op1) && !REG_P (op0)) || target == op1;
933 else
934 return rtx_equal_p (op1, target);
937 /* Return true if BINOPTAB implements a shift operation. */
939 static bool
940 shift_optab_p (optab binoptab)
942 switch (optab_to_code (binoptab))
944 case ASHIFT:
945 case SS_ASHIFT:
946 case US_ASHIFT:
947 case ASHIFTRT:
948 case LSHIFTRT:
949 case ROTATE:
950 case ROTATERT:
951 return true;
953 default:
954 return false;
958 /* Return true if BINOPTAB implements a commutative binary operation. */
960 static bool
961 commutative_optab_p (optab binoptab)
963 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
964 || binoptab == smul_widen_optab
965 || binoptab == umul_widen_optab
966 || binoptab == smul_highpart_optab
967 || binoptab == umul_highpart_optab);
970 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
971 optimizing, and if the operand is a constant that costs more than
972 1 instruction, force the constant into a register and return that
973 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
975 static rtx
976 avoid_expensive_constant (machine_mode mode, optab binoptab,
977 int opn, rtx x, bool unsignedp)
979 bool speed = optimize_insn_for_speed_p ();
981 if (mode != VOIDmode
982 && optimize
983 && CONSTANT_P (x)
984 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
985 > set_src_cost (x, mode, speed)))
987 if (CONST_INT_P (x))
989 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
990 if (intval != INTVAL (x))
991 x = GEN_INT (intval);
993 else
994 x = convert_modes (mode, VOIDmode, x, unsignedp);
995 x = force_reg (mode, x);
997 return x;
1000 /* Helper function for expand_binop: handle the case where there
1001 is an insn ICODE that directly implements the indicated operation.
1002 Returns null if this is not possible. */
1003 static rtx
1004 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
1005 rtx op0, rtx op1,
1006 rtx target, int unsignedp, enum optab_methods methods,
1007 rtx_insn *last)
1009 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1010 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1011 machine_mode mode0, mode1, tmp_mode;
1012 struct expand_operand ops[3];
1013 bool commutative_p;
1014 rtx_insn *pat;
1015 rtx xop0 = op0, xop1 = op1;
1016 bool canonicalize_op1 = false;
1018 /* If it is a commutative operator and the modes would match
1019 if we would swap the operands, we can save the conversions. */
1020 commutative_p = commutative_optab_p (binoptab);
1021 if (commutative_p
1022 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1023 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1024 std::swap (xop0, xop1);
1026 /* If we are optimizing, force expensive constants into a register. */
1027 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1028 if (!shift_optab_p (binoptab))
1029 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1030 else
1031 /* Shifts and rotates often use a different mode for op1 from op0;
1032 for VOIDmode constants we don't know the mode, so force it
1033 to be canonicalized using convert_modes. */
1034 canonicalize_op1 = true;
1036 /* In case the insn wants input operands in modes different from
1037 those of the actual operands, convert the operands. It would
1038 seem that we don't need to convert CONST_INTs, but we do, so
1039 that they're properly zero-extended, sign-extended or truncated
1040 for their mode. */
1042 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1043 if (xmode0 != VOIDmode && xmode0 != mode0)
1045 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1046 mode0 = xmode0;
1049 mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
1050 ? GET_MODE (xop1) : mode);
1051 if (xmode1 != VOIDmode && xmode1 != mode1)
1053 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1054 mode1 = xmode1;
1057 /* If operation is commutative,
1058 try to make the first operand a register.
1059 Even better, try to make it the same as the target.
1060 Also try to make the last operand a constant. */
1061 if (commutative_p
1062 && swap_commutative_operands_with_target (target, xop0, xop1))
1063 std::swap (xop0, xop1);
1065 /* Now, if insn's predicates don't allow our operands, put them into
1066 pseudo regs. */
1068 if (binoptab == vec_pack_trunc_optab
1069 || binoptab == vec_pack_usat_optab
1070 || binoptab == vec_pack_ssat_optab
1071 || binoptab == vec_pack_ufix_trunc_optab
1072 || binoptab == vec_pack_sfix_trunc_optab)
1074 /* The mode of the result is different then the mode of the
1075 arguments. */
1076 tmp_mode = insn_data[(int) icode].operand[0].mode;
1077 if (VECTOR_MODE_P (mode)
1078 && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
1080 delete_insns_since (last);
1081 return NULL_RTX;
1084 else
1085 tmp_mode = mode;
1087 create_output_operand (&ops[0], target, tmp_mode);
1088 create_input_operand (&ops[1], xop0, mode0);
1089 create_input_operand (&ops[2], xop1, mode1);
1090 pat = maybe_gen_insn (icode, 3, ops);
1091 if (pat)
1093 /* If PAT is composed of more than one insn, try to add an appropriate
1094 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1095 operand, call expand_binop again, this time without a target. */
1096 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1097 && ! add_equal_note (pat, ops[0].value,
1098 optab_to_code (binoptab),
1099 ops[1].value, ops[2].value, mode0))
1101 delete_insns_since (last);
1102 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1103 unsignedp, methods);
1106 emit_insn (pat);
1107 return ops[0].value;
1109 delete_insns_since (last);
1110 return NULL_RTX;
1113 /* Generate code to perform an operation specified by BINOPTAB
1114 on operands OP0 and OP1, with result having machine-mode MODE.
1116 UNSIGNEDP is for the case where we have to widen the operands
1117 to perform the operation. It says to use zero-extension.
1119 If TARGET is nonzero, the value
1120 is generated there, if it is convenient to do so.
1121 In all cases an rtx is returned for the locus of the value;
1122 this may or may not be TARGET. */
1125 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1126 rtx target, int unsignedp, enum optab_methods methods)
1128 enum optab_methods next_methods
1129 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1130 ? OPTAB_WIDEN : methods);
1131 enum mode_class mclass;
1132 enum insn_code icode;
1133 machine_mode wider_mode;
1134 scalar_int_mode int_mode;
1135 rtx libfunc;
1136 rtx temp;
1137 rtx_insn *entry_last = get_last_insn ();
1138 rtx_insn *last;
1140 mclass = GET_MODE_CLASS (mode);
1142 /* If subtracting an integer constant, convert this into an addition of
1143 the negated constant. */
1145 if (binoptab == sub_optab && CONST_INT_P (op1))
1147 op1 = negate_rtx (mode, op1);
1148 binoptab = add_optab;
1150 /* For shifts, constant invalid op1 might be expanded from different
1151 mode than MODE. As those are invalid, force them to a register
1152 to avoid further problems during expansion. */
1153 else if (CONST_INT_P (op1)
1154 && shift_optab_p (binoptab)
1155 && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode)))
1157 op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode));
1158 op1 = force_reg (GET_MODE_INNER (mode), op1);
1161 /* Record where to delete back to if we backtrack. */
1162 last = get_last_insn ();
1164 /* If we can do it with a three-operand insn, do so. */
1166 if (methods != OPTAB_MUST_WIDEN)
1168 if (convert_optab_p (binoptab))
1170 machine_mode from_mode = widened_mode (mode, op0, op1);
1171 icode = find_widening_optab_handler (binoptab, mode, from_mode);
1173 else
1174 icode = optab_handler (binoptab, mode);
1175 if (icode != CODE_FOR_nothing)
1177 temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
1178 target, unsignedp, methods, last);
1179 if (temp)
1180 return temp;
1184 /* If we were trying to rotate, and that didn't work, try rotating
1185 the other direction before falling back to shifts and bitwise-or. */
1186 if (((binoptab == rotl_optab
1187 && (icode = optab_handler (rotr_optab, mode)) != CODE_FOR_nothing)
1188 || (binoptab == rotr_optab
1189 && (icode = optab_handler (rotl_optab, mode)) != CODE_FOR_nothing))
1190 && is_int_mode (mode, &int_mode))
1192 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1193 rtx newop1;
1194 unsigned int bits = GET_MODE_PRECISION (int_mode);
1196 if (CONST_INT_P (op1))
1197 newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
1198 else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
1199 newop1 = negate_rtx (GET_MODE (op1), op1);
1200 else
1201 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1202 gen_int_mode (bits, GET_MODE (op1)), op1,
1203 NULL_RTX, unsignedp, OPTAB_DIRECT);
1205 temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
1206 target, unsignedp, methods, last);
1207 if (temp)
1208 return temp;
1211 /* If this is a multiply, see if we can do a widening operation that
1212 takes operands of this mode and makes a wider mode. */
1214 if (binoptab == smul_optab
1215 && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
1216 && (convert_optab_handler ((unsignedp
1217 ? umul_widen_optab
1218 : smul_widen_optab),
1219 wider_mode, mode) != CODE_FOR_nothing))
1221 /* *_widen_optab needs to determine operand mode, make sure at least
1222 one operand has non-VOID mode. */
1223 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
1224 op0 = force_reg (mode, op0);
1225 temp = expand_binop (wider_mode,
1226 unsignedp ? umul_widen_optab : smul_widen_optab,
1227 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1229 if (temp != 0)
1231 if (GET_MODE_CLASS (mode) == MODE_INT
1232 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1233 return gen_lowpart (mode, temp);
1234 else
1235 return convert_to_mode (mode, temp, unsignedp);
1239 /* If this is a vector shift by a scalar, see if we can do a vector
1240 shift by a vector. If so, broadcast the scalar into a vector. */
1241 if (mclass == MODE_VECTOR_INT)
1243 optab otheroptab = unknown_optab;
1245 if (binoptab == ashl_optab)
1246 otheroptab = vashl_optab;
1247 else if (binoptab == ashr_optab)
1248 otheroptab = vashr_optab;
1249 else if (binoptab == lshr_optab)
1250 otheroptab = vlshr_optab;
1251 else if (binoptab == rotl_optab)
1252 otheroptab = vrotl_optab;
1253 else if (binoptab == rotr_optab)
1254 otheroptab = vrotr_optab;
1256 if (otheroptab
1257 && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
1259 /* The scalar may have been extended to be too wide. Truncate
1260 it back to the proper size to fit in the broadcast vector. */
1261 scalar_mode inner_mode = GET_MODE_INNER (mode);
1262 if (!CONST_INT_P (op1)
1263 && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
1264 > GET_MODE_BITSIZE (inner_mode)))
1265 op1 = force_reg (inner_mode,
1266 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1267 GET_MODE (op1)));
1268 rtx vop1 = expand_vector_broadcast (mode, op1);
1269 if (vop1)
1271 temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
1272 target, unsignedp, methods, last);
1273 if (temp)
1274 return temp;
1279 /* Look for a wider mode of the same class for which we think we
1280 can open-code the operation. Check for a widening multiply at the
1281 wider mode as well. */
1283 if (CLASS_HAS_WIDER_MODES_P (mclass)
1284 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1285 FOR_EACH_WIDER_MODE (wider_mode, mode)
1287 machine_mode next_mode;
1288 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1289 || (binoptab == smul_optab
1290 && GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
1291 && (find_widening_optab_handler ((unsignedp
1292 ? umul_widen_optab
1293 : smul_widen_optab),
1294 next_mode, mode)
1295 != CODE_FOR_nothing)))
1297 rtx xop0 = op0, xop1 = op1;
1298 int no_extend = 0;
1300 /* For certain integer operations, we need not actually extend
1301 the narrow operands, as long as we will truncate
1302 the results to the same narrowness. */
1304 if ((binoptab == ior_optab || binoptab == and_optab
1305 || binoptab == xor_optab
1306 || binoptab == add_optab || binoptab == sub_optab
1307 || binoptab == smul_optab || binoptab == ashl_optab)
1308 && mclass == MODE_INT)
1310 no_extend = 1;
1311 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1312 xop0, unsignedp);
1313 if (binoptab != ashl_optab)
1314 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1315 xop1, unsignedp);
1318 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1320 /* The second operand of a shift must always be extended. */
1321 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1322 no_extend && binoptab != ashl_optab);
1324 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1325 unsignedp, OPTAB_DIRECT);
1326 if (temp)
1328 if (mclass != MODE_INT
1329 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1331 if (target == 0)
1332 target = gen_reg_rtx (mode);
1333 convert_move (target, temp, 0);
1334 return target;
1336 else
1337 return gen_lowpart (mode, temp);
1339 else
1340 delete_insns_since (last);
1344 /* If operation is commutative,
1345 try to make the first operand a register.
1346 Even better, try to make it the same as the target.
1347 Also try to make the last operand a constant. */
1348 if (commutative_optab_p (binoptab)
1349 && swap_commutative_operands_with_target (target, op0, op1))
1350 std::swap (op0, op1);
1352 /* These can be done a word at a time. */
1353 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1354 && is_int_mode (mode, &int_mode)
1355 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
1356 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1358 int i;
1359 rtx_insn *insns;
1361 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1362 won't be accurate, so use a new target. */
1363 if (target == 0
1364 || target == op0
1365 || target == op1
1366 || !valid_multiword_target_p (target))
1367 target = gen_reg_rtx (int_mode);
1369 start_sequence ();
1371 /* Do the actual arithmetic. */
1372 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
1374 rtx target_piece = operand_subword (target, i, 1, int_mode);
1375 rtx x = expand_binop (word_mode, binoptab,
1376 operand_subword_force (op0, i, int_mode),
1377 operand_subword_force (op1, i, int_mode),
1378 target_piece, unsignedp, next_methods);
1380 if (x == 0)
1381 break;
1383 if (target_piece != x)
1384 emit_move_insn (target_piece, x);
1387 insns = get_insns ();
1388 end_sequence ();
1390 if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
1392 emit_insn (insns);
1393 return target;
1397 /* Synthesize double word shifts from single word shifts. */
1398 if ((binoptab == lshr_optab || binoptab == ashl_optab
1399 || binoptab == ashr_optab)
1400 && is_int_mode (mode, &int_mode)
1401 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1402 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1403 && GET_MODE_PRECISION (int_mode) == GET_MODE_BITSIZE (int_mode)
1404 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1405 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1406 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1408 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1409 scalar_int_mode op1_mode;
1411 double_shift_mask = targetm.shift_truncation_mask (int_mode);
1412 shift_mask = targetm.shift_truncation_mask (word_mode);
1413 op1_mode = (GET_MODE (op1) != VOIDmode
1414 ? as_a <scalar_int_mode> (GET_MODE (op1))
1415 : word_mode);
1417 /* Apply the truncation to constant shifts. */
1418 if (double_shift_mask > 0 && CONST_INT_P (op1))
1419 op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode);
1421 if (op1 == CONST0_RTX (op1_mode))
1422 return op0;
1424 /* Make sure that this is a combination that expand_doubleword_shift
1425 can handle. See the comments there for details. */
1426 if (double_shift_mask == 0
1427 || (shift_mask == BITS_PER_WORD - 1
1428 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1430 rtx_insn *insns;
1431 rtx into_target, outof_target;
1432 rtx into_input, outof_input;
1433 int left_shift, outof_word;
1435 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1436 won't be accurate, so use a new target. */
1437 if (target == 0
1438 || target == op0
1439 || target == op1
1440 || !valid_multiword_target_p (target))
1441 target = gen_reg_rtx (int_mode);
1443 start_sequence ();
1445 /* OUTOF_* is the word we are shifting bits away from, and
1446 INTO_* is the word that we are shifting bits towards, thus
1447 they differ depending on the direction of the shift and
1448 WORDS_BIG_ENDIAN. */
1450 left_shift = binoptab == ashl_optab;
1451 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1453 outof_target = operand_subword (target, outof_word, 1, int_mode);
1454 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1456 outof_input = operand_subword_force (op0, outof_word, int_mode);
1457 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1459 if (expand_doubleword_shift (op1_mode, binoptab,
1460 outof_input, into_input, op1,
1461 outof_target, into_target,
1462 unsignedp, next_methods, shift_mask))
1464 insns = get_insns ();
1465 end_sequence ();
1467 emit_insn (insns);
1468 return target;
1470 end_sequence ();
1474 /* Synthesize double word rotates from single word shifts. */
1475 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1476 && is_int_mode (mode, &int_mode)
1477 && CONST_INT_P (op1)
1478 && GET_MODE_PRECISION (int_mode) == 2 * BITS_PER_WORD
1479 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1480 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1482 rtx_insn *insns;
1483 rtx into_target, outof_target;
1484 rtx into_input, outof_input;
1485 rtx inter;
1486 int shift_count, left_shift, outof_word;
1488 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1489 won't be accurate, so use a new target. Do this also if target is not
1490 a REG, first because having a register instead may open optimization
1491 opportunities, and second because if target and op0 happen to be MEMs
1492 designating the same location, we would risk clobbering it too early
1493 in the code sequence we generate below. */
1494 if (target == 0
1495 || target == op0
1496 || target == op1
1497 || !REG_P (target)
1498 || !valid_multiword_target_p (target))
1499 target = gen_reg_rtx (int_mode);
1501 start_sequence ();
1503 shift_count = INTVAL (op1);
1505 /* OUTOF_* is the word we are shifting bits away from, and
1506 INTO_* is the word that we are shifting bits towards, thus
1507 they differ depending on the direction of the shift and
1508 WORDS_BIG_ENDIAN. */
1510 left_shift = (binoptab == rotl_optab);
1511 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1513 outof_target = operand_subword (target, outof_word, 1, int_mode);
1514 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1516 outof_input = operand_subword_force (op0, outof_word, int_mode);
1517 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1519 if (shift_count == BITS_PER_WORD)
1521 /* This is just a word swap. */
1522 emit_move_insn (outof_target, into_input);
1523 emit_move_insn (into_target, outof_input);
1524 inter = const0_rtx;
1526 else
1528 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1529 HOST_WIDE_INT first_shift_count, second_shift_count;
1530 optab reverse_unsigned_shift, unsigned_shift;
1532 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1533 ? lshr_optab : ashl_optab);
1535 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1536 ? ashl_optab : lshr_optab);
1538 if (shift_count > BITS_PER_WORD)
1540 first_shift_count = shift_count - BITS_PER_WORD;
1541 second_shift_count = 2 * BITS_PER_WORD - shift_count;
1543 else
1545 first_shift_count = BITS_PER_WORD - shift_count;
1546 second_shift_count = shift_count;
1548 rtx first_shift_count_rtx
1549 = gen_int_shift_amount (word_mode, first_shift_count);
1550 rtx second_shift_count_rtx
1551 = gen_int_shift_amount (word_mode, second_shift_count);
1553 into_temp1 = expand_binop (word_mode, unsigned_shift,
1554 outof_input, first_shift_count_rtx,
1555 NULL_RTX, unsignedp, next_methods);
1556 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1557 into_input, second_shift_count_rtx,
1558 NULL_RTX, unsignedp, next_methods);
1560 if (into_temp1 != 0 && into_temp2 != 0)
1561 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1562 into_target, unsignedp, next_methods);
1563 else
1564 inter = 0;
1566 if (inter != 0 && inter != into_target)
1567 emit_move_insn (into_target, inter);
1569 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1570 into_input, first_shift_count_rtx,
1571 NULL_RTX, unsignedp, next_methods);
1572 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1573 outof_input, second_shift_count_rtx,
1574 NULL_RTX, unsignedp, next_methods);
1576 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1577 inter = expand_binop (word_mode, ior_optab,
1578 outof_temp1, outof_temp2,
1579 outof_target, unsignedp, next_methods);
1581 if (inter != 0 && inter != outof_target)
1582 emit_move_insn (outof_target, inter);
1585 insns = get_insns ();
1586 end_sequence ();
1588 if (inter != 0)
1590 emit_insn (insns);
1591 return target;
1595 /* These can be done a word at a time by propagating carries. */
1596 if ((binoptab == add_optab || binoptab == sub_optab)
1597 && is_int_mode (mode, &int_mode)
1598 && GET_MODE_SIZE (int_mode) >= 2 * UNITS_PER_WORD
1599 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1601 unsigned int i;
1602 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1603 const unsigned int nwords = GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD;
1604 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1605 rtx xop0, xop1, xtarget;
1607 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1608 value is one of those, use it. Otherwise, use 1 since it is the
1609 one easiest to get. */
1610 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1611 int normalizep = STORE_FLAG_VALUE;
1612 #else
1613 int normalizep = 1;
1614 #endif
1616 /* Prepare the operands. */
1617 xop0 = force_reg (int_mode, op0);
1618 xop1 = force_reg (int_mode, op1);
1620 xtarget = gen_reg_rtx (int_mode);
1622 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1623 target = xtarget;
1625 /* Indicate for flow that the entire target reg is being set. */
1626 if (REG_P (target))
1627 emit_clobber (xtarget);
1629 /* Do the actual arithmetic. */
1630 for (i = 0; i < nwords; i++)
1632 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1633 rtx target_piece = operand_subword (xtarget, index, 1, int_mode);
1634 rtx op0_piece = operand_subword_force (xop0, index, int_mode);
1635 rtx op1_piece = operand_subword_force (xop1, index, int_mode);
1636 rtx x;
1638 /* Main add/subtract of the input operands. */
1639 x = expand_binop (word_mode, binoptab,
1640 op0_piece, op1_piece,
1641 target_piece, unsignedp, next_methods);
1642 if (x == 0)
1643 break;
1645 if (i + 1 < nwords)
1647 /* Store carry from main add/subtract. */
1648 carry_out = gen_reg_rtx (word_mode);
1649 carry_out = emit_store_flag_force (carry_out,
1650 (binoptab == add_optab
1651 ? LT : GT),
1652 x, op0_piece,
1653 word_mode, 1, normalizep);
1656 if (i > 0)
1658 rtx newx;
1660 /* Add/subtract previous carry to main result. */
1661 newx = expand_binop (word_mode,
1662 normalizep == 1 ? binoptab : otheroptab,
1663 x, carry_in,
1664 NULL_RTX, 1, next_methods);
1666 if (i + 1 < nwords)
1668 /* Get out carry from adding/subtracting carry in. */
1669 rtx carry_tmp = gen_reg_rtx (word_mode);
1670 carry_tmp = emit_store_flag_force (carry_tmp,
1671 (binoptab == add_optab
1672 ? LT : GT),
1673 newx, x,
1674 word_mode, 1, normalizep);
1676 /* Logical-ior the two poss. carry together. */
1677 carry_out = expand_binop (word_mode, ior_optab,
1678 carry_out, carry_tmp,
1679 carry_out, 0, next_methods);
1680 if (carry_out == 0)
1681 break;
1683 emit_move_insn (target_piece, newx);
1685 else
1687 if (x != target_piece)
1688 emit_move_insn (target_piece, x);
1691 carry_in = carry_out;
1694 if (i == GET_MODE_BITSIZE (int_mode) / (unsigned) BITS_PER_WORD)
1696 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing
1697 || ! rtx_equal_p (target, xtarget))
1699 rtx_insn *temp = emit_move_insn (target, xtarget);
1701 set_dst_reg_note (temp, REG_EQUAL,
1702 gen_rtx_fmt_ee (optab_to_code (binoptab),
1703 int_mode, copy_rtx (xop0),
1704 copy_rtx (xop1)),
1705 target);
1707 else
1708 target = xtarget;
1710 return target;
1713 else
1714 delete_insns_since (last);
1717 /* Attempt to synthesize double word multiplies using a sequence of word
1718 mode multiplications. We first attempt to generate a sequence using a
1719 more efficient unsigned widening multiply, and if that fails we then
1720 try using a signed widening multiply. */
1722 if (binoptab == smul_optab
1723 && is_int_mode (mode, &int_mode)
1724 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1725 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1726 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1728 rtx product = NULL_RTX;
1729 if (convert_optab_handler (umul_widen_optab, int_mode, word_mode)
1730 != CODE_FOR_nothing)
1732 product = expand_doubleword_mult (int_mode, op0, op1, target,
1733 true, methods);
1734 if (!product)
1735 delete_insns_since (last);
1738 if (product == NULL_RTX
1739 && (convert_optab_handler (smul_widen_optab, int_mode, word_mode)
1740 != CODE_FOR_nothing))
1742 product = expand_doubleword_mult (int_mode, op0, op1, target,
1743 false, methods);
1744 if (!product)
1745 delete_insns_since (last);
1748 if (product != NULL_RTX)
1750 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
1752 rtx_insn *move = emit_move_insn (target ? target : product,
1753 product);
1754 set_dst_reg_note (move,
1755 REG_EQUAL,
1756 gen_rtx_fmt_ee (MULT, int_mode,
1757 copy_rtx (op0),
1758 copy_rtx (op1)),
1759 target ? target : product);
1761 return product;
1765 /* It can't be open-coded in this mode.
1766 Use a library call if one is available and caller says that's ok. */
1768 libfunc = optab_libfunc (binoptab, mode);
1769 if (libfunc
1770 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1772 rtx_insn *insns;
1773 rtx op1x = op1;
1774 machine_mode op1_mode = mode;
1775 rtx value;
1777 start_sequence ();
1779 if (shift_optab_p (binoptab))
1781 op1_mode = targetm.libgcc_shift_count_mode ();
1782 /* Specify unsigned here,
1783 since negative shift counts are meaningless. */
1784 op1x = convert_to_mode (op1_mode, op1, 1);
1787 if (GET_MODE (op0) != VOIDmode
1788 && GET_MODE (op0) != mode)
1789 op0 = convert_to_mode (mode, op0, unsignedp);
1791 /* Pass 1 for NO_QUEUE so we don't lose any increments
1792 if the libcall is cse'd or moved. */
1793 value = emit_library_call_value (libfunc,
1794 NULL_RTX, LCT_CONST, mode,
1795 op0, mode, op1x, op1_mode);
1797 insns = get_insns ();
1798 end_sequence ();
1800 bool trapv = trapv_binoptab_p (binoptab);
1801 target = gen_reg_rtx (mode);
1802 emit_libcall_block_1 (insns, target, value,
1803 trapv ? NULL_RTX
1804 : gen_rtx_fmt_ee (optab_to_code (binoptab),
1805 mode, op0, op1), trapv);
1807 return target;
1810 delete_insns_since (last);
1812 /* It can't be done in this mode. Can we do it in a wider mode? */
1814 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1815 || methods == OPTAB_MUST_WIDEN))
1817 /* Caller says, don't even try. */
1818 delete_insns_since (entry_last);
1819 return 0;
1822 /* Compute the value of METHODS to pass to recursive calls.
1823 Don't allow widening to be tried recursively. */
1825 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1827 /* Look for a wider mode of the same class for which it appears we can do
1828 the operation. */
1830 if (CLASS_HAS_WIDER_MODES_P (mclass))
1832 /* This code doesn't make sense for conversion optabs, since we
1833 wouldn't then want to extend the operands to be the same size
1834 as the result. */
1835 gcc_assert (!convert_optab_p (binoptab));
1836 FOR_EACH_WIDER_MODE (wider_mode, mode)
1838 if (optab_handler (binoptab, wider_mode)
1839 || (methods == OPTAB_LIB
1840 && optab_libfunc (binoptab, wider_mode)))
1842 rtx xop0 = op0, xop1 = op1;
1843 int no_extend = 0;
1845 /* For certain integer operations, we need not actually extend
1846 the narrow operands, as long as we will truncate
1847 the results to the same narrowness. */
1849 if ((binoptab == ior_optab || binoptab == and_optab
1850 || binoptab == xor_optab
1851 || binoptab == add_optab || binoptab == sub_optab
1852 || binoptab == smul_optab || binoptab == ashl_optab)
1853 && mclass == MODE_INT)
1854 no_extend = 1;
1856 xop0 = widen_operand (xop0, wider_mode, mode,
1857 unsignedp, no_extend);
1859 /* The second operand of a shift must always be extended. */
1860 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1861 no_extend && binoptab != ashl_optab);
1863 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1864 unsignedp, methods);
1865 if (temp)
1867 if (mclass != MODE_INT
1868 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1870 if (target == 0)
1871 target = gen_reg_rtx (mode);
1872 convert_move (target, temp, 0);
1873 return target;
1875 else
1876 return gen_lowpart (mode, temp);
1878 else
1879 delete_insns_since (last);
1884 delete_insns_since (entry_last);
1885 return 0;
1888 /* Expand a binary operator which has both signed and unsigned forms.
1889 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1890 signed operations.
1892 If we widen unsigned operands, we may use a signed wider operation instead
1893 of an unsigned wider operation, since the result would be the same. */
1896 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
1897 rtx op0, rtx op1, rtx target, int unsignedp,
1898 enum optab_methods methods)
1900 rtx temp;
1901 optab direct_optab = unsignedp ? uoptab : soptab;
1902 bool save_enable;
1904 /* Do it without widening, if possible. */
1905 temp = expand_binop (mode, direct_optab, op0, op1, target,
1906 unsignedp, OPTAB_DIRECT);
1907 if (temp || methods == OPTAB_DIRECT)
1908 return temp;
1910 /* Try widening to a signed int. Disable any direct use of any
1911 signed insn in the current mode. */
1912 save_enable = swap_optab_enable (soptab, mode, false);
1914 temp = expand_binop (mode, soptab, op0, op1, target,
1915 unsignedp, OPTAB_WIDEN);
1917 /* For unsigned operands, try widening to an unsigned int. */
1918 if (!temp && unsignedp)
1919 temp = expand_binop (mode, uoptab, op0, op1, target,
1920 unsignedp, OPTAB_WIDEN);
1921 if (temp || methods == OPTAB_WIDEN)
1922 goto egress;
1924 /* Use the right width libcall if that exists. */
1925 temp = expand_binop (mode, direct_optab, op0, op1, target,
1926 unsignedp, OPTAB_LIB);
1927 if (temp || methods == OPTAB_LIB)
1928 goto egress;
1930 /* Must widen and use a libcall, use either signed or unsigned. */
1931 temp = expand_binop (mode, soptab, op0, op1, target,
1932 unsignedp, methods);
1933 if (!temp && unsignedp)
1934 temp = expand_binop (mode, uoptab, op0, op1, target,
1935 unsignedp, methods);
1937 egress:
1938 /* Undo the fiddling above. */
1939 if (save_enable)
1940 swap_optab_enable (soptab, mode, true);
1941 return temp;
1944 /* Generate code to perform an operation specified by UNOPPTAB
1945 on operand OP0, with two results to TARG0 and TARG1.
1946 We assume that the order of the operands for the instruction
1947 is TARG0, TARG1, OP0.
1949 Either TARG0 or TARG1 may be zero, but what that means is that
1950 the result is not actually wanted. We will generate it into
1951 a dummy pseudo-reg and discard it. They may not both be zero.
1953 Returns 1 if this operation can be performed; 0 if not. */
1956 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1957 int unsignedp)
1959 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1960 enum mode_class mclass;
1961 machine_mode wider_mode;
1962 rtx_insn *entry_last = get_last_insn ();
1963 rtx_insn *last;
1965 mclass = GET_MODE_CLASS (mode);
1967 if (!targ0)
1968 targ0 = gen_reg_rtx (mode);
1969 if (!targ1)
1970 targ1 = gen_reg_rtx (mode);
1972 /* Record where to go back to if we fail. */
1973 last = get_last_insn ();
1975 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
1977 struct expand_operand ops[3];
1978 enum insn_code icode = optab_handler (unoptab, mode);
1980 create_fixed_operand (&ops[0], targ0);
1981 create_fixed_operand (&ops[1], targ1);
1982 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
1983 if (maybe_expand_insn (icode, 3, ops))
1984 return 1;
1987 /* It can't be done in this mode. Can we do it in a wider mode? */
1989 if (CLASS_HAS_WIDER_MODES_P (mclass))
1991 FOR_EACH_WIDER_MODE (wider_mode, mode)
1993 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
1995 rtx t0 = gen_reg_rtx (wider_mode);
1996 rtx t1 = gen_reg_rtx (wider_mode);
1997 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1999 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2001 convert_move (targ0, t0, unsignedp);
2002 convert_move (targ1, t1, unsignedp);
2003 return 1;
2005 else
2006 delete_insns_since (last);
2011 delete_insns_since (entry_last);
2012 return 0;
2015 /* Generate code to perform an operation specified by BINOPTAB
2016 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2017 We assume that the order of the operands for the instruction
2018 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2019 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2021 Either TARG0 or TARG1 may be zero, but what that means is that
2022 the result is not actually wanted. We will generate it into
2023 a dummy pseudo-reg and discard it. They may not both be zero.
2025 Returns 1 if this operation can be performed; 0 if not. */
2028 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2029 int unsignedp)
2031 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2032 enum mode_class mclass;
2033 machine_mode wider_mode;
2034 rtx_insn *entry_last = get_last_insn ();
2035 rtx_insn *last;
2037 mclass = GET_MODE_CLASS (mode);
2039 if (!targ0)
2040 targ0 = gen_reg_rtx (mode);
2041 if (!targ1)
2042 targ1 = gen_reg_rtx (mode);
2044 /* Record where to go back to if we fail. */
2045 last = get_last_insn ();
2047 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2049 struct expand_operand ops[4];
2050 enum insn_code icode = optab_handler (binoptab, mode);
2051 machine_mode mode0 = insn_data[icode].operand[1].mode;
2052 machine_mode mode1 = insn_data[icode].operand[2].mode;
2053 rtx xop0 = op0, xop1 = op1;
2055 /* If we are optimizing, force expensive constants into a register. */
2056 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2057 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2059 create_fixed_operand (&ops[0], targ0);
2060 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2061 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2062 create_fixed_operand (&ops[3], targ1);
2063 if (maybe_expand_insn (icode, 4, ops))
2064 return 1;
2065 delete_insns_since (last);
2068 /* It can't be done in this mode. Can we do it in a wider mode? */
2070 if (CLASS_HAS_WIDER_MODES_P (mclass))
2072 FOR_EACH_WIDER_MODE (wider_mode, mode)
2074 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2076 rtx t0 = gen_reg_rtx (wider_mode);
2077 rtx t1 = gen_reg_rtx (wider_mode);
2078 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2079 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2081 if (expand_twoval_binop (binoptab, cop0, cop1,
2082 t0, t1, unsignedp))
2084 convert_move (targ0, t0, unsignedp);
2085 convert_move (targ1, t1, unsignedp);
2086 return 1;
2088 else
2089 delete_insns_since (last);
2094 delete_insns_since (entry_last);
2095 return 0;
2098 /* Expand the two-valued library call indicated by BINOPTAB, but
2099 preserve only one of the values. If TARG0 is non-NULL, the first
2100 value is placed into TARG0; otherwise the second value is placed
2101 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2102 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2103 This routine assumes that the value returned by the library call is
2104 as if the return value was of an integral mode twice as wide as the
2105 mode of OP0. Returns 1 if the call was successful. */
2107 bool
2108 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2109 rtx targ0, rtx targ1, enum rtx_code code)
2111 machine_mode mode;
2112 machine_mode libval_mode;
2113 rtx libval;
2114 rtx_insn *insns;
2115 rtx libfunc;
2117 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2118 gcc_assert (!targ0 != !targ1);
2120 mode = GET_MODE (op0);
2121 libfunc = optab_libfunc (binoptab, mode);
2122 if (!libfunc)
2123 return false;
2125 /* The value returned by the library function will have twice as
2126 many bits as the nominal MODE. */
2127 libval_mode = smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode));
2128 start_sequence ();
2129 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2130 libval_mode,
2131 op0, mode,
2132 op1, mode);
2133 /* Get the part of VAL containing the value that we want. */
2134 libval = simplify_gen_subreg (mode, libval, libval_mode,
2135 targ0 ? 0 : GET_MODE_SIZE (mode));
2136 insns = get_insns ();
2137 end_sequence ();
2138 /* Move the into the desired location. */
2139 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2140 gen_rtx_fmt_ee (code, mode, op0, op1));
2142 return true;
2146 /* Wrapper around expand_unop which takes an rtx code to specify
2147 the operation to perform, not an optab pointer. All other
2148 arguments are the same. */
2150 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2151 rtx target, int unsignedp)
2153 optab unop = code_to_optab (code);
2154 gcc_assert (unop);
2156 return expand_unop (mode, unop, op0, target, unsignedp);
2159 /* Try calculating
2160 (clz:narrow x)
2162 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2164 A similar operation can be used for clrsb. UNOPTAB says which operation
2165 we are trying to expand. */
2166 static rtx
2167 widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
2169 opt_scalar_int_mode wider_mode_iter;
2170 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2172 scalar_int_mode wider_mode = wider_mode_iter.require ();
2173 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2175 rtx xop0, temp;
2176 rtx_insn *last;
2178 last = get_last_insn ();
2180 if (target == 0)
2181 target = gen_reg_rtx (mode);
2182 xop0 = widen_operand (op0, wider_mode, mode,
2183 unoptab != clrsb_optab, false);
2184 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2185 unoptab != clrsb_optab);
2186 if (temp != 0)
2187 temp = expand_binop
2188 (wider_mode, sub_optab, temp,
2189 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2190 - GET_MODE_PRECISION (mode),
2191 wider_mode),
2192 target, true, OPTAB_DIRECT);
2193 if (temp == 0)
2194 delete_insns_since (last);
2196 return temp;
2199 return 0;
2202 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2203 quantities, choosing which based on whether the high word is nonzero. */
2204 static rtx
2205 expand_doubleword_clz (scalar_int_mode mode, rtx op0, rtx target)
2207 rtx xop0 = force_reg (mode, op0);
2208 rtx subhi = gen_highpart (word_mode, xop0);
2209 rtx sublo = gen_lowpart (word_mode, xop0);
2210 rtx_code_label *hi0_label = gen_label_rtx ();
2211 rtx_code_label *after_label = gen_label_rtx ();
2212 rtx_insn *seq;
2213 rtx temp, result;
2215 /* If we were not given a target, use a word_mode register, not a
2216 'mode' register. The result will fit, and nobody is expecting
2217 anything bigger (the return type of __builtin_clz* is int). */
2218 if (!target)
2219 target = gen_reg_rtx (word_mode);
2221 /* In any case, write to a word_mode scratch in both branches of the
2222 conditional, so we can ensure there is a single move insn setting
2223 'target' to tag a REG_EQUAL note on. */
2224 result = gen_reg_rtx (word_mode);
2226 start_sequence ();
2228 /* If the high word is not equal to zero,
2229 then clz of the full value is clz of the high word. */
2230 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2231 word_mode, true, hi0_label);
2233 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2234 if (!temp)
2235 goto fail;
2237 if (temp != result)
2238 convert_move (result, temp, true);
2240 emit_jump_insn (targetm.gen_jump (after_label));
2241 emit_barrier ();
2243 /* Else clz of the full value is clz of the low word plus the number
2244 of bits in the high word. */
2245 emit_label (hi0_label);
2247 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2248 if (!temp)
2249 goto fail;
2250 temp = expand_binop (word_mode, add_optab, temp,
2251 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2252 result, true, OPTAB_DIRECT);
2253 if (!temp)
2254 goto fail;
2255 if (temp != result)
2256 convert_move (result, temp, true);
2258 emit_label (after_label);
2259 convert_move (target, result, true);
2261 seq = get_insns ();
2262 end_sequence ();
2264 add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
2265 emit_insn (seq);
2266 return target;
2268 fail:
2269 end_sequence ();
2270 return 0;
2273 /* Try calculating popcount of a double-word quantity as two popcount's of
2274 word-sized quantities and summing up the results. */
2275 static rtx
2276 expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
2278 rtx t0, t1, t;
2279 rtx_insn *seq;
2281 start_sequence ();
2283 t0 = expand_unop_direct (word_mode, popcount_optab,
2284 operand_subword_force (op0, 0, mode), NULL_RTX,
2285 true);
2286 t1 = expand_unop_direct (word_mode, popcount_optab,
2287 operand_subword_force (op0, 1, mode), NULL_RTX,
2288 true);
2289 if (!t0 || !t1)
2291 end_sequence ();
2292 return NULL_RTX;
2295 /* If we were not given a target, use a word_mode register, not a
2296 'mode' register. The result will fit, and nobody is expecting
2297 anything bigger (the return type of __builtin_popcount* is int). */
2298 if (!target)
2299 target = gen_reg_rtx (word_mode);
2301 t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
2303 seq = get_insns ();
2304 end_sequence ();
2306 add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
2307 emit_insn (seq);
2308 return t;
2311 /* Try calculating
2312 (parity:wide x)
2314 (parity:narrow (low (x) ^ high (x))) */
2315 static rtx
2316 expand_doubleword_parity (scalar_int_mode mode, rtx op0, rtx target)
2318 rtx t = expand_binop (word_mode, xor_optab,
2319 operand_subword_force (op0, 0, mode),
2320 operand_subword_force (op0, 1, mode),
2321 NULL_RTX, 0, OPTAB_DIRECT);
2322 return expand_unop (word_mode, parity_optab, t, target, true);
2325 /* Try calculating
2326 (bswap:narrow x)
2328 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2329 static rtx
2330 widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
2332 rtx x;
2333 rtx_insn *last;
2334 opt_scalar_int_mode wider_mode_iter;
2336 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2337 if (optab_handler (bswap_optab, wider_mode_iter.require ())
2338 != CODE_FOR_nothing)
2339 break;
2341 if (!wider_mode_iter.exists ())
2342 return NULL_RTX;
2344 scalar_int_mode wider_mode = wider_mode_iter.require ();
2345 last = get_last_insn ();
2347 x = widen_operand (op0, wider_mode, mode, true, true);
2348 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2350 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2351 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2352 if (x != 0)
2353 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2354 GET_MODE_BITSIZE (wider_mode)
2355 - GET_MODE_BITSIZE (mode),
2356 NULL_RTX, true);
2358 if (x != 0)
2360 if (target == 0)
2361 target = gen_reg_rtx (mode);
2362 emit_move_insn (target, gen_lowpart (mode, x));
2364 else
2365 delete_insns_since (last);
2367 return target;
2370 /* Try calculating bswap as two bswaps of two word-sized operands. */
2372 static rtx
2373 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2375 rtx t0, t1;
2377 t1 = expand_unop (word_mode, bswap_optab,
2378 operand_subword_force (op, 0, mode), NULL_RTX, true);
2379 t0 = expand_unop (word_mode, bswap_optab,
2380 operand_subword_force (op, 1, mode), NULL_RTX, true);
2382 if (target == 0 || !valid_multiword_target_p (target))
2383 target = gen_reg_rtx (mode);
2384 if (REG_P (target))
2385 emit_clobber (target);
2386 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2387 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2389 return target;
2392 /* Try calculating (parity x) as (and (popcount x) 1), where
2393 popcount can also be done in a wider mode. */
2394 static rtx
2395 expand_parity (scalar_int_mode mode, rtx op0, rtx target)
2397 enum mode_class mclass = GET_MODE_CLASS (mode);
2398 opt_scalar_int_mode wider_mode_iter;
2399 FOR_EACH_MODE_FROM (wider_mode_iter, mode)
2401 scalar_int_mode wider_mode = wider_mode_iter.require ();
2402 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2404 rtx xop0, temp;
2405 rtx_insn *last;
2407 last = get_last_insn ();
2409 if (target == 0 || GET_MODE (target) != wider_mode)
2410 target = gen_reg_rtx (wider_mode);
2412 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2413 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2414 true);
2415 if (temp != 0)
2416 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2417 target, true, OPTAB_DIRECT);
2419 if (temp)
2421 if (mclass != MODE_INT
2422 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2423 return convert_to_mode (mode, temp, 0);
2424 else
2425 return gen_lowpart (mode, temp);
2427 else
2428 delete_insns_since (last);
2431 return 0;
2434 /* Try calculating ctz(x) as K - clz(x & -x) ,
2435 where K is GET_MODE_PRECISION(mode) - 1.
2437 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2438 don't have to worry about what the hardware does in that case. (If
2439 the clz instruction produces the usual value at 0, which is K, the
2440 result of this code sequence will be -1; expand_ffs, below, relies
2441 on this. It might be nice to have it be K instead, for consistency
2442 with the (very few) processors that provide a ctz with a defined
2443 value, but that would take one more instruction, and it would be
2444 less convenient for expand_ffs anyway. */
2446 static rtx
2447 expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
2449 rtx_insn *seq;
2450 rtx temp;
2452 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2453 return 0;
2455 start_sequence ();
2457 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2458 if (temp)
2459 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2460 true, OPTAB_DIRECT);
2461 if (temp)
2462 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2463 if (temp)
2464 temp = expand_binop (mode, sub_optab,
2465 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2466 temp, target,
2467 true, OPTAB_DIRECT);
2468 if (temp == 0)
2470 end_sequence ();
2471 return 0;
2474 seq = get_insns ();
2475 end_sequence ();
2477 add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
2478 emit_insn (seq);
2479 return temp;
2483 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2484 else with the sequence used by expand_clz.
2486 The ffs builtin promises to return zero for a zero value and ctz/clz
2487 may have an undefined value in that case. If they do not give us a
2488 convenient value, we have to generate a test and branch. */
2489 static rtx
2490 expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
2492 HOST_WIDE_INT val = 0;
2493 bool defined_at_zero = false;
2494 rtx temp;
2495 rtx_insn *seq;
2497 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2499 start_sequence ();
2501 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2502 if (!temp)
2503 goto fail;
2505 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2507 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2509 start_sequence ();
2510 temp = expand_ctz (mode, op0, 0);
2511 if (!temp)
2512 goto fail;
2514 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2516 defined_at_zero = true;
2517 val = (GET_MODE_PRECISION (mode) - 1) - val;
2520 else
2521 return 0;
2523 if (defined_at_zero && val == -1)
2524 /* No correction needed at zero. */;
2525 else
2527 /* We don't try to do anything clever with the situation found
2528 on some processors (eg Alpha) where ctz(0:mode) ==
2529 bitsize(mode). If someone can think of a way to send N to -1
2530 and leave alone all values in the range 0..N-1 (where N is a
2531 power of two), cheaper than this test-and-branch, please add it.
2533 The test-and-branch is done after the operation itself, in case
2534 the operation sets condition codes that can be recycled for this.
2535 (This is true on i386, for instance.) */
2537 rtx_code_label *nonzero_label = gen_label_rtx ();
2538 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2539 mode, true, nonzero_label);
2541 convert_move (temp, GEN_INT (-1), false);
2542 emit_label (nonzero_label);
2545 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2546 to produce a value in the range 0..bitsize. */
2547 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2548 target, false, OPTAB_DIRECT);
2549 if (!temp)
2550 goto fail;
2552 seq = get_insns ();
2553 end_sequence ();
2555 add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
2556 emit_insn (seq);
2557 return temp;
2559 fail:
2560 end_sequence ();
2561 return 0;
2564 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2565 conditions, VAL may already be a SUBREG against which we cannot generate
2566 a further SUBREG. In this case, we expect forcing the value into a
2567 register will work around the situation. */
2569 static rtx
2570 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2571 machine_mode imode)
2573 rtx ret;
2574 ret = lowpart_subreg (omode, val, imode);
2575 if (ret == NULL)
2577 val = force_reg (imode, val);
2578 ret = lowpart_subreg (omode, val, imode);
2579 gcc_assert (ret != NULL);
2581 return ret;
2584 /* Expand a floating point absolute value or negation operation via a
2585 logical operation on the sign bit. */
2587 static rtx
2588 expand_absneg_bit (enum rtx_code code, scalar_float_mode mode,
2589 rtx op0, rtx target)
2591 const struct real_format *fmt;
2592 int bitpos, word, nwords, i;
2593 scalar_int_mode imode;
2594 rtx temp;
2595 rtx_insn *insns;
2597 /* The format has to have a simple sign bit. */
2598 fmt = REAL_MODE_FORMAT (mode);
2599 if (fmt == NULL)
2600 return NULL_RTX;
2602 bitpos = fmt->signbit_rw;
2603 if (bitpos < 0)
2604 return NULL_RTX;
2606 /* Don't create negative zeros if the format doesn't support them. */
2607 if (code == NEG && !fmt->has_signed_zero)
2608 return NULL_RTX;
2610 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2612 if (!int_mode_for_mode (mode).exists (&imode))
2613 return NULL_RTX;
2614 word = 0;
2615 nwords = 1;
2617 else
2619 imode = word_mode;
2621 if (FLOAT_WORDS_BIG_ENDIAN)
2622 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2623 else
2624 word = bitpos / BITS_PER_WORD;
2625 bitpos = bitpos % BITS_PER_WORD;
2626 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2629 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2630 if (code == ABS)
2631 mask = ~mask;
2633 if (target == 0
2634 || target == op0
2635 || (nwords > 1 && !valid_multiword_target_p (target)))
2636 target = gen_reg_rtx (mode);
2638 if (nwords > 1)
2640 start_sequence ();
2642 for (i = 0; i < nwords; ++i)
2644 rtx targ_piece = operand_subword (target, i, 1, mode);
2645 rtx op0_piece = operand_subword_force (op0, i, mode);
2647 if (i == word)
2649 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2650 op0_piece,
2651 immed_wide_int_const (mask, imode),
2652 targ_piece, 1, OPTAB_LIB_WIDEN);
2653 if (temp != targ_piece)
2654 emit_move_insn (targ_piece, temp);
2656 else
2657 emit_move_insn (targ_piece, op0_piece);
2660 insns = get_insns ();
2661 end_sequence ();
2663 emit_insn (insns);
2665 else
2667 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2668 gen_lowpart (imode, op0),
2669 immed_wide_int_const (mask, imode),
2670 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2671 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2673 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2674 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2675 target);
2678 return target;
2681 /* As expand_unop, but will fail rather than attempt the operation in a
2682 different mode or with a libcall. */
2683 static rtx
2684 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2685 int unsignedp)
2687 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2689 struct expand_operand ops[2];
2690 enum insn_code icode = optab_handler (unoptab, mode);
2691 rtx_insn *last = get_last_insn ();
2692 rtx_insn *pat;
2694 create_output_operand (&ops[0], target, mode);
2695 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2696 pat = maybe_gen_insn (icode, 2, ops);
2697 if (pat)
2699 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2700 && ! add_equal_note (pat, ops[0].value,
2701 optab_to_code (unoptab),
2702 ops[1].value, NULL_RTX, mode))
2704 delete_insns_since (last);
2705 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2708 emit_insn (pat);
2710 return ops[0].value;
2713 return 0;
2716 /* Generate code to perform an operation specified by UNOPTAB
2717 on operand OP0, with result having machine-mode MODE.
2719 UNSIGNEDP is for the case where we have to widen the operands
2720 to perform the operation. It says to use zero-extension.
2722 If TARGET is nonzero, the value
2723 is generated there, if it is convenient to do so.
2724 In all cases an rtx is returned for the locus of the value;
2725 this may or may not be TARGET. */
2728 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2729 int unsignedp)
2731 enum mode_class mclass = GET_MODE_CLASS (mode);
2732 machine_mode wider_mode;
2733 scalar_int_mode int_mode;
2734 scalar_float_mode float_mode;
2735 rtx temp;
2736 rtx libfunc;
2738 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2739 if (temp)
2740 return temp;
2742 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2744 /* Widening (or narrowing) clz needs special treatment. */
2745 if (unoptab == clz_optab)
2747 if (is_a <scalar_int_mode> (mode, &int_mode))
2749 temp = widen_leading (int_mode, op0, target, unoptab);
2750 if (temp)
2751 return temp;
2753 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2754 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2756 temp = expand_doubleword_clz (int_mode, op0, target);
2757 if (temp)
2758 return temp;
2762 goto try_libcall;
2765 if (unoptab == clrsb_optab)
2767 if (is_a <scalar_int_mode> (mode, &int_mode))
2769 temp = widen_leading (int_mode, op0, target, unoptab);
2770 if (temp)
2771 return temp;
2773 goto try_libcall;
2776 if (unoptab == popcount_optab
2777 && is_a <scalar_int_mode> (mode, &int_mode)
2778 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2779 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2780 && optimize_insn_for_speed_p ())
2782 temp = expand_doubleword_popcount (int_mode, op0, target);
2783 if (temp)
2784 return temp;
2787 if (unoptab == parity_optab
2788 && is_a <scalar_int_mode> (mode, &int_mode)
2789 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2790 && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2791 || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
2792 && optimize_insn_for_speed_p ())
2794 temp = expand_doubleword_parity (int_mode, op0, target);
2795 if (temp)
2796 return temp;
2799 /* Widening (or narrowing) bswap needs special treatment. */
2800 if (unoptab == bswap_optab)
2802 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2803 or ROTATERT. First try these directly; if this fails, then try the
2804 obvious pair of shifts with allowed widening, as this will probably
2805 be always more efficient than the other fallback methods. */
2806 if (mode == HImode)
2808 rtx_insn *last;
2809 rtx temp1, temp2;
2811 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2813 temp = expand_binop (mode, rotl_optab, op0,
2814 gen_int_shift_amount (mode, 8),
2815 target, unsignedp, OPTAB_DIRECT);
2816 if (temp)
2817 return temp;
2820 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2822 temp = expand_binop (mode, rotr_optab, op0,
2823 gen_int_shift_amount (mode, 8),
2824 target, unsignedp, OPTAB_DIRECT);
2825 if (temp)
2826 return temp;
2829 last = get_last_insn ();
2831 temp1 = expand_binop (mode, ashl_optab, op0,
2832 gen_int_shift_amount (mode, 8), NULL_RTX,
2833 unsignedp, OPTAB_WIDEN);
2834 temp2 = expand_binop (mode, lshr_optab, op0,
2835 gen_int_shift_amount (mode, 8), NULL_RTX,
2836 unsignedp, OPTAB_WIDEN);
2837 if (temp1 && temp2)
2839 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2840 unsignedp, OPTAB_WIDEN);
2841 if (temp)
2842 return temp;
2845 delete_insns_since (last);
2848 if (is_a <scalar_int_mode> (mode, &int_mode))
2850 temp = widen_bswap (int_mode, op0, target);
2851 if (temp)
2852 return temp;
2854 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2855 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2857 temp = expand_doubleword_bswap (mode, op0, target);
2858 if (temp)
2859 return temp;
2863 goto try_libcall;
2866 if (CLASS_HAS_WIDER_MODES_P (mclass))
2867 FOR_EACH_WIDER_MODE (wider_mode, mode)
2869 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2871 rtx xop0 = op0;
2872 rtx_insn *last = get_last_insn ();
2874 /* For certain operations, we need not actually extend
2875 the narrow operand, as long as we will truncate the
2876 results to the same narrowness. */
2878 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2879 (unoptab == neg_optab
2880 || unoptab == one_cmpl_optab)
2881 && mclass == MODE_INT);
2883 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2884 unsignedp);
2886 if (temp)
2888 if (mclass != MODE_INT
2889 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2891 if (target == 0)
2892 target = gen_reg_rtx (mode);
2893 convert_move (target, temp, 0);
2894 return target;
2896 else
2897 return gen_lowpart (mode, temp);
2899 else
2900 delete_insns_since (last);
2904 /* These can be done a word at a time. */
2905 if (unoptab == one_cmpl_optab
2906 && is_int_mode (mode, &int_mode)
2907 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
2908 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2910 int i;
2911 rtx_insn *insns;
2913 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2914 target = gen_reg_rtx (int_mode);
2916 start_sequence ();
2918 /* Do the actual arithmetic. */
2919 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
2921 rtx target_piece = operand_subword (target, i, 1, int_mode);
2922 rtx x = expand_unop (word_mode, unoptab,
2923 operand_subword_force (op0, i, int_mode),
2924 target_piece, unsignedp);
2926 if (target_piece != x)
2927 emit_move_insn (target_piece, x);
2930 insns = get_insns ();
2931 end_sequence ();
2933 emit_insn (insns);
2934 return target;
2937 if (optab_to_code (unoptab) == NEG)
2939 /* Try negating floating point values by flipping the sign bit. */
2940 if (is_a <scalar_float_mode> (mode, &float_mode))
2942 temp = expand_absneg_bit (NEG, float_mode, op0, target);
2943 if (temp)
2944 return temp;
2947 /* If there is no negation pattern, and we have no negative zero,
2948 try subtracting from zero. */
2949 if (!HONOR_SIGNED_ZEROS (mode))
2951 temp = expand_binop (mode, (unoptab == negv_optab
2952 ? subv_optab : sub_optab),
2953 CONST0_RTX (mode), op0, target,
2954 unsignedp, OPTAB_DIRECT);
2955 if (temp)
2956 return temp;
2960 /* Try calculating parity (x) as popcount (x) % 2. */
2961 if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
2963 temp = expand_parity (int_mode, op0, target);
2964 if (temp)
2965 return temp;
2968 /* Try implementing ffs (x) in terms of clz (x). */
2969 if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
2971 temp = expand_ffs (int_mode, op0, target);
2972 if (temp)
2973 return temp;
2976 /* Try implementing ctz (x) in terms of clz (x). */
2977 if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
2979 temp = expand_ctz (int_mode, op0, target);
2980 if (temp)
2981 return temp;
2984 try_libcall:
2985 /* Now try a library call in this mode. */
2986 libfunc = optab_libfunc (unoptab, mode);
2987 if (libfunc)
2989 rtx_insn *insns;
2990 rtx value;
2991 rtx eq_value;
2992 machine_mode outmode = mode;
2994 /* All of these functions return small values. Thus we choose to
2995 have them return something that isn't a double-word. */
2996 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2997 || unoptab == clrsb_optab || unoptab == popcount_optab
2998 || unoptab == parity_optab)
2999 outmode
3000 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3001 optab_libfunc (unoptab, mode)));
3003 start_sequence ();
3005 /* Pass 1 for NO_QUEUE so we don't lose any increments
3006 if the libcall is cse'd or moved. */
3007 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3008 op0, mode);
3009 insns = get_insns ();
3010 end_sequence ();
3012 target = gen_reg_rtx (outmode);
3013 bool trapv = trapv_unoptab_p (unoptab);
3014 if (trapv)
3015 eq_value = NULL_RTX;
3016 else
3018 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3019 if (GET_MODE_UNIT_SIZE (outmode) < GET_MODE_UNIT_SIZE (mode))
3020 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3021 else if (GET_MODE_UNIT_SIZE (outmode) > GET_MODE_UNIT_SIZE (mode))
3022 eq_value = simplify_gen_unary (ZERO_EXTEND,
3023 outmode, eq_value, mode);
3025 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
3027 return target;
3030 /* It can't be done in this mode. Can we do it in a wider mode? */
3032 if (CLASS_HAS_WIDER_MODES_P (mclass))
3034 FOR_EACH_WIDER_MODE (wider_mode, mode)
3036 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3037 || optab_libfunc (unoptab, wider_mode))
3039 rtx xop0 = op0;
3040 rtx_insn *last = get_last_insn ();
3042 /* For certain operations, we need not actually extend
3043 the narrow operand, as long as we will truncate the
3044 results to the same narrowness. */
3045 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3046 (unoptab == neg_optab
3047 || unoptab == one_cmpl_optab
3048 || unoptab == bswap_optab)
3049 && mclass == MODE_INT);
3051 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3052 unsignedp);
3054 /* If we are generating clz using wider mode, adjust the
3055 result. Similarly for clrsb. */
3056 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3057 && temp != 0)
3059 scalar_int_mode wider_int_mode
3060 = as_a <scalar_int_mode> (wider_mode);
3061 int_mode = as_a <scalar_int_mode> (mode);
3062 temp = expand_binop
3063 (wider_mode, sub_optab, temp,
3064 gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
3065 - GET_MODE_PRECISION (int_mode),
3066 wider_int_mode),
3067 target, true, OPTAB_DIRECT);
3070 /* Likewise for bswap. */
3071 if (unoptab == bswap_optab && temp != 0)
3073 scalar_int_mode wider_int_mode
3074 = as_a <scalar_int_mode> (wider_mode);
3075 int_mode = as_a <scalar_int_mode> (mode);
3076 gcc_assert (GET_MODE_PRECISION (wider_int_mode)
3077 == GET_MODE_BITSIZE (wider_int_mode)
3078 && GET_MODE_PRECISION (int_mode)
3079 == GET_MODE_BITSIZE (int_mode));
3081 temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
3082 GET_MODE_BITSIZE (wider_int_mode)
3083 - GET_MODE_BITSIZE (int_mode),
3084 NULL_RTX, true);
3087 if (temp)
3089 if (mclass != MODE_INT)
3091 if (target == 0)
3092 target = gen_reg_rtx (mode);
3093 convert_move (target, temp, 0);
3094 return target;
3096 else
3097 return gen_lowpart (mode, temp);
3099 else
3100 delete_insns_since (last);
3105 /* One final attempt at implementing negation via subtraction,
3106 this time allowing widening of the operand. */
3107 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3109 rtx temp;
3110 temp = expand_binop (mode,
3111 unoptab == negv_optab ? subv_optab : sub_optab,
3112 CONST0_RTX (mode), op0,
3113 target, unsignedp, OPTAB_LIB_WIDEN);
3114 if (temp)
3115 return temp;
3118 return 0;
3121 /* Emit code to compute the absolute value of OP0, with result to
3122 TARGET if convenient. (TARGET may be 0.) The return value says
3123 where the result actually is to be found.
3125 MODE is the mode of the operand; the mode of the result is
3126 different but can be deduced from MODE.
3131 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3132 int result_unsignedp)
3134 rtx temp;
3136 if (GET_MODE_CLASS (mode) != MODE_INT
3137 || ! flag_trapv)
3138 result_unsignedp = 1;
3140 /* First try to do it with a special abs instruction. */
3141 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3142 op0, target, 0);
3143 if (temp != 0)
3144 return temp;
3146 /* For floating point modes, try clearing the sign bit. */
3147 scalar_float_mode float_mode;
3148 if (is_a <scalar_float_mode> (mode, &float_mode))
3150 temp = expand_absneg_bit (ABS, float_mode, op0, target);
3151 if (temp)
3152 return temp;
3155 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3156 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3157 && !HONOR_SIGNED_ZEROS (mode))
3159 rtx_insn *last = get_last_insn ();
3161 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3162 op0, NULL_RTX, 0);
3163 if (temp != 0)
3164 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3165 OPTAB_WIDEN);
3167 if (temp != 0)
3168 return temp;
3170 delete_insns_since (last);
3173 /* If this machine has expensive jumps, we can do integer absolute
3174 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3175 where W is the width of MODE. */
3177 scalar_int_mode int_mode;
3178 if (is_int_mode (mode, &int_mode)
3179 && BRANCH_COST (optimize_insn_for_speed_p (),
3180 false) >= 2)
3182 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3183 GET_MODE_PRECISION (int_mode) - 1,
3184 NULL_RTX, 0);
3186 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3187 OPTAB_LIB_WIDEN);
3188 if (temp != 0)
3189 temp = expand_binop (int_mode,
3190 result_unsignedp ? sub_optab : subv_optab,
3191 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3193 if (temp != 0)
3194 return temp;
3197 return NULL_RTX;
3201 expand_abs (machine_mode mode, rtx op0, rtx target,
3202 int result_unsignedp, int safe)
3204 rtx temp;
3205 rtx_code_label *op1;
3207 if (GET_MODE_CLASS (mode) != MODE_INT
3208 || ! flag_trapv)
3209 result_unsignedp = 1;
3211 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3212 if (temp != 0)
3213 return temp;
3215 /* If that does not win, use conditional jump and negate. */
3217 /* It is safe to use the target if it is the same
3218 as the source if this is also a pseudo register */
3219 if (op0 == target && REG_P (op0)
3220 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3221 safe = 1;
3223 op1 = gen_label_rtx ();
3224 if (target == 0 || ! safe
3225 || GET_MODE (target) != mode
3226 || (MEM_P (target) && MEM_VOLATILE_P (target))
3227 || (REG_P (target)
3228 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3229 target = gen_reg_rtx (mode);
3231 emit_move_insn (target, op0);
3232 NO_DEFER_POP;
3234 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3235 NULL_RTX, NULL, op1,
3236 profile_probability::uninitialized ());
3238 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3239 target, target, 0);
3240 if (op0 != target)
3241 emit_move_insn (target, op0);
3242 emit_label (op1);
3243 OK_DEFER_POP;
3244 return target;
3247 /* Emit code to compute the one's complement absolute value of OP0
3248 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3249 (TARGET may be NULL_RTX.) The return value says where the result
3250 actually is to be found.
3252 MODE is the mode of the operand; the mode of the result is
3253 different but can be deduced from MODE. */
3256 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3258 rtx temp;
3260 /* Not applicable for floating point modes. */
3261 if (FLOAT_MODE_P (mode))
3262 return NULL_RTX;
3264 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3265 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3267 rtx_insn *last = get_last_insn ();
3269 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3270 if (temp != 0)
3271 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3272 OPTAB_WIDEN);
3274 if (temp != 0)
3275 return temp;
3277 delete_insns_since (last);
3280 /* If this machine has expensive jumps, we can do one's complement
3281 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3283 scalar_int_mode int_mode;
3284 if (is_int_mode (mode, &int_mode)
3285 && BRANCH_COST (optimize_insn_for_speed_p (),
3286 false) >= 2)
3288 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3289 GET_MODE_PRECISION (int_mode) - 1,
3290 NULL_RTX, 0);
3292 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3293 OPTAB_LIB_WIDEN);
3295 if (temp != 0)
3296 return temp;
3299 return NULL_RTX;
3302 /* A subroutine of expand_copysign, perform the copysign operation using the
3303 abs and neg primitives advertised to exist on the target. The assumption
3304 is that we have a split register file, and leaving op0 in fp registers,
3305 and not playing with subregs so much, will help the register allocator. */
3307 static rtx
3308 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3309 int bitpos, bool op0_is_abs)
3311 scalar_int_mode imode;
3312 enum insn_code icode;
3313 rtx sign;
3314 rtx_code_label *label;
3316 if (target == op1)
3317 target = NULL_RTX;
3319 /* Check if the back end provides an insn that handles signbit for the
3320 argument's mode. */
3321 icode = optab_handler (signbit_optab, mode);
3322 if (icode != CODE_FOR_nothing)
3324 imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
3325 sign = gen_reg_rtx (imode);
3326 emit_unop_insn (icode, sign, op1, UNKNOWN);
3328 else
3330 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3332 if (!int_mode_for_mode (mode).exists (&imode))
3333 return NULL_RTX;
3334 op1 = gen_lowpart (imode, op1);
3336 else
3338 int word;
3340 imode = word_mode;
3341 if (FLOAT_WORDS_BIG_ENDIAN)
3342 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3343 else
3344 word = bitpos / BITS_PER_WORD;
3345 bitpos = bitpos % BITS_PER_WORD;
3346 op1 = operand_subword_force (op1, word, mode);
3349 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3350 sign = expand_binop (imode, and_optab, op1,
3351 immed_wide_int_const (mask, imode),
3352 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3355 if (!op0_is_abs)
3357 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3358 if (op0 == NULL)
3359 return NULL_RTX;
3360 target = op0;
3362 else
3364 if (target == NULL_RTX)
3365 target = copy_to_reg (op0);
3366 else
3367 emit_move_insn (target, op0);
3370 label = gen_label_rtx ();
3371 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3373 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3374 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3375 else
3376 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3377 if (op0 != target)
3378 emit_move_insn (target, op0);
3380 emit_label (label);
3382 return target;
3386 /* A subroutine of expand_copysign, perform the entire copysign operation
3387 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3388 is true if op0 is known to have its sign bit clear. */
3390 static rtx
3391 expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3392 int bitpos, bool op0_is_abs)
3394 scalar_int_mode imode;
3395 int word, nwords, i;
3396 rtx temp;
3397 rtx_insn *insns;
3399 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3401 if (!int_mode_for_mode (mode).exists (&imode))
3402 return NULL_RTX;
3403 word = 0;
3404 nwords = 1;
3406 else
3408 imode = word_mode;
3410 if (FLOAT_WORDS_BIG_ENDIAN)
3411 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3412 else
3413 word = bitpos / BITS_PER_WORD;
3414 bitpos = bitpos % BITS_PER_WORD;
3415 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3418 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3420 if (target == 0
3421 || target == op0
3422 || target == op1
3423 || (nwords > 1 && !valid_multiword_target_p (target)))
3424 target = gen_reg_rtx (mode);
3426 if (nwords > 1)
3428 start_sequence ();
3430 for (i = 0; i < nwords; ++i)
3432 rtx targ_piece = operand_subword (target, i, 1, mode);
3433 rtx op0_piece = operand_subword_force (op0, i, mode);
3435 if (i == word)
3437 if (!op0_is_abs)
3438 op0_piece
3439 = expand_binop (imode, and_optab, op0_piece,
3440 immed_wide_int_const (~mask, imode),
3441 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3442 op1 = expand_binop (imode, and_optab,
3443 operand_subword_force (op1, i, mode),
3444 immed_wide_int_const (mask, imode),
3445 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3447 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3448 targ_piece, 1, OPTAB_LIB_WIDEN);
3449 if (temp != targ_piece)
3450 emit_move_insn (targ_piece, temp);
3452 else
3453 emit_move_insn (targ_piece, op0_piece);
3456 insns = get_insns ();
3457 end_sequence ();
3459 emit_insn (insns);
3461 else
3463 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3464 immed_wide_int_const (mask, imode),
3465 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3467 op0 = gen_lowpart (imode, op0);
3468 if (!op0_is_abs)
3469 op0 = expand_binop (imode, and_optab, op0,
3470 immed_wide_int_const (~mask, imode),
3471 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3473 temp = expand_binop (imode, ior_optab, op0, op1,
3474 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3475 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3478 return target;
3481 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3482 scalar floating point mode. Return NULL if we do not know how to
3483 expand the operation inline. */
3486 expand_copysign (rtx op0, rtx op1, rtx target)
3488 scalar_float_mode mode;
3489 const struct real_format *fmt;
3490 bool op0_is_abs;
3491 rtx temp;
3493 mode = as_a <scalar_float_mode> (GET_MODE (op0));
3494 gcc_assert (GET_MODE (op1) == mode);
3496 /* First try to do it with a special instruction. */
3497 temp = expand_binop (mode, copysign_optab, op0, op1,
3498 target, 0, OPTAB_DIRECT);
3499 if (temp)
3500 return temp;
3502 fmt = REAL_MODE_FORMAT (mode);
3503 if (fmt == NULL || !fmt->has_signed_zero)
3504 return NULL_RTX;
3506 op0_is_abs = false;
3507 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3509 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3510 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3511 op0_is_abs = true;
3514 if (fmt->signbit_ro >= 0
3515 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3516 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3517 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3519 temp = expand_copysign_absneg (mode, op0, op1, target,
3520 fmt->signbit_ro, op0_is_abs);
3521 if (temp)
3522 return temp;
3525 if (fmt->signbit_rw < 0)
3526 return NULL_RTX;
3527 return expand_copysign_bit (mode, op0, op1, target,
3528 fmt->signbit_rw, op0_is_abs);
3531 /* Generate an instruction whose insn-code is INSN_CODE,
3532 with two operands: an output TARGET and an input OP0.
3533 TARGET *must* be nonzero, and the output is always stored there.
3534 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3535 the value that is stored into TARGET.
3537 Return false if expansion failed. */
3539 bool
3540 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3541 enum rtx_code code)
3543 struct expand_operand ops[2];
3544 rtx_insn *pat;
3546 create_output_operand (&ops[0], target, GET_MODE (target));
3547 create_input_operand (&ops[1], op0, GET_MODE (op0));
3548 pat = maybe_gen_insn (icode, 2, ops);
3549 if (!pat)
3550 return false;
3552 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3553 && code != UNKNOWN)
3554 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
3555 GET_MODE (op0));
3557 emit_insn (pat);
3559 if (ops[0].value != target)
3560 emit_move_insn (target, ops[0].value);
3561 return true;
3563 /* Generate an instruction whose insn-code is INSN_CODE,
3564 with two operands: an output TARGET and an input OP0.
3565 TARGET *must* be nonzero, and the output is always stored there.
3566 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3567 the value that is stored into TARGET. */
3569 void
3570 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3572 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3573 gcc_assert (ok);
3576 struct no_conflict_data
3578 rtx target;
3579 rtx_insn *first, *insn;
3580 bool must_stay;
3583 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3584 the currently examined clobber / store has to stay in the list of
3585 insns that constitute the actual libcall block. */
3586 static void
3587 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3589 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3591 /* If this inns directly contributes to setting the target, it must stay. */
3592 if (reg_overlap_mentioned_p (p->target, dest))
3593 p->must_stay = true;
3594 /* If we haven't committed to keeping any other insns in the list yet,
3595 there is nothing more to check. */
3596 else if (p->insn == p->first)
3597 return;
3598 /* If this insn sets / clobbers a register that feeds one of the insns
3599 already in the list, this insn has to stay too. */
3600 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3601 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3602 || reg_used_between_p (dest, p->first, p->insn)
3603 /* Likewise if this insn depends on a register set by a previous
3604 insn in the list, or if it sets a result (presumably a hard
3605 register) that is set or clobbered by a previous insn.
3606 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3607 SET_DEST perform the former check on the address, and the latter
3608 check on the MEM. */
3609 || (GET_CODE (set) == SET
3610 && (modified_in_p (SET_SRC (set), p->first)
3611 || modified_in_p (SET_DEST (set), p->first)
3612 || modified_between_p (SET_SRC (set), p->first, p->insn)
3613 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3614 p->must_stay = true;
3618 /* Emit code to make a call to a constant function or a library call.
3620 INSNS is a list containing all insns emitted in the call.
3621 These insns leave the result in RESULT. Our block is to copy RESULT
3622 to TARGET, which is logically equivalent to EQUIV.
3624 We first emit any insns that set a pseudo on the assumption that these are
3625 loading constants into registers; doing so allows them to be safely cse'ed
3626 between blocks. Then we emit all the other insns in the block, followed by
3627 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3628 note with an operand of EQUIV. */
3630 static void
3631 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3632 bool equiv_may_trap)
3634 rtx final_dest = target;
3635 rtx_insn *next, *last, *insn;
3637 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3638 into a MEM later. Protect the libcall block from this change. */
3639 if (! REG_P (target) || REG_USERVAR_P (target))
3640 target = gen_reg_rtx (GET_MODE (target));
3642 /* If we're using non-call exceptions, a libcall corresponding to an
3643 operation that may trap may also trap. */
3644 /* ??? See the comment in front of make_reg_eh_region_note. */
3645 if (cfun->can_throw_non_call_exceptions
3646 && (equiv_may_trap || may_trap_p (equiv)))
3648 for (insn = insns; insn; insn = NEXT_INSN (insn))
3649 if (CALL_P (insn))
3651 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3652 if (note)
3654 int lp_nr = INTVAL (XEXP (note, 0));
3655 if (lp_nr == 0 || lp_nr == INT_MIN)
3656 remove_note (insn, note);
3660 else
3662 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3663 reg note to indicate that this call cannot throw or execute a nonlocal
3664 goto (unless there is already a REG_EH_REGION note, in which case
3665 we update it). */
3666 for (insn = insns; insn; insn = NEXT_INSN (insn))
3667 if (CALL_P (insn))
3668 make_reg_eh_region_note_nothrow_nononlocal (insn);
3671 /* First emit all insns that set pseudos. Remove them from the list as
3672 we go. Avoid insns that set pseudos which were referenced in previous
3673 insns. These can be generated by move_by_pieces, for example,
3674 to update an address. Similarly, avoid insns that reference things
3675 set in previous insns. */
3677 for (insn = insns; insn; insn = next)
3679 rtx set = single_set (insn);
3681 next = NEXT_INSN (insn);
3683 if (set != 0 && REG_P (SET_DEST (set))
3684 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3686 struct no_conflict_data data;
3688 data.target = const0_rtx;
3689 data.first = insns;
3690 data.insn = insn;
3691 data.must_stay = 0;
3692 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3693 if (! data.must_stay)
3695 if (PREV_INSN (insn))
3696 SET_NEXT_INSN (PREV_INSN (insn)) = next;
3697 else
3698 insns = next;
3700 if (next)
3701 SET_PREV_INSN (next) = PREV_INSN (insn);
3703 add_insn (insn);
3707 /* Some ports use a loop to copy large arguments onto the stack.
3708 Don't move anything outside such a loop. */
3709 if (LABEL_P (insn))
3710 break;
3713 /* Write the remaining insns followed by the final copy. */
3714 for (insn = insns; insn; insn = next)
3716 next = NEXT_INSN (insn);
3718 add_insn (insn);
3721 last = emit_move_insn (target, result);
3722 if (equiv)
3723 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3725 if (final_dest != target)
3726 emit_move_insn (final_dest, target);
3729 void
3730 emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
3732 emit_libcall_block_1 (insns, target, result, equiv, false);
3735 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3736 PURPOSE describes how this comparison will be used. CODE is the rtx
3737 comparison code we will be using.
3739 ??? Actually, CODE is slightly weaker than that. A target is still
3740 required to implement all of the normal bcc operations, but not
3741 required to implement all (or any) of the unordered bcc operations. */
3744 can_compare_p (enum rtx_code code, machine_mode mode,
3745 enum can_compare_purpose purpose)
3747 rtx test;
3748 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3751 enum insn_code icode;
3753 if (purpose == ccp_jump
3754 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3755 && insn_operand_matches (icode, 0, test))
3756 return 1;
3757 if (purpose == ccp_store_flag
3758 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3759 && insn_operand_matches (icode, 1, test))
3760 return 1;
3761 if (purpose == ccp_cmov
3762 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3763 return 1;
3765 mode = GET_MODE_WIDER_MODE (mode).else_void ();
3766 PUT_MODE (test, mode);
3768 while (mode != VOIDmode);
3770 return 0;
3773 /* This function is called when we are going to emit a compare instruction that
3774 compares the values found in X and Y, using the rtl operator COMPARISON.
3776 If they have mode BLKmode, then SIZE specifies the size of both operands.
3778 UNSIGNEDP nonzero says that the operands are unsigned;
3779 this matters if they need to be widened (as given by METHODS).
3781 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
3782 if we failed to produce one.
3784 *PMODE is the mode of the inputs (in case they are const_int).
3786 This function performs all the setup necessary so that the caller only has
3787 to emit a single comparison insn. This setup can involve doing a BLKmode
3788 comparison or emitting a library call to perform the comparison if no insn
3789 is available to handle it.
3790 The values which are passed in through pointers can be modified; the caller
3791 should perform the comparison on the modified values. Constant
3792 comparisons must have already been folded. */
3794 static void
3795 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3796 int unsignedp, enum optab_methods methods,
3797 rtx *ptest, machine_mode *pmode)
3799 machine_mode mode = *pmode;
3800 rtx libfunc, test;
3801 machine_mode cmp_mode;
3802 enum mode_class mclass;
3804 /* The other methods are not needed. */
3805 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3806 || methods == OPTAB_LIB_WIDEN);
3808 /* If we are optimizing, force expensive constants into a register. */
3809 if (CONSTANT_P (x) && optimize
3810 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
3811 > COSTS_N_INSNS (1)))
3812 x = force_reg (mode, x);
3814 if (CONSTANT_P (y) && optimize
3815 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
3816 > COSTS_N_INSNS (1)))
3817 y = force_reg (mode, y);
3819 #if HAVE_cc0
3820 /* Make sure if we have a canonical comparison. The RTL
3821 documentation states that canonical comparisons are required only
3822 for targets which have cc0. */
3823 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3824 #endif
3826 /* Don't let both operands fail to indicate the mode. */
3827 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3828 x = force_reg (mode, x);
3829 if (mode == VOIDmode)
3830 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3832 /* Handle all BLKmode compares. */
3834 if (mode == BLKmode)
3836 machine_mode result_mode;
3837 enum insn_code cmp_code;
3838 rtx result;
3839 rtx opalign
3840 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3842 gcc_assert (size);
3844 /* Try to use a memory block compare insn - either cmpstr
3845 or cmpmem will do. */
3846 opt_scalar_int_mode cmp_mode_iter;
3847 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT)
3849 scalar_int_mode cmp_mode = cmp_mode_iter.require ();
3850 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3851 if (cmp_code == CODE_FOR_nothing)
3852 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3853 if (cmp_code == CODE_FOR_nothing)
3854 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3855 if (cmp_code == CODE_FOR_nothing)
3856 continue;
3858 /* Must make sure the size fits the insn's mode. */
3859 if (CONST_INT_P (size)
3860 ? UINTVAL (size) > GET_MODE_MASK (cmp_mode)
3861 : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
3862 > GET_MODE_BITSIZE (cmp_mode)))
3863 continue;
3865 result_mode = insn_data[cmp_code].operand[0].mode;
3866 result = gen_reg_rtx (result_mode);
3867 size = convert_to_mode (cmp_mode, size, 1);
3868 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3870 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3871 *pmode = result_mode;
3872 return;
3875 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3876 goto fail;
3878 /* Otherwise call a library function. */
3879 result = emit_block_comp_via_libcall (x, y, size);
3881 x = result;
3882 y = const0_rtx;
3883 mode = TYPE_MODE (integer_type_node);
3884 methods = OPTAB_LIB_WIDEN;
3885 unsignedp = false;
3888 /* Don't allow operands to the compare to trap, as that can put the
3889 compare and branch in different basic blocks. */
3890 if (cfun->can_throw_non_call_exceptions)
3892 if (may_trap_p (x))
3893 x = copy_to_reg (x);
3894 if (may_trap_p (y))
3895 y = copy_to_reg (y);
3898 if (GET_MODE_CLASS (mode) == MODE_CC)
3900 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
3901 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3902 gcc_assert (icode != CODE_FOR_nothing
3903 && insn_operand_matches (icode, 0, test));
3904 *ptest = test;
3905 return;
3908 mclass = GET_MODE_CLASS (mode);
3909 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3910 FOR_EACH_MODE_FROM (cmp_mode, mode)
3912 enum insn_code icode;
3913 icode = optab_handler (cbranch_optab, cmp_mode);
3914 if (icode != CODE_FOR_nothing
3915 && insn_operand_matches (icode, 0, test))
3917 rtx_insn *last = get_last_insn ();
3918 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3919 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3920 if (op0 && op1
3921 && insn_operand_matches (icode, 1, op0)
3922 && insn_operand_matches (icode, 2, op1))
3924 XEXP (test, 0) = op0;
3925 XEXP (test, 1) = op1;
3926 *ptest = test;
3927 *pmode = cmp_mode;
3928 return;
3930 delete_insns_since (last);
3933 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3934 break;
3937 if (methods != OPTAB_LIB_WIDEN)
3938 goto fail;
3940 if (SCALAR_FLOAT_MODE_P (mode))
3942 /* Small trick if UNORDERED isn't implemented by the hardware. */
3943 if (comparison == UNORDERED && rtx_equal_p (x, y))
3945 prepare_cmp_insn (x, y, UNLT, NULL_RTX, unsignedp, OPTAB_WIDEN,
3946 ptest, pmode);
3947 if (*ptest)
3948 return;
3951 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
3953 else
3955 rtx result;
3956 machine_mode ret_mode;
3958 /* Handle a libcall just for the mode we are using. */
3959 libfunc = optab_libfunc (cmp_optab, mode);
3960 gcc_assert (libfunc);
3962 /* If we want unsigned, and this mode has a distinct unsigned
3963 comparison routine, use that. */
3964 if (unsignedp)
3966 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
3967 if (ulibfunc)
3968 libfunc = ulibfunc;
3971 ret_mode = targetm.libgcc_cmp_return_mode ();
3972 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3973 ret_mode, x, mode, y, mode);
3975 /* There are two kinds of comparison routines. Biased routines
3976 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3977 of gcc expect that the comparison operation is equivalent
3978 to the modified comparison. For signed comparisons compare the
3979 result against 1 in the biased case, and zero in the unbiased
3980 case. For unsigned comparisons always compare against 1 after
3981 biasing the unbiased result by adding 1. This gives us a way to
3982 represent LTU.
3983 The comparisons in the fixed-point helper library are always
3984 biased. */
3985 x = result;
3986 y = const1_rtx;
3988 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
3990 if (unsignedp)
3991 x = plus_constant (ret_mode, result, 1);
3992 else
3993 y = const0_rtx;
3996 *pmode = ret_mode;
3997 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
3998 ptest, pmode);
4001 return;
4003 fail:
4004 *ptest = NULL_RTX;
4007 /* Before emitting an insn with code ICODE, make sure that X, which is going
4008 to be used for operand OPNUM of the insn, is converted from mode MODE to
4009 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4010 that it is accepted by the operand predicate. Return the new value. */
4013 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
4014 machine_mode wider_mode, int unsignedp)
4016 if (mode != wider_mode)
4017 x = convert_modes (wider_mode, mode, x, unsignedp);
4019 if (!insn_operand_matches (icode, opnum, x))
4021 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
4022 if (reload_completed)
4023 return NULL_RTX;
4024 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
4025 return NULL_RTX;
4026 x = copy_to_mode_reg (op_mode, x);
4029 return x;
4032 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4033 we can do the branch. */
4035 static void
4036 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
4037 profile_probability prob)
4039 machine_mode optab_mode;
4040 enum mode_class mclass;
4041 enum insn_code icode;
4042 rtx_insn *insn;
4044 mclass = GET_MODE_CLASS (mode);
4045 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4046 icode = optab_handler (cbranch_optab, optab_mode);
4048 gcc_assert (icode != CODE_FOR_nothing);
4049 gcc_assert (insn_operand_matches (icode, 0, test));
4050 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4051 XEXP (test, 1), label));
4052 if (prob.initialized_p ()
4053 && profile_status_for_fn (cfun) != PROFILE_ABSENT
4054 && insn
4055 && JUMP_P (insn)
4056 && any_condjump_p (insn)
4057 && !find_reg_note (insn, REG_BR_PROB, 0))
4058 add_reg_br_prob_note (insn, prob);
4061 /* Generate code to compare X with Y so that the condition codes are
4062 set and to jump to LABEL if the condition is true. If X is a
4063 constant and Y is not a constant, then the comparison is swapped to
4064 ensure that the comparison RTL has the canonical form.
4066 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4067 need to be widened. UNSIGNEDP is also used to select the proper
4068 branch condition code.
4070 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4072 MODE is the mode of the inputs (in case they are const_int).
4074 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4075 It will be potentially converted into an unsigned variant based on
4076 UNSIGNEDP to select a proper jump instruction.
4078 PROB is the probability of jumping to LABEL. */
4080 void
4081 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4082 machine_mode mode, int unsignedp, rtx label,
4083 profile_probability prob)
4085 rtx op0 = x, op1 = y;
4086 rtx test;
4088 /* Swap operands and condition to ensure canonical RTL. */
4089 if (swap_commutative_operands_p (x, y)
4090 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4092 op0 = y, op1 = x;
4093 comparison = swap_condition (comparison);
4096 /* If OP0 is still a constant, then both X and Y must be constants
4097 or the opposite comparison is not supported. Force X into a register
4098 to create canonical RTL. */
4099 if (CONSTANT_P (op0))
4100 op0 = force_reg (mode, op0);
4102 if (unsignedp)
4103 comparison = unsigned_condition (comparison);
4105 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4106 &test, &mode);
4107 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4111 /* Emit a library call comparison between floating point X and Y.
4112 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4114 static void
4115 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4116 rtx *ptest, machine_mode *pmode)
4118 enum rtx_code swapped = swap_condition (comparison);
4119 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4120 machine_mode orig_mode = GET_MODE (x);
4121 machine_mode mode;
4122 rtx true_rtx, false_rtx;
4123 rtx value, target, equiv;
4124 rtx_insn *insns;
4125 rtx libfunc = 0;
4126 bool reversed_p = false;
4127 scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
4129 FOR_EACH_MODE_FROM (mode, orig_mode)
4131 if (code_to_optab (comparison)
4132 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4133 break;
4135 if (code_to_optab (swapped)
4136 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4138 std::swap (x, y);
4139 comparison = swapped;
4140 break;
4143 if (code_to_optab (reversed)
4144 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4146 comparison = reversed;
4147 reversed_p = true;
4148 break;
4152 gcc_assert (mode != VOIDmode);
4154 if (mode != orig_mode)
4156 x = convert_to_mode (mode, x, 0);
4157 y = convert_to_mode (mode, y, 0);
4160 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4161 the RTL. The allows the RTL optimizers to delete the libcall if the
4162 condition can be determined at compile-time. */
4163 if (comparison == UNORDERED
4164 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4166 true_rtx = const_true_rtx;
4167 false_rtx = const0_rtx;
4169 else
4171 switch (comparison)
4173 case EQ:
4174 true_rtx = const0_rtx;
4175 false_rtx = const_true_rtx;
4176 break;
4178 case NE:
4179 true_rtx = const_true_rtx;
4180 false_rtx = const0_rtx;
4181 break;
4183 case GT:
4184 true_rtx = const1_rtx;
4185 false_rtx = const0_rtx;
4186 break;
4188 case GE:
4189 true_rtx = const0_rtx;
4190 false_rtx = constm1_rtx;
4191 break;
4193 case LT:
4194 true_rtx = constm1_rtx;
4195 false_rtx = const0_rtx;
4196 break;
4198 case LE:
4199 true_rtx = const0_rtx;
4200 false_rtx = const1_rtx;
4201 break;
4203 default:
4204 gcc_unreachable ();
4208 if (comparison == UNORDERED)
4210 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4211 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4212 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4213 temp, const_true_rtx, equiv);
4215 else
4217 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4218 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4219 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4220 equiv, true_rtx, false_rtx);
4223 start_sequence ();
4224 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4225 cmp_mode, x, mode, y, mode);
4226 insns = get_insns ();
4227 end_sequence ();
4229 target = gen_reg_rtx (cmp_mode);
4230 emit_libcall_block (insns, target, value, equiv);
4232 if (comparison == UNORDERED
4233 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4234 || reversed_p)
4235 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4236 else
4237 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4239 *pmode = cmp_mode;
4242 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4244 void
4245 emit_indirect_jump (rtx loc)
4247 if (!targetm.have_indirect_jump ())
4248 sorry ("indirect jumps are not available on this target");
4249 else
4251 struct expand_operand ops[1];
4252 create_address_operand (&ops[0], loc);
4253 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4254 emit_barrier ();
4259 /* Emit a conditional move instruction if the machine supports one for that
4260 condition and machine mode.
4262 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4263 the mode to use should they be constants. If it is VOIDmode, they cannot
4264 both be constants.
4266 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4267 should be stored there. MODE is the mode to use should they be constants.
4268 If it is VOIDmode, they cannot both be constants.
4270 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4271 is not supported. */
4274 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4275 machine_mode cmode, rtx op2, rtx op3,
4276 machine_mode mode, int unsignedp)
4278 rtx comparison;
4279 rtx_insn *last;
4280 enum insn_code icode;
4281 enum rtx_code reversed;
4283 /* If the two source operands are identical, that's just a move. */
4285 if (rtx_equal_p (op2, op3))
4287 if (!target)
4288 target = gen_reg_rtx (mode);
4290 emit_move_insn (target, op3);
4291 return target;
4294 /* If one operand is constant, make it the second one. Only do this
4295 if the other operand is not constant as well. */
4297 if (swap_commutative_operands_p (op0, op1))
4299 std::swap (op0, op1);
4300 code = swap_condition (code);
4303 /* get_condition will prefer to generate LT and GT even if the old
4304 comparison was against zero, so undo that canonicalization here since
4305 comparisons against zero are cheaper. */
4306 if (code == LT && op1 == const1_rtx)
4307 code = LE, op1 = const0_rtx;
4308 else if (code == GT && op1 == constm1_rtx)
4309 code = GE, op1 = const0_rtx;
4311 if (cmode == VOIDmode)
4312 cmode = GET_MODE (op0);
4314 enum rtx_code orig_code = code;
4315 bool swapped = false;
4316 if (swap_commutative_operands_p (op2, op3)
4317 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4318 != UNKNOWN))
4320 std::swap (op2, op3);
4321 code = reversed;
4322 swapped = true;
4325 if (mode == VOIDmode)
4326 mode = GET_MODE (op2);
4328 icode = direct_optab_handler (movcc_optab, mode);
4330 if (icode == CODE_FOR_nothing)
4331 return NULL_RTX;
4333 if (!target)
4334 target = gen_reg_rtx (mode);
4336 for (int pass = 0; ; pass++)
4338 code = unsignedp ? unsigned_condition (code) : code;
4339 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4341 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4342 punt and let the caller figure out how best to deal with this
4343 situation. */
4344 if (COMPARISON_P (comparison))
4346 saved_pending_stack_adjust save;
4347 save_pending_stack_adjust (&save);
4348 last = get_last_insn ();
4349 do_pending_stack_adjust ();
4350 machine_mode cmpmode = cmode;
4351 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4352 GET_CODE (comparison), NULL_RTX, unsignedp,
4353 OPTAB_WIDEN, &comparison, &cmpmode);
4354 if (comparison)
4356 struct expand_operand ops[4];
4358 create_output_operand (&ops[0], target, mode);
4359 create_fixed_operand (&ops[1], comparison);
4360 create_input_operand (&ops[2], op2, mode);
4361 create_input_operand (&ops[3], op3, mode);
4362 if (maybe_expand_insn (icode, 4, ops))
4364 if (ops[0].value != target)
4365 convert_move (target, ops[0].value, false);
4366 return target;
4369 delete_insns_since (last);
4370 restore_pending_stack_adjust (&save);
4373 if (pass == 1)
4374 return NULL_RTX;
4376 /* If the preferred op2/op3 order is not usable, retry with other
4377 operand order, perhaps it will expand successfully. */
4378 if (swapped)
4379 code = orig_code;
4380 else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1,
4381 NULL))
4382 != UNKNOWN)
4383 code = reversed;
4384 else
4385 return NULL_RTX;
4386 std::swap (op2, op3);
4391 /* Emit a conditional negate or bitwise complement using the
4392 negcc or notcc optabs if available. Return NULL_RTX if such operations
4393 are not available. Otherwise return the RTX holding the result.
4394 TARGET is the desired destination of the result. COMP is the comparison
4395 on which to negate. If COND is true move into TARGET the negation
4396 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4397 CODE is either NEG or NOT. MODE is the machine mode in which the
4398 operation is performed. */
4401 emit_conditional_neg_or_complement (rtx target, rtx_code code,
4402 machine_mode mode, rtx cond, rtx op1,
4403 rtx op2)
4405 optab op = unknown_optab;
4406 if (code == NEG)
4407 op = negcc_optab;
4408 else if (code == NOT)
4409 op = notcc_optab;
4410 else
4411 gcc_unreachable ();
4413 insn_code icode = direct_optab_handler (op, mode);
4415 if (icode == CODE_FOR_nothing)
4416 return NULL_RTX;
4418 if (!target)
4419 target = gen_reg_rtx (mode);
4421 rtx_insn *last = get_last_insn ();
4422 struct expand_operand ops[4];
4424 create_output_operand (&ops[0], target, mode);
4425 create_fixed_operand (&ops[1], cond);
4426 create_input_operand (&ops[2], op1, mode);
4427 create_input_operand (&ops[3], op2, mode);
4429 if (maybe_expand_insn (icode, 4, ops))
4431 if (ops[0].value != target)
4432 convert_move (target, ops[0].value, false);
4434 return target;
4436 delete_insns_since (last);
4437 return NULL_RTX;
4440 /* Emit a conditional addition instruction if the machine supports one for that
4441 condition and machine mode.
4443 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4444 the mode to use should they be constants. If it is VOIDmode, they cannot
4445 both be constants.
4447 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4448 should be stored there. MODE is the mode to use should they be constants.
4449 If it is VOIDmode, they cannot both be constants.
4451 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4452 is not supported. */
4455 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4456 machine_mode cmode, rtx op2, rtx op3,
4457 machine_mode mode, int unsignedp)
4459 rtx comparison;
4460 rtx_insn *last;
4461 enum insn_code icode;
4463 /* If one operand is constant, make it the second one. Only do this
4464 if the other operand is not constant as well. */
4466 if (swap_commutative_operands_p (op0, op1))
4468 std::swap (op0, op1);
4469 code = swap_condition (code);
4472 /* get_condition will prefer to generate LT and GT even if the old
4473 comparison was against zero, so undo that canonicalization here since
4474 comparisons against zero are cheaper. */
4475 if (code == LT && op1 == const1_rtx)
4476 code = LE, op1 = const0_rtx;
4477 else if (code == GT && op1 == constm1_rtx)
4478 code = GE, op1 = const0_rtx;
4480 if (cmode == VOIDmode)
4481 cmode = GET_MODE (op0);
4483 if (mode == VOIDmode)
4484 mode = GET_MODE (op2);
4486 icode = optab_handler (addcc_optab, mode);
4488 if (icode == CODE_FOR_nothing)
4489 return 0;
4491 if (!target)
4492 target = gen_reg_rtx (mode);
4494 code = unsignedp ? unsigned_condition (code) : code;
4495 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4497 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4498 return NULL and let the caller figure out how best to deal with this
4499 situation. */
4500 if (!COMPARISON_P (comparison))
4501 return NULL_RTX;
4503 do_pending_stack_adjust ();
4504 last = get_last_insn ();
4505 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4506 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4507 &comparison, &cmode);
4508 if (comparison)
4510 struct expand_operand ops[4];
4512 create_output_operand (&ops[0], target, mode);
4513 create_fixed_operand (&ops[1], comparison);
4514 create_input_operand (&ops[2], op2, mode);
4515 create_input_operand (&ops[3], op3, mode);
4516 if (maybe_expand_insn (icode, 4, ops))
4518 if (ops[0].value != target)
4519 convert_move (target, ops[0].value, false);
4520 return target;
4523 delete_insns_since (last);
4524 return NULL_RTX;
4527 /* These functions attempt to generate an insn body, rather than
4528 emitting the insn, but if the gen function already emits them, we
4529 make no attempt to turn them back into naked patterns. */
4531 /* Generate and return an insn body to add Y to X. */
4533 rtx_insn *
4534 gen_add2_insn (rtx x, rtx y)
4536 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4538 gcc_assert (insn_operand_matches (icode, 0, x));
4539 gcc_assert (insn_operand_matches (icode, 1, x));
4540 gcc_assert (insn_operand_matches (icode, 2, y));
4542 return GEN_FCN (icode) (x, x, y);
4545 /* Generate and return an insn body to add r1 and c,
4546 storing the result in r0. */
4548 rtx_insn *
4549 gen_add3_insn (rtx r0, rtx r1, rtx c)
4551 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4553 if (icode == CODE_FOR_nothing
4554 || !insn_operand_matches (icode, 0, r0)
4555 || !insn_operand_matches (icode, 1, r1)
4556 || !insn_operand_matches (icode, 2, c))
4557 return NULL;
4559 return GEN_FCN (icode) (r0, r1, c);
4563 have_add2_insn (rtx x, rtx y)
4565 enum insn_code icode;
4567 gcc_assert (GET_MODE (x) != VOIDmode);
4569 icode = optab_handler (add_optab, GET_MODE (x));
4571 if (icode == CODE_FOR_nothing)
4572 return 0;
4574 if (!insn_operand_matches (icode, 0, x)
4575 || !insn_operand_matches (icode, 1, x)
4576 || !insn_operand_matches (icode, 2, y))
4577 return 0;
4579 return 1;
4582 /* Generate and return an insn body to add Y to X. */
4584 rtx_insn *
4585 gen_addptr3_insn (rtx x, rtx y, rtx z)
4587 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4589 gcc_assert (insn_operand_matches (icode, 0, x));
4590 gcc_assert (insn_operand_matches (icode, 1, y));
4591 gcc_assert (insn_operand_matches (icode, 2, z));
4593 return GEN_FCN (icode) (x, y, z);
4596 /* Return true if the target implements an addptr pattern and X, Y,
4597 and Z are valid for the pattern predicates. */
4600 have_addptr3_insn (rtx x, rtx y, rtx z)
4602 enum insn_code icode;
4604 gcc_assert (GET_MODE (x) != VOIDmode);
4606 icode = optab_handler (addptr3_optab, GET_MODE (x));
4608 if (icode == CODE_FOR_nothing)
4609 return 0;
4611 if (!insn_operand_matches (icode, 0, x)
4612 || !insn_operand_matches (icode, 1, y)
4613 || !insn_operand_matches (icode, 2, z))
4614 return 0;
4616 return 1;
4619 /* Generate and return an insn body to subtract Y from X. */
4621 rtx_insn *
4622 gen_sub2_insn (rtx x, rtx y)
4624 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4626 gcc_assert (insn_operand_matches (icode, 0, x));
4627 gcc_assert (insn_operand_matches (icode, 1, x));
4628 gcc_assert (insn_operand_matches (icode, 2, y));
4630 return GEN_FCN (icode) (x, x, y);
4633 /* Generate and return an insn body to subtract r1 and c,
4634 storing the result in r0. */
4636 rtx_insn *
4637 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4639 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4641 if (icode == CODE_FOR_nothing
4642 || !insn_operand_matches (icode, 0, r0)
4643 || !insn_operand_matches (icode, 1, r1)
4644 || !insn_operand_matches (icode, 2, c))
4645 return NULL;
4647 return GEN_FCN (icode) (r0, r1, c);
4651 have_sub2_insn (rtx x, rtx y)
4653 enum insn_code icode;
4655 gcc_assert (GET_MODE (x) != VOIDmode);
4657 icode = optab_handler (sub_optab, GET_MODE (x));
4659 if (icode == CODE_FOR_nothing)
4660 return 0;
4662 if (!insn_operand_matches (icode, 0, x)
4663 || !insn_operand_matches (icode, 1, x)
4664 || !insn_operand_matches (icode, 2, y))
4665 return 0;
4667 return 1;
4670 /* Generate the body of an insn to extend Y (with mode MFROM)
4671 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4673 rtx_insn *
4674 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4675 machine_mode mfrom, int unsignedp)
4677 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4678 return GEN_FCN (icode) (x, y);
4681 /* Generate code to convert FROM to floating point
4682 and store in TO. FROM must be fixed point and not VOIDmode.
4683 UNSIGNEDP nonzero means regard FROM as unsigned.
4684 Normally this is done by correcting the final value
4685 if it is negative. */
4687 void
4688 expand_float (rtx to, rtx from, int unsignedp)
4690 enum insn_code icode;
4691 rtx target = to;
4692 scalar_mode from_mode, to_mode;
4693 machine_mode fmode, imode;
4694 bool can_do_signed = false;
4696 /* Crash now, because we won't be able to decide which mode to use. */
4697 gcc_assert (GET_MODE (from) != VOIDmode);
4699 /* Look for an insn to do the conversion. Do it in the specified
4700 modes if possible; otherwise convert either input, output or both to
4701 wider mode. If the integer mode is wider than the mode of FROM,
4702 we can do the conversion signed even if the input is unsigned. */
4704 FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
4705 FOR_EACH_MODE_FROM (imode, GET_MODE (from))
4707 int doing_unsigned = unsignedp;
4709 if (fmode != GET_MODE (to)
4710 && (significand_size (fmode)
4711 < GET_MODE_UNIT_PRECISION (GET_MODE (from))))
4712 continue;
4714 icode = can_float_p (fmode, imode, unsignedp);
4715 if (icode == CODE_FOR_nothing && unsignedp)
4717 enum insn_code scode = can_float_p (fmode, imode, 0);
4718 if (scode != CODE_FOR_nothing)
4719 can_do_signed = true;
4720 if (imode != GET_MODE (from))
4721 icode = scode, doing_unsigned = 0;
4724 if (icode != CODE_FOR_nothing)
4726 if (imode != GET_MODE (from))
4727 from = convert_to_mode (imode, from, unsignedp);
4729 if (fmode != GET_MODE (to))
4730 target = gen_reg_rtx (fmode);
4732 emit_unop_insn (icode, target, from,
4733 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4735 if (target != to)
4736 convert_move (to, target, 0);
4737 return;
4741 /* Unsigned integer, and no way to convert directly. Convert as signed,
4742 then unconditionally adjust the result. */
4743 if (unsignedp
4744 && can_do_signed
4745 && is_a <scalar_mode> (GET_MODE (to), &to_mode)
4746 && is_a <scalar_mode> (GET_MODE (from), &from_mode))
4748 opt_scalar_mode fmode_iter;
4749 rtx_code_label *label = gen_label_rtx ();
4750 rtx temp;
4751 REAL_VALUE_TYPE offset;
4753 /* Look for a usable floating mode FMODE wider than the source and at
4754 least as wide as the target. Using FMODE will avoid rounding woes
4755 with unsigned values greater than the signed maximum value. */
4757 FOR_EACH_MODE_FROM (fmode_iter, to_mode)
4759 scalar_mode fmode = fmode_iter.require ();
4760 if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
4761 && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
4762 break;
4765 if (!fmode_iter.exists (&fmode))
4767 /* There is no such mode. Pretend the target is wide enough. */
4768 fmode = to_mode;
4770 /* Avoid double-rounding when TO is narrower than FROM. */
4771 if ((significand_size (fmode) + 1)
4772 < GET_MODE_PRECISION (from_mode))
4774 rtx temp1;
4775 rtx_code_label *neglabel = gen_label_rtx ();
4777 /* Don't use TARGET if it isn't a register, is a hard register,
4778 or is the wrong mode. */
4779 if (!REG_P (target)
4780 || REGNO (target) < FIRST_PSEUDO_REGISTER
4781 || GET_MODE (target) != fmode)
4782 target = gen_reg_rtx (fmode);
4784 imode = from_mode;
4785 do_pending_stack_adjust ();
4787 /* Test whether the sign bit is set. */
4788 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4789 0, neglabel);
4791 /* The sign bit is not set. Convert as signed. */
4792 expand_float (target, from, 0);
4793 emit_jump_insn (targetm.gen_jump (label));
4794 emit_barrier ();
4796 /* The sign bit is set.
4797 Convert to a usable (positive signed) value by shifting right
4798 one bit, while remembering if a nonzero bit was shifted
4799 out; i.e., compute (from & 1) | (from >> 1). */
4801 emit_label (neglabel);
4802 temp = expand_binop (imode, and_optab, from, const1_rtx,
4803 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4804 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4805 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4806 OPTAB_LIB_WIDEN);
4807 expand_float (target, temp, 0);
4809 /* Multiply by 2 to undo the shift above. */
4810 temp = expand_binop (fmode, add_optab, target, target,
4811 target, 0, OPTAB_LIB_WIDEN);
4812 if (temp != target)
4813 emit_move_insn (target, temp);
4815 do_pending_stack_adjust ();
4816 emit_label (label);
4817 goto done;
4821 /* If we are about to do some arithmetic to correct for an
4822 unsigned operand, do it in a pseudo-register. */
4824 if (to_mode != fmode
4825 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4826 target = gen_reg_rtx (fmode);
4828 /* Convert as signed integer to floating. */
4829 expand_float (target, from, 0);
4831 /* If FROM is negative (and therefore TO is negative),
4832 correct its value by 2**bitwidth. */
4834 do_pending_stack_adjust ();
4835 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
4836 0, label);
4839 real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
4840 temp = expand_binop (fmode, add_optab, target,
4841 const_double_from_real_value (offset, fmode),
4842 target, 0, OPTAB_LIB_WIDEN);
4843 if (temp != target)
4844 emit_move_insn (target, temp);
4846 do_pending_stack_adjust ();
4847 emit_label (label);
4848 goto done;
4851 /* No hardware instruction available; call a library routine. */
4853 rtx libfunc;
4854 rtx_insn *insns;
4855 rtx value;
4856 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4858 if (is_narrower_int_mode (GET_MODE (from), SImode))
4859 from = convert_to_mode (SImode, from, unsignedp);
4861 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4862 gcc_assert (libfunc);
4864 start_sequence ();
4866 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4867 GET_MODE (to), from, GET_MODE (from));
4868 insns = get_insns ();
4869 end_sequence ();
4871 emit_libcall_block (insns, target, value,
4872 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4873 GET_MODE (to), from));
4876 done:
4878 /* Copy result to requested destination
4879 if we have been computing in a temp location. */
4881 if (target != to)
4883 if (GET_MODE (target) == GET_MODE (to))
4884 emit_move_insn (to, target);
4885 else
4886 convert_move (to, target, 0);
4890 /* Generate code to convert FROM to fixed point and store in TO. FROM
4891 must be floating point. */
4893 void
4894 expand_fix (rtx to, rtx from, int unsignedp)
4896 enum insn_code icode;
4897 rtx target = to;
4898 machine_mode fmode, imode;
4899 opt_scalar_mode fmode_iter;
4900 bool must_trunc = false;
4902 /* We first try to find a pair of modes, one real and one integer, at
4903 least as wide as FROM and TO, respectively, in which we can open-code
4904 this conversion. If the integer mode is wider than the mode of TO,
4905 we can do the conversion either signed or unsigned. */
4907 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
4908 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
4910 int doing_unsigned = unsignedp;
4912 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4913 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4914 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4916 if (icode != CODE_FOR_nothing)
4918 rtx_insn *last = get_last_insn ();
4919 if (fmode != GET_MODE (from))
4920 from = convert_to_mode (fmode, from, 0);
4922 if (must_trunc)
4924 rtx temp = gen_reg_rtx (GET_MODE (from));
4925 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4926 temp, 0);
4929 if (imode != GET_MODE (to))
4930 target = gen_reg_rtx (imode);
4932 if (maybe_emit_unop_insn (icode, target, from,
4933 doing_unsigned ? UNSIGNED_FIX : FIX))
4935 if (target != to)
4936 convert_move (to, target, unsignedp);
4937 return;
4939 delete_insns_since (last);
4943 /* For an unsigned conversion, there is one more way to do it.
4944 If we have a signed conversion, we generate code that compares
4945 the real value to the largest representable positive number. If if
4946 is smaller, the conversion is done normally. Otherwise, subtract
4947 one plus the highest signed number, convert, and add it back.
4949 We only need to check all real modes, since we know we didn't find
4950 anything with a wider integer mode.
4952 This code used to extend FP value into mode wider than the destination.
4953 This is needed for decimal float modes which cannot accurately
4954 represent one plus the highest signed number of the same size, but
4955 not for binary modes. Consider, for instance conversion from SFmode
4956 into DImode.
4958 The hot path through the code is dealing with inputs smaller than 2^63
4959 and doing just the conversion, so there is no bits to lose.
4961 In the other path we know the value is positive in the range 2^63..2^64-1
4962 inclusive. (as for other input overflow happens and result is undefined)
4963 So we know that the most important bit set in mantissa corresponds to
4964 2^63. The subtraction of 2^63 should not generate any rounding as it
4965 simply clears out that bit. The rest is trivial. */
4967 scalar_int_mode to_mode;
4968 if (unsignedp
4969 && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
4970 && HWI_COMPUTABLE_MODE_P (to_mode))
4971 FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
4973 scalar_mode fmode = fmode_iter.require ();
4974 if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
4975 0, &must_trunc)
4976 && (!DECIMAL_FLOAT_MODE_P (fmode)
4977 || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
4979 int bitsize;
4980 REAL_VALUE_TYPE offset;
4981 rtx limit;
4982 rtx_code_label *lab1, *lab2;
4983 rtx_insn *insn;
4985 bitsize = GET_MODE_PRECISION (to_mode);
4986 real_2expN (&offset, bitsize - 1, fmode);
4987 limit = const_double_from_real_value (offset, fmode);
4988 lab1 = gen_label_rtx ();
4989 lab2 = gen_label_rtx ();
4991 if (fmode != GET_MODE (from))
4992 from = convert_to_mode (fmode, from, 0);
4994 /* See if we need to do the subtraction. */
4995 do_pending_stack_adjust ();
4996 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
4997 GET_MODE (from), 0, lab1);
4999 /* If not, do the signed "fix" and branch around fixup code. */
5000 expand_fix (to, from, 0);
5001 emit_jump_insn (targetm.gen_jump (lab2));
5002 emit_barrier ();
5004 /* Otherwise, subtract 2**(N-1), convert to signed number,
5005 then add 2**(N-1). Do the addition using XOR since this
5006 will often generate better code. */
5007 emit_label (lab1);
5008 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5009 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5010 expand_fix (to, target, 0);
5011 target = expand_binop (to_mode, xor_optab, to,
5012 gen_int_mode
5013 (HOST_WIDE_INT_1 << (bitsize - 1),
5014 to_mode),
5015 to, 1, OPTAB_LIB_WIDEN);
5017 if (target != to)
5018 emit_move_insn (to, target);
5020 emit_label (lab2);
5022 if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
5024 /* Make a place for a REG_NOTE and add it. */
5025 insn = emit_move_insn (to, to);
5026 set_dst_reg_note (insn, REG_EQUAL,
5027 gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
5028 copy_rtx (from)),
5029 to);
5032 return;
5036 /* We can't do it with an insn, so use a library call. But first ensure
5037 that the mode of TO is at least as wide as SImode, since those are the
5038 only library calls we know about. */
5040 if (is_narrower_int_mode (GET_MODE (to), SImode))
5042 target = gen_reg_rtx (SImode);
5044 expand_fix (target, from, unsignedp);
5046 else
5048 rtx_insn *insns;
5049 rtx value;
5050 rtx libfunc;
5052 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5053 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5054 gcc_assert (libfunc);
5056 start_sequence ();
5058 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5059 GET_MODE (to), from, GET_MODE (from));
5060 insns = get_insns ();
5061 end_sequence ();
5063 emit_libcall_block (insns, target, value,
5064 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5065 GET_MODE (to), from));
5068 if (target != to)
5070 if (GET_MODE (to) == GET_MODE (target))
5071 emit_move_insn (to, target);
5072 else
5073 convert_move (to, target, 0);
5078 /* Promote integer arguments for a libcall if necessary.
5079 emit_library_call_value cannot do the promotion because it does not
5080 know if it should do a signed or unsigned promotion. This is because
5081 there are no tree types defined for libcalls. */
5083 static rtx
5084 prepare_libcall_arg (rtx arg, int uintp)
5086 scalar_int_mode mode;
5087 machine_mode arg_mode;
5088 if (is_a <scalar_int_mode> (GET_MODE (arg), &mode))
5090 /* If we need to promote the integer function argument we need to do
5091 it here instead of inside emit_library_call_value because in
5092 emit_library_call_value we don't know if we should do a signed or
5093 unsigned promotion. */
5095 int unsigned_p = 0;
5096 arg_mode = promote_function_mode (NULL_TREE, mode,
5097 &unsigned_p, NULL_TREE, 0);
5098 if (arg_mode != mode)
5099 return convert_to_mode (arg_mode, arg, uintp);
5101 return arg;
5104 /* Generate code to convert FROM or TO a fixed-point.
5105 If UINTP is true, either TO or FROM is an unsigned integer.
5106 If SATP is true, we need to saturate the result. */
5108 void
5109 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5111 machine_mode to_mode = GET_MODE (to);
5112 machine_mode from_mode = GET_MODE (from);
5113 convert_optab tab;
5114 enum rtx_code this_code;
5115 enum insn_code code;
5116 rtx_insn *insns;
5117 rtx value;
5118 rtx libfunc;
5120 if (to_mode == from_mode)
5122 emit_move_insn (to, from);
5123 return;
5126 if (uintp)
5128 tab = satp ? satfractuns_optab : fractuns_optab;
5129 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5131 else
5133 tab = satp ? satfract_optab : fract_optab;
5134 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5136 code = convert_optab_handler (tab, to_mode, from_mode);
5137 if (code != CODE_FOR_nothing)
5139 emit_unop_insn (code, to, from, this_code);
5140 return;
5143 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5144 gcc_assert (libfunc);
5146 from = prepare_libcall_arg (from, uintp);
5147 from_mode = GET_MODE (from);
5149 start_sequence ();
5150 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5151 from, from_mode);
5152 insns = get_insns ();
5153 end_sequence ();
5155 emit_libcall_block (insns, to, value,
5156 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5159 /* Generate code to convert FROM to fixed point and store in TO. FROM
5160 must be floating point, TO must be signed. Use the conversion optab
5161 TAB to do the conversion. */
5163 bool
5164 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5166 enum insn_code icode;
5167 rtx target = to;
5168 machine_mode fmode, imode;
5170 /* We first try to find a pair of modes, one real and one integer, at
5171 least as wide as FROM and TO, respectively, in which we can open-code
5172 this conversion. If the integer mode is wider than the mode of TO,
5173 we can do the conversion either signed or unsigned. */
5175 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5176 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5178 icode = convert_optab_handler (tab, imode, fmode);
5179 if (icode != CODE_FOR_nothing)
5181 rtx_insn *last = get_last_insn ();
5182 if (fmode != GET_MODE (from))
5183 from = convert_to_mode (fmode, from, 0);
5185 if (imode != GET_MODE (to))
5186 target = gen_reg_rtx (imode);
5188 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5190 delete_insns_since (last);
5191 continue;
5193 if (target != to)
5194 convert_move (to, target, 0);
5195 return true;
5199 return false;
5202 /* Report whether we have an instruction to perform the operation
5203 specified by CODE on operands of mode MODE. */
5205 have_insn_for (enum rtx_code code, machine_mode mode)
5207 return (code_to_optab (code)
5208 && (optab_handler (code_to_optab (code), mode)
5209 != CODE_FOR_nothing));
5212 /* Print information about the current contents of the optabs on
5213 STDERR. */
5215 DEBUG_FUNCTION void
5216 debug_optab_libfuncs (void)
5218 int i, j, k;
5220 /* Dump the arithmetic optabs. */
5221 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5222 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5224 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5225 if (l)
5227 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5228 fprintf (stderr, "%s\t%s:\t%s\n",
5229 GET_RTX_NAME (optab_to_code ((optab) i)),
5230 GET_MODE_NAME (j),
5231 XSTR (l, 0));
5235 /* Dump the conversion optabs. */
5236 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5237 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5238 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5240 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5241 (machine_mode) k);
5242 if (l)
5244 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5245 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5246 GET_RTX_NAME (optab_to_code ((optab) i)),
5247 GET_MODE_NAME (j),
5248 GET_MODE_NAME (k),
5249 XSTR (l, 0));
5254 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5255 CODE. Return 0 on failure. */
5257 rtx_insn *
5258 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5260 machine_mode mode = GET_MODE (op1);
5261 enum insn_code icode;
5262 rtx_insn *insn;
5263 rtx trap_rtx;
5265 if (mode == VOIDmode)
5266 return 0;
5268 icode = optab_handler (ctrap_optab, mode);
5269 if (icode == CODE_FOR_nothing)
5270 return 0;
5272 /* Some targets only accept a zero trap code. */
5273 if (!insn_operand_matches (icode, 3, tcode))
5274 return 0;
5276 do_pending_stack_adjust ();
5277 start_sequence ();
5278 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5279 &trap_rtx, &mode);
5280 if (!trap_rtx)
5281 insn = NULL;
5282 else
5283 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5284 tcode);
5286 /* If that failed, then give up. */
5287 if (insn == 0)
5289 end_sequence ();
5290 return 0;
5293 emit_insn (insn);
5294 insn = get_insns ();
5295 end_sequence ();
5296 return insn;
5299 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5300 or unsigned operation code. */
5302 enum rtx_code
5303 get_rtx_code (enum tree_code tcode, bool unsignedp)
5305 enum rtx_code code;
5306 switch (tcode)
5308 case EQ_EXPR:
5309 code = EQ;
5310 break;
5311 case NE_EXPR:
5312 code = NE;
5313 break;
5314 case LT_EXPR:
5315 code = unsignedp ? LTU : LT;
5316 break;
5317 case LE_EXPR:
5318 code = unsignedp ? LEU : LE;
5319 break;
5320 case GT_EXPR:
5321 code = unsignedp ? GTU : GT;
5322 break;
5323 case GE_EXPR:
5324 code = unsignedp ? GEU : GE;
5325 break;
5327 case UNORDERED_EXPR:
5328 code = UNORDERED;
5329 break;
5330 case ORDERED_EXPR:
5331 code = ORDERED;
5332 break;
5333 case UNLT_EXPR:
5334 code = UNLT;
5335 break;
5336 case UNLE_EXPR:
5337 code = UNLE;
5338 break;
5339 case UNGT_EXPR:
5340 code = UNGT;
5341 break;
5342 case UNGE_EXPR:
5343 code = UNGE;
5344 break;
5345 case UNEQ_EXPR:
5346 code = UNEQ;
5347 break;
5348 case LTGT_EXPR:
5349 code = LTGT;
5350 break;
5352 case BIT_AND_EXPR:
5353 code = AND;
5354 break;
5356 case BIT_IOR_EXPR:
5357 code = IOR;
5358 break;
5360 default:
5361 gcc_unreachable ();
5363 return code;
5366 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
5367 select signed or unsigned operators. OPNO holds the index of the
5368 first comparison operand for insn ICODE. Do not generate the
5369 compare instruction itself. */
5371 static rtx
5372 vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
5373 tree t_op0, tree t_op1, bool unsignedp,
5374 enum insn_code icode, unsigned int opno)
5376 struct expand_operand ops[2];
5377 rtx rtx_op0, rtx_op1;
5378 machine_mode m0, m1;
5379 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5381 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5383 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5384 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5385 cases, use the original mode. */
5386 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5387 EXPAND_STACK_PARM);
5388 m0 = GET_MODE (rtx_op0);
5389 if (m0 == VOIDmode)
5390 m0 = TYPE_MODE (TREE_TYPE (t_op0));
5392 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5393 EXPAND_STACK_PARM);
5394 m1 = GET_MODE (rtx_op1);
5395 if (m1 == VOIDmode)
5396 m1 = TYPE_MODE (TREE_TYPE (t_op1));
5398 create_input_operand (&ops[0], rtx_op0, m0);
5399 create_input_operand (&ops[1], rtx_op1, m1);
5400 if (!maybe_legitimize_operands (icode, opno, 2, ops))
5401 gcc_unreachable ();
5402 return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
5405 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
5406 the first vec_perm operand, assuming the second operand is a constant
5407 vector of zeros. Return the shift distance in bits if so, or NULL_RTX
5408 if the vec_perm is not a shift. MODE is the mode of the value being
5409 shifted. */
5410 static rtx
5411 shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel)
5413 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
5414 poly_int64 first = sel[0];
5415 if (maybe_ge (sel[0], GET_MODE_NUNITS (mode)))
5416 return NULL_RTX;
5418 if (!sel.series_p (0, 1, first, 1))
5420 unsigned int nelt;
5421 if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
5422 return NULL_RTX;
5423 for (unsigned int i = 1; i < nelt; i++)
5425 poly_int64 expected = i + first;
5426 /* Indices into the second vector are all equivalent. */
5427 if (maybe_lt (sel[i], nelt)
5428 ? maybe_ne (sel[i], expected)
5429 : maybe_lt (expected, nelt))
5430 return NULL_RTX;
5434 return gen_int_shift_amount (mode, first * bitsize);
5437 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn. */
5439 static rtx
5440 expand_vec_perm_1 (enum insn_code icode, rtx target,
5441 rtx v0, rtx v1, rtx sel)
5443 machine_mode tmode = GET_MODE (target);
5444 machine_mode smode = GET_MODE (sel);
5445 struct expand_operand ops[4];
5447 gcc_assert (GET_MODE_CLASS (smode) == MODE_VECTOR_INT
5448 || mode_for_int_vector (tmode).require () == smode);
5449 create_output_operand (&ops[0], target, tmode);
5450 create_input_operand (&ops[3], sel, smode);
5452 /* Make an effort to preserve v0 == v1. The target expander is able to
5453 rely on this to determine if we're permuting a single input operand. */
5454 if (rtx_equal_p (v0, v1))
5456 if (!insn_operand_matches (icode, 1, v0))
5457 v0 = force_reg (tmode, v0);
5458 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5459 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5461 create_fixed_operand (&ops[1], v0);
5462 create_fixed_operand (&ops[2], v0);
5464 else
5466 create_input_operand (&ops[1], v0, tmode);
5467 create_input_operand (&ops[2], v1, tmode);
5470 if (maybe_expand_insn (icode, 4, ops))
5471 return ops[0].value;
5472 return NULL_RTX;
5475 /* Implement a permutation of vectors v0 and v1 using the permutation
5476 vector in SEL and return the result. Use TARGET to hold the result
5477 if nonnull and convenient.
5479 MODE is the mode of the vectors being permuted (V0 and V1). SEL_MODE
5480 is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
5481 to have a particular mode. */
5484 expand_vec_perm_const (machine_mode mode, rtx v0, rtx v1,
5485 const vec_perm_builder &sel, machine_mode sel_mode,
5486 rtx target)
5488 if (!target || !register_operand (target, mode))
5489 target = gen_reg_rtx (mode);
5491 /* Set QIMODE to a different vector mode with byte elements.
5492 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5493 machine_mode qimode;
5494 if (!qimode_for_vec_perm (mode).exists (&qimode))
5495 qimode = VOIDmode;
5497 rtx_insn *last = get_last_insn ();
5499 bool single_arg_p = rtx_equal_p (v0, v1);
5500 /* Always specify two input vectors here and leave the target to handle
5501 cases in which the inputs are equal. Not all backends can cope with
5502 the single-input representation when testing for a double-input
5503 target instruction. */
5504 vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode));
5506 /* See if this can be handled with a vec_shr. We only do this if the
5507 second vector is all zeroes. */
5508 insn_code shift_code = optab_handler (vec_shr_optab, mode);
5509 insn_code shift_code_qi = ((qimode != VOIDmode && qimode != mode)
5510 ? optab_handler (vec_shr_optab, qimode)
5511 : CODE_FOR_nothing);
5513 if (v1 == CONST0_RTX (GET_MODE (v1))
5514 && (shift_code != CODE_FOR_nothing
5515 || shift_code_qi != CODE_FOR_nothing))
5517 rtx shift_amt = shift_amt_for_vec_perm_mask (mode, indices);
5518 if (shift_amt)
5520 struct expand_operand ops[3];
5521 if (shift_code != CODE_FOR_nothing)
5523 create_output_operand (&ops[0], target, mode);
5524 create_input_operand (&ops[1], v0, mode);
5525 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
5526 if (maybe_expand_insn (shift_code, 3, ops))
5527 return ops[0].value;
5529 if (shift_code_qi != CODE_FOR_nothing)
5531 rtx tmp = gen_reg_rtx (qimode);
5532 create_output_operand (&ops[0], tmp, qimode);
5533 create_input_operand (&ops[1], gen_lowpart (qimode, v0), qimode);
5534 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
5535 if (maybe_expand_insn (shift_code_qi, 3, ops))
5536 return gen_lowpart (mode, ops[0].value);
5541 if (targetm.vectorize.vec_perm_const != NULL)
5543 v0 = force_reg (mode, v0);
5544 if (single_arg_p)
5545 v1 = v0;
5546 else
5547 v1 = force_reg (mode, v1);
5549 if (targetm.vectorize.vec_perm_const (mode, target, v0, v1, indices))
5550 return target;
5553 /* Fall back to a constant byte-based permutation. */
5554 vec_perm_indices qimode_indices;
5555 rtx target_qi = NULL_RTX, v0_qi = NULL_RTX, v1_qi = NULL_RTX;
5556 if (qimode != VOIDmode)
5558 qimode_indices.new_expanded_vector (indices, GET_MODE_UNIT_SIZE (mode));
5559 target_qi = gen_reg_rtx (qimode);
5560 v0_qi = gen_lowpart (qimode, v0);
5561 v1_qi = gen_lowpart (qimode, v1);
5562 if (targetm.vectorize.vec_perm_const != NULL
5563 && targetm.vectorize.vec_perm_const (qimode, target_qi, v0_qi,
5564 v1_qi, qimode_indices))
5565 return gen_lowpart (mode, target_qi);
5568 /* Otherwise expand as a fully variable permuation. */
5570 /* The optabs are only defined for selectors with the same width
5571 as the values being permuted. */
5572 machine_mode required_sel_mode;
5573 if (!mode_for_int_vector (mode).exists (&required_sel_mode)
5574 || !VECTOR_MODE_P (required_sel_mode))
5576 delete_insns_since (last);
5577 return NULL_RTX;
5580 /* We know that it is semantically valid to treat SEL as having SEL_MODE.
5581 If that isn't the mode we want then we need to prove that using
5582 REQUIRED_SEL_MODE is OK. */
5583 if (sel_mode != required_sel_mode)
5585 if (!selector_fits_mode_p (required_sel_mode, indices))
5587 delete_insns_since (last);
5588 return NULL_RTX;
5590 sel_mode = required_sel_mode;
5593 insn_code icode = direct_optab_handler (vec_perm_optab, mode);
5594 if (icode != CODE_FOR_nothing)
5596 rtx sel_rtx = vec_perm_indices_to_rtx (sel_mode, indices);
5597 rtx tmp = expand_vec_perm_1 (icode, target, v0, v1, sel_rtx);
5598 if (tmp)
5599 return tmp;
5602 if (qimode != VOIDmode
5603 && selector_fits_mode_p (qimode, qimode_indices))
5605 icode = direct_optab_handler (vec_perm_optab, qimode);
5606 if (icode != CODE_FOR_nothing)
5608 rtx sel_qi = vec_perm_indices_to_rtx (qimode, qimode_indices);
5609 rtx tmp = expand_vec_perm_1 (icode, target_qi, v0_qi, v1_qi, sel_qi);
5610 if (tmp)
5611 return gen_lowpart (mode, tmp);
5615 delete_insns_since (last);
5616 return NULL_RTX;
5619 /* Implement a permutation of vectors v0 and v1 using the permutation
5620 vector in SEL and return the result. Use TARGET to hold the result
5621 if nonnull and convenient.
5623 MODE is the mode of the vectors being permuted (V0 and V1).
5624 SEL must have the integer equivalent of MODE and is known to be
5625 unsuitable for permutes with a constant permutation vector. */
5628 expand_vec_perm_var (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
5630 enum insn_code icode;
5631 unsigned int i, u;
5632 rtx tmp, sel_qi;
5634 u = GET_MODE_UNIT_SIZE (mode);
5636 if (!target || GET_MODE (target) != mode)
5637 target = gen_reg_rtx (mode);
5639 icode = direct_optab_handler (vec_perm_optab, mode);
5640 if (icode != CODE_FOR_nothing)
5642 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5643 if (tmp)
5644 return tmp;
5647 /* As a special case to aid several targets, lower the element-based
5648 permutation to a byte-based permutation and try again. */
5649 machine_mode qimode;
5650 if (!qimode_for_vec_perm (mode).exists (&qimode)
5651 || maybe_gt (GET_MODE_NUNITS (qimode), GET_MODE_MASK (QImode) + 1))
5652 return NULL_RTX;
5653 icode = direct_optab_handler (vec_perm_optab, qimode);
5654 if (icode == CODE_FOR_nothing)
5655 return NULL_RTX;
5657 /* Multiply each element by its byte size. */
5658 machine_mode selmode = GET_MODE (sel);
5659 if (u == 2)
5660 sel = expand_simple_binop (selmode, PLUS, sel, sel,
5661 NULL, 0, OPTAB_DIRECT);
5662 else
5663 sel = expand_simple_binop (selmode, ASHIFT, sel,
5664 gen_int_shift_amount (selmode, exact_log2 (u)),
5665 NULL, 0, OPTAB_DIRECT);
5666 gcc_assert (sel != NULL);
5668 /* Broadcast the low byte each element into each of its bytes.
5669 The encoding has U interleaved stepped patterns, one for each
5670 byte of an element. */
5671 vec_perm_builder const_sel (GET_MODE_SIZE (mode), u, 3);
5672 unsigned int low_byte_in_u = BYTES_BIG_ENDIAN ? u - 1 : 0;
5673 for (i = 0; i < 3; ++i)
5674 for (unsigned int j = 0; j < u; ++j)
5675 const_sel.quick_push (i * u + low_byte_in_u);
5676 sel = gen_lowpart (qimode, sel);
5677 sel = expand_vec_perm_const (qimode, sel, sel, const_sel, qimode, NULL);
5678 gcc_assert (sel != NULL);
5680 /* Add the byte offset to each byte element. */
5681 /* Note that the definition of the indicies here is memory ordering,
5682 so there should be no difference between big and little endian. */
5683 rtx_vector_builder byte_indices (qimode, u, 1);
5684 for (i = 0; i < u; ++i)
5685 byte_indices.quick_push (GEN_INT (i));
5686 tmp = byte_indices.build ();
5687 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
5688 sel, 0, OPTAB_DIRECT);
5689 gcc_assert (sel_qi != NULL);
5691 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5692 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5693 gen_lowpart (qimode, v1), sel_qi);
5694 if (tmp)
5695 tmp = gen_lowpart (mode, tmp);
5696 return tmp;
5699 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5700 three operands. */
5703 expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5704 rtx target)
5706 struct expand_operand ops[4];
5707 machine_mode mode = TYPE_MODE (vec_cond_type);
5708 machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0));
5709 enum insn_code icode = get_vcond_mask_icode (mode, mask_mode);
5710 rtx mask, rtx_op1, rtx_op2;
5712 if (icode == CODE_FOR_nothing)
5713 return 0;
5715 mask = expand_normal (op0);
5716 rtx_op1 = expand_normal (op1);
5717 rtx_op2 = expand_normal (op2);
5719 mask = force_reg (mask_mode, mask);
5720 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5722 create_output_operand (&ops[0], target, mode);
5723 create_input_operand (&ops[1], rtx_op1, mode);
5724 create_input_operand (&ops[2], rtx_op2, mode);
5725 create_input_operand (&ops[3], mask, mask_mode);
5726 expand_insn (icode, 4, ops);
5728 return ops[0].value;
5731 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5732 three operands. */
5735 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5736 rtx target)
5738 struct expand_operand ops[6];
5739 enum insn_code icode;
5740 rtx comparison, rtx_op1, rtx_op2;
5741 machine_mode mode = TYPE_MODE (vec_cond_type);
5742 machine_mode cmp_op_mode;
5743 bool unsignedp;
5744 tree op0a, op0b;
5745 enum tree_code tcode;
5747 if (COMPARISON_CLASS_P (op0))
5749 op0a = TREE_OPERAND (op0, 0);
5750 op0b = TREE_OPERAND (op0, 1);
5751 tcode = TREE_CODE (op0);
5753 else
5755 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
5756 if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0)))
5757 != CODE_FOR_nothing)
5758 return expand_vec_cond_mask_expr (vec_cond_type, op0, op1,
5759 op2, target);
5760 /* Fake op0 < 0. */
5761 else
5763 gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0)))
5764 == MODE_VECTOR_INT);
5765 op0a = op0;
5766 op0b = build_zero_cst (TREE_TYPE (op0));
5767 tcode = LT_EXPR;
5770 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
5771 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5774 gcc_assert (known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (cmp_op_mode))
5775 && known_eq (GET_MODE_NUNITS (mode),
5776 GET_MODE_NUNITS (cmp_op_mode)));
5778 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
5779 if (icode == CODE_FOR_nothing)
5781 if (tcode == EQ_EXPR || tcode == NE_EXPR)
5782 icode = get_vcond_eq_icode (mode, cmp_op_mode);
5783 if (icode == CODE_FOR_nothing)
5784 return 0;
5787 comparison = vector_compare_rtx (VOIDmode, tcode, op0a, op0b, unsignedp,
5788 icode, 4);
5789 rtx_op1 = expand_normal (op1);
5790 rtx_op2 = expand_normal (op2);
5792 create_output_operand (&ops[0], target, mode);
5793 create_input_operand (&ops[1], rtx_op1, mode);
5794 create_input_operand (&ops[2], rtx_op2, mode);
5795 create_fixed_operand (&ops[3], comparison);
5796 create_fixed_operand (&ops[4], XEXP (comparison, 0));
5797 create_fixed_operand (&ops[5], XEXP (comparison, 1));
5798 expand_insn (icode, 6, ops);
5799 return ops[0].value;
5802 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
5803 Use TARGET for the result if nonnull and convenient. */
5806 expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
5808 struct expand_operand ops[3];
5809 enum insn_code icode;
5810 machine_mode emode = GET_MODE_INNER (vmode);
5812 icode = direct_optab_handler (vec_series_optab, vmode);
5813 gcc_assert (icode != CODE_FOR_nothing);
5815 create_output_operand (&ops[0], target, vmode);
5816 create_input_operand (&ops[1], op0, emode);
5817 create_input_operand (&ops[2], op1, emode);
5819 expand_insn (icode, 3, ops);
5820 return ops[0].value;
5823 /* Generate insns for a vector comparison into a mask. */
5826 expand_vec_cmp_expr (tree type, tree exp, rtx target)
5828 struct expand_operand ops[4];
5829 enum insn_code icode;
5830 rtx comparison;
5831 machine_mode mask_mode = TYPE_MODE (type);
5832 machine_mode vmode;
5833 bool unsignedp;
5834 tree op0a, op0b;
5835 enum tree_code tcode;
5837 op0a = TREE_OPERAND (exp, 0);
5838 op0b = TREE_OPERAND (exp, 1);
5839 tcode = TREE_CODE (exp);
5841 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5842 vmode = TYPE_MODE (TREE_TYPE (op0a));
5844 icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
5845 if (icode == CODE_FOR_nothing)
5847 if (tcode == EQ_EXPR || tcode == NE_EXPR)
5848 icode = get_vec_cmp_eq_icode (vmode, mask_mode);
5849 if (icode == CODE_FOR_nothing)
5850 return 0;
5853 comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
5854 unsignedp, icode, 2);
5855 create_output_operand (&ops[0], target, mask_mode);
5856 create_fixed_operand (&ops[1], comparison);
5857 create_fixed_operand (&ops[2], XEXP (comparison, 0));
5858 create_fixed_operand (&ops[3], XEXP (comparison, 1));
5859 expand_insn (icode, 4, ops);
5860 return ops[0].value;
5863 /* Expand a highpart multiply. */
5866 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
5867 rtx target, bool uns_p)
5869 struct expand_operand eops[3];
5870 enum insn_code icode;
5871 int method, i;
5872 machine_mode wmode;
5873 rtx m1, m2;
5874 optab tab1, tab2;
5876 method = can_mult_highpart_p (mode, uns_p);
5877 switch (method)
5879 case 0:
5880 return NULL_RTX;
5881 case 1:
5882 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
5883 return expand_binop (mode, tab1, op0, op1, target, uns_p,
5884 OPTAB_LIB_WIDEN);
5885 case 2:
5886 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
5887 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
5888 break;
5889 case 3:
5890 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
5891 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
5892 if (BYTES_BIG_ENDIAN)
5893 std::swap (tab1, tab2);
5894 break;
5895 default:
5896 gcc_unreachable ();
5899 icode = optab_handler (tab1, mode);
5900 wmode = insn_data[icode].operand[0].mode;
5901 gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode),
5902 GET_MODE_NUNITS (mode)));
5903 gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode), GET_MODE_SIZE (mode)));
5905 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5906 create_input_operand (&eops[1], op0, mode);
5907 create_input_operand (&eops[2], op1, mode);
5908 expand_insn (icode, 3, eops);
5909 m1 = gen_lowpart (mode, eops[0].value);
5911 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5912 create_input_operand (&eops[1], op0, mode);
5913 create_input_operand (&eops[2], op1, mode);
5914 expand_insn (optab_handler (tab2, mode), 3, eops);
5915 m2 = gen_lowpart (mode, eops[0].value);
5917 vec_perm_builder sel;
5918 if (method == 2)
5920 /* The encoding has 2 interleaved stepped patterns. */
5921 sel.new_vector (GET_MODE_NUNITS (mode), 2, 3);
5922 for (i = 0; i < 6; ++i)
5923 sel.quick_push (!BYTES_BIG_ENDIAN + (i & ~1)
5924 + ((i & 1) ? GET_MODE_NUNITS (mode) : 0));
5926 else
5928 /* The encoding has a single interleaved stepped pattern. */
5929 sel.new_vector (GET_MODE_NUNITS (mode), 1, 3);
5930 for (i = 0; i < 3; ++i)
5931 sel.quick_push (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
5934 return expand_vec_perm_const (mode, m1, m2, sel, BLKmode, target);
5937 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5938 pattern. */
5940 static void
5941 find_cc_set (rtx x, const_rtx pat, void *data)
5943 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
5944 && GET_CODE (pat) == SET)
5946 rtx *p_cc_reg = (rtx *) data;
5947 gcc_assert (!*p_cc_reg);
5948 *p_cc_reg = x;
5952 /* This is a helper function for the other atomic operations. This function
5953 emits a loop that contains SEQ that iterates until a compare-and-swap
5954 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5955 a set of instructions that takes a value from OLD_REG as an input and
5956 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5957 set to the current contents of MEM. After SEQ, a compare-and-swap will
5958 attempt to update MEM with NEW_REG. The function returns true when the
5959 loop was generated successfully. */
5961 static bool
5962 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5964 machine_mode mode = GET_MODE (mem);
5965 rtx_code_label *label;
5966 rtx cmp_reg, success, oldval;
5968 /* The loop we want to generate looks like
5970 cmp_reg = mem;
5971 label:
5972 old_reg = cmp_reg;
5973 seq;
5974 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5975 if (success)
5976 goto label;
5978 Note that we only do the plain load from memory once. Subsequent
5979 iterations use the value loaded by the compare-and-swap pattern. */
5981 label = gen_label_rtx ();
5982 cmp_reg = gen_reg_rtx (mode);
5984 emit_move_insn (cmp_reg, mem);
5985 emit_label (label);
5986 emit_move_insn (old_reg, cmp_reg);
5987 if (seq)
5988 emit_insn (seq);
5990 success = NULL_RTX;
5991 oldval = cmp_reg;
5992 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
5993 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
5994 MEMMODEL_RELAXED))
5995 return false;
5997 if (oldval != cmp_reg)
5998 emit_move_insn (cmp_reg, oldval);
6000 /* Mark this jump predicted not taken. */
6001 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
6002 GET_MODE (success), 1, label,
6003 profile_probability::guessed_never ());
6004 return true;
6008 /* This function tries to emit an atomic_exchange intruction. VAL is written
6009 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6010 using TARGET if possible. */
6012 static rtx
6013 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6015 machine_mode mode = GET_MODE (mem);
6016 enum insn_code icode;
6018 /* If the target supports the exchange directly, great. */
6019 icode = direct_optab_handler (atomic_exchange_optab, mode);
6020 if (icode != CODE_FOR_nothing)
6022 struct expand_operand ops[4];
6024 create_output_operand (&ops[0], target, mode);
6025 create_fixed_operand (&ops[1], mem);
6026 create_input_operand (&ops[2], val, mode);
6027 create_integer_operand (&ops[3], model);
6028 if (maybe_expand_insn (icode, 4, ops))
6029 return ops[0].value;
6032 return NULL_RTX;
6035 /* This function tries to implement an atomic exchange operation using
6036 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6037 The previous contents of *MEM are returned, using TARGET if possible.
6038 Since this instructionn is an acquire barrier only, stronger memory
6039 models may require additional barriers to be emitted. */
6041 static rtx
6042 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
6043 enum memmodel model)
6045 machine_mode mode = GET_MODE (mem);
6046 enum insn_code icode;
6047 rtx_insn *last_insn = get_last_insn ();
6049 icode = optab_handler (sync_lock_test_and_set_optab, mode);
6051 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
6052 exists, and the memory model is stronger than acquire, add a release
6053 barrier before the instruction. */
6055 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
6056 expand_mem_thread_fence (model);
6058 if (icode != CODE_FOR_nothing)
6060 struct expand_operand ops[3];
6061 create_output_operand (&ops[0], target, mode);
6062 create_fixed_operand (&ops[1], mem);
6063 create_input_operand (&ops[2], val, mode);
6064 if (maybe_expand_insn (icode, 3, ops))
6065 return ops[0].value;
6068 /* If an external test-and-set libcall is provided, use that instead of
6069 any external compare-and-swap that we might get from the compare-and-
6070 swap-loop expansion later. */
6071 if (!can_compare_and_swap_p (mode, false))
6073 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
6074 if (libfunc != NULL)
6076 rtx addr;
6078 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6079 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6080 mode, addr, ptr_mode,
6081 val, mode);
6085 /* If the test_and_set can't be emitted, eliminate any barrier that might
6086 have been emitted. */
6087 delete_insns_since (last_insn);
6088 return NULL_RTX;
6091 /* This function tries to implement an atomic exchange operation using a
6092 compare_and_swap loop. VAL is written to *MEM. The previous contents of
6093 *MEM are returned, using TARGET if possible. No memory model is required
6094 since a compare_and_swap loop is seq-cst. */
6096 static rtx
6097 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
6099 machine_mode mode = GET_MODE (mem);
6101 if (can_compare_and_swap_p (mode, true))
6103 if (!target || !register_operand (target, mode))
6104 target = gen_reg_rtx (mode);
6105 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6106 return target;
6109 return NULL_RTX;
6112 /* This function tries to implement an atomic test-and-set operation
6113 using the atomic_test_and_set instruction pattern. A boolean value
6114 is returned from the operation, using TARGET if possible. */
6116 static rtx
6117 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6119 machine_mode pat_bool_mode;
6120 struct expand_operand ops[3];
6122 if (!targetm.have_atomic_test_and_set ())
6123 return NULL_RTX;
6125 /* While we always get QImode from __atomic_test_and_set, we get
6126 other memory modes from __sync_lock_test_and_set. Note that we
6127 use no endian adjustment here. This matches the 4.6 behavior
6128 in the Sparc backend. */
6129 enum insn_code icode = targetm.code_for_atomic_test_and_set;
6130 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
6131 if (GET_MODE (mem) != QImode)
6132 mem = adjust_address_nv (mem, QImode, 0);
6134 pat_bool_mode = insn_data[icode].operand[0].mode;
6135 create_output_operand (&ops[0], target, pat_bool_mode);
6136 create_fixed_operand (&ops[1], mem);
6137 create_integer_operand (&ops[2], model);
6139 if (maybe_expand_insn (icode, 3, ops))
6140 return ops[0].value;
6141 return NULL_RTX;
6144 /* This function expands the legacy _sync_lock test_and_set operation which is
6145 generally an atomic exchange. Some limited targets only allow the
6146 constant 1 to be stored. This is an ACQUIRE operation.
6148 TARGET is an optional place to stick the return value.
6149 MEM is where VAL is stored. */
6152 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
6154 rtx ret;
6156 /* Try an atomic_exchange first. */
6157 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
6158 if (ret)
6159 return ret;
6161 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
6162 MEMMODEL_SYNC_ACQUIRE);
6163 if (ret)
6164 return ret;
6166 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6167 if (ret)
6168 return ret;
6170 /* If there are no other options, try atomic_test_and_set if the value
6171 being stored is 1. */
6172 if (val == const1_rtx)
6173 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
6175 return ret;
6178 /* This function expands the atomic test_and_set operation:
6179 atomically store a boolean TRUE into MEM and return the previous value.
6181 MEMMODEL is the memory model variant to use.
6182 TARGET is an optional place to stick the return value. */
6185 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6187 machine_mode mode = GET_MODE (mem);
6188 rtx ret, trueval, subtarget;
6190 ret = maybe_emit_atomic_test_and_set (target, mem, model);
6191 if (ret)
6192 return ret;
6194 /* Be binary compatible with non-default settings of trueval, and different
6195 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6196 another only has atomic-exchange. */
6197 if (targetm.atomic_test_and_set_trueval == 1)
6199 trueval = const1_rtx;
6200 subtarget = target ? target : gen_reg_rtx (mode);
6202 else
6204 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
6205 subtarget = gen_reg_rtx (mode);
6208 /* Try the atomic-exchange optab... */
6209 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
6211 /* ... then an atomic-compare-and-swap loop ... */
6212 if (!ret)
6213 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
6215 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6216 if (!ret)
6217 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
6219 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6220 things with the value 1. Thus we try again without trueval. */
6221 if (!ret && targetm.atomic_test_and_set_trueval != 1)
6222 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
6224 /* Failing all else, assume a single threaded environment and simply
6225 perform the operation. */
6226 if (!ret)
6228 /* If the result is ignored skip the move to target. */
6229 if (subtarget != const0_rtx)
6230 emit_move_insn (subtarget, mem);
6232 emit_move_insn (mem, trueval);
6233 ret = subtarget;
6236 /* Recall that have to return a boolean value; rectify if trueval
6237 is not exactly one. */
6238 if (targetm.atomic_test_and_set_trueval != 1)
6239 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
6241 return ret;
6244 /* This function expands the atomic exchange operation:
6245 atomically store VAL in MEM and return the previous value in MEM.
6247 MEMMODEL is the memory model variant to use.
6248 TARGET is an optional place to stick the return value. */
6251 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6253 machine_mode mode = GET_MODE (mem);
6254 rtx ret;
6256 /* If loads are not atomic for the required size and we are not called to
6257 provide a __sync builtin, do not do anything so that we stay consistent
6258 with atomic loads of the same size. */
6259 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6260 return NULL_RTX;
6262 ret = maybe_emit_atomic_exchange (target, mem, val, model);
6264 /* Next try a compare-and-swap loop for the exchange. */
6265 if (!ret)
6266 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6268 return ret;
6271 /* This function expands the atomic compare exchange operation:
6273 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6274 *PTARGET_OVAL is an optional place to store the old value from memory.
6275 Both target parameters may be NULL or const0_rtx to indicate that we do
6276 not care about that return value. Both target parameters are updated on
6277 success to the actual location of the corresponding result.
6279 MEMMODEL is the memory model variant to use.
6281 The return value of the function is true for success. */
6283 bool
6284 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
6285 rtx mem, rtx expected, rtx desired,
6286 bool is_weak, enum memmodel succ_model,
6287 enum memmodel fail_model)
6289 machine_mode mode = GET_MODE (mem);
6290 struct expand_operand ops[8];
6291 enum insn_code icode;
6292 rtx target_oval, target_bool = NULL_RTX;
6293 rtx libfunc;
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 (succ_model))
6299 return false;
6301 /* Load expected into a register for the compare and swap. */
6302 if (MEM_P (expected))
6303 expected = copy_to_reg (expected);
6305 /* Make sure we always have some place to put the return oldval.
6306 Further, make sure that place is distinct from the input expected,
6307 just in case we need that path down below. */
6308 if (ptarget_oval && *ptarget_oval == const0_rtx)
6309 ptarget_oval = NULL;
6311 if (ptarget_oval == NULL
6312 || (target_oval = *ptarget_oval) == NULL
6313 || reg_overlap_mentioned_p (expected, target_oval))
6314 target_oval = gen_reg_rtx (mode);
6316 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6317 if (icode != CODE_FOR_nothing)
6319 machine_mode bool_mode = insn_data[icode].operand[0].mode;
6321 if (ptarget_bool && *ptarget_bool == const0_rtx)
6322 ptarget_bool = NULL;
6324 /* Make sure we always have a place for the bool operand. */
6325 if (ptarget_bool == NULL
6326 || (target_bool = *ptarget_bool) == NULL
6327 || GET_MODE (target_bool) != bool_mode)
6328 target_bool = gen_reg_rtx (bool_mode);
6330 /* Emit the compare_and_swap. */
6331 create_output_operand (&ops[0], target_bool, bool_mode);
6332 create_output_operand (&ops[1], target_oval, mode);
6333 create_fixed_operand (&ops[2], mem);
6334 create_input_operand (&ops[3], expected, mode);
6335 create_input_operand (&ops[4], desired, mode);
6336 create_integer_operand (&ops[5], is_weak);
6337 create_integer_operand (&ops[6], succ_model);
6338 create_integer_operand (&ops[7], fail_model);
6339 if (maybe_expand_insn (icode, 8, ops))
6341 /* Return success/failure. */
6342 target_bool = ops[0].value;
6343 target_oval = ops[1].value;
6344 goto success;
6348 /* Otherwise fall back to the original __sync_val_compare_and_swap
6349 which is always seq-cst. */
6350 icode = optab_handler (sync_compare_and_swap_optab, mode);
6351 if (icode != CODE_FOR_nothing)
6353 rtx cc_reg;
6355 create_output_operand (&ops[0], target_oval, mode);
6356 create_fixed_operand (&ops[1], mem);
6357 create_input_operand (&ops[2], expected, mode);
6358 create_input_operand (&ops[3], desired, mode);
6359 if (!maybe_expand_insn (icode, 4, ops))
6360 return false;
6362 target_oval = ops[0].value;
6364 /* If the caller isn't interested in the boolean return value,
6365 skip the computation of it. */
6366 if (ptarget_bool == NULL)
6367 goto success;
6369 /* Otherwise, work out if the compare-and-swap succeeded. */
6370 cc_reg = NULL_RTX;
6371 if (have_insn_for (COMPARE, CCmode))
6372 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
6373 if (cc_reg)
6375 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6376 const0_rtx, VOIDmode, 0, 1);
6377 goto success;
6379 goto success_bool_from_val;
6382 /* Also check for library support for __sync_val_compare_and_swap. */
6383 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6384 if (libfunc != NULL)
6386 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6387 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6388 mode, addr, ptr_mode,
6389 expected, mode, desired, mode);
6390 emit_move_insn (target_oval, target);
6392 /* Compute the boolean return value only if requested. */
6393 if (ptarget_bool)
6394 goto success_bool_from_val;
6395 else
6396 goto success;
6399 /* Failure. */
6400 return false;
6402 success_bool_from_val:
6403 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
6404 expected, VOIDmode, 1, 1);
6405 success:
6406 /* Make sure that the oval output winds up where the caller asked. */
6407 if (ptarget_oval)
6408 *ptarget_oval = target_oval;
6409 if (ptarget_bool)
6410 *ptarget_bool = target_bool;
6411 return true;
6414 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
6416 static void
6417 expand_asm_memory_blockage (void)
6419 rtx asm_op, clob;
6421 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
6422 rtvec_alloc (0), rtvec_alloc (0),
6423 rtvec_alloc (0), UNKNOWN_LOCATION);
6424 MEM_VOLATILE_P (asm_op) = 1;
6426 clob = gen_rtx_SCRATCH (VOIDmode);
6427 clob = gen_rtx_MEM (BLKmode, clob);
6428 clob = gen_rtx_CLOBBER (VOIDmode, clob);
6430 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
6433 /* Do not propagate memory accesses across this point. */
6435 static void
6436 expand_memory_blockage (void)
6438 if (targetm.have_memory_blockage ())
6439 emit_insn (targetm.gen_memory_blockage ());
6440 else
6441 expand_asm_memory_blockage ();
6444 /* This routine will either emit the mem_thread_fence pattern or issue a
6445 sync_synchronize to generate a fence for memory model MEMMODEL. */
6447 void
6448 expand_mem_thread_fence (enum memmodel model)
6450 if (is_mm_relaxed (model))
6451 return;
6452 if (targetm.have_mem_thread_fence ())
6454 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
6455 expand_memory_blockage ();
6457 else if (targetm.have_memory_barrier ())
6458 emit_insn (targetm.gen_memory_barrier ());
6459 else if (synchronize_libfunc != NULL_RTX)
6460 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode);
6461 else
6462 expand_memory_blockage ();
6465 /* Emit a signal fence with given memory model. */
6467 void
6468 expand_mem_signal_fence (enum memmodel model)
6470 /* No machine barrier is required to implement a signal fence, but
6471 a compiler memory barrier must be issued, except for relaxed MM. */
6472 if (!is_mm_relaxed (model))
6473 expand_memory_blockage ();
6476 /* This function expands the atomic load operation:
6477 return the atomically loaded value in MEM.
6479 MEMMODEL is the memory model variant to use.
6480 TARGET is an option place to stick the return value. */
6483 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6485 machine_mode mode = GET_MODE (mem);
6486 enum insn_code icode;
6488 /* If the target supports the load directly, great. */
6489 icode = direct_optab_handler (atomic_load_optab, mode);
6490 if (icode != CODE_FOR_nothing)
6492 struct expand_operand ops[3];
6493 rtx_insn *last = get_last_insn ();
6494 if (is_mm_seq_cst (model))
6495 expand_memory_blockage ();
6497 create_output_operand (&ops[0], target, mode);
6498 create_fixed_operand (&ops[1], mem);
6499 create_integer_operand (&ops[2], model);
6500 if (maybe_expand_insn (icode, 3, ops))
6502 if (!is_mm_relaxed (model))
6503 expand_memory_blockage ();
6504 return ops[0].value;
6506 delete_insns_since (last);
6509 /* If the size of the object is greater than word size on this target,
6510 then we assume that a load will not be atomic. We could try to
6511 emulate a load with a compare-and-swap operation, but the store that
6512 doing this could result in would be incorrect if this is a volatile
6513 atomic load or targetting read-only-mapped memory. */
6514 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
6515 /* If there is no atomic load, leave the library call. */
6516 return NULL_RTX;
6518 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6519 if (!target || target == const0_rtx)
6520 target = gen_reg_rtx (mode);
6522 /* For SEQ_CST, emit a barrier before the load. */
6523 if (is_mm_seq_cst (model))
6524 expand_mem_thread_fence (model);
6526 emit_move_insn (target, mem);
6528 /* Emit the appropriate barrier after the load. */
6529 expand_mem_thread_fence (model);
6531 return target;
6534 /* This function expands the atomic store operation:
6535 Atomically store VAL in MEM.
6536 MEMMODEL is the memory model variant to use.
6537 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6538 function returns const0_rtx if a pattern was emitted. */
6541 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6543 machine_mode mode = GET_MODE (mem);
6544 enum insn_code icode;
6545 struct expand_operand ops[3];
6547 /* If the target supports the store directly, great. */
6548 icode = direct_optab_handler (atomic_store_optab, mode);
6549 if (icode != CODE_FOR_nothing)
6551 rtx_insn *last = get_last_insn ();
6552 if (!is_mm_relaxed (model))
6553 expand_memory_blockage ();
6554 create_fixed_operand (&ops[0], mem);
6555 create_input_operand (&ops[1], val, mode);
6556 create_integer_operand (&ops[2], model);
6557 if (maybe_expand_insn (icode, 3, ops))
6559 if (is_mm_seq_cst (model))
6560 expand_memory_blockage ();
6561 return const0_rtx;
6563 delete_insns_since (last);
6566 /* If using __sync_lock_release is a viable alternative, try it.
6567 Note that this will not be set to true if we are expanding a generic
6568 __atomic_store_n. */
6569 if (use_release)
6571 icode = direct_optab_handler (sync_lock_release_optab, mode);
6572 if (icode != CODE_FOR_nothing)
6574 create_fixed_operand (&ops[0], mem);
6575 create_input_operand (&ops[1], const0_rtx, mode);
6576 if (maybe_expand_insn (icode, 2, ops))
6578 /* lock_release is only a release barrier. */
6579 if (is_mm_seq_cst (model))
6580 expand_mem_thread_fence (model);
6581 return const0_rtx;
6586 /* If the size of the object is greater than word size on this target,
6587 a default store will not be atomic. */
6588 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
6590 /* If loads are atomic or we are called to provide a __sync builtin,
6591 we can try a atomic_exchange and throw away the result. Otherwise,
6592 don't do anything so that we do not create an inconsistency between
6593 loads and stores. */
6594 if (can_atomic_load_p (mode) || is_mm_sync (model))
6596 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6597 if (!target)
6598 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem,
6599 val);
6600 if (target)
6601 return const0_rtx;
6603 return NULL_RTX;
6606 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6607 expand_mem_thread_fence (model);
6609 emit_move_insn (mem, val);
6611 /* For SEQ_CST, also emit a barrier after the store. */
6612 if (is_mm_seq_cst (model))
6613 expand_mem_thread_fence (model);
6615 return const0_rtx;
6619 /* Structure containing the pointers and values required to process the
6620 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6622 struct atomic_op_functions
6624 direct_optab mem_fetch_before;
6625 direct_optab mem_fetch_after;
6626 direct_optab mem_no_result;
6627 optab fetch_before;
6628 optab fetch_after;
6629 direct_optab no_result;
6630 enum rtx_code reverse_code;
6634 /* Fill in structure pointed to by OP with the various optab entries for an
6635 operation of type CODE. */
6637 static void
6638 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6640 gcc_assert (op!= NULL);
6642 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6643 in the source code during compilation, and the optab entries are not
6644 computable until runtime. Fill in the values at runtime. */
6645 switch (code)
6647 case PLUS:
6648 op->mem_fetch_before = atomic_fetch_add_optab;
6649 op->mem_fetch_after = atomic_add_fetch_optab;
6650 op->mem_no_result = atomic_add_optab;
6651 op->fetch_before = sync_old_add_optab;
6652 op->fetch_after = sync_new_add_optab;
6653 op->no_result = sync_add_optab;
6654 op->reverse_code = MINUS;
6655 break;
6656 case MINUS:
6657 op->mem_fetch_before = atomic_fetch_sub_optab;
6658 op->mem_fetch_after = atomic_sub_fetch_optab;
6659 op->mem_no_result = atomic_sub_optab;
6660 op->fetch_before = sync_old_sub_optab;
6661 op->fetch_after = sync_new_sub_optab;
6662 op->no_result = sync_sub_optab;
6663 op->reverse_code = PLUS;
6664 break;
6665 case XOR:
6666 op->mem_fetch_before = atomic_fetch_xor_optab;
6667 op->mem_fetch_after = atomic_xor_fetch_optab;
6668 op->mem_no_result = atomic_xor_optab;
6669 op->fetch_before = sync_old_xor_optab;
6670 op->fetch_after = sync_new_xor_optab;
6671 op->no_result = sync_xor_optab;
6672 op->reverse_code = XOR;
6673 break;
6674 case AND:
6675 op->mem_fetch_before = atomic_fetch_and_optab;
6676 op->mem_fetch_after = atomic_and_fetch_optab;
6677 op->mem_no_result = atomic_and_optab;
6678 op->fetch_before = sync_old_and_optab;
6679 op->fetch_after = sync_new_and_optab;
6680 op->no_result = sync_and_optab;
6681 op->reverse_code = UNKNOWN;
6682 break;
6683 case IOR:
6684 op->mem_fetch_before = atomic_fetch_or_optab;
6685 op->mem_fetch_after = atomic_or_fetch_optab;
6686 op->mem_no_result = atomic_or_optab;
6687 op->fetch_before = sync_old_ior_optab;
6688 op->fetch_after = sync_new_ior_optab;
6689 op->no_result = sync_ior_optab;
6690 op->reverse_code = UNKNOWN;
6691 break;
6692 case NOT:
6693 op->mem_fetch_before = atomic_fetch_nand_optab;
6694 op->mem_fetch_after = atomic_nand_fetch_optab;
6695 op->mem_no_result = atomic_nand_optab;
6696 op->fetch_before = sync_old_nand_optab;
6697 op->fetch_after = sync_new_nand_optab;
6698 op->no_result = sync_nand_optab;
6699 op->reverse_code = UNKNOWN;
6700 break;
6701 default:
6702 gcc_unreachable ();
6706 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6707 using memory order MODEL. If AFTER is true the operation needs to return
6708 the value of *MEM after the operation, otherwise the previous value.
6709 TARGET is an optional place to place the result. The result is unused if
6710 it is const0_rtx.
6711 Return the result if there is a better sequence, otherwise NULL_RTX. */
6713 static rtx
6714 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6715 enum memmodel model, bool after)
6717 /* If the value is prefetched, or not used, it may be possible to replace
6718 the sequence with a native exchange operation. */
6719 if (!after || target == const0_rtx)
6721 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6722 if (code == AND && val == const0_rtx)
6724 if (target == const0_rtx)
6725 target = gen_reg_rtx (GET_MODE (mem));
6726 return maybe_emit_atomic_exchange (target, mem, val, model);
6729 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6730 if (code == IOR && val == constm1_rtx)
6732 if (target == const0_rtx)
6733 target = gen_reg_rtx (GET_MODE (mem));
6734 return maybe_emit_atomic_exchange (target, mem, val, model);
6738 return NULL_RTX;
6741 /* Try to emit an instruction for a specific operation varaition.
6742 OPTAB contains the OP functions.
6743 TARGET is an optional place to return the result. const0_rtx means unused.
6744 MEM is the memory location to operate on.
6745 VAL is the value to use in the operation.
6746 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6747 MODEL is the memory model, if used.
6748 AFTER is true if the returned result is the value after the operation. */
6750 static rtx
6751 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6752 rtx val, bool use_memmodel, enum memmodel model, bool after)
6754 machine_mode mode = GET_MODE (mem);
6755 struct expand_operand ops[4];
6756 enum insn_code icode;
6757 int op_counter = 0;
6758 int num_ops;
6760 /* Check to see if there is a result returned. */
6761 if (target == const0_rtx)
6763 if (use_memmodel)
6765 icode = direct_optab_handler (optab->mem_no_result, mode);
6766 create_integer_operand (&ops[2], model);
6767 num_ops = 3;
6769 else
6771 icode = direct_optab_handler (optab->no_result, mode);
6772 num_ops = 2;
6775 /* Otherwise, we need to generate a result. */
6776 else
6778 if (use_memmodel)
6780 icode = direct_optab_handler (after ? optab->mem_fetch_after
6781 : optab->mem_fetch_before, mode);
6782 create_integer_operand (&ops[3], model);
6783 num_ops = 4;
6785 else
6787 icode = optab_handler (after ? optab->fetch_after
6788 : optab->fetch_before, mode);
6789 num_ops = 3;
6791 create_output_operand (&ops[op_counter++], target, mode);
6793 if (icode == CODE_FOR_nothing)
6794 return NULL_RTX;
6796 create_fixed_operand (&ops[op_counter++], mem);
6797 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6798 create_convert_operand_to (&ops[op_counter++], val, mode, true);
6800 if (maybe_expand_insn (icode, num_ops, ops))
6801 return (target == const0_rtx ? const0_rtx : ops[0].value);
6803 return NULL_RTX;
6807 /* This function expands an atomic fetch_OP or OP_fetch operation:
6808 TARGET is an option place to stick the return value. const0_rtx indicates
6809 the result is unused.
6810 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6811 CODE is the operation being performed (OP)
6812 MEMMODEL is the memory model variant to use.
6813 AFTER is true to return the result of the operation (OP_fetch).
6814 AFTER is false to return the value before the operation (fetch_OP).
6816 This function will *only* generate instructions if there is a direct
6817 optab. No compare and swap loops or libcalls will be generated. */
6819 static rtx
6820 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6821 enum rtx_code code, enum memmodel model,
6822 bool after)
6824 machine_mode mode = GET_MODE (mem);
6825 struct atomic_op_functions optab;
6826 rtx result;
6827 bool unused_result = (target == const0_rtx);
6829 get_atomic_op_for_code (&optab, code);
6831 /* Check to see if there are any better instructions. */
6832 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6833 if (result)
6834 return result;
6836 /* Check for the case where the result isn't used and try those patterns. */
6837 if (unused_result)
6839 /* Try the memory model variant first. */
6840 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6841 if (result)
6842 return result;
6844 /* Next try the old style withuot a memory model. */
6845 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6846 if (result)
6847 return result;
6849 /* There is no no-result pattern, so try patterns with a result. */
6850 target = NULL_RTX;
6853 /* Try the __atomic version. */
6854 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6855 if (result)
6856 return result;
6858 /* Try the older __sync version. */
6859 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6860 if (result)
6861 return result;
6863 /* If the fetch value can be calculated from the other variation of fetch,
6864 try that operation. */
6865 if (after || unused_result || optab.reverse_code != UNKNOWN)
6867 /* Try the __atomic version, then the older __sync version. */
6868 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6869 if (!result)
6870 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6872 if (result)
6874 /* If the result isn't used, no need to do compensation code. */
6875 if (unused_result)
6876 return result;
6878 /* Issue compensation code. Fetch_after == fetch_before OP val.
6879 Fetch_before == after REVERSE_OP val. */
6880 if (!after)
6881 code = optab.reverse_code;
6882 if (code == NOT)
6884 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6885 true, OPTAB_LIB_WIDEN);
6886 result = expand_simple_unop (mode, NOT, result, target, true);
6888 else
6889 result = expand_simple_binop (mode, code, result, val, target,
6890 true, OPTAB_LIB_WIDEN);
6891 return result;
6895 /* No direct opcode can be generated. */
6896 return NULL_RTX;
6901 /* This function expands an atomic fetch_OP or OP_fetch operation:
6902 TARGET is an option place to stick the return value. const0_rtx indicates
6903 the result is unused.
6904 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6905 CODE is the operation being performed (OP)
6906 MEMMODEL is the memory model variant to use.
6907 AFTER is true to return the result of the operation (OP_fetch).
6908 AFTER is false to return the value before the operation (fetch_OP). */
6910 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6911 enum memmodel model, bool after)
6913 machine_mode mode = GET_MODE (mem);
6914 rtx result;
6915 bool unused_result = (target == const0_rtx);
6917 /* If loads are not atomic for the required size and we are not called to
6918 provide a __sync builtin, do not do anything so that we stay consistent
6919 with atomic loads of the same size. */
6920 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6921 return NULL_RTX;
6923 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6924 after);
6926 if (result)
6927 return result;
6929 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6930 if (code == PLUS || code == MINUS)
6932 rtx tmp;
6933 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6935 start_sequence ();
6936 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6937 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6938 model, after);
6939 if (result)
6941 /* PLUS worked so emit the insns and return. */
6942 tmp = get_insns ();
6943 end_sequence ();
6944 emit_insn (tmp);
6945 return result;
6948 /* PLUS did not work, so throw away the negation code and continue. */
6949 end_sequence ();
6952 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6953 if (!can_compare_and_swap_p (mode, false))
6955 rtx libfunc;
6956 bool fixup = false;
6957 enum rtx_code orig_code = code;
6958 struct atomic_op_functions optab;
6960 get_atomic_op_for_code (&optab, code);
6961 libfunc = optab_libfunc (after ? optab.fetch_after
6962 : optab.fetch_before, mode);
6963 if (libfunc == NULL
6964 && (after || unused_result || optab.reverse_code != UNKNOWN))
6966 fixup = true;
6967 if (!after)
6968 code = optab.reverse_code;
6969 libfunc = optab_libfunc (after ? optab.fetch_before
6970 : optab.fetch_after, mode);
6972 if (libfunc != NULL)
6974 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6975 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
6976 addr, ptr_mode, val, mode);
6978 if (!unused_result && fixup)
6979 result = expand_simple_binop (mode, code, result, val, target,
6980 true, OPTAB_LIB_WIDEN);
6981 return result;
6984 /* We need the original code for any further attempts. */
6985 code = orig_code;
6988 /* If nothing else has succeeded, default to a compare and swap loop. */
6989 if (can_compare_and_swap_p (mode, true))
6991 rtx_insn *insn;
6992 rtx t0 = gen_reg_rtx (mode), t1;
6994 start_sequence ();
6996 /* If the result is used, get a register for it. */
6997 if (!unused_result)
6999 if (!target || !register_operand (target, mode))
7000 target = gen_reg_rtx (mode);
7001 /* If fetch_before, copy the value now. */
7002 if (!after)
7003 emit_move_insn (target, t0);
7005 else
7006 target = const0_rtx;
7008 t1 = t0;
7009 if (code == NOT)
7011 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7012 true, OPTAB_LIB_WIDEN);
7013 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7015 else
7016 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
7017 OPTAB_LIB_WIDEN);
7019 /* For after, copy the value now. */
7020 if (!unused_result && after)
7021 emit_move_insn (target, t1);
7022 insn = get_insns ();
7023 end_sequence ();
7025 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7026 return target;
7029 return NULL_RTX;
7032 /* Return true if OPERAND is suitable for operand number OPNO of
7033 instruction ICODE. */
7035 bool
7036 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
7038 return (!insn_data[(int) icode].operand[opno].predicate
7039 || (insn_data[(int) icode].operand[opno].predicate
7040 (operand, insn_data[(int) icode].operand[opno].mode)));
7043 /* TARGET is a target of a multiword operation that we are going to
7044 implement as a series of word-mode operations. Return true if
7045 TARGET is suitable for this purpose. */
7047 bool
7048 valid_multiword_target_p (rtx target)
7050 machine_mode mode;
7051 int i, size;
7053 mode = GET_MODE (target);
7054 if (!GET_MODE_SIZE (mode).is_constant (&size))
7055 return false;
7056 for (i = 0; i < size; i += UNITS_PER_WORD)
7057 if (!validate_subreg (word_mode, mode, target, i))
7058 return false;
7059 return true;
7062 /* Make OP describe an input operand that has value INTVAL and that has
7063 no inherent mode. This function should only be used for operands that
7064 are always expand-time constants. The backend may request that INTVAL
7065 be copied into a different kind of rtx, but it must specify the mode
7066 of that rtx if so. */
7068 void
7069 create_integer_operand (struct expand_operand *op, poly_int64 intval)
7071 create_expand_operand (op, EXPAND_INTEGER,
7072 gen_int_mode (intval, MAX_MODE_INT),
7073 VOIDmode, false, intval);
7076 /* Like maybe_legitimize_operand, but do not change the code of the
7077 current rtx value. */
7079 static bool
7080 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
7081 struct expand_operand *op)
7083 /* See if the operand matches in its current form. */
7084 if (insn_operand_matches (icode, opno, op->value))
7085 return true;
7087 /* If the operand is a memory whose address has no side effects,
7088 try forcing the address into a non-virtual pseudo register.
7089 The check for side effects is important because copy_to_mode_reg
7090 cannot handle things like auto-modified addresses. */
7091 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
7093 rtx addr, mem;
7095 mem = op->value;
7096 addr = XEXP (mem, 0);
7097 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
7098 && !side_effects_p (addr))
7100 rtx_insn *last;
7101 machine_mode mode;
7103 last = get_last_insn ();
7104 mode = get_address_mode (mem);
7105 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
7106 if (insn_operand_matches (icode, opno, mem))
7108 op->value = mem;
7109 return true;
7111 delete_insns_since (last);
7115 return false;
7118 /* Try to make OP match operand OPNO of instruction ICODE. Return true
7119 on success, storing the new operand value back in OP. */
7121 static bool
7122 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
7123 struct expand_operand *op)
7125 machine_mode mode, imode;
7126 bool old_volatile_ok, result;
7128 mode = op->mode;
7129 switch (op->type)
7131 case EXPAND_FIXED:
7132 old_volatile_ok = volatile_ok;
7133 volatile_ok = true;
7134 result = maybe_legitimize_operand_same_code (icode, opno, op);
7135 volatile_ok = old_volatile_ok;
7136 return result;
7138 case EXPAND_OUTPUT:
7139 gcc_assert (mode != VOIDmode);
7140 if (op->value
7141 && op->value != const0_rtx
7142 && GET_MODE (op->value) == mode
7143 && maybe_legitimize_operand_same_code (icode, opno, op))
7144 return true;
7146 op->value = gen_reg_rtx (mode);
7147 op->target = 0;
7148 break;
7150 case EXPAND_INPUT:
7151 input:
7152 gcc_assert (mode != VOIDmode);
7153 gcc_assert (GET_MODE (op->value) == VOIDmode
7154 || GET_MODE (op->value) == mode);
7155 if (maybe_legitimize_operand_same_code (icode, opno, op))
7156 return true;
7158 op->value = copy_to_mode_reg (mode, op->value);
7159 break;
7161 case EXPAND_CONVERT_TO:
7162 gcc_assert (mode != VOIDmode);
7163 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
7164 goto input;
7166 case EXPAND_CONVERT_FROM:
7167 if (GET_MODE (op->value) != VOIDmode)
7168 mode = GET_MODE (op->value);
7169 else
7170 /* The caller must tell us what mode this value has. */
7171 gcc_assert (mode != VOIDmode);
7173 imode = insn_data[(int) icode].operand[opno].mode;
7174 if (imode != VOIDmode && imode != mode)
7176 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
7177 mode = imode;
7179 goto input;
7181 case EXPAND_ADDRESS:
7182 op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
7183 op->value);
7184 goto input;
7186 case EXPAND_INTEGER:
7187 mode = insn_data[(int) icode].operand[opno].mode;
7188 if (mode != VOIDmode
7189 && known_eq (trunc_int_for_mode (op->int_value, mode),
7190 op->int_value))
7192 op->value = gen_int_mode (op->int_value, mode);
7193 goto input;
7195 break;
7197 return insn_operand_matches (icode, opno, op->value);
7200 /* Make OP describe an input operand that should have the same value
7201 as VALUE, after any mode conversion that the target might request.
7202 TYPE is the type of VALUE. */
7204 void
7205 create_convert_operand_from_type (struct expand_operand *op,
7206 rtx value, tree type)
7208 create_convert_operand_from (op, value, TYPE_MODE (type),
7209 TYPE_UNSIGNED (type));
7212 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7213 of instruction ICODE. Return true on success, leaving the new operand
7214 values in the OPS themselves. Emit no code on failure. */
7216 bool
7217 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
7218 unsigned int nops, struct expand_operand *ops)
7220 rtx_insn *last;
7221 unsigned int i;
7223 last = get_last_insn ();
7224 for (i = 0; i < nops; i++)
7225 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
7227 delete_insns_since (last);
7228 return false;
7230 return true;
7233 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7234 as its operands. Return the instruction pattern on success,
7235 and emit any necessary set-up code. Return null and emit no
7236 code on failure. */
7238 rtx_insn *
7239 maybe_gen_insn (enum insn_code icode, unsigned int nops,
7240 struct expand_operand *ops)
7242 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
7243 if (!maybe_legitimize_operands (icode, 0, nops, ops))
7244 return NULL;
7246 switch (nops)
7248 case 1:
7249 return GEN_FCN (icode) (ops[0].value);
7250 case 2:
7251 return GEN_FCN (icode) (ops[0].value, ops[1].value);
7252 case 3:
7253 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
7254 case 4:
7255 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7256 ops[3].value);
7257 case 5:
7258 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7259 ops[3].value, ops[4].value);
7260 case 6:
7261 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7262 ops[3].value, ops[4].value, ops[5].value);
7263 case 7:
7264 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7265 ops[3].value, ops[4].value, ops[5].value,
7266 ops[6].value);
7267 case 8:
7268 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7269 ops[3].value, ops[4].value, ops[5].value,
7270 ops[6].value, ops[7].value);
7271 case 9:
7272 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7273 ops[3].value, ops[4].value, ops[5].value,
7274 ops[6].value, ops[7].value, ops[8].value);
7276 gcc_unreachable ();
7279 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7280 as its operands. Return true on success and emit no code on failure. */
7282 bool
7283 maybe_expand_insn (enum insn_code icode, unsigned int nops,
7284 struct expand_operand *ops)
7286 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7287 if (pat)
7289 emit_insn (pat);
7290 return true;
7292 return false;
7295 /* Like maybe_expand_insn, but for jumps. */
7297 bool
7298 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
7299 struct expand_operand *ops)
7301 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7302 if (pat)
7304 emit_jump_insn (pat);
7305 return true;
7307 return false;
7310 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7311 as its operands. */
7313 void
7314 expand_insn (enum insn_code icode, unsigned int nops,
7315 struct expand_operand *ops)
7317 if (!maybe_expand_insn (icode, nops, ops))
7318 gcc_unreachable ();
7321 /* Like expand_insn, but for jumps. */
7323 void
7324 expand_jump_insn (enum insn_code icode, unsigned int nops,
7325 struct expand_operand *ops)
7327 if (!maybe_expand_jump_insn (icode, nops, ops))
7328 gcc_unreachable ();