re PR bootstrap/83396 (Bootstrap failures with Statement Frontiers)
[official-gcc.git] / gcc / optabs.c
blob518ce7a972cfaa7593d44252856cf422afc6fa1f
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2017 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"
37 /* Include insn-config.h before expr.h so that HAVE_conditional_move
38 is properly defined. */
39 #include "stor-layout.h"
40 #include "except.h"
41 #include "dojump.h"
42 #include "explow.h"
43 #include "expr.h"
44 #include "optabs-tree.h"
45 #include "libfuncs.h"
47 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
48 machine_mode *);
49 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
50 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
52 /* Debug facility for use in GDB. */
53 void debug_optab_libfuncs (void);
55 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
56 the result of operation CODE applied to OP0 (and OP1 if it is a binary
57 operation).
59 If the last insn does not set TARGET, don't do anything, but return 1.
61 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
62 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
63 try again, ensuring that TARGET is not one of the operands. */
65 static int
66 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
68 rtx_insn *last_insn;
69 rtx set;
70 rtx note;
72 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
74 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
75 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
76 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
77 && GET_RTX_CLASS (code) != RTX_COMPARE
78 && GET_RTX_CLASS (code) != RTX_UNARY)
79 return 1;
81 if (GET_CODE (target) == ZERO_EXTRACT)
82 return 1;
84 for (last_insn = insns;
85 NEXT_INSN (last_insn) != NULL_RTX;
86 last_insn = NEXT_INSN (last_insn))
89 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
90 a value changing in the insn, so the note would be invalid for CSE. */
91 if (reg_overlap_mentioned_p (target, op0)
92 || (op1 && reg_overlap_mentioned_p (target, op1)))
94 if (MEM_P (target)
95 && (rtx_equal_p (target, op0)
96 || (op1 && rtx_equal_p (target, op1))))
98 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
99 over expanding it as temp = MEM op X, MEM = temp. If the target
100 supports MEM = MEM op X instructions, it is sometimes too hard
101 to reconstruct that form later, especially if X is also a memory,
102 and due to multiple occurrences of addresses the address might
103 be forced into register unnecessarily.
104 Note that not emitting the REG_EQUIV note might inhibit
105 CSE in some cases. */
106 set = single_set (last_insn);
107 if (set
108 && GET_CODE (SET_SRC (set)) == code
109 && MEM_P (SET_DEST (set))
110 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
111 || (op1 && rtx_equal_p (SET_DEST (set),
112 XEXP (SET_SRC (set), 1)))))
113 return 1;
115 return 0;
118 set = set_for_reg_notes (last_insn);
119 if (set == NULL_RTX)
120 return 1;
122 if (! rtx_equal_p (SET_DEST (set), target)
123 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
124 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
125 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
126 return 1;
128 if (GET_RTX_CLASS (code) == RTX_UNARY)
129 switch (code)
131 case FFS:
132 case CLZ:
133 case CTZ:
134 case CLRSB:
135 case POPCOUNT:
136 case PARITY:
137 case BSWAP:
138 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
140 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
141 if (GET_MODE_UNIT_SIZE (GET_MODE (op0))
142 > GET_MODE_UNIT_SIZE (GET_MODE (target)))
143 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
144 note, GET_MODE (op0));
145 else
146 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
147 note, GET_MODE (op0));
148 break;
150 /* FALLTHRU */
151 default:
152 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
153 break;
155 else
156 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
158 set_unique_reg_note (last_insn, REG_EQUAL, note);
160 return 1;
163 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
164 for a widening operation would be. In most cases this would be OP0, but if
165 that's a constant it'll be VOIDmode, which isn't useful. */
167 static machine_mode
168 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
170 machine_mode m0 = GET_MODE (op0);
171 machine_mode m1 = GET_MODE (op1);
172 machine_mode result;
174 if (m0 == VOIDmode && m1 == VOIDmode)
175 return to_mode;
176 else if (m0 == VOIDmode || GET_MODE_UNIT_SIZE (m0) < GET_MODE_UNIT_SIZE (m1))
177 result = m1;
178 else
179 result = m0;
181 if (GET_MODE_UNIT_SIZE (result) > GET_MODE_UNIT_SIZE (to_mode))
182 return to_mode;
184 return result;
187 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
188 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
189 not actually do a sign-extend or zero-extend, but can leave the
190 higher-order bits of the result rtx undefined, for example, in the case
191 of logical operations, but not right shifts. */
193 static rtx
194 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
195 int unsignedp, int no_extend)
197 rtx result;
198 scalar_int_mode int_mode;
200 /* If we don't have to extend and this is a constant, return it. */
201 if (no_extend && GET_MODE (op) == VOIDmode)
202 return op;
204 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
205 extend since it will be more efficient to do so unless the signedness of
206 a promoted object differs from our extension. */
207 if (! no_extend
208 || !is_a <scalar_int_mode> (mode, &int_mode)
209 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
210 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
211 return convert_modes (mode, oldmode, op, unsignedp);
213 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
214 SUBREG. */
215 if (GET_MODE_SIZE (int_mode) <= UNITS_PER_WORD)
216 return gen_lowpart (int_mode, force_reg (GET_MODE (op), op));
218 /* Otherwise, get an object of MODE, clobber it, and set the low-order
219 part to OP. */
221 result = gen_reg_rtx (int_mode);
222 emit_clobber (result);
223 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
224 return result;
227 /* Expand vector widening operations.
229 There are two different classes of operations handled here:
230 1) Operations whose result is wider than all the arguments to the operation.
231 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
232 In this case OP0 and optionally OP1 would be initialized,
233 but WIDE_OP wouldn't (not relevant for this case).
234 2) Operations whose result is of the same size as the last argument to the
235 operation, but wider than all the other arguments to the operation.
236 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
237 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
239 E.g, when called to expand the following operations, this is how
240 the arguments will be initialized:
241 nops OP0 OP1 WIDE_OP
242 widening-sum 2 oprnd0 - oprnd1
243 widening-dot-product 3 oprnd0 oprnd1 oprnd2
244 widening-mult 2 oprnd0 oprnd1 -
245 type-promotion (vec-unpack) 1 oprnd0 - - */
248 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
249 rtx target, int unsignedp)
251 struct expand_operand eops[4];
252 tree oprnd0, oprnd1, oprnd2;
253 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
254 optab widen_pattern_optab;
255 enum insn_code icode;
256 int nops = TREE_CODE_LENGTH (ops->code);
257 int op;
259 oprnd0 = ops->op0;
260 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
261 widen_pattern_optab =
262 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
263 if (ops->code == WIDEN_MULT_PLUS_EXPR
264 || ops->code == WIDEN_MULT_MINUS_EXPR)
265 icode = find_widening_optab_handler (widen_pattern_optab,
266 TYPE_MODE (TREE_TYPE (ops->op2)),
267 tmode0);
268 else
269 icode = optab_handler (widen_pattern_optab, tmode0);
270 gcc_assert (icode != CODE_FOR_nothing);
272 if (nops >= 2)
274 oprnd1 = ops->op1;
275 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
278 /* The last operand is of a wider mode than the rest of the operands. */
279 if (nops == 2)
280 wmode = tmode1;
281 else if (nops == 3)
283 gcc_assert (tmode1 == tmode0);
284 gcc_assert (op1);
285 oprnd2 = ops->op2;
286 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
289 op = 0;
290 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
291 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
292 if (op1)
293 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
294 if (wide_op)
295 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
296 expand_insn (icode, op, eops);
297 return eops[0].value;
300 /* Generate code to perform an operation specified by TERNARY_OPTAB
301 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
303 UNSIGNEDP is for the case where we have to widen the operands
304 to perform the operation. It says to use zero-extension.
306 If TARGET is nonzero, the value
307 is generated there, if it is convenient to do so.
308 In all cases an rtx is returned for the locus of the value;
309 this may or may not be TARGET. */
312 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
313 rtx op1, rtx op2, rtx target, int unsignedp)
315 struct expand_operand ops[4];
316 enum insn_code icode = optab_handler (ternary_optab, mode);
318 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
320 create_output_operand (&ops[0], target, mode);
321 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
322 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
323 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
324 expand_insn (icode, 4, ops);
325 return ops[0].value;
329 /* Like expand_binop, but return a constant rtx if the result can be
330 calculated at compile time. The arguments and return value are
331 otherwise the same as for expand_binop. */
334 simplify_expand_binop (machine_mode mode, optab binoptab,
335 rtx op0, rtx op1, rtx target, int unsignedp,
336 enum optab_methods methods)
338 if (CONSTANT_P (op0) && CONSTANT_P (op1))
340 rtx x = simplify_binary_operation (optab_to_code (binoptab),
341 mode, op0, op1);
342 if (x)
343 return x;
346 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
349 /* Like simplify_expand_binop, but always put the result in TARGET.
350 Return true if the expansion succeeded. */
352 bool
353 force_expand_binop (machine_mode mode, optab binoptab,
354 rtx op0, rtx op1, rtx target, int unsignedp,
355 enum optab_methods methods)
357 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
358 target, unsignedp, methods);
359 if (x == 0)
360 return false;
361 if (x != target)
362 emit_move_insn (target, x);
363 return true;
366 /* Create a new vector value in VMODE with all elements set to OP. The
367 mode of OP must be the element mode of VMODE. If OP is a constant,
368 then the return value will be a constant. */
370 static rtx
371 expand_vector_broadcast (machine_mode vmode, rtx op)
373 enum insn_code icode;
374 rtvec vec;
375 rtx ret;
376 int i, n;
378 gcc_checking_assert (VECTOR_MODE_P (vmode));
380 if (valid_for_const_vec_duplicate_p (vmode, op))
381 return gen_const_vec_duplicate (vmode, op);
383 /* ??? If the target doesn't have a vec_init, then we have no easy way
384 of performing this operation. Most of this sort of generic support
385 is hidden away in the vector lowering support in gimple. */
386 icode = convert_optab_handler (vec_init_optab, vmode,
387 GET_MODE_INNER (vmode));
388 if (icode == CODE_FOR_nothing)
389 return NULL;
391 n = GET_MODE_NUNITS (vmode);
392 vec = rtvec_alloc (n);
393 for (i = 0; i < n; ++i)
394 RTVEC_ELT (vec, i) = op;
395 ret = gen_reg_rtx (vmode);
396 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
398 return ret;
401 /* This subroutine of expand_doubleword_shift handles the cases in which
402 the effective shift value is >= BITS_PER_WORD. The arguments and return
403 value are the same as for the parent routine, except that SUPERWORD_OP1
404 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
405 INTO_TARGET may be null if the caller has decided to calculate it. */
407 static bool
408 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
409 rtx outof_target, rtx into_target,
410 int unsignedp, enum optab_methods methods)
412 if (into_target != 0)
413 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
414 into_target, unsignedp, methods))
415 return false;
417 if (outof_target != 0)
419 /* For a signed right shift, we must fill OUTOF_TARGET with copies
420 of the sign bit, otherwise we must fill it with zeros. */
421 if (binoptab != ashr_optab)
422 emit_move_insn (outof_target, CONST0_RTX (word_mode));
423 else
424 if (!force_expand_binop (word_mode, binoptab,
425 outof_input, GEN_INT (BITS_PER_WORD - 1),
426 outof_target, unsignedp, methods))
427 return false;
429 return true;
432 /* This subroutine of expand_doubleword_shift handles the cases in which
433 the effective shift value is < BITS_PER_WORD. The arguments and return
434 value are the same as for the parent routine. */
436 static bool
437 expand_subword_shift (scalar_int_mode op1_mode, optab binoptab,
438 rtx outof_input, rtx into_input, rtx op1,
439 rtx outof_target, rtx into_target,
440 int unsignedp, enum optab_methods methods,
441 unsigned HOST_WIDE_INT shift_mask)
443 optab reverse_unsigned_shift, unsigned_shift;
444 rtx tmp, carries;
446 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
447 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
449 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
450 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
451 the opposite direction to BINOPTAB. */
452 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
454 carries = outof_input;
455 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
456 op1_mode), op1_mode);
457 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
458 0, true, methods);
460 else
462 /* We must avoid shifting by BITS_PER_WORD bits since that is either
463 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
464 has unknown behavior. Do a single shift first, then shift by the
465 remainder. It's OK to use ~OP1 as the remainder if shift counts
466 are truncated to the mode size. */
467 carries = expand_binop (word_mode, reverse_unsigned_shift,
468 outof_input, const1_rtx, 0, unsignedp, methods);
469 if (shift_mask == BITS_PER_WORD - 1)
471 tmp = immed_wide_int_const
472 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
473 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
474 0, true, methods);
476 else
478 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
479 op1_mode), op1_mode);
480 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
481 0, true, methods);
484 if (tmp == 0 || carries == 0)
485 return false;
486 carries = expand_binop (word_mode, reverse_unsigned_shift,
487 carries, tmp, 0, unsignedp, methods);
488 if (carries == 0)
489 return false;
491 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
492 so the result can go directly into INTO_TARGET if convenient. */
493 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
494 into_target, unsignedp, methods);
495 if (tmp == 0)
496 return false;
498 /* Now OR in the bits carried over from OUTOF_INPUT. */
499 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
500 into_target, unsignedp, methods))
501 return false;
503 /* Use a standard word_mode shift for the out-of half. */
504 if (outof_target != 0)
505 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
506 outof_target, unsignedp, methods))
507 return false;
509 return true;
513 /* Try implementing expand_doubleword_shift using conditional moves.
514 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
515 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
516 are the shift counts to use in the former and latter case. All other
517 arguments are the same as the parent routine. */
519 static bool
520 expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
521 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
522 rtx outof_input, rtx into_input,
523 rtx subword_op1, rtx superword_op1,
524 rtx outof_target, rtx into_target,
525 int unsignedp, enum optab_methods methods,
526 unsigned HOST_WIDE_INT shift_mask)
528 rtx outof_superword, into_superword;
530 /* Put the superword version of the output into OUTOF_SUPERWORD and
531 INTO_SUPERWORD. */
532 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
533 if (outof_target != 0 && subword_op1 == superword_op1)
535 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
536 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
537 into_superword = outof_target;
538 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
539 outof_superword, 0, unsignedp, methods))
540 return false;
542 else
544 into_superword = gen_reg_rtx (word_mode);
545 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
546 outof_superword, into_superword,
547 unsignedp, methods))
548 return false;
551 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
552 if (!expand_subword_shift (op1_mode, binoptab,
553 outof_input, into_input, subword_op1,
554 outof_target, into_target,
555 unsignedp, methods, shift_mask))
556 return false;
558 /* Select between them. Do the INTO half first because INTO_SUPERWORD
559 might be the current value of OUTOF_TARGET. */
560 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
561 into_target, into_superword, word_mode, false))
562 return false;
564 if (outof_target != 0)
565 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
566 outof_target, outof_superword,
567 word_mode, false))
568 return false;
570 return true;
573 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
574 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
575 input operand; the shift moves bits in the direction OUTOF_INPUT->
576 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
577 of the target. OP1 is the shift count and OP1_MODE is its mode.
578 If OP1 is constant, it will have been truncated as appropriate
579 and is known to be nonzero.
581 If SHIFT_MASK is zero, the result of word shifts is undefined when the
582 shift count is outside the range [0, BITS_PER_WORD). This routine must
583 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
585 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
586 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
587 fill with zeros or sign bits as appropriate.
589 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
590 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
591 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
592 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
593 are undefined.
595 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
596 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
597 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
598 function wants to calculate it itself.
600 Return true if the shift could be successfully synthesized. */
602 static bool
603 expand_doubleword_shift (scalar_int_mode op1_mode, optab binoptab,
604 rtx outof_input, rtx into_input, rtx op1,
605 rtx outof_target, rtx into_target,
606 int unsignedp, enum optab_methods methods,
607 unsigned HOST_WIDE_INT shift_mask)
609 rtx superword_op1, tmp, cmp1, cmp2;
610 enum rtx_code cmp_code;
612 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
613 fill the result with sign or zero bits as appropriate. If so, the value
614 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
615 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
616 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
618 This isn't worthwhile for constant shifts since the optimizers will
619 cope better with in-range shift counts. */
620 if (shift_mask >= BITS_PER_WORD
621 && outof_target != 0
622 && !CONSTANT_P (op1))
624 if (!expand_doubleword_shift (op1_mode, binoptab,
625 outof_input, into_input, op1,
626 0, into_target,
627 unsignedp, methods, shift_mask))
628 return false;
629 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
630 outof_target, unsignedp, methods))
631 return false;
632 return true;
635 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
636 is true when the effective shift value is less than BITS_PER_WORD.
637 Set SUPERWORD_OP1 to the shift count that should be used to shift
638 OUTOF_INPUT into INTO_TARGET when the condition is false. */
639 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
640 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
642 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
643 is a subword shift count. */
644 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
645 0, true, methods);
646 cmp2 = CONST0_RTX (op1_mode);
647 cmp_code = EQ;
648 superword_op1 = op1;
650 else
652 /* Set CMP1 to OP1 - BITS_PER_WORD. */
653 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
654 0, true, methods);
655 cmp2 = CONST0_RTX (op1_mode);
656 cmp_code = LT;
657 superword_op1 = cmp1;
659 if (cmp1 == 0)
660 return false;
662 /* If we can compute the condition at compile time, pick the
663 appropriate subroutine. */
664 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
665 if (tmp != 0 && CONST_INT_P (tmp))
667 if (tmp == const0_rtx)
668 return expand_superword_shift (binoptab, outof_input, superword_op1,
669 outof_target, into_target,
670 unsignedp, methods);
671 else
672 return expand_subword_shift (op1_mode, binoptab,
673 outof_input, into_input, op1,
674 outof_target, into_target,
675 unsignedp, methods, shift_mask);
678 /* Try using conditional moves to generate straight-line code. */
679 if (HAVE_conditional_move)
681 rtx_insn *start = get_last_insn ();
682 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
683 cmp_code, cmp1, cmp2,
684 outof_input, into_input,
685 op1, superword_op1,
686 outof_target, into_target,
687 unsignedp, methods, shift_mask))
688 return true;
689 delete_insns_since (start);
692 /* As a last resort, use branches to select the correct alternative. */
693 rtx_code_label *subword_label = gen_label_rtx ();
694 rtx_code_label *done_label = gen_label_rtx ();
696 NO_DEFER_POP;
697 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
698 0, 0, subword_label,
699 profile_probability::uninitialized ());
700 OK_DEFER_POP;
702 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
703 outof_target, into_target,
704 unsignedp, methods))
705 return false;
707 emit_jump_insn (targetm.gen_jump (done_label));
708 emit_barrier ();
709 emit_label (subword_label);
711 if (!expand_subword_shift (op1_mode, binoptab,
712 outof_input, into_input, op1,
713 outof_target, into_target,
714 unsignedp, methods, shift_mask))
715 return false;
717 emit_label (done_label);
718 return true;
721 /* Subroutine of expand_binop. Perform a double word multiplication of
722 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
723 as the target's word_mode. This function return NULL_RTX if anything
724 goes wrong, in which case it may have already emitted instructions
725 which need to be deleted.
727 If we want to multiply two two-word values and have normal and widening
728 multiplies of single-word values, we can do this with three smaller
729 multiplications.
731 The multiplication proceeds as follows:
732 _______________________
733 [__op0_high_|__op0_low__]
734 _______________________
735 * [__op1_high_|__op1_low__]
736 _______________________________________________
737 _______________________
738 (1) [__op0_low__*__op1_low__]
739 _______________________
740 (2a) [__op0_low__*__op1_high_]
741 _______________________
742 (2b) [__op0_high_*__op1_low__]
743 _______________________
744 (3) [__op0_high_*__op1_high_]
747 This gives a 4-word result. Since we are only interested in the
748 lower 2 words, partial result (3) and the upper words of (2a) and
749 (2b) don't need to be calculated. Hence (2a) and (2b) can be
750 calculated using non-widening multiplication.
752 (1), however, needs to be calculated with an unsigned widening
753 multiplication. If this operation is not directly supported we
754 try using a signed widening multiplication and adjust the result.
755 This adjustment works as follows:
757 If both operands are positive then no adjustment is needed.
759 If the operands have different signs, for example op0_low < 0 and
760 op1_low >= 0, the instruction treats the most significant bit of
761 op0_low as a sign bit instead of a bit with significance
762 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
763 with 2**BITS_PER_WORD - op0_low, and two's complements the
764 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
765 the result.
767 Similarly, if both operands are negative, we need to add
768 (op0_low + op1_low) * 2**BITS_PER_WORD.
770 We use a trick to adjust quickly. We logically shift op0_low right
771 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
772 op0_high (op1_high) before it is used to calculate 2b (2a). If no
773 logical shift exists, we do an arithmetic right shift and subtract
774 the 0 or -1. */
776 static rtx
777 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
778 bool umulp, enum optab_methods methods)
780 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
781 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
782 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
783 rtx product, adjust, product_high, temp;
785 rtx op0_high = operand_subword_force (op0, high, mode);
786 rtx op0_low = operand_subword_force (op0, low, mode);
787 rtx op1_high = operand_subword_force (op1, high, mode);
788 rtx op1_low = operand_subword_force (op1, low, mode);
790 /* If we're using an unsigned multiply to directly compute the product
791 of the low-order words of the operands and perform any required
792 adjustments of the operands, we begin by trying two more multiplications
793 and then computing the appropriate sum.
795 We have checked above that the required addition is provided.
796 Full-word addition will normally always succeed, especially if
797 it is provided at all, so we don't worry about its failure. The
798 multiplication may well fail, however, so we do handle that. */
800 if (!umulp)
802 /* ??? This could be done with emit_store_flag where available. */
803 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
804 NULL_RTX, 1, methods);
805 if (temp)
806 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
807 NULL_RTX, 0, OPTAB_DIRECT);
808 else
810 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
811 NULL_RTX, 0, methods);
812 if (!temp)
813 return NULL_RTX;
814 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
815 NULL_RTX, 0, OPTAB_DIRECT);
818 if (!op0_high)
819 return NULL_RTX;
822 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
823 NULL_RTX, 0, OPTAB_DIRECT);
824 if (!adjust)
825 return NULL_RTX;
827 /* OP0_HIGH should now be dead. */
829 if (!umulp)
831 /* ??? This could be done with emit_store_flag where available. */
832 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
833 NULL_RTX, 1, methods);
834 if (temp)
835 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
836 NULL_RTX, 0, OPTAB_DIRECT);
837 else
839 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
840 NULL_RTX, 0, methods);
841 if (!temp)
842 return NULL_RTX;
843 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
844 NULL_RTX, 0, OPTAB_DIRECT);
847 if (!op1_high)
848 return NULL_RTX;
851 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
852 NULL_RTX, 0, OPTAB_DIRECT);
853 if (!temp)
854 return NULL_RTX;
856 /* OP1_HIGH should now be dead. */
858 adjust = expand_binop (word_mode, add_optab, adjust, temp,
859 NULL_RTX, 0, OPTAB_DIRECT);
861 if (target && !REG_P (target))
862 target = NULL_RTX;
864 /* *_widen_optab needs to determine operand mode, make sure at least
865 one operand has non-VOID mode. */
866 if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
867 op0_low = force_reg (word_mode, op0_low);
869 if (umulp)
870 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
871 target, 1, OPTAB_DIRECT);
872 else
873 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
874 target, 1, OPTAB_DIRECT);
876 if (!product)
877 return NULL_RTX;
879 product_high = operand_subword (product, high, 1, mode);
880 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
881 NULL_RTX, 0, OPTAB_DIRECT);
882 emit_move_insn (product_high, adjust);
883 return product;
886 /* Wrapper around expand_binop which takes an rtx code to specify
887 the operation to perform, not an optab pointer. All other
888 arguments are the same. */
890 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
891 rtx op1, rtx target, int unsignedp,
892 enum optab_methods methods)
894 optab binop = code_to_optab (code);
895 gcc_assert (binop);
897 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
900 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
901 binop. Order them according to commutative_operand_precedence and, if
902 possible, try to put TARGET or a pseudo first. */
903 static bool
904 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
906 int op0_prec = commutative_operand_precedence (op0);
907 int op1_prec = commutative_operand_precedence (op1);
909 if (op0_prec < op1_prec)
910 return true;
912 if (op0_prec > op1_prec)
913 return false;
915 /* With equal precedence, both orders are ok, but it is better if the
916 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
917 if (target == 0 || REG_P (target))
918 return (REG_P (op1) && !REG_P (op0)) || target == op1;
919 else
920 return rtx_equal_p (op1, target);
923 /* Return true if BINOPTAB implements a shift operation. */
925 static bool
926 shift_optab_p (optab binoptab)
928 switch (optab_to_code (binoptab))
930 case ASHIFT:
931 case SS_ASHIFT:
932 case US_ASHIFT:
933 case ASHIFTRT:
934 case LSHIFTRT:
935 case ROTATE:
936 case ROTATERT:
937 return true;
939 default:
940 return false;
944 /* Return true if BINOPTAB implements a commutative binary operation. */
946 static bool
947 commutative_optab_p (optab binoptab)
949 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
950 || binoptab == smul_widen_optab
951 || binoptab == umul_widen_optab
952 || binoptab == smul_highpart_optab
953 || binoptab == umul_highpart_optab);
956 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
957 optimizing, and if the operand is a constant that costs more than
958 1 instruction, force the constant into a register and return that
959 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
961 static rtx
962 avoid_expensive_constant (machine_mode mode, optab binoptab,
963 int opn, rtx x, bool unsignedp)
965 bool speed = optimize_insn_for_speed_p ();
967 if (mode != VOIDmode
968 && optimize
969 && CONSTANT_P (x)
970 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
971 > set_src_cost (x, mode, speed)))
973 if (CONST_INT_P (x))
975 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
976 if (intval != INTVAL (x))
977 x = GEN_INT (intval);
979 else
980 x = convert_modes (mode, VOIDmode, x, unsignedp);
981 x = force_reg (mode, x);
983 return x;
986 /* Helper function for expand_binop: handle the case where there
987 is an insn ICODE that directly implements the indicated operation.
988 Returns null if this is not possible. */
989 static rtx
990 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
991 rtx op0, rtx op1,
992 rtx target, int unsignedp, enum optab_methods methods,
993 rtx_insn *last)
995 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
996 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
997 machine_mode mode0, mode1, tmp_mode;
998 struct expand_operand ops[3];
999 bool commutative_p;
1000 rtx_insn *pat;
1001 rtx xop0 = op0, xop1 = op1;
1002 bool canonicalize_op1 = false;
1004 /* If it is a commutative operator and the modes would match
1005 if we would swap the operands, we can save the conversions. */
1006 commutative_p = commutative_optab_p (binoptab);
1007 if (commutative_p
1008 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1009 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1010 std::swap (xop0, xop1);
1012 /* If we are optimizing, force expensive constants into a register. */
1013 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1014 if (!shift_optab_p (binoptab))
1015 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1016 else
1017 /* Shifts and rotates often use a different mode for op1 from op0;
1018 for VOIDmode constants we don't know the mode, so force it
1019 to be canonicalized using convert_modes. */
1020 canonicalize_op1 = true;
1022 /* In case the insn wants input operands in modes different from
1023 those of the actual operands, convert the operands. It would
1024 seem that we don't need to convert CONST_INTs, but we do, so
1025 that they're properly zero-extended, sign-extended or truncated
1026 for their mode. */
1028 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1029 if (xmode0 != VOIDmode && xmode0 != mode0)
1031 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1032 mode0 = xmode0;
1035 mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
1036 ? GET_MODE (xop1) : mode);
1037 if (xmode1 != VOIDmode && xmode1 != mode1)
1039 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1040 mode1 = xmode1;
1043 /* If operation is commutative,
1044 try to make the first operand a register.
1045 Even better, try to make it the same as the target.
1046 Also try to make the last operand a constant. */
1047 if (commutative_p
1048 && swap_commutative_operands_with_target (target, xop0, xop1))
1049 std::swap (xop0, xop1);
1051 /* Now, if insn's predicates don't allow our operands, put them into
1052 pseudo regs. */
1054 if (binoptab == vec_pack_trunc_optab
1055 || binoptab == vec_pack_usat_optab
1056 || binoptab == vec_pack_ssat_optab
1057 || binoptab == vec_pack_ufix_trunc_optab
1058 || binoptab == vec_pack_sfix_trunc_optab)
1060 /* The mode of the result is different then the mode of the
1061 arguments. */
1062 tmp_mode = insn_data[(int) icode].operand[0].mode;
1063 if (VECTOR_MODE_P (mode)
1064 && GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1066 delete_insns_since (last);
1067 return NULL_RTX;
1070 else
1071 tmp_mode = mode;
1073 create_output_operand (&ops[0], target, tmp_mode);
1074 create_input_operand (&ops[1], xop0, mode0);
1075 create_input_operand (&ops[2], xop1, mode1);
1076 pat = maybe_gen_insn (icode, 3, ops);
1077 if (pat)
1079 /* If PAT is composed of more than one insn, try to add an appropriate
1080 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1081 operand, call expand_binop again, this time without a target. */
1082 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1083 && ! add_equal_note (pat, ops[0].value,
1084 optab_to_code (binoptab),
1085 ops[1].value, ops[2].value))
1087 delete_insns_since (last);
1088 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1089 unsignedp, methods);
1092 emit_insn (pat);
1093 return ops[0].value;
1095 delete_insns_since (last);
1096 return NULL_RTX;
1099 /* Generate code to perform an operation specified by BINOPTAB
1100 on operands OP0 and OP1, with result having machine-mode MODE.
1102 UNSIGNEDP is for the case where we have to widen the operands
1103 to perform the operation. It says to use zero-extension.
1105 If TARGET is nonzero, the value
1106 is generated there, if it is convenient to do so.
1107 In all cases an rtx is returned for the locus of the value;
1108 this may or may not be TARGET. */
1111 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1112 rtx target, int unsignedp, enum optab_methods methods)
1114 enum optab_methods next_methods
1115 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1116 ? OPTAB_WIDEN : methods);
1117 enum mode_class mclass;
1118 enum insn_code icode;
1119 machine_mode wider_mode;
1120 scalar_int_mode int_mode;
1121 rtx libfunc;
1122 rtx temp;
1123 rtx_insn *entry_last = get_last_insn ();
1124 rtx_insn *last;
1126 mclass = GET_MODE_CLASS (mode);
1128 /* If subtracting an integer constant, convert this into an addition of
1129 the negated constant. */
1131 if (binoptab == sub_optab && CONST_INT_P (op1))
1133 op1 = negate_rtx (mode, op1);
1134 binoptab = add_optab;
1136 /* For shifts, constant invalid op1 might be expanded from different
1137 mode than MODE. As those are invalid, force them to a register
1138 to avoid further problems during expansion. */
1139 else if (CONST_INT_P (op1)
1140 && shift_optab_p (binoptab)
1141 && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode)))
1143 op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode));
1144 op1 = force_reg (GET_MODE_INNER (mode), op1);
1147 /* Record where to delete back to if we backtrack. */
1148 last = get_last_insn ();
1150 /* If we can do it with a three-operand insn, do so. */
1152 if (methods != OPTAB_MUST_WIDEN)
1154 if (convert_optab_p (binoptab))
1156 machine_mode from_mode = widened_mode (mode, op0, op1);
1157 icode = find_widening_optab_handler (binoptab, mode, from_mode);
1159 else
1160 icode = optab_handler (binoptab, mode);
1161 if (icode != CODE_FOR_nothing)
1163 temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
1164 target, unsignedp, methods, last);
1165 if (temp)
1166 return temp;
1170 /* If we were trying to rotate, and that didn't work, try rotating
1171 the other direction before falling back to shifts and bitwise-or. */
1172 if (((binoptab == rotl_optab
1173 && (icode = optab_handler (rotr_optab, mode)) != CODE_FOR_nothing)
1174 || (binoptab == rotr_optab
1175 && (icode = optab_handler (rotl_optab, mode)) != CODE_FOR_nothing))
1176 && is_int_mode (mode, &int_mode))
1178 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1179 rtx newop1;
1180 unsigned int bits = GET_MODE_PRECISION (int_mode);
1182 if (CONST_INT_P (op1))
1183 newop1 = GEN_INT (bits - INTVAL (op1));
1184 else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
1185 newop1 = negate_rtx (GET_MODE (op1), op1);
1186 else
1187 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1188 gen_int_mode (bits, GET_MODE (op1)), op1,
1189 NULL_RTX, unsignedp, OPTAB_DIRECT);
1191 temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
1192 target, unsignedp, methods, last);
1193 if (temp)
1194 return temp;
1197 /* If this is a multiply, see if we can do a widening operation that
1198 takes operands of this mode and makes a wider mode. */
1200 if (binoptab == smul_optab
1201 && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
1202 && (convert_optab_handler ((unsignedp
1203 ? umul_widen_optab
1204 : smul_widen_optab),
1205 wider_mode, mode) != CODE_FOR_nothing))
1207 /* *_widen_optab needs to determine operand mode, make sure at least
1208 one operand has non-VOID mode. */
1209 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
1210 op0 = force_reg (mode, op0);
1211 temp = expand_binop (wider_mode,
1212 unsignedp ? umul_widen_optab : smul_widen_optab,
1213 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1215 if (temp != 0)
1217 if (GET_MODE_CLASS (mode) == MODE_INT
1218 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1219 return gen_lowpart (mode, temp);
1220 else
1221 return convert_to_mode (mode, temp, unsignedp);
1225 /* If this is a vector shift by a scalar, see if we can do a vector
1226 shift by a vector. If so, broadcast the scalar into a vector. */
1227 if (mclass == MODE_VECTOR_INT)
1229 optab otheroptab = unknown_optab;
1231 if (binoptab == ashl_optab)
1232 otheroptab = vashl_optab;
1233 else if (binoptab == ashr_optab)
1234 otheroptab = vashr_optab;
1235 else if (binoptab == lshr_optab)
1236 otheroptab = vlshr_optab;
1237 else if (binoptab == rotl_optab)
1238 otheroptab = vrotl_optab;
1239 else if (binoptab == rotr_optab)
1240 otheroptab = vrotr_optab;
1242 if (otheroptab
1243 && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
1245 /* The scalar may have been extended to be too wide. Truncate
1246 it back to the proper size to fit in the broadcast vector. */
1247 scalar_mode inner_mode = GET_MODE_INNER (mode);
1248 if (!CONST_INT_P (op1)
1249 && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
1250 > GET_MODE_BITSIZE (inner_mode)))
1251 op1 = force_reg (inner_mode,
1252 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1253 GET_MODE (op1)));
1254 rtx vop1 = expand_vector_broadcast (mode, op1);
1255 if (vop1)
1257 temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
1258 target, unsignedp, methods, last);
1259 if (temp)
1260 return temp;
1265 /* Look for a wider mode of the same class for which we think we
1266 can open-code the operation. Check for a widening multiply at the
1267 wider mode as well. */
1269 if (CLASS_HAS_WIDER_MODES_P (mclass)
1270 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1271 FOR_EACH_WIDER_MODE (wider_mode, mode)
1273 machine_mode next_mode;
1274 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1275 || (binoptab == smul_optab
1276 && GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
1277 && (find_widening_optab_handler ((unsignedp
1278 ? umul_widen_optab
1279 : smul_widen_optab),
1280 next_mode, mode)
1281 != CODE_FOR_nothing)))
1283 rtx xop0 = op0, xop1 = op1;
1284 int no_extend = 0;
1286 /* For certain integer operations, we need not actually extend
1287 the narrow operands, as long as we will truncate
1288 the results to the same narrowness. */
1290 if ((binoptab == ior_optab || binoptab == and_optab
1291 || binoptab == xor_optab
1292 || binoptab == add_optab || binoptab == sub_optab
1293 || binoptab == smul_optab || binoptab == ashl_optab)
1294 && mclass == MODE_INT)
1296 no_extend = 1;
1297 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1298 xop0, unsignedp);
1299 if (binoptab != ashl_optab)
1300 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1301 xop1, unsignedp);
1304 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1306 /* The second operand of a shift must always be extended. */
1307 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1308 no_extend && binoptab != ashl_optab);
1310 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1311 unsignedp, OPTAB_DIRECT);
1312 if (temp)
1314 if (mclass != MODE_INT
1315 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1317 if (target == 0)
1318 target = gen_reg_rtx (mode);
1319 convert_move (target, temp, 0);
1320 return target;
1322 else
1323 return gen_lowpart (mode, temp);
1325 else
1326 delete_insns_since (last);
1330 /* If operation is commutative,
1331 try to make the first operand a register.
1332 Even better, try to make it the same as the target.
1333 Also try to make the last operand a constant. */
1334 if (commutative_optab_p (binoptab)
1335 && swap_commutative_operands_with_target (target, op0, op1))
1336 std::swap (op0, op1);
1338 /* These can be done a word at a time. */
1339 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1340 && is_int_mode (mode, &int_mode)
1341 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
1342 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1344 int i;
1345 rtx_insn *insns;
1347 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1348 won't be accurate, so use a new target. */
1349 if (target == 0
1350 || target == op0
1351 || target == op1
1352 || !valid_multiword_target_p (target))
1353 target = gen_reg_rtx (int_mode);
1355 start_sequence ();
1357 /* Do the actual arithmetic. */
1358 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
1360 rtx target_piece = operand_subword (target, i, 1, int_mode);
1361 rtx x = expand_binop (word_mode, binoptab,
1362 operand_subword_force (op0, i, int_mode),
1363 operand_subword_force (op1, i, int_mode),
1364 target_piece, unsignedp, next_methods);
1366 if (x == 0)
1367 break;
1369 if (target_piece != x)
1370 emit_move_insn (target_piece, x);
1373 insns = get_insns ();
1374 end_sequence ();
1376 if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
1378 emit_insn (insns);
1379 return target;
1383 /* Synthesize double word shifts from single word shifts. */
1384 if ((binoptab == lshr_optab || binoptab == ashl_optab
1385 || binoptab == ashr_optab)
1386 && is_int_mode (mode, &int_mode)
1387 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1388 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1389 && GET_MODE_PRECISION (int_mode) == GET_MODE_BITSIZE (int_mode)
1390 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1391 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1392 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1394 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1395 scalar_int_mode op1_mode;
1397 double_shift_mask = targetm.shift_truncation_mask (int_mode);
1398 shift_mask = targetm.shift_truncation_mask (word_mode);
1399 op1_mode = (GET_MODE (op1) != VOIDmode
1400 ? as_a <scalar_int_mode> (GET_MODE (op1))
1401 : word_mode);
1403 /* Apply the truncation to constant shifts. */
1404 if (double_shift_mask > 0 && CONST_INT_P (op1))
1405 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1407 if (op1 == CONST0_RTX (op1_mode))
1408 return op0;
1410 /* Make sure that this is a combination that expand_doubleword_shift
1411 can handle. See the comments there for details. */
1412 if (double_shift_mask == 0
1413 || (shift_mask == BITS_PER_WORD - 1
1414 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1416 rtx_insn *insns;
1417 rtx into_target, outof_target;
1418 rtx into_input, outof_input;
1419 int left_shift, outof_word;
1421 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1422 won't be accurate, so use a new target. */
1423 if (target == 0
1424 || target == op0
1425 || target == op1
1426 || !valid_multiword_target_p (target))
1427 target = gen_reg_rtx (int_mode);
1429 start_sequence ();
1431 /* OUTOF_* is the word we are shifting bits away from, and
1432 INTO_* is the word that we are shifting bits towards, thus
1433 they differ depending on the direction of the shift and
1434 WORDS_BIG_ENDIAN. */
1436 left_shift = binoptab == ashl_optab;
1437 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1439 outof_target = operand_subword (target, outof_word, 1, int_mode);
1440 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1442 outof_input = operand_subword_force (op0, outof_word, int_mode);
1443 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1445 if (expand_doubleword_shift (op1_mode, binoptab,
1446 outof_input, into_input, op1,
1447 outof_target, into_target,
1448 unsignedp, next_methods, shift_mask))
1450 insns = get_insns ();
1451 end_sequence ();
1453 emit_insn (insns);
1454 return target;
1456 end_sequence ();
1460 /* Synthesize double word rotates from single word shifts. */
1461 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1462 && is_int_mode (mode, &int_mode)
1463 && CONST_INT_P (op1)
1464 && GET_MODE_PRECISION (int_mode) == 2 * BITS_PER_WORD
1465 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1466 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1468 rtx_insn *insns;
1469 rtx into_target, outof_target;
1470 rtx into_input, outof_input;
1471 rtx inter;
1472 int shift_count, left_shift, outof_word;
1474 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1475 won't be accurate, so use a new target. Do this also if target is not
1476 a REG, first because having a register instead may open optimization
1477 opportunities, and second because if target and op0 happen to be MEMs
1478 designating the same location, we would risk clobbering it too early
1479 in the code sequence we generate below. */
1480 if (target == 0
1481 || target == op0
1482 || target == op1
1483 || !REG_P (target)
1484 || !valid_multiword_target_p (target))
1485 target = gen_reg_rtx (int_mode);
1487 start_sequence ();
1489 shift_count = INTVAL (op1);
1491 /* OUTOF_* is the word we are shifting bits away from, and
1492 INTO_* is the word that we are shifting bits towards, thus
1493 they differ depending on the direction of the shift and
1494 WORDS_BIG_ENDIAN. */
1496 left_shift = (binoptab == rotl_optab);
1497 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1499 outof_target = operand_subword (target, outof_word, 1, int_mode);
1500 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1502 outof_input = operand_subword_force (op0, outof_word, int_mode);
1503 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1505 if (shift_count == BITS_PER_WORD)
1507 /* This is just a word swap. */
1508 emit_move_insn (outof_target, into_input);
1509 emit_move_insn (into_target, outof_input);
1510 inter = const0_rtx;
1512 else
1514 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1515 rtx first_shift_count, second_shift_count;
1516 optab reverse_unsigned_shift, unsigned_shift;
1518 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1519 ? lshr_optab : ashl_optab);
1521 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1522 ? ashl_optab : lshr_optab);
1524 if (shift_count > BITS_PER_WORD)
1526 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1527 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1529 else
1531 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1532 second_shift_count = GEN_INT (shift_count);
1535 into_temp1 = expand_binop (word_mode, unsigned_shift,
1536 outof_input, first_shift_count,
1537 NULL_RTX, unsignedp, next_methods);
1538 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1539 into_input, second_shift_count,
1540 NULL_RTX, unsignedp, next_methods);
1542 if (into_temp1 != 0 && into_temp2 != 0)
1543 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1544 into_target, unsignedp, next_methods);
1545 else
1546 inter = 0;
1548 if (inter != 0 && inter != into_target)
1549 emit_move_insn (into_target, inter);
1551 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1552 into_input, first_shift_count,
1553 NULL_RTX, unsignedp, next_methods);
1554 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1555 outof_input, second_shift_count,
1556 NULL_RTX, unsignedp, next_methods);
1558 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1559 inter = expand_binop (word_mode, ior_optab,
1560 outof_temp1, outof_temp2,
1561 outof_target, unsignedp, next_methods);
1563 if (inter != 0 && inter != outof_target)
1564 emit_move_insn (outof_target, inter);
1567 insns = get_insns ();
1568 end_sequence ();
1570 if (inter != 0)
1572 emit_insn (insns);
1573 return target;
1577 /* These can be done a word at a time by propagating carries. */
1578 if ((binoptab == add_optab || binoptab == sub_optab)
1579 && is_int_mode (mode, &int_mode)
1580 && GET_MODE_SIZE (int_mode) >= 2 * UNITS_PER_WORD
1581 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1583 unsigned int i;
1584 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1585 const unsigned int nwords = GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD;
1586 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1587 rtx xop0, xop1, xtarget;
1589 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1590 value is one of those, use it. Otherwise, use 1 since it is the
1591 one easiest to get. */
1592 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1593 int normalizep = STORE_FLAG_VALUE;
1594 #else
1595 int normalizep = 1;
1596 #endif
1598 /* Prepare the operands. */
1599 xop0 = force_reg (int_mode, op0);
1600 xop1 = force_reg (int_mode, op1);
1602 xtarget = gen_reg_rtx (int_mode);
1604 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1605 target = xtarget;
1607 /* Indicate for flow that the entire target reg is being set. */
1608 if (REG_P (target))
1609 emit_clobber (xtarget);
1611 /* Do the actual arithmetic. */
1612 for (i = 0; i < nwords; i++)
1614 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1615 rtx target_piece = operand_subword (xtarget, index, 1, int_mode);
1616 rtx op0_piece = operand_subword_force (xop0, index, int_mode);
1617 rtx op1_piece = operand_subword_force (xop1, index, int_mode);
1618 rtx x;
1620 /* Main add/subtract of the input operands. */
1621 x = expand_binop (word_mode, binoptab,
1622 op0_piece, op1_piece,
1623 target_piece, unsignedp, next_methods);
1624 if (x == 0)
1625 break;
1627 if (i + 1 < nwords)
1629 /* Store carry from main add/subtract. */
1630 carry_out = gen_reg_rtx (word_mode);
1631 carry_out = emit_store_flag_force (carry_out,
1632 (binoptab == add_optab
1633 ? LT : GT),
1634 x, op0_piece,
1635 word_mode, 1, normalizep);
1638 if (i > 0)
1640 rtx newx;
1642 /* Add/subtract previous carry to main result. */
1643 newx = expand_binop (word_mode,
1644 normalizep == 1 ? binoptab : otheroptab,
1645 x, carry_in,
1646 NULL_RTX, 1, next_methods);
1648 if (i + 1 < nwords)
1650 /* Get out carry from adding/subtracting carry in. */
1651 rtx carry_tmp = gen_reg_rtx (word_mode);
1652 carry_tmp = emit_store_flag_force (carry_tmp,
1653 (binoptab == add_optab
1654 ? LT : GT),
1655 newx, x,
1656 word_mode, 1, normalizep);
1658 /* Logical-ior the two poss. carry together. */
1659 carry_out = expand_binop (word_mode, ior_optab,
1660 carry_out, carry_tmp,
1661 carry_out, 0, next_methods);
1662 if (carry_out == 0)
1663 break;
1665 emit_move_insn (target_piece, newx);
1667 else
1669 if (x != target_piece)
1670 emit_move_insn (target_piece, x);
1673 carry_in = carry_out;
1676 if (i == GET_MODE_BITSIZE (int_mode) / (unsigned) BITS_PER_WORD)
1678 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing
1679 || ! rtx_equal_p (target, xtarget))
1681 rtx_insn *temp = emit_move_insn (target, xtarget);
1683 set_dst_reg_note (temp, REG_EQUAL,
1684 gen_rtx_fmt_ee (optab_to_code (binoptab),
1685 int_mode, copy_rtx (xop0),
1686 copy_rtx (xop1)),
1687 target);
1689 else
1690 target = xtarget;
1692 return target;
1695 else
1696 delete_insns_since (last);
1699 /* Attempt to synthesize double word multiplies using a sequence of word
1700 mode multiplications. We first attempt to generate a sequence using a
1701 more efficient unsigned widening multiply, and if that fails we then
1702 try using a signed widening multiply. */
1704 if (binoptab == smul_optab
1705 && is_int_mode (mode, &int_mode)
1706 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1707 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1708 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1710 rtx product = NULL_RTX;
1711 if (convert_optab_handler (umul_widen_optab, int_mode, word_mode)
1712 != CODE_FOR_nothing)
1714 product = expand_doubleword_mult (int_mode, op0, op1, target,
1715 true, methods);
1716 if (!product)
1717 delete_insns_since (last);
1720 if (product == NULL_RTX
1721 && (convert_optab_handler (smul_widen_optab, int_mode, word_mode)
1722 != CODE_FOR_nothing))
1724 product = expand_doubleword_mult (int_mode, op0, op1, target,
1725 false, methods);
1726 if (!product)
1727 delete_insns_since (last);
1730 if (product != NULL_RTX)
1732 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
1734 rtx_insn *move = emit_move_insn (target ? target : product,
1735 product);
1736 set_dst_reg_note (move,
1737 REG_EQUAL,
1738 gen_rtx_fmt_ee (MULT, int_mode,
1739 copy_rtx (op0),
1740 copy_rtx (op1)),
1741 target ? target : product);
1743 return product;
1747 /* It can't be open-coded in this mode.
1748 Use a library call if one is available and caller says that's ok. */
1750 libfunc = optab_libfunc (binoptab, mode);
1751 if (libfunc
1752 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1754 rtx_insn *insns;
1755 rtx op1x = op1;
1756 machine_mode op1_mode = mode;
1757 rtx value;
1759 start_sequence ();
1761 if (shift_optab_p (binoptab))
1763 op1_mode = targetm.libgcc_shift_count_mode ();
1764 /* Specify unsigned here,
1765 since negative shift counts are meaningless. */
1766 op1x = convert_to_mode (op1_mode, op1, 1);
1769 if (GET_MODE (op0) != VOIDmode
1770 && GET_MODE (op0) != mode)
1771 op0 = convert_to_mode (mode, op0, unsignedp);
1773 /* Pass 1 for NO_QUEUE so we don't lose any increments
1774 if the libcall is cse'd or moved. */
1775 value = emit_library_call_value (libfunc,
1776 NULL_RTX, LCT_CONST, mode,
1777 op0, mode, op1x, op1_mode);
1779 insns = get_insns ();
1780 end_sequence ();
1782 bool trapv = trapv_binoptab_p (binoptab);
1783 target = gen_reg_rtx (mode);
1784 emit_libcall_block_1 (insns, target, value,
1785 trapv ? NULL_RTX
1786 : gen_rtx_fmt_ee (optab_to_code (binoptab),
1787 mode, op0, op1), trapv);
1789 return target;
1792 delete_insns_since (last);
1794 /* It can't be done in this mode. Can we do it in a wider mode? */
1796 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1797 || methods == OPTAB_MUST_WIDEN))
1799 /* Caller says, don't even try. */
1800 delete_insns_since (entry_last);
1801 return 0;
1804 /* Compute the value of METHODS to pass to recursive calls.
1805 Don't allow widening to be tried recursively. */
1807 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1809 /* Look for a wider mode of the same class for which it appears we can do
1810 the operation. */
1812 if (CLASS_HAS_WIDER_MODES_P (mclass))
1814 /* This code doesn't make sense for conversion optabs, since we
1815 wouldn't then want to extend the operands to be the same size
1816 as the result. */
1817 gcc_assert (!convert_optab_p (binoptab));
1818 FOR_EACH_WIDER_MODE (wider_mode, mode)
1820 if (optab_handler (binoptab, wider_mode)
1821 || (methods == OPTAB_LIB
1822 && optab_libfunc (binoptab, wider_mode)))
1824 rtx xop0 = op0, xop1 = op1;
1825 int no_extend = 0;
1827 /* For certain integer operations, we need not actually extend
1828 the narrow operands, as long as we will truncate
1829 the results to the same narrowness. */
1831 if ((binoptab == ior_optab || binoptab == and_optab
1832 || binoptab == xor_optab
1833 || binoptab == add_optab || binoptab == sub_optab
1834 || binoptab == smul_optab || binoptab == ashl_optab)
1835 && mclass == MODE_INT)
1836 no_extend = 1;
1838 xop0 = widen_operand (xop0, wider_mode, mode,
1839 unsignedp, no_extend);
1841 /* The second operand of a shift must always be extended. */
1842 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1843 no_extend && binoptab != ashl_optab);
1845 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1846 unsignedp, methods);
1847 if (temp)
1849 if (mclass != MODE_INT
1850 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1852 if (target == 0)
1853 target = gen_reg_rtx (mode);
1854 convert_move (target, temp, 0);
1855 return target;
1857 else
1858 return gen_lowpart (mode, temp);
1860 else
1861 delete_insns_since (last);
1866 delete_insns_since (entry_last);
1867 return 0;
1870 /* Expand a binary operator which has both signed and unsigned forms.
1871 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1872 signed operations.
1874 If we widen unsigned operands, we may use a signed wider operation instead
1875 of an unsigned wider operation, since the result would be the same. */
1878 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
1879 rtx op0, rtx op1, rtx target, int unsignedp,
1880 enum optab_methods methods)
1882 rtx temp;
1883 optab direct_optab = unsignedp ? uoptab : soptab;
1884 bool save_enable;
1886 /* Do it without widening, if possible. */
1887 temp = expand_binop (mode, direct_optab, op0, op1, target,
1888 unsignedp, OPTAB_DIRECT);
1889 if (temp || methods == OPTAB_DIRECT)
1890 return temp;
1892 /* Try widening to a signed int. Disable any direct use of any
1893 signed insn in the current mode. */
1894 save_enable = swap_optab_enable (soptab, mode, false);
1896 temp = expand_binop (mode, soptab, op0, op1, target,
1897 unsignedp, OPTAB_WIDEN);
1899 /* For unsigned operands, try widening to an unsigned int. */
1900 if (!temp && unsignedp)
1901 temp = expand_binop (mode, uoptab, op0, op1, target,
1902 unsignedp, OPTAB_WIDEN);
1903 if (temp || methods == OPTAB_WIDEN)
1904 goto egress;
1906 /* Use the right width libcall if that exists. */
1907 temp = expand_binop (mode, direct_optab, op0, op1, target,
1908 unsignedp, OPTAB_LIB);
1909 if (temp || methods == OPTAB_LIB)
1910 goto egress;
1912 /* Must widen and use a libcall, use either signed or unsigned. */
1913 temp = expand_binop (mode, soptab, op0, op1, target,
1914 unsignedp, methods);
1915 if (!temp && unsignedp)
1916 temp = expand_binop (mode, uoptab, op0, op1, target,
1917 unsignedp, methods);
1919 egress:
1920 /* Undo the fiddling above. */
1921 if (save_enable)
1922 swap_optab_enable (soptab, mode, true);
1923 return temp;
1926 /* Generate code to perform an operation specified by UNOPPTAB
1927 on operand OP0, with two results to TARG0 and TARG1.
1928 We assume that the order of the operands for the instruction
1929 is TARG0, TARG1, OP0.
1931 Either TARG0 or TARG1 may be zero, but what that means is that
1932 the result is not actually wanted. We will generate it into
1933 a dummy pseudo-reg and discard it. They may not both be zero.
1935 Returns 1 if this operation can be performed; 0 if not. */
1938 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1939 int unsignedp)
1941 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1942 enum mode_class mclass;
1943 machine_mode wider_mode;
1944 rtx_insn *entry_last = get_last_insn ();
1945 rtx_insn *last;
1947 mclass = GET_MODE_CLASS (mode);
1949 if (!targ0)
1950 targ0 = gen_reg_rtx (mode);
1951 if (!targ1)
1952 targ1 = gen_reg_rtx (mode);
1954 /* Record where to go back to if we fail. */
1955 last = get_last_insn ();
1957 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
1959 struct expand_operand ops[3];
1960 enum insn_code icode = optab_handler (unoptab, mode);
1962 create_fixed_operand (&ops[0], targ0);
1963 create_fixed_operand (&ops[1], targ1);
1964 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
1965 if (maybe_expand_insn (icode, 3, ops))
1966 return 1;
1969 /* It can't be done in this mode. Can we do it in a wider mode? */
1971 if (CLASS_HAS_WIDER_MODES_P (mclass))
1973 FOR_EACH_WIDER_MODE (wider_mode, mode)
1975 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
1977 rtx t0 = gen_reg_rtx (wider_mode);
1978 rtx t1 = gen_reg_rtx (wider_mode);
1979 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1981 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
1983 convert_move (targ0, t0, unsignedp);
1984 convert_move (targ1, t1, unsignedp);
1985 return 1;
1987 else
1988 delete_insns_since (last);
1993 delete_insns_since (entry_last);
1994 return 0;
1997 /* Generate code to perform an operation specified by BINOPTAB
1998 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1999 We assume that the order of the operands for the instruction
2000 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2001 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2003 Either TARG0 or TARG1 may be zero, but what that means is that
2004 the result is not actually wanted. We will generate it into
2005 a dummy pseudo-reg and discard it. They may not both be zero.
2007 Returns 1 if this operation can be performed; 0 if not. */
2010 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2011 int unsignedp)
2013 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2014 enum mode_class mclass;
2015 machine_mode wider_mode;
2016 rtx_insn *entry_last = get_last_insn ();
2017 rtx_insn *last;
2019 mclass = GET_MODE_CLASS (mode);
2021 if (!targ0)
2022 targ0 = gen_reg_rtx (mode);
2023 if (!targ1)
2024 targ1 = gen_reg_rtx (mode);
2026 /* Record where to go back to if we fail. */
2027 last = get_last_insn ();
2029 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2031 struct expand_operand ops[4];
2032 enum insn_code icode = optab_handler (binoptab, mode);
2033 machine_mode mode0 = insn_data[icode].operand[1].mode;
2034 machine_mode mode1 = insn_data[icode].operand[2].mode;
2035 rtx xop0 = op0, xop1 = op1;
2037 /* If we are optimizing, force expensive constants into a register. */
2038 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2039 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2041 create_fixed_operand (&ops[0], targ0);
2042 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2043 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2044 create_fixed_operand (&ops[3], targ1);
2045 if (maybe_expand_insn (icode, 4, ops))
2046 return 1;
2047 delete_insns_since (last);
2050 /* It can't be done in this mode. Can we do it in a wider mode? */
2052 if (CLASS_HAS_WIDER_MODES_P (mclass))
2054 FOR_EACH_WIDER_MODE (wider_mode, mode)
2056 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2058 rtx t0 = gen_reg_rtx (wider_mode);
2059 rtx t1 = gen_reg_rtx (wider_mode);
2060 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2061 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2063 if (expand_twoval_binop (binoptab, cop0, cop1,
2064 t0, t1, unsignedp))
2066 convert_move (targ0, t0, unsignedp);
2067 convert_move (targ1, t1, unsignedp);
2068 return 1;
2070 else
2071 delete_insns_since (last);
2076 delete_insns_since (entry_last);
2077 return 0;
2080 /* Expand the two-valued library call indicated by BINOPTAB, but
2081 preserve only one of the values. If TARG0 is non-NULL, the first
2082 value is placed into TARG0; otherwise the second value is placed
2083 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2084 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2085 This routine assumes that the value returned by the library call is
2086 as if the return value was of an integral mode twice as wide as the
2087 mode of OP0. Returns 1 if the call was successful. */
2089 bool
2090 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2091 rtx targ0, rtx targ1, enum rtx_code code)
2093 machine_mode mode;
2094 machine_mode libval_mode;
2095 rtx libval;
2096 rtx_insn *insns;
2097 rtx libfunc;
2099 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2100 gcc_assert (!targ0 != !targ1);
2102 mode = GET_MODE (op0);
2103 libfunc = optab_libfunc (binoptab, mode);
2104 if (!libfunc)
2105 return false;
2107 /* The value returned by the library function will have twice as
2108 many bits as the nominal MODE. */
2109 libval_mode = smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode));
2110 start_sequence ();
2111 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2112 libval_mode,
2113 op0, mode,
2114 op1, mode);
2115 /* Get the part of VAL containing the value that we want. */
2116 libval = simplify_gen_subreg (mode, libval, libval_mode,
2117 targ0 ? 0 : GET_MODE_SIZE (mode));
2118 insns = get_insns ();
2119 end_sequence ();
2120 /* Move the into the desired location. */
2121 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2122 gen_rtx_fmt_ee (code, mode, op0, op1));
2124 return true;
2128 /* Wrapper around expand_unop which takes an rtx code to specify
2129 the operation to perform, not an optab pointer. All other
2130 arguments are the same. */
2132 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2133 rtx target, int unsignedp)
2135 optab unop = code_to_optab (code);
2136 gcc_assert (unop);
2138 return expand_unop (mode, unop, op0, target, unsignedp);
2141 /* Try calculating
2142 (clz:narrow x)
2144 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2146 A similar operation can be used for clrsb. UNOPTAB says which operation
2147 we are trying to expand. */
2148 static rtx
2149 widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
2151 opt_scalar_int_mode wider_mode_iter;
2152 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2154 scalar_int_mode wider_mode = wider_mode_iter.require ();
2155 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2157 rtx xop0, temp;
2158 rtx_insn *last;
2160 last = get_last_insn ();
2162 if (target == 0)
2163 target = gen_reg_rtx (mode);
2164 xop0 = widen_operand (op0, wider_mode, mode,
2165 unoptab != clrsb_optab, false);
2166 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2167 unoptab != clrsb_optab);
2168 if (temp != 0)
2169 temp = expand_binop
2170 (wider_mode, sub_optab, temp,
2171 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2172 - GET_MODE_PRECISION (mode),
2173 wider_mode),
2174 target, true, OPTAB_DIRECT);
2175 if (temp == 0)
2176 delete_insns_since (last);
2178 return temp;
2181 return 0;
2184 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2185 quantities, choosing which based on whether the high word is nonzero. */
2186 static rtx
2187 expand_doubleword_clz (scalar_int_mode mode, rtx op0, rtx target)
2189 rtx xop0 = force_reg (mode, op0);
2190 rtx subhi = gen_highpart (word_mode, xop0);
2191 rtx sublo = gen_lowpart (word_mode, xop0);
2192 rtx_code_label *hi0_label = gen_label_rtx ();
2193 rtx_code_label *after_label = gen_label_rtx ();
2194 rtx_insn *seq;
2195 rtx temp, result;
2197 /* If we were not given a target, use a word_mode register, not a
2198 'mode' register. The result will fit, and nobody is expecting
2199 anything bigger (the return type of __builtin_clz* is int). */
2200 if (!target)
2201 target = gen_reg_rtx (word_mode);
2203 /* In any case, write to a word_mode scratch in both branches of the
2204 conditional, so we can ensure there is a single move insn setting
2205 'target' to tag a REG_EQUAL note on. */
2206 result = gen_reg_rtx (word_mode);
2208 start_sequence ();
2210 /* If the high word is not equal to zero,
2211 then clz of the full value is clz of the high word. */
2212 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2213 word_mode, true, hi0_label);
2215 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2216 if (!temp)
2217 goto fail;
2219 if (temp != result)
2220 convert_move (result, temp, true);
2222 emit_jump_insn (targetm.gen_jump (after_label));
2223 emit_barrier ();
2225 /* Else clz of the full value is clz of the low word plus the number
2226 of bits in the high word. */
2227 emit_label (hi0_label);
2229 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2230 if (!temp)
2231 goto fail;
2232 temp = expand_binop (word_mode, add_optab, temp,
2233 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2234 result, true, OPTAB_DIRECT);
2235 if (!temp)
2236 goto fail;
2237 if (temp != result)
2238 convert_move (result, temp, true);
2240 emit_label (after_label);
2241 convert_move (target, result, true);
2243 seq = get_insns ();
2244 end_sequence ();
2246 add_equal_note (seq, target, CLZ, xop0, 0);
2247 emit_insn (seq);
2248 return target;
2250 fail:
2251 end_sequence ();
2252 return 0;
2255 /* Try calculating popcount of a double-word quantity as two popcount's of
2256 word-sized quantities and summing up the results. */
2257 static rtx
2258 expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
2260 rtx t0, t1, t;
2261 rtx_insn *seq;
2263 start_sequence ();
2265 t0 = expand_unop_direct (word_mode, popcount_optab,
2266 operand_subword_force (op0, 0, mode), NULL_RTX,
2267 true);
2268 t1 = expand_unop_direct (word_mode, popcount_optab,
2269 operand_subword_force (op0, 1, mode), NULL_RTX,
2270 true);
2271 if (!t0 || !t1)
2273 end_sequence ();
2274 return NULL_RTX;
2277 /* If we were not given a target, use a word_mode register, not a
2278 'mode' register. The result will fit, and nobody is expecting
2279 anything bigger (the return type of __builtin_popcount* is int). */
2280 if (!target)
2281 target = gen_reg_rtx (word_mode);
2283 t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
2285 seq = get_insns ();
2286 end_sequence ();
2288 add_equal_note (seq, t, POPCOUNT, op0, 0);
2289 emit_insn (seq);
2290 return t;
2293 /* Try calculating
2294 (parity:wide x)
2296 (parity:narrow (low (x) ^ high (x))) */
2297 static rtx
2298 expand_doubleword_parity (scalar_int_mode mode, rtx op0, rtx target)
2300 rtx t = expand_binop (word_mode, xor_optab,
2301 operand_subword_force (op0, 0, mode),
2302 operand_subword_force (op0, 1, mode),
2303 NULL_RTX, 0, OPTAB_DIRECT);
2304 return expand_unop (word_mode, parity_optab, t, target, true);
2307 /* Try calculating
2308 (bswap:narrow x)
2310 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2311 static rtx
2312 widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
2314 rtx x;
2315 rtx_insn *last;
2316 opt_scalar_int_mode wider_mode_iter;
2318 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2319 if (optab_handler (bswap_optab, wider_mode_iter.require ())
2320 != CODE_FOR_nothing)
2321 break;
2323 if (!wider_mode_iter.exists ())
2324 return NULL_RTX;
2326 scalar_int_mode wider_mode = wider_mode_iter.require ();
2327 last = get_last_insn ();
2329 x = widen_operand (op0, wider_mode, mode, true, true);
2330 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2332 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2333 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2334 if (x != 0)
2335 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2336 GET_MODE_BITSIZE (wider_mode)
2337 - GET_MODE_BITSIZE (mode),
2338 NULL_RTX, true);
2340 if (x != 0)
2342 if (target == 0)
2343 target = gen_reg_rtx (mode);
2344 emit_move_insn (target, gen_lowpart (mode, x));
2346 else
2347 delete_insns_since (last);
2349 return target;
2352 /* Try calculating bswap as two bswaps of two word-sized operands. */
2354 static rtx
2355 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2357 rtx t0, t1;
2359 t1 = expand_unop (word_mode, bswap_optab,
2360 operand_subword_force (op, 0, mode), NULL_RTX, true);
2361 t0 = expand_unop (word_mode, bswap_optab,
2362 operand_subword_force (op, 1, mode), NULL_RTX, true);
2364 if (target == 0 || !valid_multiword_target_p (target))
2365 target = gen_reg_rtx (mode);
2366 if (REG_P (target))
2367 emit_clobber (target);
2368 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2369 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2371 return target;
2374 /* Try calculating (parity x) as (and (popcount x) 1), where
2375 popcount can also be done in a wider mode. */
2376 static rtx
2377 expand_parity (scalar_int_mode mode, rtx op0, rtx target)
2379 enum mode_class mclass = GET_MODE_CLASS (mode);
2380 opt_scalar_int_mode wider_mode_iter;
2381 FOR_EACH_MODE_FROM (wider_mode_iter, mode)
2383 scalar_int_mode wider_mode = wider_mode_iter.require ();
2384 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2386 rtx xop0, temp;
2387 rtx_insn *last;
2389 last = get_last_insn ();
2391 if (target == 0 || GET_MODE (target) != wider_mode)
2392 target = gen_reg_rtx (wider_mode);
2394 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2395 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2396 true);
2397 if (temp != 0)
2398 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2399 target, true, OPTAB_DIRECT);
2401 if (temp)
2403 if (mclass != MODE_INT
2404 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2405 return convert_to_mode (mode, temp, 0);
2406 else
2407 return gen_lowpart (mode, temp);
2409 else
2410 delete_insns_since (last);
2413 return 0;
2416 /* Try calculating ctz(x) as K - clz(x & -x) ,
2417 where K is GET_MODE_PRECISION(mode) - 1.
2419 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2420 don't have to worry about what the hardware does in that case. (If
2421 the clz instruction produces the usual value at 0, which is K, the
2422 result of this code sequence will be -1; expand_ffs, below, relies
2423 on this. It might be nice to have it be K instead, for consistency
2424 with the (very few) processors that provide a ctz with a defined
2425 value, but that would take one more instruction, and it would be
2426 less convenient for expand_ffs anyway. */
2428 static rtx
2429 expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
2431 rtx_insn *seq;
2432 rtx temp;
2434 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2435 return 0;
2437 start_sequence ();
2439 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2440 if (temp)
2441 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2442 true, OPTAB_DIRECT);
2443 if (temp)
2444 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2445 if (temp)
2446 temp = expand_binop (mode, sub_optab,
2447 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2448 temp, target,
2449 true, OPTAB_DIRECT);
2450 if (temp == 0)
2452 end_sequence ();
2453 return 0;
2456 seq = get_insns ();
2457 end_sequence ();
2459 add_equal_note (seq, temp, CTZ, op0, 0);
2460 emit_insn (seq);
2461 return temp;
2465 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2466 else with the sequence used by expand_clz.
2468 The ffs builtin promises to return zero for a zero value and ctz/clz
2469 may have an undefined value in that case. If they do not give us a
2470 convenient value, we have to generate a test and branch. */
2471 static rtx
2472 expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
2474 HOST_WIDE_INT val = 0;
2475 bool defined_at_zero = false;
2476 rtx temp;
2477 rtx_insn *seq;
2479 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2481 start_sequence ();
2483 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2484 if (!temp)
2485 goto fail;
2487 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2489 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2491 start_sequence ();
2492 temp = expand_ctz (mode, op0, 0);
2493 if (!temp)
2494 goto fail;
2496 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2498 defined_at_zero = true;
2499 val = (GET_MODE_PRECISION (mode) - 1) - val;
2502 else
2503 return 0;
2505 if (defined_at_zero && val == -1)
2506 /* No correction needed at zero. */;
2507 else
2509 /* We don't try to do anything clever with the situation found
2510 on some processors (eg Alpha) where ctz(0:mode) ==
2511 bitsize(mode). If someone can think of a way to send N to -1
2512 and leave alone all values in the range 0..N-1 (where N is a
2513 power of two), cheaper than this test-and-branch, please add it.
2515 The test-and-branch is done after the operation itself, in case
2516 the operation sets condition codes that can be recycled for this.
2517 (This is true on i386, for instance.) */
2519 rtx_code_label *nonzero_label = gen_label_rtx ();
2520 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2521 mode, true, nonzero_label);
2523 convert_move (temp, GEN_INT (-1), false);
2524 emit_label (nonzero_label);
2527 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2528 to produce a value in the range 0..bitsize. */
2529 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2530 target, false, OPTAB_DIRECT);
2531 if (!temp)
2532 goto fail;
2534 seq = get_insns ();
2535 end_sequence ();
2537 add_equal_note (seq, temp, FFS, op0, 0);
2538 emit_insn (seq);
2539 return temp;
2541 fail:
2542 end_sequence ();
2543 return 0;
2546 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2547 conditions, VAL may already be a SUBREG against which we cannot generate
2548 a further SUBREG. In this case, we expect forcing the value into a
2549 register will work around the situation. */
2551 static rtx
2552 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2553 machine_mode imode)
2555 rtx ret;
2556 ret = lowpart_subreg (omode, val, imode);
2557 if (ret == NULL)
2559 val = force_reg (imode, val);
2560 ret = lowpart_subreg (omode, val, imode);
2561 gcc_assert (ret != NULL);
2563 return ret;
2566 /* Expand a floating point absolute value or negation operation via a
2567 logical operation on the sign bit. */
2569 static rtx
2570 expand_absneg_bit (enum rtx_code code, scalar_float_mode mode,
2571 rtx op0, rtx target)
2573 const struct real_format *fmt;
2574 int bitpos, word, nwords, i;
2575 scalar_int_mode imode;
2576 rtx temp;
2577 rtx_insn *insns;
2579 /* The format has to have a simple sign bit. */
2580 fmt = REAL_MODE_FORMAT (mode);
2581 if (fmt == NULL)
2582 return NULL_RTX;
2584 bitpos = fmt->signbit_rw;
2585 if (bitpos < 0)
2586 return NULL_RTX;
2588 /* Don't create negative zeros if the format doesn't support them. */
2589 if (code == NEG && !fmt->has_signed_zero)
2590 return NULL_RTX;
2592 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2594 if (!int_mode_for_mode (mode).exists (&imode))
2595 return NULL_RTX;
2596 word = 0;
2597 nwords = 1;
2599 else
2601 imode = word_mode;
2603 if (FLOAT_WORDS_BIG_ENDIAN)
2604 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2605 else
2606 word = bitpos / BITS_PER_WORD;
2607 bitpos = bitpos % BITS_PER_WORD;
2608 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2611 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2612 if (code == ABS)
2613 mask = ~mask;
2615 if (target == 0
2616 || target == op0
2617 || (nwords > 1 && !valid_multiword_target_p (target)))
2618 target = gen_reg_rtx (mode);
2620 if (nwords > 1)
2622 start_sequence ();
2624 for (i = 0; i < nwords; ++i)
2626 rtx targ_piece = operand_subword (target, i, 1, mode);
2627 rtx op0_piece = operand_subword_force (op0, i, mode);
2629 if (i == word)
2631 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2632 op0_piece,
2633 immed_wide_int_const (mask, imode),
2634 targ_piece, 1, OPTAB_LIB_WIDEN);
2635 if (temp != targ_piece)
2636 emit_move_insn (targ_piece, temp);
2638 else
2639 emit_move_insn (targ_piece, op0_piece);
2642 insns = get_insns ();
2643 end_sequence ();
2645 emit_insn (insns);
2647 else
2649 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2650 gen_lowpart (imode, op0),
2651 immed_wide_int_const (mask, imode),
2652 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2653 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2655 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2656 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2657 target);
2660 return target;
2663 /* As expand_unop, but will fail rather than attempt the operation in a
2664 different mode or with a libcall. */
2665 static rtx
2666 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2667 int unsignedp)
2669 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2671 struct expand_operand ops[2];
2672 enum insn_code icode = optab_handler (unoptab, mode);
2673 rtx_insn *last = get_last_insn ();
2674 rtx_insn *pat;
2676 create_output_operand (&ops[0], target, mode);
2677 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2678 pat = maybe_gen_insn (icode, 2, ops);
2679 if (pat)
2681 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2682 && ! add_equal_note (pat, ops[0].value,
2683 optab_to_code (unoptab),
2684 ops[1].value, NULL_RTX))
2686 delete_insns_since (last);
2687 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2690 emit_insn (pat);
2692 return ops[0].value;
2695 return 0;
2698 /* Generate code to perform an operation specified by UNOPTAB
2699 on operand OP0, with result having machine-mode MODE.
2701 UNSIGNEDP is for the case where we have to widen the operands
2702 to perform the operation. It says to use zero-extension.
2704 If TARGET is nonzero, the value
2705 is generated there, if it is convenient to do so.
2706 In all cases an rtx is returned for the locus of the value;
2707 this may or may not be TARGET. */
2710 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2711 int unsignedp)
2713 enum mode_class mclass = GET_MODE_CLASS (mode);
2714 machine_mode wider_mode;
2715 scalar_int_mode int_mode;
2716 scalar_float_mode float_mode;
2717 rtx temp;
2718 rtx libfunc;
2720 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2721 if (temp)
2722 return temp;
2724 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2726 /* Widening (or narrowing) clz needs special treatment. */
2727 if (unoptab == clz_optab)
2729 if (is_a <scalar_int_mode> (mode, &int_mode))
2731 temp = widen_leading (int_mode, op0, target, unoptab);
2732 if (temp)
2733 return temp;
2735 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2736 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2738 temp = expand_doubleword_clz (int_mode, op0, target);
2739 if (temp)
2740 return temp;
2744 goto try_libcall;
2747 if (unoptab == clrsb_optab)
2749 if (is_a <scalar_int_mode> (mode, &int_mode))
2751 temp = widen_leading (int_mode, op0, target, unoptab);
2752 if (temp)
2753 return temp;
2755 goto try_libcall;
2758 if (unoptab == popcount_optab
2759 && is_a <scalar_int_mode> (mode, &int_mode)
2760 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2761 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2762 && optimize_insn_for_speed_p ())
2764 temp = expand_doubleword_popcount (int_mode, op0, target);
2765 if (temp)
2766 return temp;
2769 if (unoptab == parity_optab
2770 && is_a <scalar_int_mode> (mode, &int_mode)
2771 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2772 && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2773 || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
2774 && optimize_insn_for_speed_p ())
2776 temp = expand_doubleword_parity (int_mode, op0, target);
2777 if (temp)
2778 return temp;
2781 /* Widening (or narrowing) bswap needs special treatment. */
2782 if (unoptab == bswap_optab)
2784 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2785 or ROTATERT. First try these directly; if this fails, then try the
2786 obvious pair of shifts with allowed widening, as this will probably
2787 be always more efficient than the other fallback methods. */
2788 if (mode == HImode)
2790 rtx_insn *last;
2791 rtx temp1, temp2;
2793 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2795 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
2796 unsignedp, OPTAB_DIRECT);
2797 if (temp)
2798 return temp;
2801 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2803 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
2804 unsignedp, OPTAB_DIRECT);
2805 if (temp)
2806 return temp;
2809 last = get_last_insn ();
2811 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
2812 unsignedp, OPTAB_WIDEN);
2813 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
2814 unsignedp, OPTAB_WIDEN);
2815 if (temp1 && temp2)
2817 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2818 unsignedp, OPTAB_WIDEN);
2819 if (temp)
2820 return temp;
2823 delete_insns_since (last);
2826 if (is_a <scalar_int_mode> (mode, &int_mode))
2828 temp = widen_bswap (int_mode, op0, target);
2829 if (temp)
2830 return temp;
2832 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2833 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2835 temp = expand_doubleword_bswap (mode, op0, target);
2836 if (temp)
2837 return temp;
2841 goto try_libcall;
2844 if (CLASS_HAS_WIDER_MODES_P (mclass))
2845 FOR_EACH_WIDER_MODE (wider_mode, mode)
2847 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2849 rtx xop0 = op0;
2850 rtx_insn *last = get_last_insn ();
2852 /* For certain operations, we need not actually extend
2853 the narrow operand, as long as we will truncate the
2854 results to the same narrowness. */
2856 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2857 (unoptab == neg_optab
2858 || unoptab == one_cmpl_optab)
2859 && mclass == MODE_INT);
2861 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2862 unsignedp);
2864 if (temp)
2866 if (mclass != MODE_INT
2867 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2869 if (target == 0)
2870 target = gen_reg_rtx (mode);
2871 convert_move (target, temp, 0);
2872 return target;
2874 else
2875 return gen_lowpart (mode, temp);
2877 else
2878 delete_insns_since (last);
2882 /* These can be done a word at a time. */
2883 if (unoptab == one_cmpl_optab
2884 && is_int_mode (mode, &int_mode)
2885 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
2886 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2888 int i;
2889 rtx_insn *insns;
2891 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2892 target = gen_reg_rtx (int_mode);
2894 start_sequence ();
2896 /* Do the actual arithmetic. */
2897 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
2899 rtx target_piece = operand_subword (target, i, 1, int_mode);
2900 rtx x = expand_unop (word_mode, unoptab,
2901 operand_subword_force (op0, i, int_mode),
2902 target_piece, unsignedp);
2904 if (target_piece != x)
2905 emit_move_insn (target_piece, x);
2908 insns = get_insns ();
2909 end_sequence ();
2911 emit_insn (insns);
2912 return target;
2915 if (optab_to_code (unoptab) == NEG)
2917 /* Try negating floating point values by flipping the sign bit. */
2918 if (is_a <scalar_float_mode> (mode, &float_mode))
2920 temp = expand_absneg_bit (NEG, float_mode, op0, target);
2921 if (temp)
2922 return temp;
2925 /* If there is no negation pattern, and we have no negative zero,
2926 try subtracting from zero. */
2927 if (!HONOR_SIGNED_ZEROS (mode))
2929 temp = expand_binop (mode, (unoptab == negv_optab
2930 ? subv_optab : sub_optab),
2931 CONST0_RTX (mode), op0, target,
2932 unsignedp, OPTAB_DIRECT);
2933 if (temp)
2934 return temp;
2938 /* Try calculating parity (x) as popcount (x) % 2. */
2939 if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
2941 temp = expand_parity (int_mode, op0, target);
2942 if (temp)
2943 return temp;
2946 /* Try implementing ffs (x) in terms of clz (x). */
2947 if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
2949 temp = expand_ffs (int_mode, op0, target);
2950 if (temp)
2951 return temp;
2954 /* Try implementing ctz (x) in terms of clz (x). */
2955 if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
2957 temp = expand_ctz (int_mode, op0, target);
2958 if (temp)
2959 return temp;
2962 try_libcall:
2963 /* Now try a library call in this mode. */
2964 libfunc = optab_libfunc (unoptab, mode);
2965 if (libfunc)
2967 rtx_insn *insns;
2968 rtx value;
2969 rtx eq_value;
2970 machine_mode outmode = mode;
2972 /* All of these functions return small values. Thus we choose to
2973 have them return something that isn't a double-word. */
2974 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2975 || unoptab == clrsb_optab || unoptab == popcount_optab
2976 || unoptab == parity_optab)
2977 outmode
2978 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
2979 optab_libfunc (unoptab, mode)));
2981 start_sequence ();
2983 /* Pass 1 for NO_QUEUE so we don't lose any increments
2984 if the libcall is cse'd or moved. */
2985 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
2986 op0, mode);
2987 insns = get_insns ();
2988 end_sequence ();
2990 target = gen_reg_rtx (outmode);
2991 bool trapv = trapv_unoptab_p (unoptab);
2992 if (trapv)
2993 eq_value = NULL_RTX;
2994 else
2996 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
2997 if (GET_MODE_UNIT_SIZE (outmode) < GET_MODE_UNIT_SIZE (mode))
2998 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
2999 else if (GET_MODE_UNIT_SIZE (outmode) > GET_MODE_UNIT_SIZE (mode))
3000 eq_value = simplify_gen_unary (ZERO_EXTEND,
3001 outmode, eq_value, mode);
3003 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
3005 return target;
3008 /* It can't be done in this mode. Can we do it in a wider mode? */
3010 if (CLASS_HAS_WIDER_MODES_P (mclass))
3012 FOR_EACH_WIDER_MODE (wider_mode, mode)
3014 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3015 || optab_libfunc (unoptab, wider_mode))
3017 rtx xop0 = op0;
3018 rtx_insn *last = get_last_insn ();
3020 /* For certain operations, we need not actually extend
3021 the narrow operand, as long as we will truncate the
3022 results to the same narrowness. */
3023 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3024 (unoptab == neg_optab
3025 || unoptab == one_cmpl_optab
3026 || unoptab == bswap_optab)
3027 && mclass == MODE_INT);
3029 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3030 unsignedp);
3032 /* If we are generating clz using wider mode, adjust the
3033 result. Similarly for clrsb. */
3034 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3035 && temp != 0)
3037 scalar_int_mode wider_int_mode
3038 = as_a <scalar_int_mode> (wider_mode);
3039 int_mode = as_a <scalar_int_mode> (mode);
3040 temp = expand_binop
3041 (wider_mode, sub_optab, temp,
3042 gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
3043 - GET_MODE_PRECISION (int_mode),
3044 wider_int_mode),
3045 target, true, OPTAB_DIRECT);
3048 /* Likewise for bswap. */
3049 if (unoptab == bswap_optab && temp != 0)
3051 scalar_int_mode wider_int_mode
3052 = as_a <scalar_int_mode> (wider_mode);
3053 int_mode = as_a <scalar_int_mode> (mode);
3054 gcc_assert (GET_MODE_PRECISION (wider_int_mode)
3055 == GET_MODE_BITSIZE (wider_int_mode)
3056 && GET_MODE_PRECISION (int_mode)
3057 == GET_MODE_BITSIZE (int_mode));
3059 temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
3060 GET_MODE_BITSIZE (wider_int_mode)
3061 - GET_MODE_BITSIZE (int_mode),
3062 NULL_RTX, true);
3065 if (temp)
3067 if (mclass != MODE_INT)
3069 if (target == 0)
3070 target = gen_reg_rtx (mode);
3071 convert_move (target, temp, 0);
3072 return target;
3074 else
3075 return gen_lowpart (mode, temp);
3077 else
3078 delete_insns_since (last);
3083 /* One final attempt at implementing negation via subtraction,
3084 this time allowing widening of the operand. */
3085 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3087 rtx temp;
3088 temp = expand_binop (mode,
3089 unoptab == negv_optab ? subv_optab : sub_optab,
3090 CONST0_RTX (mode), op0,
3091 target, unsignedp, OPTAB_LIB_WIDEN);
3092 if (temp)
3093 return temp;
3096 return 0;
3099 /* Emit code to compute the absolute value of OP0, with result to
3100 TARGET if convenient. (TARGET may be 0.) The return value says
3101 where the result actually is to be found.
3103 MODE is the mode of the operand; the mode of the result is
3104 different but can be deduced from MODE.
3109 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3110 int result_unsignedp)
3112 rtx temp;
3114 if (GET_MODE_CLASS (mode) != MODE_INT
3115 || ! flag_trapv)
3116 result_unsignedp = 1;
3118 /* First try to do it with a special abs instruction. */
3119 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3120 op0, target, 0);
3121 if (temp != 0)
3122 return temp;
3124 /* For floating point modes, try clearing the sign bit. */
3125 scalar_float_mode float_mode;
3126 if (is_a <scalar_float_mode> (mode, &float_mode))
3128 temp = expand_absneg_bit (ABS, float_mode, op0, target);
3129 if (temp)
3130 return temp;
3133 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3134 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3135 && !HONOR_SIGNED_ZEROS (mode))
3137 rtx_insn *last = get_last_insn ();
3139 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3140 op0, NULL_RTX, 0);
3141 if (temp != 0)
3142 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3143 OPTAB_WIDEN);
3145 if (temp != 0)
3146 return temp;
3148 delete_insns_since (last);
3151 /* If this machine has expensive jumps, we can do integer absolute
3152 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3153 where W is the width of MODE. */
3155 scalar_int_mode int_mode;
3156 if (is_int_mode (mode, &int_mode)
3157 && BRANCH_COST (optimize_insn_for_speed_p (),
3158 false) >= 2)
3160 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3161 GET_MODE_PRECISION (int_mode) - 1,
3162 NULL_RTX, 0);
3164 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3165 OPTAB_LIB_WIDEN);
3166 if (temp != 0)
3167 temp = expand_binop (int_mode,
3168 result_unsignedp ? sub_optab : subv_optab,
3169 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3171 if (temp != 0)
3172 return temp;
3175 return NULL_RTX;
3179 expand_abs (machine_mode mode, rtx op0, rtx target,
3180 int result_unsignedp, int safe)
3182 rtx temp;
3183 rtx_code_label *op1;
3185 if (GET_MODE_CLASS (mode) != MODE_INT
3186 || ! flag_trapv)
3187 result_unsignedp = 1;
3189 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3190 if (temp != 0)
3191 return temp;
3193 /* If that does not win, use conditional jump and negate. */
3195 /* It is safe to use the target if it is the same
3196 as the source if this is also a pseudo register */
3197 if (op0 == target && REG_P (op0)
3198 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3199 safe = 1;
3201 op1 = gen_label_rtx ();
3202 if (target == 0 || ! safe
3203 || GET_MODE (target) != mode
3204 || (MEM_P (target) && MEM_VOLATILE_P (target))
3205 || (REG_P (target)
3206 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3207 target = gen_reg_rtx (mode);
3209 emit_move_insn (target, op0);
3210 NO_DEFER_POP;
3212 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3213 NULL_RTX, NULL, op1,
3214 profile_probability::uninitialized ());
3216 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3217 target, target, 0);
3218 if (op0 != target)
3219 emit_move_insn (target, op0);
3220 emit_label (op1);
3221 OK_DEFER_POP;
3222 return target;
3225 /* Emit code to compute the one's complement absolute value of OP0
3226 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3227 (TARGET may be NULL_RTX.) The return value says where the result
3228 actually is to be found.
3230 MODE is the mode of the operand; the mode of the result is
3231 different but can be deduced from MODE. */
3234 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3236 rtx temp;
3238 /* Not applicable for floating point modes. */
3239 if (FLOAT_MODE_P (mode))
3240 return NULL_RTX;
3242 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3243 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3245 rtx_insn *last = get_last_insn ();
3247 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3248 if (temp != 0)
3249 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3250 OPTAB_WIDEN);
3252 if (temp != 0)
3253 return temp;
3255 delete_insns_since (last);
3258 /* If this machine has expensive jumps, we can do one's complement
3259 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3261 scalar_int_mode int_mode;
3262 if (is_int_mode (mode, &int_mode)
3263 && BRANCH_COST (optimize_insn_for_speed_p (),
3264 false) >= 2)
3266 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3267 GET_MODE_PRECISION (int_mode) - 1,
3268 NULL_RTX, 0);
3270 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3271 OPTAB_LIB_WIDEN);
3273 if (temp != 0)
3274 return temp;
3277 return NULL_RTX;
3280 /* A subroutine of expand_copysign, perform the copysign operation using the
3281 abs and neg primitives advertised to exist on the target. The assumption
3282 is that we have a split register file, and leaving op0 in fp registers,
3283 and not playing with subregs so much, will help the register allocator. */
3285 static rtx
3286 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3287 int bitpos, bool op0_is_abs)
3289 scalar_int_mode imode;
3290 enum insn_code icode;
3291 rtx sign;
3292 rtx_code_label *label;
3294 if (target == op1)
3295 target = NULL_RTX;
3297 /* Check if the back end provides an insn that handles signbit for the
3298 argument's mode. */
3299 icode = optab_handler (signbit_optab, mode);
3300 if (icode != CODE_FOR_nothing)
3302 imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
3303 sign = gen_reg_rtx (imode);
3304 emit_unop_insn (icode, sign, op1, UNKNOWN);
3306 else
3308 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3310 if (!int_mode_for_mode (mode).exists (&imode))
3311 return NULL_RTX;
3312 op1 = gen_lowpart (imode, op1);
3314 else
3316 int word;
3318 imode = word_mode;
3319 if (FLOAT_WORDS_BIG_ENDIAN)
3320 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3321 else
3322 word = bitpos / BITS_PER_WORD;
3323 bitpos = bitpos % BITS_PER_WORD;
3324 op1 = operand_subword_force (op1, word, mode);
3327 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3328 sign = expand_binop (imode, and_optab, op1,
3329 immed_wide_int_const (mask, imode),
3330 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3333 if (!op0_is_abs)
3335 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3336 if (op0 == NULL)
3337 return NULL_RTX;
3338 target = op0;
3340 else
3342 if (target == NULL_RTX)
3343 target = copy_to_reg (op0);
3344 else
3345 emit_move_insn (target, op0);
3348 label = gen_label_rtx ();
3349 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3351 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3352 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3353 else
3354 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3355 if (op0 != target)
3356 emit_move_insn (target, op0);
3358 emit_label (label);
3360 return target;
3364 /* A subroutine of expand_copysign, perform the entire copysign operation
3365 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3366 is true if op0 is known to have its sign bit clear. */
3368 static rtx
3369 expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3370 int bitpos, bool op0_is_abs)
3372 scalar_int_mode imode;
3373 int word, nwords, i;
3374 rtx temp;
3375 rtx_insn *insns;
3377 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3379 if (!int_mode_for_mode (mode).exists (&imode))
3380 return NULL_RTX;
3381 word = 0;
3382 nwords = 1;
3384 else
3386 imode = word_mode;
3388 if (FLOAT_WORDS_BIG_ENDIAN)
3389 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3390 else
3391 word = bitpos / BITS_PER_WORD;
3392 bitpos = bitpos % BITS_PER_WORD;
3393 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3396 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3398 if (target == 0
3399 || target == op0
3400 || target == op1
3401 || (nwords > 1 && !valid_multiword_target_p (target)))
3402 target = gen_reg_rtx (mode);
3404 if (nwords > 1)
3406 start_sequence ();
3408 for (i = 0; i < nwords; ++i)
3410 rtx targ_piece = operand_subword (target, i, 1, mode);
3411 rtx op0_piece = operand_subword_force (op0, i, mode);
3413 if (i == word)
3415 if (!op0_is_abs)
3416 op0_piece
3417 = expand_binop (imode, and_optab, op0_piece,
3418 immed_wide_int_const (~mask, imode),
3419 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3420 op1 = expand_binop (imode, and_optab,
3421 operand_subword_force (op1, i, mode),
3422 immed_wide_int_const (mask, imode),
3423 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3425 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3426 targ_piece, 1, OPTAB_LIB_WIDEN);
3427 if (temp != targ_piece)
3428 emit_move_insn (targ_piece, temp);
3430 else
3431 emit_move_insn (targ_piece, op0_piece);
3434 insns = get_insns ();
3435 end_sequence ();
3437 emit_insn (insns);
3439 else
3441 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3442 immed_wide_int_const (mask, imode),
3443 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3445 op0 = gen_lowpart (imode, op0);
3446 if (!op0_is_abs)
3447 op0 = expand_binop (imode, and_optab, op0,
3448 immed_wide_int_const (~mask, imode),
3449 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3451 temp = expand_binop (imode, ior_optab, op0, op1,
3452 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3453 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3456 return target;
3459 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3460 scalar floating point mode. Return NULL if we do not know how to
3461 expand the operation inline. */
3464 expand_copysign (rtx op0, rtx op1, rtx target)
3466 scalar_float_mode mode;
3467 const struct real_format *fmt;
3468 bool op0_is_abs;
3469 rtx temp;
3471 mode = as_a <scalar_float_mode> (GET_MODE (op0));
3472 gcc_assert (GET_MODE (op1) == mode);
3474 /* First try to do it with a special instruction. */
3475 temp = expand_binop (mode, copysign_optab, op0, op1,
3476 target, 0, OPTAB_DIRECT);
3477 if (temp)
3478 return temp;
3480 fmt = REAL_MODE_FORMAT (mode);
3481 if (fmt == NULL || !fmt->has_signed_zero)
3482 return NULL_RTX;
3484 op0_is_abs = false;
3485 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3487 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3488 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3489 op0_is_abs = true;
3492 if (fmt->signbit_ro >= 0
3493 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3494 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3495 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3497 temp = expand_copysign_absneg (mode, op0, op1, target,
3498 fmt->signbit_ro, op0_is_abs);
3499 if (temp)
3500 return temp;
3503 if (fmt->signbit_rw < 0)
3504 return NULL_RTX;
3505 return expand_copysign_bit (mode, op0, op1, target,
3506 fmt->signbit_rw, op0_is_abs);
3509 /* Generate an instruction whose insn-code is INSN_CODE,
3510 with two operands: an output TARGET and an input OP0.
3511 TARGET *must* be nonzero, and the output is always stored there.
3512 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3513 the value that is stored into TARGET.
3515 Return false if expansion failed. */
3517 bool
3518 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3519 enum rtx_code code)
3521 struct expand_operand ops[2];
3522 rtx_insn *pat;
3524 create_output_operand (&ops[0], target, GET_MODE (target));
3525 create_input_operand (&ops[1], op0, GET_MODE (op0));
3526 pat = maybe_gen_insn (icode, 2, ops);
3527 if (!pat)
3528 return false;
3530 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3531 && code != UNKNOWN)
3532 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3534 emit_insn (pat);
3536 if (ops[0].value != target)
3537 emit_move_insn (target, ops[0].value);
3538 return true;
3540 /* Generate an instruction whose insn-code is INSN_CODE,
3541 with two operands: an output TARGET and an input OP0.
3542 TARGET *must* be nonzero, and the output is always stored there.
3543 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3544 the value that is stored into TARGET. */
3546 void
3547 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3549 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3550 gcc_assert (ok);
3553 struct no_conflict_data
3555 rtx target;
3556 rtx_insn *first, *insn;
3557 bool must_stay;
3560 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3561 the currently examined clobber / store has to stay in the list of
3562 insns that constitute the actual libcall block. */
3563 static void
3564 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3566 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3568 /* If this inns directly contributes to setting the target, it must stay. */
3569 if (reg_overlap_mentioned_p (p->target, dest))
3570 p->must_stay = true;
3571 /* If we haven't committed to keeping any other insns in the list yet,
3572 there is nothing more to check. */
3573 else if (p->insn == p->first)
3574 return;
3575 /* If this insn sets / clobbers a register that feeds one of the insns
3576 already in the list, this insn has to stay too. */
3577 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3578 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3579 || reg_used_between_p (dest, p->first, p->insn)
3580 /* Likewise if this insn depends on a register set by a previous
3581 insn in the list, or if it sets a result (presumably a hard
3582 register) that is set or clobbered by a previous insn.
3583 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3584 SET_DEST perform the former check on the address, and the latter
3585 check on the MEM. */
3586 || (GET_CODE (set) == SET
3587 && (modified_in_p (SET_SRC (set), p->first)
3588 || modified_in_p (SET_DEST (set), p->first)
3589 || modified_between_p (SET_SRC (set), p->first, p->insn)
3590 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3591 p->must_stay = true;
3595 /* Emit code to make a call to a constant function or a library call.
3597 INSNS is a list containing all insns emitted in the call.
3598 These insns leave the result in RESULT. Our block is to copy RESULT
3599 to TARGET, which is logically equivalent to EQUIV.
3601 We first emit any insns that set a pseudo on the assumption that these are
3602 loading constants into registers; doing so allows them to be safely cse'ed
3603 between blocks. Then we emit all the other insns in the block, followed by
3604 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3605 note with an operand of EQUIV. */
3607 static void
3608 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3609 bool equiv_may_trap)
3611 rtx final_dest = target;
3612 rtx_insn *next, *last, *insn;
3614 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3615 into a MEM later. Protect the libcall block from this change. */
3616 if (! REG_P (target) || REG_USERVAR_P (target))
3617 target = gen_reg_rtx (GET_MODE (target));
3619 /* If we're using non-call exceptions, a libcall corresponding to an
3620 operation that may trap may also trap. */
3621 /* ??? See the comment in front of make_reg_eh_region_note. */
3622 if (cfun->can_throw_non_call_exceptions
3623 && (equiv_may_trap || may_trap_p (equiv)))
3625 for (insn = insns; insn; insn = NEXT_INSN (insn))
3626 if (CALL_P (insn))
3628 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3629 if (note)
3631 int lp_nr = INTVAL (XEXP (note, 0));
3632 if (lp_nr == 0 || lp_nr == INT_MIN)
3633 remove_note (insn, note);
3637 else
3639 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3640 reg note to indicate that this call cannot throw or execute a nonlocal
3641 goto (unless there is already a REG_EH_REGION note, in which case
3642 we update it). */
3643 for (insn = insns; insn; insn = NEXT_INSN (insn))
3644 if (CALL_P (insn))
3645 make_reg_eh_region_note_nothrow_nononlocal (insn);
3648 /* First emit all insns that set pseudos. Remove them from the list as
3649 we go. Avoid insns that set pseudos which were referenced in previous
3650 insns. These can be generated by move_by_pieces, for example,
3651 to update an address. Similarly, avoid insns that reference things
3652 set in previous insns. */
3654 for (insn = insns; insn; insn = next)
3656 rtx set = single_set (insn);
3658 next = NEXT_INSN (insn);
3660 if (set != 0 && REG_P (SET_DEST (set))
3661 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3663 struct no_conflict_data data;
3665 data.target = const0_rtx;
3666 data.first = insns;
3667 data.insn = insn;
3668 data.must_stay = 0;
3669 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3670 if (! data.must_stay)
3672 if (PREV_INSN (insn))
3673 SET_NEXT_INSN (PREV_INSN (insn)) = next;
3674 else
3675 insns = next;
3677 if (next)
3678 SET_PREV_INSN (next) = PREV_INSN (insn);
3680 add_insn (insn);
3684 /* Some ports use a loop to copy large arguments onto the stack.
3685 Don't move anything outside such a loop. */
3686 if (LABEL_P (insn))
3687 break;
3690 /* Write the remaining insns followed by the final copy. */
3691 for (insn = insns; insn; insn = next)
3693 next = NEXT_INSN (insn);
3695 add_insn (insn);
3698 last = emit_move_insn (target, result);
3699 if (equiv)
3700 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3702 if (final_dest != target)
3703 emit_move_insn (final_dest, target);
3706 void
3707 emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
3709 emit_libcall_block_1 (insns, target, result, equiv, false);
3712 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3713 PURPOSE describes how this comparison will be used. CODE is the rtx
3714 comparison code we will be using.
3716 ??? Actually, CODE is slightly weaker than that. A target is still
3717 required to implement all of the normal bcc operations, but not
3718 required to implement all (or any) of the unordered bcc operations. */
3721 can_compare_p (enum rtx_code code, machine_mode mode,
3722 enum can_compare_purpose purpose)
3724 rtx test;
3725 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3728 enum insn_code icode;
3730 if (purpose == ccp_jump
3731 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3732 && insn_operand_matches (icode, 0, test))
3733 return 1;
3734 if (purpose == ccp_store_flag
3735 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3736 && insn_operand_matches (icode, 1, test))
3737 return 1;
3738 if (purpose == ccp_cmov
3739 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3740 return 1;
3742 mode = GET_MODE_WIDER_MODE (mode).else_void ();
3743 PUT_MODE (test, mode);
3745 while (mode != VOIDmode);
3747 return 0;
3750 /* This function is called when we are going to emit a compare instruction that
3751 compares the values found in X and Y, using the rtl operator COMPARISON.
3753 If they have mode BLKmode, then SIZE specifies the size of both operands.
3755 UNSIGNEDP nonzero says that the operands are unsigned;
3756 this matters if they need to be widened (as given by METHODS).
3758 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
3759 if we failed to produce one.
3761 *PMODE is the mode of the inputs (in case they are const_int).
3763 This function performs all the setup necessary so that the caller only has
3764 to emit a single comparison insn. This setup can involve doing a BLKmode
3765 comparison or emitting a library call to perform the comparison if no insn
3766 is available to handle it.
3767 The values which are passed in through pointers can be modified; the caller
3768 should perform the comparison on the modified values. Constant
3769 comparisons must have already been folded. */
3771 static void
3772 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3773 int unsignedp, enum optab_methods methods,
3774 rtx *ptest, machine_mode *pmode)
3776 machine_mode mode = *pmode;
3777 rtx libfunc, test;
3778 machine_mode cmp_mode;
3779 enum mode_class mclass;
3781 /* The other methods are not needed. */
3782 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3783 || methods == OPTAB_LIB_WIDEN);
3785 /* If we are optimizing, force expensive constants into a register. */
3786 if (CONSTANT_P (x) && optimize
3787 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
3788 > COSTS_N_INSNS (1)))
3789 x = force_reg (mode, x);
3791 if (CONSTANT_P (y) && optimize
3792 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
3793 > COSTS_N_INSNS (1)))
3794 y = force_reg (mode, y);
3796 #if HAVE_cc0
3797 /* Make sure if we have a canonical comparison. The RTL
3798 documentation states that canonical comparisons are required only
3799 for targets which have cc0. */
3800 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3801 #endif
3803 /* Don't let both operands fail to indicate the mode. */
3804 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3805 x = force_reg (mode, x);
3806 if (mode == VOIDmode)
3807 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3809 /* Handle all BLKmode compares. */
3811 if (mode == BLKmode)
3813 machine_mode result_mode;
3814 enum insn_code cmp_code;
3815 rtx result;
3816 rtx opalign
3817 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3819 gcc_assert (size);
3821 /* Try to use a memory block compare insn - either cmpstr
3822 or cmpmem will do. */
3823 opt_scalar_int_mode cmp_mode_iter;
3824 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT)
3826 scalar_int_mode cmp_mode = cmp_mode_iter.require ();
3827 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3828 if (cmp_code == CODE_FOR_nothing)
3829 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3830 if (cmp_code == CODE_FOR_nothing)
3831 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3832 if (cmp_code == CODE_FOR_nothing)
3833 continue;
3835 /* Must make sure the size fits the insn's mode. */
3836 if (CONST_INT_P (size)
3837 ? INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode))
3838 : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
3839 > GET_MODE_BITSIZE (cmp_mode)))
3840 continue;
3842 result_mode = insn_data[cmp_code].operand[0].mode;
3843 result = gen_reg_rtx (result_mode);
3844 size = convert_to_mode (cmp_mode, size, 1);
3845 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3847 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3848 *pmode = result_mode;
3849 return;
3852 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3853 goto fail;
3855 /* Otherwise call a library function. */
3856 result = emit_block_comp_via_libcall (XEXP (x, 0), XEXP (y, 0), size);
3858 x = result;
3859 y = const0_rtx;
3860 mode = TYPE_MODE (integer_type_node);
3861 methods = OPTAB_LIB_WIDEN;
3862 unsignedp = false;
3865 /* Don't allow operands to the compare to trap, as that can put the
3866 compare and branch in different basic blocks. */
3867 if (cfun->can_throw_non_call_exceptions)
3869 if (may_trap_p (x))
3870 x = copy_to_reg (x);
3871 if (may_trap_p (y))
3872 y = copy_to_reg (y);
3875 if (GET_MODE_CLASS (mode) == MODE_CC)
3877 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
3878 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3879 gcc_assert (icode != CODE_FOR_nothing
3880 && insn_operand_matches (icode, 0, test));
3881 *ptest = test;
3882 return;
3885 mclass = GET_MODE_CLASS (mode);
3886 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3887 FOR_EACH_MODE_FROM (cmp_mode, mode)
3889 enum insn_code icode;
3890 icode = optab_handler (cbranch_optab, cmp_mode);
3891 if (icode != CODE_FOR_nothing
3892 && insn_operand_matches (icode, 0, test))
3894 rtx_insn *last = get_last_insn ();
3895 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3896 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3897 if (op0 && op1
3898 && insn_operand_matches (icode, 1, op0)
3899 && insn_operand_matches (icode, 2, op1))
3901 XEXP (test, 0) = op0;
3902 XEXP (test, 1) = op1;
3903 *ptest = test;
3904 *pmode = cmp_mode;
3905 return;
3907 delete_insns_since (last);
3910 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3911 break;
3914 if (methods != OPTAB_LIB_WIDEN)
3915 goto fail;
3917 if (!SCALAR_FLOAT_MODE_P (mode))
3919 rtx result;
3920 machine_mode ret_mode;
3922 /* Handle a libcall just for the mode we are using. */
3923 libfunc = optab_libfunc (cmp_optab, mode);
3924 gcc_assert (libfunc);
3926 /* If we want unsigned, and this mode has a distinct unsigned
3927 comparison routine, use that. */
3928 if (unsignedp)
3930 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
3931 if (ulibfunc)
3932 libfunc = ulibfunc;
3935 ret_mode = targetm.libgcc_cmp_return_mode ();
3936 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3937 ret_mode, x, mode, y, mode);
3939 /* There are two kinds of comparison routines. Biased routines
3940 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3941 of gcc expect that the comparison operation is equivalent
3942 to the modified comparison. For signed comparisons compare the
3943 result against 1 in the biased case, and zero in the unbiased
3944 case. For unsigned comparisons always compare against 1 after
3945 biasing the unbiased result by adding 1. This gives us a way to
3946 represent LTU.
3947 The comparisons in the fixed-point helper library are always
3948 biased. */
3949 x = result;
3950 y = const1_rtx;
3952 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
3954 if (unsignedp)
3955 x = plus_constant (ret_mode, result, 1);
3956 else
3957 y = const0_rtx;
3960 *pmode = ret_mode;
3961 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
3962 ptest, pmode);
3964 else
3965 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
3967 return;
3969 fail:
3970 *ptest = NULL_RTX;
3973 /* Before emitting an insn with code ICODE, make sure that X, which is going
3974 to be used for operand OPNUM of the insn, is converted from mode MODE to
3975 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3976 that it is accepted by the operand predicate. Return the new value. */
3979 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
3980 machine_mode wider_mode, int unsignedp)
3982 if (mode != wider_mode)
3983 x = convert_modes (wider_mode, mode, x, unsignedp);
3985 if (!insn_operand_matches (icode, opnum, x))
3987 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
3988 if (reload_completed)
3989 return NULL_RTX;
3990 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
3991 return NULL_RTX;
3992 x = copy_to_mode_reg (op_mode, x);
3995 return x;
3998 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3999 we can do the branch. */
4001 static void
4002 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
4003 profile_probability prob)
4005 machine_mode optab_mode;
4006 enum mode_class mclass;
4007 enum insn_code icode;
4008 rtx_insn *insn;
4010 mclass = GET_MODE_CLASS (mode);
4011 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4012 icode = optab_handler (cbranch_optab, optab_mode);
4014 gcc_assert (icode != CODE_FOR_nothing);
4015 gcc_assert (insn_operand_matches (icode, 0, test));
4016 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4017 XEXP (test, 1), label));
4018 if (prob.initialized_p ()
4019 && profile_status_for_fn (cfun) != PROFILE_ABSENT
4020 && insn
4021 && JUMP_P (insn)
4022 && any_condjump_p (insn)
4023 && !find_reg_note (insn, REG_BR_PROB, 0))
4024 add_reg_br_prob_note (insn, prob);
4027 /* Generate code to compare X with Y so that the condition codes are
4028 set and to jump to LABEL if the condition is true. If X is a
4029 constant and Y is not a constant, then the comparison is swapped to
4030 ensure that the comparison RTL has the canonical form.
4032 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4033 need to be widened. UNSIGNEDP is also used to select the proper
4034 branch condition code.
4036 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4038 MODE is the mode of the inputs (in case they are const_int).
4040 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4041 It will be potentially converted into an unsigned variant based on
4042 UNSIGNEDP to select a proper jump instruction.
4044 PROB is the probability of jumping to LABEL. */
4046 void
4047 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4048 machine_mode mode, int unsignedp, rtx label,
4049 profile_probability prob)
4051 rtx op0 = x, op1 = y;
4052 rtx test;
4054 /* Swap operands and condition to ensure canonical RTL. */
4055 if (swap_commutative_operands_p (x, y)
4056 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4058 op0 = y, op1 = x;
4059 comparison = swap_condition (comparison);
4062 /* If OP0 is still a constant, then both X and Y must be constants
4063 or the opposite comparison is not supported. Force X into a register
4064 to create canonical RTL. */
4065 if (CONSTANT_P (op0))
4066 op0 = force_reg (mode, op0);
4068 if (unsignedp)
4069 comparison = unsigned_condition (comparison);
4071 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4072 &test, &mode);
4073 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4077 /* Emit a library call comparison between floating point X and Y.
4078 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4080 static void
4081 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4082 rtx *ptest, machine_mode *pmode)
4084 enum rtx_code swapped = swap_condition (comparison);
4085 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4086 machine_mode orig_mode = GET_MODE (x);
4087 machine_mode mode;
4088 rtx true_rtx, false_rtx;
4089 rtx value, target, equiv;
4090 rtx_insn *insns;
4091 rtx libfunc = 0;
4092 bool reversed_p = false;
4093 scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
4095 FOR_EACH_MODE_FROM (mode, orig_mode)
4097 if (code_to_optab (comparison)
4098 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4099 break;
4101 if (code_to_optab (swapped)
4102 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4104 std::swap (x, y);
4105 comparison = swapped;
4106 break;
4109 if (code_to_optab (reversed)
4110 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4112 comparison = reversed;
4113 reversed_p = true;
4114 break;
4118 gcc_assert (mode != VOIDmode);
4120 if (mode != orig_mode)
4122 x = convert_to_mode (mode, x, 0);
4123 y = convert_to_mode (mode, y, 0);
4126 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4127 the RTL. The allows the RTL optimizers to delete the libcall if the
4128 condition can be determined at compile-time. */
4129 if (comparison == UNORDERED
4130 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4132 true_rtx = const_true_rtx;
4133 false_rtx = const0_rtx;
4135 else
4137 switch (comparison)
4139 case EQ:
4140 true_rtx = const0_rtx;
4141 false_rtx = const_true_rtx;
4142 break;
4144 case NE:
4145 true_rtx = const_true_rtx;
4146 false_rtx = const0_rtx;
4147 break;
4149 case GT:
4150 true_rtx = const1_rtx;
4151 false_rtx = const0_rtx;
4152 break;
4154 case GE:
4155 true_rtx = const0_rtx;
4156 false_rtx = constm1_rtx;
4157 break;
4159 case LT:
4160 true_rtx = constm1_rtx;
4161 false_rtx = const0_rtx;
4162 break;
4164 case LE:
4165 true_rtx = const0_rtx;
4166 false_rtx = const1_rtx;
4167 break;
4169 default:
4170 gcc_unreachable ();
4174 if (comparison == UNORDERED)
4176 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4177 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4178 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4179 temp, const_true_rtx, equiv);
4181 else
4183 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4184 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4185 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4186 equiv, true_rtx, false_rtx);
4189 start_sequence ();
4190 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4191 cmp_mode, x, mode, y, mode);
4192 insns = get_insns ();
4193 end_sequence ();
4195 target = gen_reg_rtx (cmp_mode);
4196 emit_libcall_block (insns, target, value, equiv);
4198 if (comparison == UNORDERED
4199 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4200 || reversed_p)
4201 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4202 else
4203 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4205 *pmode = cmp_mode;
4208 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4210 void
4211 emit_indirect_jump (rtx loc)
4213 if (!targetm.have_indirect_jump ())
4214 sorry ("indirect jumps are not available on this target");
4215 else
4217 struct expand_operand ops[1];
4218 create_address_operand (&ops[0], loc);
4219 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4220 emit_barrier ();
4225 /* Emit a conditional move instruction if the machine supports one for that
4226 condition and machine mode.
4228 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4229 the mode to use should they be constants. If it is VOIDmode, they cannot
4230 both be constants.
4232 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4233 should be stored there. MODE is the mode to use should they be constants.
4234 If it is VOIDmode, they cannot both be constants.
4236 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4237 is not supported. */
4240 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4241 machine_mode cmode, rtx op2, rtx op3,
4242 machine_mode mode, int unsignedp)
4244 rtx comparison;
4245 rtx_insn *last;
4246 enum insn_code icode;
4247 enum rtx_code reversed;
4249 /* If the two source operands are identical, that's just a move. */
4251 if (rtx_equal_p (op2, op3))
4253 if (!target)
4254 target = gen_reg_rtx (mode);
4256 emit_move_insn (target, op3);
4257 return target;
4260 /* If one operand is constant, make it the second one. Only do this
4261 if the other operand is not constant as well. */
4263 if (swap_commutative_operands_p (op0, op1))
4265 std::swap (op0, op1);
4266 code = swap_condition (code);
4269 /* get_condition will prefer to generate LT and GT even if the old
4270 comparison was against zero, so undo that canonicalization here since
4271 comparisons against zero are cheaper. */
4272 if (code == LT && op1 == const1_rtx)
4273 code = LE, op1 = const0_rtx;
4274 else if (code == GT && op1 == constm1_rtx)
4275 code = GE, op1 = const0_rtx;
4277 if (cmode == VOIDmode)
4278 cmode = GET_MODE (op0);
4280 enum rtx_code orig_code = code;
4281 bool swapped = false;
4282 if (swap_commutative_operands_p (op2, op3)
4283 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4284 != UNKNOWN))
4286 std::swap (op2, op3);
4287 code = reversed;
4288 swapped = true;
4291 if (mode == VOIDmode)
4292 mode = GET_MODE (op2);
4294 icode = direct_optab_handler (movcc_optab, mode);
4296 if (icode == CODE_FOR_nothing)
4297 return NULL_RTX;
4299 if (!target)
4300 target = gen_reg_rtx (mode);
4302 for (int pass = 0; ; pass++)
4304 code = unsignedp ? unsigned_condition (code) : code;
4305 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4307 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4308 punt and let the caller figure out how best to deal with this
4309 situation. */
4310 if (COMPARISON_P (comparison))
4312 saved_pending_stack_adjust save;
4313 save_pending_stack_adjust (&save);
4314 last = get_last_insn ();
4315 do_pending_stack_adjust ();
4316 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4317 GET_CODE (comparison), NULL_RTX, unsignedp,
4318 OPTAB_WIDEN, &comparison, &cmode);
4319 if (comparison)
4321 struct expand_operand ops[4];
4323 create_output_operand (&ops[0], target, mode);
4324 create_fixed_operand (&ops[1], comparison);
4325 create_input_operand (&ops[2], op2, mode);
4326 create_input_operand (&ops[3], op3, mode);
4327 if (maybe_expand_insn (icode, 4, ops))
4329 if (ops[0].value != target)
4330 convert_move (target, ops[0].value, false);
4331 return target;
4334 delete_insns_since (last);
4335 restore_pending_stack_adjust (&save);
4338 if (pass == 1)
4339 return NULL_RTX;
4341 /* If the preferred op2/op3 order is not usable, retry with other
4342 operand order, perhaps it will expand successfully. */
4343 if (swapped)
4344 code = orig_code;
4345 else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1,
4346 NULL))
4347 != UNKNOWN)
4348 code = reversed;
4349 else
4350 return NULL_RTX;
4351 std::swap (op2, op3);
4356 /* Emit a conditional negate or bitwise complement using the
4357 negcc or notcc optabs if available. Return NULL_RTX if such operations
4358 are not available. Otherwise return the RTX holding the result.
4359 TARGET is the desired destination of the result. COMP is the comparison
4360 on which to negate. If COND is true move into TARGET the negation
4361 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4362 CODE is either NEG or NOT. MODE is the machine mode in which the
4363 operation is performed. */
4366 emit_conditional_neg_or_complement (rtx target, rtx_code code,
4367 machine_mode mode, rtx cond, rtx op1,
4368 rtx op2)
4370 optab op = unknown_optab;
4371 if (code == NEG)
4372 op = negcc_optab;
4373 else if (code == NOT)
4374 op = notcc_optab;
4375 else
4376 gcc_unreachable ();
4378 insn_code icode = direct_optab_handler (op, mode);
4380 if (icode == CODE_FOR_nothing)
4381 return NULL_RTX;
4383 if (!target)
4384 target = gen_reg_rtx (mode);
4386 rtx_insn *last = get_last_insn ();
4387 struct expand_operand ops[4];
4389 create_output_operand (&ops[0], target, mode);
4390 create_fixed_operand (&ops[1], cond);
4391 create_input_operand (&ops[2], op1, mode);
4392 create_input_operand (&ops[3], op2, mode);
4394 if (maybe_expand_insn (icode, 4, ops))
4396 if (ops[0].value != target)
4397 convert_move (target, ops[0].value, false);
4399 return target;
4401 delete_insns_since (last);
4402 return NULL_RTX;
4405 /* Emit a conditional addition instruction if the machine supports one for that
4406 condition and machine mode.
4408 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4409 the mode to use should they be constants. If it is VOIDmode, they cannot
4410 both be constants.
4412 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4413 should be stored there. MODE is the mode to use should they be constants.
4414 If it is VOIDmode, they cannot both be constants.
4416 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4417 is not supported. */
4420 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4421 machine_mode cmode, rtx op2, rtx op3,
4422 machine_mode mode, int unsignedp)
4424 rtx comparison;
4425 rtx_insn *last;
4426 enum insn_code icode;
4428 /* If one operand is constant, make it the second one. Only do this
4429 if the other operand is not constant as well. */
4431 if (swap_commutative_operands_p (op0, op1))
4433 std::swap (op0, op1);
4434 code = swap_condition (code);
4437 /* get_condition will prefer to generate LT and GT even if the old
4438 comparison was against zero, so undo that canonicalization here since
4439 comparisons against zero are cheaper. */
4440 if (code == LT && op1 == const1_rtx)
4441 code = LE, op1 = const0_rtx;
4442 else if (code == GT && op1 == constm1_rtx)
4443 code = GE, op1 = const0_rtx;
4445 if (cmode == VOIDmode)
4446 cmode = GET_MODE (op0);
4448 if (mode == VOIDmode)
4449 mode = GET_MODE (op2);
4451 icode = optab_handler (addcc_optab, mode);
4453 if (icode == CODE_FOR_nothing)
4454 return 0;
4456 if (!target)
4457 target = gen_reg_rtx (mode);
4459 code = unsignedp ? unsigned_condition (code) : code;
4460 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4462 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4463 return NULL and let the caller figure out how best to deal with this
4464 situation. */
4465 if (!COMPARISON_P (comparison))
4466 return NULL_RTX;
4468 do_pending_stack_adjust ();
4469 last = get_last_insn ();
4470 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4471 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4472 &comparison, &cmode);
4473 if (comparison)
4475 struct expand_operand ops[4];
4477 create_output_operand (&ops[0], target, mode);
4478 create_fixed_operand (&ops[1], comparison);
4479 create_input_operand (&ops[2], op2, mode);
4480 create_input_operand (&ops[3], op3, mode);
4481 if (maybe_expand_insn (icode, 4, ops))
4483 if (ops[0].value != target)
4484 convert_move (target, ops[0].value, false);
4485 return target;
4488 delete_insns_since (last);
4489 return NULL_RTX;
4492 /* These functions attempt to generate an insn body, rather than
4493 emitting the insn, but if the gen function already emits them, we
4494 make no attempt to turn them back into naked patterns. */
4496 /* Generate and return an insn body to add Y to X. */
4498 rtx_insn *
4499 gen_add2_insn (rtx x, rtx y)
4501 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4503 gcc_assert (insn_operand_matches (icode, 0, x));
4504 gcc_assert (insn_operand_matches (icode, 1, x));
4505 gcc_assert (insn_operand_matches (icode, 2, y));
4507 return GEN_FCN (icode) (x, x, y);
4510 /* Generate and return an insn body to add r1 and c,
4511 storing the result in r0. */
4513 rtx_insn *
4514 gen_add3_insn (rtx r0, rtx r1, rtx c)
4516 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4518 if (icode == CODE_FOR_nothing
4519 || !insn_operand_matches (icode, 0, r0)
4520 || !insn_operand_matches (icode, 1, r1)
4521 || !insn_operand_matches (icode, 2, c))
4522 return NULL;
4524 return GEN_FCN (icode) (r0, r1, c);
4528 have_add2_insn (rtx x, rtx y)
4530 enum insn_code icode;
4532 gcc_assert (GET_MODE (x) != VOIDmode);
4534 icode = optab_handler (add_optab, GET_MODE (x));
4536 if (icode == CODE_FOR_nothing)
4537 return 0;
4539 if (!insn_operand_matches (icode, 0, x)
4540 || !insn_operand_matches (icode, 1, x)
4541 || !insn_operand_matches (icode, 2, y))
4542 return 0;
4544 return 1;
4547 /* Generate and return an insn body to add Y to X. */
4549 rtx_insn *
4550 gen_addptr3_insn (rtx x, rtx y, rtx z)
4552 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4554 gcc_assert (insn_operand_matches (icode, 0, x));
4555 gcc_assert (insn_operand_matches (icode, 1, y));
4556 gcc_assert (insn_operand_matches (icode, 2, z));
4558 return GEN_FCN (icode) (x, y, z);
4561 /* Return true if the target implements an addptr pattern and X, Y,
4562 and Z are valid for the pattern predicates. */
4565 have_addptr3_insn (rtx x, rtx y, rtx z)
4567 enum insn_code icode;
4569 gcc_assert (GET_MODE (x) != VOIDmode);
4571 icode = optab_handler (addptr3_optab, GET_MODE (x));
4573 if (icode == CODE_FOR_nothing)
4574 return 0;
4576 if (!insn_operand_matches (icode, 0, x)
4577 || !insn_operand_matches (icode, 1, y)
4578 || !insn_operand_matches (icode, 2, z))
4579 return 0;
4581 return 1;
4584 /* Generate and return an insn body to subtract Y from X. */
4586 rtx_insn *
4587 gen_sub2_insn (rtx x, rtx y)
4589 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4591 gcc_assert (insn_operand_matches (icode, 0, x));
4592 gcc_assert (insn_operand_matches (icode, 1, x));
4593 gcc_assert (insn_operand_matches (icode, 2, y));
4595 return GEN_FCN (icode) (x, x, y);
4598 /* Generate and return an insn body to subtract r1 and c,
4599 storing the result in r0. */
4601 rtx_insn *
4602 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4604 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4606 if (icode == CODE_FOR_nothing
4607 || !insn_operand_matches (icode, 0, r0)
4608 || !insn_operand_matches (icode, 1, r1)
4609 || !insn_operand_matches (icode, 2, c))
4610 return NULL;
4612 return GEN_FCN (icode) (r0, r1, c);
4616 have_sub2_insn (rtx x, rtx y)
4618 enum insn_code icode;
4620 gcc_assert (GET_MODE (x) != VOIDmode);
4622 icode = optab_handler (sub_optab, GET_MODE (x));
4624 if (icode == CODE_FOR_nothing)
4625 return 0;
4627 if (!insn_operand_matches (icode, 0, x)
4628 || !insn_operand_matches (icode, 1, x)
4629 || !insn_operand_matches (icode, 2, y))
4630 return 0;
4632 return 1;
4635 /* Generate the body of an insn to extend Y (with mode MFROM)
4636 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4638 rtx_insn *
4639 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4640 machine_mode mfrom, int unsignedp)
4642 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4643 return GEN_FCN (icode) (x, y);
4646 /* Generate code to convert FROM to floating point
4647 and store in TO. FROM must be fixed point and not VOIDmode.
4648 UNSIGNEDP nonzero means regard FROM as unsigned.
4649 Normally this is done by correcting the final value
4650 if it is negative. */
4652 void
4653 expand_float (rtx to, rtx from, int unsignedp)
4655 enum insn_code icode;
4656 rtx target = to;
4657 scalar_mode from_mode, to_mode;
4658 machine_mode fmode, imode;
4659 bool can_do_signed = false;
4661 /* Crash now, because we won't be able to decide which mode to use. */
4662 gcc_assert (GET_MODE (from) != VOIDmode);
4664 /* Look for an insn to do the conversion. Do it in the specified
4665 modes if possible; otherwise convert either input, output or both to
4666 wider mode. If the integer mode is wider than the mode of FROM,
4667 we can do the conversion signed even if the input is unsigned. */
4669 FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
4670 FOR_EACH_MODE_FROM (imode, GET_MODE (from))
4672 int doing_unsigned = unsignedp;
4674 if (fmode != GET_MODE (to)
4675 && (significand_size (fmode)
4676 < GET_MODE_UNIT_PRECISION (GET_MODE (from))))
4677 continue;
4679 icode = can_float_p (fmode, imode, unsignedp);
4680 if (icode == CODE_FOR_nothing && unsignedp)
4682 enum insn_code scode = can_float_p (fmode, imode, 0);
4683 if (scode != CODE_FOR_nothing)
4684 can_do_signed = true;
4685 if (imode != GET_MODE (from))
4686 icode = scode, doing_unsigned = 0;
4689 if (icode != CODE_FOR_nothing)
4691 if (imode != GET_MODE (from))
4692 from = convert_to_mode (imode, from, unsignedp);
4694 if (fmode != GET_MODE (to))
4695 target = gen_reg_rtx (fmode);
4697 emit_unop_insn (icode, target, from,
4698 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4700 if (target != to)
4701 convert_move (to, target, 0);
4702 return;
4706 /* Unsigned integer, and no way to convert directly. Convert as signed,
4707 then unconditionally adjust the result. */
4708 if (unsignedp
4709 && can_do_signed
4710 && is_a <scalar_mode> (GET_MODE (to), &to_mode)
4711 && is_a <scalar_mode> (GET_MODE (from), &from_mode))
4713 opt_scalar_mode fmode_iter;
4714 rtx_code_label *label = gen_label_rtx ();
4715 rtx temp;
4716 REAL_VALUE_TYPE offset;
4718 /* Look for a usable floating mode FMODE wider than the source and at
4719 least as wide as the target. Using FMODE will avoid rounding woes
4720 with unsigned values greater than the signed maximum value. */
4722 FOR_EACH_MODE_FROM (fmode_iter, to_mode)
4724 scalar_mode fmode = fmode_iter.require ();
4725 if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
4726 && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
4727 break;
4730 if (!fmode_iter.exists (&fmode))
4732 /* There is no such mode. Pretend the target is wide enough. */
4733 fmode = to_mode;
4735 /* Avoid double-rounding when TO is narrower than FROM. */
4736 if ((significand_size (fmode) + 1)
4737 < GET_MODE_PRECISION (from_mode))
4739 rtx temp1;
4740 rtx_code_label *neglabel = gen_label_rtx ();
4742 /* Don't use TARGET if it isn't a register, is a hard register,
4743 or is the wrong mode. */
4744 if (!REG_P (target)
4745 || REGNO (target) < FIRST_PSEUDO_REGISTER
4746 || GET_MODE (target) != fmode)
4747 target = gen_reg_rtx (fmode);
4749 imode = from_mode;
4750 do_pending_stack_adjust ();
4752 /* Test whether the sign bit is set. */
4753 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4754 0, neglabel);
4756 /* The sign bit is not set. Convert as signed. */
4757 expand_float (target, from, 0);
4758 emit_jump_insn (targetm.gen_jump (label));
4759 emit_barrier ();
4761 /* The sign bit is set.
4762 Convert to a usable (positive signed) value by shifting right
4763 one bit, while remembering if a nonzero bit was shifted
4764 out; i.e., compute (from & 1) | (from >> 1). */
4766 emit_label (neglabel);
4767 temp = expand_binop (imode, and_optab, from, const1_rtx,
4768 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4769 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4770 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4771 OPTAB_LIB_WIDEN);
4772 expand_float (target, temp, 0);
4774 /* Multiply by 2 to undo the shift above. */
4775 temp = expand_binop (fmode, add_optab, target, target,
4776 target, 0, OPTAB_LIB_WIDEN);
4777 if (temp != target)
4778 emit_move_insn (target, temp);
4780 do_pending_stack_adjust ();
4781 emit_label (label);
4782 goto done;
4786 /* If we are about to do some arithmetic to correct for an
4787 unsigned operand, do it in a pseudo-register. */
4789 if (to_mode != fmode
4790 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4791 target = gen_reg_rtx (fmode);
4793 /* Convert as signed integer to floating. */
4794 expand_float (target, from, 0);
4796 /* If FROM is negative (and therefore TO is negative),
4797 correct its value by 2**bitwidth. */
4799 do_pending_stack_adjust ();
4800 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
4801 0, label);
4804 real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
4805 temp = expand_binop (fmode, add_optab, target,
4806 const_double_from_real_value (offset, fmode),
4807 target, 0, OPTAB_LIB_WIDEN);
4808 if (temp != target)
4809 emit_move_insn (target, temp);
4811 do_pending_stack_adjust ();
4812 emit_label (label);
4813 goto done;
4816 /* No hardware instruction available; call a library routine. */
4818 rtx libfunc;
4819 rtx_insn *insns;
4820 rtx value;
4821 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4823 if (is_narrower_int_mode (GET_MODE (from), SImode))
4824 from = convert_to_mode (SImode, from, unsignedp);
4826 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4827 gcc_assert (libfunc);
4829 start_sequence ();
4831 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4832 GET_MODE (to), from, GET_MODE (from));
4833 insns = get_insns ();
4834 end_sequence ();
4836 emit_libcall_block (insns, target, value,
4837 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4838 GET_MODE (to), from));
4841 done:
4843 /* Copy result to requested destination
4844 if we have been computing in a temp location. */
4846 if (target != to)
4848 if (GET_MODE (target) == GET_MODE (to))
4849 emit_move_insn (to, target);
4850 else
4851 convert_move (to, target, 0);
4855 /* Generate code to convert FROM to fixed point and store in TO. FROM
4856 must be floating point. */
4858 void
4859 expand_fix (rtx to, rtx from, int unsignedp)
4861 enum insn_code icode;
4862 rtx target = to;
4863 machine_mode fmode, imode;
4864 opt_scalar_mode fmode_iter;
4865 bool must_trunc = false;
4867 /* We first try to find a pair of modes, one real and one integer, at
4868 least as wide as FROM and TO, respectively, in which we can open-code
4869 this conversion. If the integer mode is wider than the mode of TO,
4870 we can do the conversion either signed or unsigned. */
4872 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
4873 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
4875 int doing_unsigned = unsignedp;
4877 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4878 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4879 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4881 if (icode != CODE_FOR_nothing)
4883 rtx_insn *last = get_last_insn ();
4884 if (fmode != GET_MODE (from))
4885 from = convert_to_mode (fmode, from, 0);
4887 if (must_trunc)
4889 rtx temp = gen_reg_rtx (GET_MODE (from));
4890 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4891 temp, 0);
4894 if (imode != GET_MODE (to))
4895 target = gen_reg_rtx (imode);
4897 if (maybe_emit_unop_insn (icode, target, from,
4898 doing_unsigned ? UNSIGNED_FIX : FIX))
4900 if (target != to)
4901 convert_move (to, target, unsignedp);
4902 return;
4904 delete_insns_since (last);
4908 /* For an unsigned conversion, there is one more way to do it.
4909 If we have a signed conversion, we generate code that compares
4910 the real value to the largest representable positive number. If if
4911 is smaller, the conversion is done normally. Otherwise, subtract
4912 one plus the highest signed number, convert, and add it back.
4914 We only need to check all real modes, since we know we didn't find
4915 anything with a wider integer mode.
4917 This code used to extend FP value into mode wider than the destination.
4918 This is needed for decimal float modes which cannot accurately
4919 represent one plus the highest signed number of the same size, but
4920 not for binary modes. Consider, for instance conversion from SFmode
4921 into DImode.
4923 The hot path through the code is dealing with inputs smaller than 2^63
4924 and doing just the conversion, so there is no bits to lose.
4926 In the other path we know the value is positive in the range 2^63..2^64-1
4927 inclusive. (as for other input overflow happens and result is undefined)
4928 So we know that the most important bit set in mantissa corresponds to
4929 2^63. The subtraction of 2^63 should not generate any rounding as it
4930 simply clears out that bit. The rest is trivial. */
4932 scalar_int_mode to_mode;
4933 if (unsignedp
4934 && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
4935 && HWI_COMPUTABLE_MODE_P (to_mode))
4936 FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
4938 scalar_mode fmode = fmode_iter.require ();
4939 if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
4940 0, &must_trunc)
4941 && (!DECIMAL_FLOAT_MODE_P (fmode)
4942 || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
4944 int bitsize;
4945 REAL_VALUE_TYPE offset;
4946 rtx limit;
4947 rtx_code_label *lab1, *lab2;
4948 rtx_insn *insn;
4950 bitsize = GET_MODE_PRECISION (to_mode);
4951 real_2expN (&offset, bitsize - 1, fmode);
4952 limit = const_double_from_real_value (offset, fmode);
4953 lab1 = gen_label_rtx ();
4954 lab2 = gen_label_rtx ();
4956 if (fmode != GET_MODE (from))
4957 from = convert_to_mode (fmode, from, 0);
4959 /* See if we need to do the subtraction. */
4960 do_pending_stack_adjust ();
4961 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
4962 GET_MODE (from), 0, lab1);
4964 /* If not, do the signed "fix" and branch around fixup code. */
4965 expand_fix (to, from, 0);
4966 emit_jump_insn (targetm.gen_jump (lab2));
4967 emit_barrier ();
4969 /* Otherwise, subtract 2**(N-1), convert to signed number,
4970 then add 2**(N-1). Do the addition using XOR since this
4971 will often generate better code. */
4972 emit_label (lab1);
4973 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4974 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4975 expand_fix (to, target, 0);
4976 target = expand_binop (to_mode, xor_optab, to,
4977 gen_int_mode
4978 (HOST_WIDE_INT_1 << (bitsize - 1),
4979 to_mode),
4980 to, 1, OPTAB_LIB_WIDEN);
4982 if (target != to)
4983 emit_move_insn (to, target);
4985 emit_label (lab2);
4987 if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
4989 /* Make a place for a REG_NOTE and add it. */
4990 insn = emit_move_insn (to, to);
4991 set_dst_reg_note (insn, REG_EQUAL,
4992 gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
4993 copy_rtx (from)),
4994 to);
4997 return;
5001 /* We can't do it with an insn, so use a library call. But first ensure
5002 that the mode of TO is at least as wide as SImode, since those are the
5003 only library calls we know about. */
5005 if (is_narrower_int_mode (GET_MODE (to), SImode))
5007 target = gen_reg_rtx (SImode);
5009 expand_fix (target, from, unsignedp);
5011 else
5013 rtx_insn *insns;
5014 rtx value;
5015 rtx libfunc;
5017 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5018 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5019 gcc_assert (libfunc);
5021 start_sequence ();
5023 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5024 GET_MODE (to), from, GET_MODE (from));
5025 insns = get_insns ();
5026 end_sequence ();
5028 emit_libcall_block (insns, target, value,
5029 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5030 GET_MODE (to), from));
5033 if (target != to)
5035 if (GET_MODE (to) == GET_MODE (target))
5036 emit_move_insn (to, target);
5037 else
5038 convert_move (to, target, 0);
5043 /* Promote integer arguments for a libcall if necessary.
5044 emit_library_call_value cannot do the promotion because it does not
5045 know if it should do a signed or unsigned promotion. This is because
5046 there are no tree types defined for libcalls. */
5048 static rtx
5049 prepare_libcall_arg (rtx arg, int uintp)
5051 scalar_int_mode mode;
5052 machine_mode arg_mode;
5053 if (is_a <scalar_int_mode> (GET_MODE (arg), &mode))
5055 /* If we need to promote the integer function argument we need to do
5056 it here instead of inside emit_library_call_value because in
5057 emit_library_call_value we don't know if we should do a signed or
5058 unsigned promotion. */
5060 int unsigned_p = 0;
5061 arg_mode = promote_function_mode (NULL_TREE, mode,
5062 &unsigned_p, NULL_TREE, 0);
5063 if (arg_mode != mode)
5064 return convert_to_mode (arg_mode, arg, uintp);
5066 return arg;
5069 /* Generate code to convert FROM or TO a fixed-point.
5070 If UINTP is true, either TO or FROM is an unsigned integer.
5071 If SATP is true, we need to saturate the result. */
5073 void
5074 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5076 machine_mode to_mode = GET_MODE (to);
5077 machine_mode from_mode = GET_MODE (from);
5078 convert_optab tab;
5079 enum rtx_code this_code;
5080 enum insn_code code;
5081 rtx_insn *insns;
5082 rtx value;
5083 rtx libfunc;
5085 if (to_mode == from_mode)
5087 emit_move_insn (to, from);
5088 return;
5091 if (uintp)
5093 tab = satp ? satfractuns_optab : fractuns_optab;
5094 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5096 else
5098 tab = satp ? satfract_optab : fract_optab;
5099 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5101 code = convert_optab_handler (tab, to_mode, from_mode);
5102 if (code != CODE_FOR_nothing)
5104 emit_unop_insn (code, to, from, this_code);
5105 return;
5108 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5109 gcc_assert (libfunc);
5111 from = prepare_libcall_arg (from, uintp);
5112 from_mode = GET_MODE (from);
5114 start_sequence ();
5115 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5116 from, from_mode);
5117 insns = get_insns ();
5118 end_sequence ();
5120 emit_libcall_block (insns, to, value,
5121 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5124 /* Generate code to convert FROM to fixed point and store in TO. FROM
5125 must be floating point, TO must be signed. Use the conversion optab
5126 TAB to do the conversion. */
5128 bool
5129 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5131 enum insn_code icode;
5132 rtx target = to;
5133 machine_mode fmode, imode;
5135 /* We first try to find a pair of modes, one real and one integer, at
5136 least as wide as FROM and TO, respectively, in which we can open-code
5137 this conversion. If the integer mode is wider than the mode of TO,
5138 we can do the conversion either signed or unsigned. */
5140 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5141 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5143 icode = convert_optab_handler (tab, imode, fmode);
5144 if (icode != CODE_FOR_nothing)
5146 rtx_insn *last = get_last_insn ();
5147 if (fmode != GET_MODE (from))
5148 from = convert_to_mode (fmode, from, 0);
5150 if (imode != GET_MODE (to))
5151 target = gen_reg_rtx (imode);
5153 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5155 delete_insns_since (last);
5156 continue;
5158 if (target != to)
5159 convert_move (to, target, 0);
5160 return true;
5164 return false;
5167 /* Report whether we have an instruction to perform the operation
5168 specified by CODE on operands of mode MODE. */
5170 have_insn_for (enum rtx_code code, machine_mode mode)
5172 return (code_to_optab (code)
5173 && (optab_handler (code_to_optab (code), mode)
5174 != CODE_FOR_nothing));
5177 /* Print information about the current contents of the optabs on
5178 STDERR. */
5180 DEBUG_FUNCTION void
5181 debug_optab_libfuncs (void)
5183 int i, j, k;
5185 /* Dump the arithmetic optabs. */
5186 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5187 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5189 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5190 if (l)
5192 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5193 fprintf (stderr, "%s\t%s:\t%s\n",
5194 GET_RTX_NAME (optab_to_code ((optab) i)),
5195 GET_MODE_NAME (j),
5196 XSTR (l, 0));
5200 /* Dump the conversion optabs. */
5201 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5202 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5203 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5205 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5206 (machine_mode) k);
5207 if (l)
5209 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5210 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5211 GET_RTX_NAME (optab_to_code ((optab) i)),
5212 GET_MODE_NAME (j),
5213 GET_MODE_NAME (k),
5214 XSTR (l, 0));
5219 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5220 CODE. Return 0 on failure. */
5222 rtx_insn *
5223 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5225 machine_mode mode = GET_MODE (op1);
5226 enum insn_code icode;
5227 rtx_insn *insn;
5228 rtx trap_rtx;
5230 if (mode == VOIDmode)
5231 return 0;
5233 icode = optab_handler (ctrap_optab, mode);
5234 if (icode == CODE_FOR_nothing)
5235 return 0;
5237 /* Some targets only accept a zero trap code. */
5238 if (!insn_operand_matches (icode, 3, tcode))
5239 return 0;
5241 do_pending_stack_adjust ();
5242 start_sequence ();
5243 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5244 &trap_rtx, &mode);
5245 if (!trap_rtx)
5246 insn = NULL;
5247 else
5248 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5249 tcode);
5251 /* If that failed, then give up. */
5252 if (insn == 0)
5254 end_sequence ();
5255 return 0;
5258 emit_insn (insn);
5259 insn = get_insns ();
5260 end_sequence ();
5261 return insn;
5264 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5265 or unsigned operation code. */
5267 enum rtx_code
5268 get_rtx_code (enum tree_code tcode, bool unsignedp)
5270 enum rtx_code code;
5271 switch (tcode)
5273 case EQ_EXPR:
5274 code = EQ;
5275 break;
5276 case NE_EXPR:
5277 code = NE;
5278 break;
5279 case LT_EXPR:
5280 code = unsignedp ? LTU : LT;
5281 break;
5282 case LE_EXPR:
5283 code = unsignedp ? LEU : LE;
5284 break;
5285 case GT_EXPR:
5286 code = unsignedp ? GTU : GT;
5287 break;
5288 case GE_EXPR:
5289 code = unsignedp ? GEU : GE;
5290 break;
5292 case UNORDERED_EXPR:
5293 code = UNORDERED;
5294 break;
5295 case ORDERED_EXPR:
5296 code = ORDERED;
5297 break;
5298 case UNLT_EXPR:
5299 code = UNLT;
5300 break;
5301 case UNLE_EXPR:
5302 code = UNLE;
5303 break;
5304 case UNGT_EXPR:
5305 code = UNGT;
5306 break;
5307 case UNGE_EXPR:
5308 code = UNGE;
5309 break;
5310 case UNEQ_EXPR:
5311 code = UNEQ;
5312 break;
5313 case LTGT_EXPR:
5314 code = LTGT;
5315 break;
5317 case BIT_AND_EXPR:
5318 code = AND;
5319 break;
5321 case BIT_IOR_EXPR:
5322 code = IOR;
5323 break;
5325 default:
5326 gcc_unreachable ();
5328 return code;
5331 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
5332 select signed or unsigned operators. OPNO holds the index of the
5333 first comparison operand for insn ICODE. Do not generate the
5334 compare instruction itself. */
5336 static rtx
5337 vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
5338 tree t_op0, tree t_op1, bool unsignedp,
5339 enum insn_code icode, unsigned int opno)
5341 struct expand_operand ops[2];
5342 rtx rtx_op0, rtx_op1;
5343 machine_mode m0, m1;
5344 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5346 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5348 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5349 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5350 cases, use the original mode. */
5351 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5352 EXPAND_STACK_PARM);
5353 m0 = GET_MODE (rtx_op0);
5354 if (m0 == VOIDmode)
5355 m0 = TYPE_MODE (TREE_TYPE (t_op0));
5357 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5358 EXPAND_STACK_PARM);
5359 m1 = GET_MODE (rtx_op1);
5360 if (m1 == VOIDmode)
5361 m1 = TYPE_MODE (TREE_TYPE (t_op1));
5363 create_input_operand (&ops[0], rtx_op0, m0);
5364 create_input_operand (&ops[1], rtx_op1, m1);
5365 if (!maybe_legitimize_operands (icode, opno, 2, ops))
5366 gcc_unreachable ();
5367 return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
5370 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
5371 vec_perm operand, assuming the second operand is a constant vector of zeroes.
5372 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
5373 shift. */
5374 static rtx
5375 shift_amt_for_vec_perm_mask (rtx sel)
5377 unsigned int i, first, nelt = GET_MODE_NUNITS (GET_MODE (sel));
5378 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (GET_MODE (sel));
5380 if (GET_CODE (sel) != CONST_VECTOR)
5381 return NULL_RTX;
5383 first = INTVAL (CONST_VECTOR_ELT (sel, 0));
5384 if (first >= nelt)
5385 return NULL_RTX;
5386 for (i = 1; i < nelt; i++)
5388 int idx = INTVAL (CONST_VECTOR_ELT (sel, i));
5389 unsigned int expected = i + first;
5390 /* Indices into the second vector are all equivalent. */
5391 if (idx < 0 || (MIN (nelt, (unsigned) idx) != MIN (nelt, expected)))
5392 return NULL_RTX;
5395 return GEN_INT (first * bitsize);
5398 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
5400 static rtx
5401 expand_vec_perm_1 (enum insn_code icode, rtx target,
5402 rtx v0, rtx v1, rtx sel)
5404 machine_mode tmode = GET_MODE (target);
5405 machine_mode smode = GET_MODE (sel);
5406 struct expand_operand ops[4];
5408 create_output_operand (&ops[0], target, tmode);
5409 create_input_operand (&ops[3], sel, smode);
5411 /* Make an effort to preserve v0 == v1. The target expander is able to
5412 rely on this to determine if we're permuting a single input operand. */
5413 if (rtx_equal_p (v0, v1))
5415 if (!insn_operand_matches (icode, 1, v0))
5416 v0 = force_reg (tmode, v0);
5417 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5418 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5420 create_fixed_operand (&ops[1], v0);
5421 create_fixed_operand (&ops[2], v0);
5423 else
5425 create_input_operand (&ops[1], v0, tmode);
5426 create_input_operand (&ops[2], v1, tmode);
5429 if (maybe_expand_insn (icode, 4, ops))
5430 return ops[0].value;
5431 return NULL_RTX;
5434 /* Generate instructions for vec_perm optab given its mode
5435 and three operands. */
5438 expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
5440 enum insn_code icode;
5441 machine_mode qimode;
5442 unsigned int i, w, e, u;
5443 rtx tmp, sel_qi = NULL;
5444 rtvec vec;
5446 if (!target || GET_MODE (target) != mode)
5447 target = gen_reg_rtx (mode);
5449 w = GET_MODE_SIZE (mode);
5450 e = GET_MODE_NUNITS (mode);
5451 u = GET_MODE_UNIT_SIZE (mode);
5453 /* Set QIMODE to a different vector mode with byte elements.
5454 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5455 if (GET_MODE_INNER (mode) == QImode
5456 || !mode_for_vector (QImode, w).exists (&qimode)
5457 || !VECTOR_MODE_P (qimode))
5458 qimode = VOIDmode;
5460 /* If the input is a constant, expand it specially. */
5461 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
5462 if (GET_CODE (sel) == CONST_VECTOR)
5464 /* See if this can be handled with a vec_shr. We only do this if the
5465 second vector is all zeroes. */
5466 enum insn_code shift_code = optab_handler (vec_shr_optab, mode);
5467 enum insn_code shift_code_qi = ((qimode != VOIDmode && qimode != mode)
5468 ? optab_handler (vec_shr_optab, qimode)
5469 : CODE_FOR_nothing);
5470 rtx shift_amt = NULL_RTX;
5471 if (v1 == CONST0_RTX (GET_MODE (v1))
5472 && (shift_code != CODE_FOR_nothing
5473 || shift_code_qi != CODE_FOR_nothing))
5475 shift_amt = shift_amt_for_vec_perm_mask (sel);
5476 if (shift_amt)
5478 struct expand_operand ops[3];
5479 if (shift_code != CODE_FOR_nothing)
5481 create_output_operand (&ops[0], target, mode);
5482 create_input_operand (&ops[1], v0, mode);
5483 create_convert_operand_from_type (&ops[2], shift_amt,
5484 sizetype);
5485 if (maybe_expand_insn (shift_code, 3, ops))
5486 return ops[0].value;
5488 if (shift_code_qi != CODE_FOR_nothing)
5490 tmp = gen_reg_rtx (qimode);
5491 create_output_operand (&ops[0], tmp, qimode);
5492 create_input_operand (&ops[1], gen_lowpart (qimode, v0),
5493 qimode);
5494 create_convert_operand_from_type (&ops[2], shift_amt,
5495 sizetype);
5496 if (maybe_expand_insn (shift_code_qi, 3, ops))
5497 return gen_lowpart (mode, ops[0].value);
5502 icode = direct_optab_handler (vec_perm_const_optab, mode);
5503 if (icode != CODE_FOR_nothing)
5505 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5506 if (tmp)
5507 return tmp;
5510 /* Fall back to a constant byte-based permutation. */
5511 if (qimode != VOIDmode)
5513 vec = rtvec_alloc (w);
5514 for (i = 0; i < e; ++i)
5516 unsigned int j, this_e;
5518 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
5519 this_e &= 2 * e - 1;
5520 this_e *= u;
5522 for (j = 0; j < u; ++j)
5523 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
5525 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
5527 icode = direct_optab_handler (vec_perm_const_optab, qimode);
5528 if (icode != CODE_FOR_nothing)
5530 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5531 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5532 gen_lowpart (qimode, v1), sel_qi);
5533 if (tmp)
5534 return gen_lowpart (mode, tmp);
5539 /* Otherwise expand as a fully variable permuation. */
5540 icode = direct_optab_handler (vec_perm_optab, mode);
5541 if (icode != CODE_FOR_nothing)
5543 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5544 if (tmp)
5545 return tmp;
5548 /* As a special case to aid several targets, lower the element-based
5549 permutation to a byte-based permutation and try again. */
5550 if (qimode == VOIDmode)
5551 return NULL_RTX;
5552 icode = direct_optab_handler (vec_perm_optab, qimode);
5553 if (icode == CODE_FOR_nothing)
5554 return NULL_RTX;
5556 if (sel_qi == NULL)
5558 /* Multiply each element by its byte size. */
5559 machine_mode selmode = GET_MODE (sel);
5560 if (u == 2)
5561 sel = expand_simple_binop (selmode, PLUS, sel, sel,
5562 NULL, 0, OPTAB_DIRECT);
5563 else
5564 sel = expand_simple_binop (selmode, ASHIFT, sel,
5565 GEN_INT (exact_log2 (u)),
5566 NULL, 0, OPTAB_DIRECT);
5567 gcc_assert (sel != NULL);
5569 /* Broadcast the low byte each element into each of its bytes. */
5570 vec = rtvec_alloc (w);
5571 for (i = 0; i < w; ++i)
5573 int this_e = i / u * u;
5574 if (BYTES_BIG_ENDIAN)
5575 this_e += u - 1;
5576 RTVEC_ELT (vec, i) = GEN_INT (this_e);
5578 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5579 sel = gen_lowpart (qimode, sel);
5580 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
5581 gcc_assert (sel != NULL);
5583 /* Add the byte offset to each byte element. */
5584 /* Note that the definition of the indicies here is memory ordering,
5585 so there should be no difference between big and little endian. */
5586 vec = rtvec_alloc (w);
5587 for (i = 0; i < w; ++i)
5588 RTVEC_ELT (vec, i) = GEN_INT (i % u);
5589 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5590 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
5591 sel, 0, OPTAB_DIRECT);
5592 gcc_assert (sel_qi != NULL);
5595 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5596 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5597 gen_lowpart (qimode, v1), sel_qi);
5598 if (tmp)
5599 tmp = gen_lowpart (mode, tmp);
5600 return tmp;
5603 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5604 three operands. */
5607 expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5608 rtx target)
5610 struct expand_operand ops[4];
5611 machine_mode mode = TYPE_MODE (vec_cond_type);
5612 machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0));
5613 enum insn_code icode = get_vcond_mask_icode (mode, mask_mode);
5614 rtx mask, rtx_op1, rtx_op2;
5616 if (icode == CODE_FOR_nothing)
5617 return 0;
5619 mask = expand_normal (op0);
5620 rtx_op1 = expand_normal (op1);
5621 rtx_op2 = expand_normal (op2);
5623 mask = force_reg (mask_mode, mask);
5624 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5626 create_output_operand (&ops[0], target, mode);
5627 create_input_operand (&ops[1], rtx_op1, mode);
5628 create_input_operand (&ops[2], rtx_op2, mode);
5629 create_input_operand (&ops[3], mask, mask_mode);
5630 expand_insn (icode, 4, ops);
5632 return ops[0].value;
5635 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5636 three operands. */
5639 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5640 rtx target)
5642 struct expand_operand ops[6];
5643 enum insn_code icode;
5644 rtx comparison, rtx_op1, rtx_op2;
5645 machine_mode mode = TYPE_MODE (vec_cond_type);
5646 machine_mode cmp_op_mode;
5647 bool unsignedp;
5648 tree op0a, op0b;
5649 enum tree_code tcode;
5651 if (COMPARISON_CLASS_P (op0))
5653 op0a = TREE_OPERAND (op0, 0);
5654 op0b = TREE_OPERAND (op0, 1);
5655 tcode = TREE_CODE (op0);
5657 else
5659 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
5660 if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0)))
5661 != CODE_FOR_nothing)
5662 return expand_vec_cond_mask_expr (vec_cond_type, op0, op1,
5663 op2, target);
5664 /* Fake op0 < 0. */
5665 else
5667 gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0)))
5668 == MODE_VECTOR_INT);
5669 op0a = op0;
5670 op0b = build_zero_cst (TREE_TYPE (op0));
5671 tcode = LT_EXPR;
5674 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
5675 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5678 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
5679 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
5681 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
5682 if (icode == CODE_FOR_nothing)
5684 if (tcode == EQ_EXPR || tcode == NE_EXPR)
5685 icode = get_vcond_eq_icode (mode, cmp_op_mode);
5686 if (icode == CODE_FOR_nothing)
5687 return 0;
5690 comparison = vector_compare_rtx (VOIDmode, tcode, op0a, op0b, unsignedp,
5691 icode, 4);
5692 rtx_op1 = expand_normal (op1);
5693 rtx_op2 = expand_normal (op2);
5695 create_output_operand (&ops[0], target, mode);
5696 create_input_operand (&ops[1], rtx_op1, mode);
5697 create_input_operand (&ops[2], rtx_op2, mode);
5698 create_fixed_operand (&ops[3], comparison);
5699 create_fixed_operand (&ops[4], XEXP (comparison, 0));
5700 create_fixed_operand (&ops[5], XEXP (comparison, 1));
5701 expand_insn (icode, 6, ops);
5702 return ops[0].value;
5705 /* Generate insns for a vector comparison into a mask. */
5708 expand_vec_cmp_expr (tree type, tree exp, rtx target)
5710 struct expand_operand ops[4];
5711 enum insn_code icode;
5712 rtx comparison;
5713 machine_mode mask_mode = TYPE_MODE (type);
5714 machine_mode vmode;
5715 bool unsignedp;
5716 tree op0a, op0b;
5717 enum tree_code tcode;
5719 op0a = TREE_OPERAND (exp, 0);
5720 op0b = TREE_OPERAND (exp, 1);
5721 tcode = TREE_CODE (exp);
5723 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5724 vmode = TYPE_MODE (TREE_TYPE (op0a));
5726 icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
5727 if (icode == CODE_FOR_nothing)
5729 if (tcode == EQ_EXPR || tcode == NE_EXPR)
5730 icode = get_vec_cmp_eq_icode (vmode, mask_mode);
5731 if (icode == CODE_FOR_nothing)
5732 return 0;
5735 comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
5736 unsignedp, icode, 2);
5737 create_output_operand (&ops[0], target, mask_mode);
5738 create_fixed_operand (&ops[1], comparison);
5739 create_fixed_operand (&ops[2], XEXP (comparison, 0));
5740 create_fixed_operand (&ops[3], XEXP (comparison, 1));
5741 expand_insn (icode, 4, ops);
5742 return ops[0].value;
5745 /* Expand a highpart multiply. */
5748 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
5749 rtx target, bool uns_p)
5751 struct expand_operand eops[3];
5752 enum insn_code icode;
5753 int method, i, nunits;
5754 machine_mode wmode;
5755 rtx m1, m2, perm;
5756 optab tab1, tab2;
5757 rtvec v;
5759 method = can_mult_highpart_p (mode, uns_p);
5760 switch (method)
5762 case 0:
5763 return NULL_RTX;
5764 case 1:
5765 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
5766 return expand_binop (mode, tab1, op0, op1, target, uns_p,
5767 OPTAB_LIB_WIDEN);
5768 case 2:
5769 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
5770 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
5771 break;
5772 case 3:
5773 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
5774 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
5775 if (BYTES_BIG_ENDIAN)
5776 std::swap (tab1, tab2);
5777 break;
5778 default:
5779 gcc_unreachable ();
5782 icode = optab_handler (tab1, mode);
5783 nunits = GET_MODE_NUNITS (mode);
5784 wmode = insn_data[icode].operand[0].mode;
5785 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
5786 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
5788 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5789 create_input_operand (&eops[1], op0, mode);
5790 create_input_operand (&eops[2], op1, mode);
5791 expand_insn (icode, 3, eops);
5792 m1 = gen_lowpart (mode, eops[0].value);
5794 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5795 create_input_operand (&eops[1], op0, mode);
5796 create_input_operand (&eops[2], op1, mode);
5797 expand_insn (optab_handler (tab2, mode), 3, eops);
5798 m2 = gen_lowpart (mode, eops[0].value);
5800 v = rtvec_alloc (nunits);
5801 if (method == 2)
5803 for (i = 0; i < nunits; ++i)
5804 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
5805 + ((i & 1) ? nunits : 0));
5806 perm = gen_rtx_CONST_VECTOR (mode, v);
5808 else
5810 int base = BYTES_BIG_ENDIAN ? 0 : 1;
5811 perm = gen_const_vec_series (mode, GEN_INT (base), GEN_INT (2));
5814 return expand_vec_perm (mode, m1, m2, perm, target);
5817 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5818 pattern. */
5820 static void
5821 find_cc_set (rtx x, const_rtx pat, void *data)
5823 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
5824 && GET_CODE (pat) == SET)
5826 rtx *p_cc_reg = (rtx *) data;
5827 gcc_assert (!*p_cc_reg);
5828 *p_cc_reg = x;
5832 /* This is a helper function for the other atomic operations. This function
5833 emits a loop that contains SEQ that iterates until a compare-and-swap
5834 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5835 a set of instructions that takes a value from OLD_REG as an input and
5836 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5837 set to the current contents of MEM. After SEQ, a compare-and-swap will
5838 attempt to update MEM with NEW_REG. The function returns true when the
5839 loop was generated successfully. */
5841 static bool
5842 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5844 machine_mode mode = GET_MODE (mem);
5845 rtx_code_label *label;
5846 rtx cmp_reg, success, oldval;
5848 /* The loop we want to generate looks like
5850 cmp_reg = mem;
5851 label:
5852 old_reg = cmp_reg;
5853 seq;
5854 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5855 if (success)
5856 goto label;
5858 Note that we only do the plain load from memory once. Subsequent
5859 iterations use the value loaded by the compare-and-swap pattern. */
5861 label = gen_label_rtx ();
5862 cmp_reg = gen_reg_rtx (mode);
5864 emit_move_insn (cmp_reg, mem);
5865 emit_label (label);
5866 emit_move_insn (old_reg, cmp_reg);
5867 if (seq)
5868 emit_insn (seq);
5870 success = NULL_RTX;
5871 oldval = cmp_reg;
5872 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
5873 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
5874 MEMMODEL_RELAXED))
5875 return false;
5877 if (oldval != cmp_reg)
5878 emit_move_insn (cmp_reg, oldval);
5880 /* Mark this jump predicted not taken. */
5881 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
5882 GET_MODE (success), 1, label,
5883 profile_probability::guessed_never ());
5884 return true;
5888 /* This function tries to emit an atomic_exchange intruction. VAL is written
5889 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
5890 using TARGET if possible. */
5892 static rtx
5893 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5895 machine_mode mode = GET_MODE (mem);
5896 enum insn_code icode;
5898 /* If the target supports the exchange directly, great. */
5899 icode = direct_optab_handler (atomic_exchange_optab, mode);
5900 if (icode != CODE_FOR_nothing)
5902 struct expand_operand ops[4];
5904 create_output_operand (&ops[0], target, mode);
5905 create_fixed_operand (&ops[1], mem);
5906 create_input_operand (&ops[2], val, mode);
5907 create_integer_operand (&ops[3], model);
5908 if (maybe_expand_insn (icode, 4, ops))
5909 return ops[0].value;
5912 return NULL_RTX;
5915 /* This function tries to implement an atomic exchange operation using
5916 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
5917 The previous contents of *MEM are returned, using TARGET if possible.
5918 Since this instructionn is an acquire barrier only, stronger memory
5919 models may require additional barriers to be emitted. */
5921 static rtx
5922 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
5923 enum memmodel model)
5925 machine_mode mode = GET_MODE (mem);
5926 enum insn_code icode;
5927 rtx_insn *last_insn = get_last_insn ();
5929 icode = optab_handler (sync_lock_test_and_set_optab, mode);
5931 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
5932 exists, and the memory model is stronger than acquire, add a release
5933 barrier before the instruction. */
5935 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
5936 expand_mem_thread_fence (model);
5938 if (icode != CODE_FOR_nothing)
5940 struct expand_operand ops[3];
5941 create_output_operand (&ops[0], target, mode);
5942 create_fixed_operand (&ops[1], mem);
5943 create_input_operand (&ops[2], val, mode);
5944 if (maybe_expand_insn (icode, 3, ops))
5945 return ops[0].value;
5948 /* If an external test-and-set libcall is provided, use that instead of
5949 any external compare-and-swap that we might get from the compare-and-
5950 swap-loop expansion later. */
5951 if (!can_compare_and_swap_p (mode, false))
5953 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
5954 if (libfunc != NULL)
5956 rtx addr;
5958 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5959 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5960 mode, addr, ptr_mode,
5961 val, mode);
5965 /* If the test_and_set can't be emitted, eliminate any barrier that might
5966 have been emitted. */
5967 delete_insns_since (last_insn);
5968 return NULL_RTX;
5971 /* This function tries to implement an atomic exchange operation using a
5972 compare_and_swap loop. VAL is written to *MEM. The previous contents of
5973 *MEM are returned, using TARGET if possible. No memory model is required
5974 since a compare_and_swap loop is seq-cst. */
5976 static rtx
5977 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
5979 machine_mode mode = GET_MODE (mem);
5981 if (can_compare_and_swap_p (mode, true))
5983 if (!target || !register_operand (target, mode))
5984 target = gen_reg_rtx (mode);
5985 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
5986 return target;
5989 return NULL_RTX;
5992 /* This function tries to implement an atomic test-and-set operation
5993 using the atomic_test_and_set instruction pattern. A boolean value
5994 is returned from the operation, using TARGET if possible. */
5996 static rtx
5997 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5999 machine_mode pat_bool_mode;
6000 struct expand_operand ops[3];
6002 if (!targetm.have_atomic_test_and_set ())
6003 return NULL_RTX;
6005 /* While we always get QImode from __atomic_test_and_set, we get
6006 other memory modes from __sync_lock_test_and_set. Note that we
6007 use no endian adjustment here. This matches the 4.6 behavior
6008 in the Sparc backend. */
6009 enum insn_code icode = targetm.code_for_atomic_test_and_set;
6010 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
6011 if (GET_MODE (mem) != QImode)
6012 mem = adjust_address_nv (mem, QImode, 0);
6014 pat_bool_mode = insn_data[icode].operand[0].mode;
6015 create_output_operand (&ops[0], target, pat_bool_mode);
6016 create_fixed_operand (&ops[1], mem);
6017 create_integer_operand (&ops[2], model);
6019 if (maybe_expand_insn (icode, 3, ops))
6020 return ops[0].value;
6021 return NULL_RTX;
6024 /* This function expands the legacy _sync_lock test_and_set operation which is
6025 generally an atomic exchange. Some limited targets only allow the
6026 constant 1 to be stored. This is an ACQUIRE operation.
6028 TARGET is an optional place to stick the return value.
6029 MEM is where VAL is stored. */
6032 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
6034 rtx ret;
6036 /* Try an atomic_exchange first. */
6037 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
6038 if (ret)
6039 return ret;
6041 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
6042 MEMMODEL_SYNC_ACQUIRE);
6043 if (ret)
6044 return ret;
6046 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6047 if (ret)
6048 return ret;
6050 /* If there are no other options, try atomic_test_and_set if the value
6051 being stored is 1. */
6052 if (val == const1_rtx)
6053 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
6055 return ret;
6058 /* This function expands the atomic test_and_set operation:
6059 atomically store a boolean TRUE into MEM and return the previous value.
6061 MEMMODEL is the memory model variant to use.
6062 TARGET is an optional place to stick the return value. */
6065 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6067 machine_mode mode = GET_MODE (mem);
6068 rtx ret, trueval, subtarget;
6070 ret = maybe_emit_atomic_test_and_set (target, mem, model);
6071 if (ret)
6072 return ret;
6074 /* Be binary compatible with non-default settings of trueval, and different
6075 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6076 another only has atomic-exchange. */
6077 if (targetm.atomic_test_and_set_trueval == 1)
6079 trueval = const1_rtx;
6080 subtarget = target ? target : gen_reg_rtx (mode);
6082 else
6084 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
6085 subtarget = gen_reg_rtx (mode);
6088 /* Try the atomic-exchange optab... */
6089 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
6091 /* ... then an atomic-compare-and-swap loop ... */
6092 if (!ret)
6093 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
6095 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6096 if (!ret)
6097 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
6099 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6100 things with the value 1. Thus we try again without trueval. */
6101 if (!ret && targetm.atomic_test_and_set_trueval != 1)
6102 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
6104 /* Failing all else, assume a single threaded environment and simply
6105 perform the operation. */
6106 if (!ret)
6108 /* If the result is ignored skip the move to target. */
6109 if (subtarget != const0_rtx)
6110 emit_move_insn (subtarget, mem);
6112 emit_move_insn (mem, trueval);
6113 ret = subtarget;
6116 /* Recall that have to return a boolean value; rectify if trueval
6117 is not exactly one. */
6118 if (targetm.atomic_test_and_set_trueval != 1)
6119 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
6121 return ret;
6124 /* This function expands the atomic exchange operation:
6125 atomically store VAL in MEM and return the previous value in MEM.
6127 MEMMODEL is the memory model variant to use.
6128 TARGET is an optional place to stick the return value. */
6131 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6133 machine_mode mode = GET_MODE (mem);
6134 rtx ret;
6136 /* If loads are not atomic for the required size and we are not called to
6137 provide a __sync builtin, do not do anything so that we stay consistent
6138 with atomic loads of the same size. */
6139 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6140 return NULL_RTX;
6142 ret = maybe_emit_atomic_exchange (target, mem, val, model);
6144 /* Next try a compare-and-swap loop for the exchange. */
6145 if (!ret)
6146 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6148 return ret;
6151 /* This function expands the atomic compare exchange operation:
6153 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6154 *PTARGET_OVAL is an optional place to store the old value from memory.
6155 Both target parameters may be NULL or const0_rtx to indicate that we do
6156 not care about that return value. Both target parameters are updated on
6157 success to the actual location of the corresponding result.
6159 MEMMODEL is the memory model variant to use.
6161 The return value of the function is true for success. */
6163 bool
6164 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
6165 rtx mem, rtx expected, rtx desired,
6166 bool is_weak, enum memmodel succ_model,
6167 enum memmodel fail_model)
6169 machine_mode mode = GET_MODE (mem);
6170 struct expand_operand ops[8];
6171 enum insn_code icode;
6172 rtx target_oval, target_bool = NULL_RTX;
6173 rtx libfunc;
6175 /* If loads are not atomic for the required size and we are not called to
6176 provide a __sync builtin, do not do anything so that we stay consistent
6177 with atomic loads of the same size. */
6178 if (!can_atomic_load_p (mode) && !is_mm_sync (succ_model))
6179 return false;
6181 /* Load expected into a register for the compare and swap. */
6182 if (MEM_P (expected))
6183 expected = copy_to_reg (expected);
6185 /* Make sure we always have some place to put the return oldval.
6186 Further, make sure that place is distinct from the input expected,
6187 just in case we need that path down below. */
6188 if (ptarget_oval && *ptarget_oval == const0_rtx)
6189 ptarget_oval = NULL;
6191 if (ptarget_oval == NULL
6192 || (target_oval = *ptarget_oval) == NULL
6193 || reg_overlap_mentioned_p (expected, target_oval))
6194 target_oval = gen_reg_rtx (mode);
6196 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6197 if (icode != CODE_FOR_nothing)
6199 machine_mode bool_mode = insn_data[icode].operand[0].mode;
6201 if (ptarget_bool && *ptarget_bool == const0_rtx)
6202 ptarget_bool = NULL;
6204 /* Make sure we always have a place for the bool operand. */
6205 if (ptarget_bool == NULL
6206 || (target_bool = *ptarget_bool) == NULL
6207 || GET_MODE (target_bool) != bool_mode)
6208 target_bool = gen_reg_rtx (bool_mode);
6210 /* Emit the compare_and_swap. */
6211 create_output_operand (&ops[0], target_bool, bool_mode);
6212 create_output_operand (&ops[1], target_oval, mode);
6213 create_fixed_operand (&ops[2], mem);
6214 create_input_operand (&ops[3], expected, mode);
6215 create_input_operand (&ops[4], desired, mode);
6216 create_integer_operand (&ops[5], is_weak);
6217 create_integer_operand (&ops[6], succ_model);
6218 create_integer_operand (&ops[7], fail_model);
6219 if (maybe_expand_insn (icode, 8, ops))
6221 /* Return success/failure. */
6222 target_bool = ops[0].value;
6223 target_oval = ops[1].value;
6224 goto success;
6228 /* Otherwise fall back to the original __sync_val_compare_and_swap
6229 which is always seq-cst. */
6230 icode = optab_handler (sync_compare_and_swap_optab, mode);
6231 if (icode != CODE_FOR_nothing)
6233 rtx cc_reg;
6235 create_output_operand (&ops[0], target_oval, mode);
6236 create_fixed_operand (&ops[1], mem);
6237 create_input_operand (&ops[2], expected, mode);
6238 create_input_operand (&ops[3], desired, mode);
6239 if (!maybe_expand_insn (icode, 4, ops))
6240 return false;
6242 target_oval = ops[0].value;
6244 /* If the caller isn't interested in the boolean return value,
6245 skip the computation of it. */
6246 if (ptarget_bool == NULL)
6247 goto success;
6249 /* Otherwise, work out if the compare-and-swap succeeded. */
6250 cc_reg = NULL_RTX;
6251 if (have_insn_for (COMPARE, CCmode))
6252 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
6253 if (cc_reg)
6255 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6256 const0_rtx, VOIDmode, 0, 1);
6257 goto success;
6259 goto success_bool_from_val;
6262 /* Also check for library support for __sync_val_compare_and_swap. */
6263 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6264 if (libfunc != NULL)
6266 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6267 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6268 mode, addr, ptr_mode,
6269 expected, mode, desired, mode);
6270 emit_move_insn (target_oval, target);
6272 /* Compute the boolean return value only if requested. */
6273 if (ptarget_bool)
6274 goto success_bool_from_val;
6275 else
6276 goto success;
6279 /* Failure. */
6280 return false;
6282 success_bool_from_val:
6283 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
6284 expected, VOIDmode, 1, 1);
6285 success:
6286 /* Make sure that the oval output winds up where the caller asked. */
6287 if (ptarget_oval)
6288 *ptarget_oval = target_oval;
6289 if (ptarget_bool)
6290 *ptarget_bool = target_bool;
6291 return true;
6294 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
6296 static void
6297 expand_asm_memory_blockage (void)
6299 rtx asm_op, clob;
6301 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
6302 rtvec_alloc (0), rtvec_alloc (0),
6303 rtvec_alloc (0), UNKNOWN_LOCATION);
6304 MEM_VOLATILE_P (asm_op) = 1;
6306 clob = gen_rtx_SCRATCH (VOIDmode);
6307 clob = gen_rtx_MEM (BLKmode, clob);
6308 clob = gen_rtx_CLOBBER (VOIDmode, clob);
6310 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
6313 /* Do not propagate memory accesses across this point. */
6315 static void
6316 expand_memory_blockage (void)
6318 if (targetm.have_memory_blockage ())
6319 emit_insn (targetm.gen_memory_blockage ());
6320 else
6321 expand_asm_memory_blockage ();
6324 /* This routine will either emit the mem_thread_fence pattern or issue a
6325 sync_synchronize to generate a fence for memory model MEMMODEL. */
6327 void
6328 expand_mem_thread_fence (enum memmodel model)
6330 if (is_mm_relaxed (model))
6331 return;
6332 if (targetm.have_mem_thread_fence ())
6334 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
6335 expand_memory_blockage ();
6337 else if (targetm.have_memory_barrier ())
6338 emit_insn (targetm.gen_memory_barrier ());
6339 else if (synchronize_libfunc != NULL_RTX)
6340 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode);
6341 else
6342 expand_memory_blockage ();
6345 /* Emit a signal fence with given memory model. */
6347 void
6348 expand_mem_signal_fence (enum memmodel model)
6350 /* No machine barrier is required to implement a signal fence, but
6351 a compiler memory barrier must be issued, except for relaxed MM. */
6352 if (!is_mm_relaxed (model))
6353 expand_memory_blockage ();
6356 /* This function expands the atomic load operation:
6357 return the atomically loaded value in MEM.
6359 MEMMODEL is the memory model variant to use.
6360 TARGET is an option place to stick the return value. */
6363 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6365 machine_mode mode = GET_MODE (mem);
6366 enum insn_code icode;
6368 /* If the target supports the load directly, great. */
6369 icode = direct_optab_handler (atomic_load_optab, mode);
6370 if (icode != CODE_FOR_nothing)
6372 struct expand_operand ops[3];
6373 rtx_insn *last = get_last_insn ();
6374 if (is_mm_seq_cst (model))
6375 expand_memory_blockage ();
6377 create_output_operand (&ops[0], target, mode);
6378 create_fixed_operand (&ops[1], mem);
6379 create_integer_operand (&ops[2], model);
6380 if (maybe_expand_insn (icode, 3, ops))
6382 if (!is_mm_relaxed (model))
6383 expand_memory_blockage ();
6384 return ops[0].value;
6386 delete_insns_since (last);
6389 /* If the size of the object is greater than word size on this target,
6390 then we assume that a load will not be atomic. We could try to
6391 emulate a load with a compare-and-swap operation, but the store that
6392 doing this could result in would be incorrect if this is a volatile
6393 atomic load or targetting read-only-mapped memory. */
6394 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6395 /* If there is no atomic load, leave the library call. */
6396 return NULL_RTX;
6398 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6399 if (!target || target == const0_rtx)
6400 target = gen_reg_rtx (mode);
6402 /* For SEQ_CST, emit a barrier before the load. */
6403 if (is_mm_seq_cst (model))
6404 expand_mem_thread_fence (model);
6406 emit_move_insn (target, mem);
6408 /* Emit the appropriate barrier after the load. */
6409 expand_mem_thread_fence (model);
6411 return target;
6414 /* This function expands the atomic store operation:
6415 Atomically store VAL in MEM.
6416 MEMMODEL is the memory model variant to use.
6417 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6418 function returns const0_rtx if a pattern was emitted. */
6421 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6423 machine_mode mode = GET_MODE (mem);
6424 enum insn_code icode;
6425 struct expand_operand ops[3];
6427 /* If the target supports the store directly, great. */
6428 icode = direct_optab_handler (atomic_store_optab, mode);
6429 if (icode != CODE_FOR_nothing)
6431 rtx_insn *last = get_last_insn ();
6432 if (!is_mm_relaxed (model))
6433 expand_memory_blockage ();
6434 create_fixed_operand (&ops[0], mem);
6435 create_input_operand (&ops[1], val, mode);
6436 create_integer_operand (&ops[2], model);
6437 if (maybe_expand_insn (icode, 3, ops))
6439 if (is_mm_seq_cst (model))
6440 expand_memory_blockage ();
6441 return const0_rtx;
6443 delete_insns_since (last);
6446 /* If using __sync_lock_release is a viable alternative, try it.
6447 Note that this will not be set to true if we are expanding a generic
6448 __atomic_store_n. */
6449 if (use_release)
6451 icode = direct_optab_handler (sync_lock_release_optab, mode);
6452 if (icode != CODE_FOR_nothing)
6454 create_fixed_operand (&ops[0], mem);
6455 create_input_operand (&ops[1], const0_rtx, mode);
6456 if (maybe_expand_insn (icode, 2, ops))
6458 /* lock_release is only a release barrier. */
6459 if (is_mm_seq_cst (model))
6460 expand_mem_thread_fence (model);
6461 return const0_rtx;
6466 /* If the size of the object is greater than word size on this target,
6467 a default store will not be atomic. */
6468 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6470 /* If loads are atomic or we are called to provide a __sync builtin,
6471 we can try a atomic_exchange and throw away the result. Otherwise,
6472 don't do anything so that we do not create an inconsistency between
6473 loads and stores. */
6474 if (can_atomic_load_p (mode) || is_mm_sync (model))
6476 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6477 if (!target)
6478 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem,
6479 val);
6480 if (target)
6481 return const0_rtx;
6483 return NULL_RTX;
6486 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6487 expand_mem_thread_fence (model);
6489 emit_move_insn (mem, val);
6491 /* For SEQ_CST, also emit a barrier after the store. */
6492 if (is_mm_seq_cst (model))
6493 expand_mem_thread_fence (model);
6495 return const0_rtx;
6499 /* Structure containing the pointers and values required to process the
6500 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6502 struct atomic_op_functions
6504 direct_optab mem_fetch_before;
6505 direct_optab mem_fetch_after;
6506 direct_optab mem_no_result;
6507 optab fetch_before;
6508 optab fetch_after;
6509 direct_optab no_result;
6510 enum rtx_code reverse_code;
6514 /* Fill in structure pointed to by OP with the various optab entries for an
6515 operation of type CODE. */
6517 static void
6518 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6520 gcc_assert (op!= NULL);
6522 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6523 in the source code during compilation, and the optab entries are not
6524 computable until runtime. Fill in the values at runtime. */
6525 switch (code)
6527 case PLUS:
6528 op->mem_fetch_before = atomic_fetch_add_optab;
6529 op->mem_fetch_after = atomic_add_fetch_optab;
6530 op->mem_no_result = atomic_add_optab;
6531 op->fetch_before = sync_old_add_optab;
6532 op->fetch_after = sync_new_add_optab;
6533 op->no_result = sync_add_optab;
6534 op->reverse_code = MINUS;
6535 break;
6536 case MINUS:
6537 op->mem_fetch_before = atomic_fetch_sub_optab;
6538 op->mem_fetch_after = atomic_sub_fetch_optab;
6539 op->mem_no_result = atomic_sub_optab;
6540 op->fetch_before = sync_old_sub_optab;
6541 op->fetch_after = sync_new_sub_optab;
6542 op->no_result = sync_sub_optab;
6543 op->reverse_code = PLUS;
6544 break;
6545 case XOR:
6546 op->mem_fetch_before = atomic_fetch_xor_optab;
6547 op->mem_fetch_after = atomic_xor_fetch_optab;
6548 op->mem_no_result = atomic_xor_optab;
6549 op->fetch_before = sync_old_xor_optab;
6550 op->fetch_after = sync_new_xor_optab;
6551 op->no_result = sync_xor_optab;
6552 op->reverse_code = XOR;
6553 break;
6554 case AND:
6555 op->mem_fetch_before = atomic_fetch_and_optab;
6556 op->mem_fetch_after = atomic_and_fetch_optab;
6557 op->mem_no_result = atomic_and_optab;
6558 op->fetch_before = sync_old_and_optab;
6559 op->fetch_after = sync_new_and_optab;
6560 op->no_result = sync_and_optab;
6561 op->reverse_code = UNKNOWN;
6562 break;
6563 case IOR:
6564 op->mem_fetch_before = atomic_fetch_or_optab;
6565 op->mem_fetch_after = atomic_or_fetch_optab;
6566 op->mem_no_result = atomic_or_optab;
6567 op->fetch_before = sync_old_ior_optab;
6568 op->fetch_after = sync_new_ior_optab;
6569 op->no_result = sync_ior_optab;
6570 op->reverse_code = UNKNOWN;
6571 break;
6572 case NOT:
6573 op->mem_fetch_before = atomic_fetch_nand_optab;
6574 op->mem_fetch_after = atomic_nand_fetch_optab;
6575 op->mem_no_result = atomic_nand_optab;
6576 op->fetch_before = sync_old_nand_optab;
6577 op->fetch_after = sync_new_nand_optab;
6578 op->no_result = sync_nand_optab;
6579 op->reverse_code = UNKNOWN;
6580 break;
6581 default:
6582 gcc_unreachable ();
6586 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6587 using memory order MODEL. If AFTER is true the operation needs to return
6588 the value of *MEM after the operation, otherwise the previous value.
6589 TARGET is an optional place to place the result. The result is unused if
6590 it is const0_rtx.
6591 Return the result if there is a better sequence, otherwise NULL_RTX. */
6593 static rtx
6594 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6595 enum memmodel model, bool after)
6597 /* If the value is prefetched, or not used, it may be possible to replace
6598 the sequence with a native exchange operation. */
6599 if (!after || target == const0_rtx)
6601 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6602 if (code == AND && val == const0_rtx)
6604 if (target == const0_rtx)
6605 target = gen_reg_rtx (GET_MODE (mem));
6606 return maybe_emit_atomic_exchange (target, mem, val, model);
6609 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6610 if (code == IOR && val == constm1_rtx)
6612 if (target == const0_rtx)
6613 target = gen_reg_rtx (GET_MODE (mem));
6614 return maybe_emit_atomic_exchange (target, mem, val, model);
6618 return NULL_RTX;
6621 /* Try to emit an instruction for a specific operation varaition.
6622 OPTAB contains the OP functions.
6623 TARGET is an optional place to return the result. const0_rtx means unused.
6624 MEM is the memory location to operate on.
6625 VAL is the value to use in the operation.
6626 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6627 MODEL is the memory model, if used.
6628 AFTER is true if the returned result is the value after the operation. */
6630 static rtx
6631 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6632 rtx val, bool use_memmodel, enum memmodel model, bool after)
6634 machine_mode mode = GET_MODE (mem);
6635 struct expand_operand ops[4];
6636 enum insn_code icode;
6637 int op_counter = 0;
6638 int num_ops;
6640 /* Check to see if there is a result returned. */
6641 if (target == const0_rtx)
6643 if (use_memmodel)
6645 icode = direct_optab_handler (optab->mem_no_result, mode);
6646 create_integer_operand (&ops[2], model);
6647 num_ops = 3;
6649 else
6651 icode = direct_optab_handler (optab->no_result, mode);
6652 num_ops = 2;
6655 /* Otherwise, we need to generate a result. */
6656 else
6658 if (use_memmodel)
6660 icode = direct_optab_handler (after ? optab->mem_fetch_after
6661 : optab->mem_fetch_before, mode);
6662 create_integer_operand (&ops[3], model);
6663 num_ops = 4;
6665 else
6667 icode = optab_handler (after ? optab->fetch_after
6668 : optab->fetch_before, mode);
6669 num_ops = 3;
6671 create_output_operand (&ops[op_counter++], target, mode);
6673 if (icode == CODE_FOR_nothing)
6674 return NULL_RTX;
6676 create_fixed_operand (&ops[op_counter++], mem);
6677 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6678 create_convert_operand_to (&ops[op_counter++], val, mode, true);
6680 if (maybe_expand_insn (icode, num_ops, ops))
6681 return (target == const0_rtx ? const0_rtx : ops[0].value);
6683 return NULL_RTX;
6687 /* This function expands an atomic fetch_OP or OP_fetch operation:
6688 TARGET is an option place to stick the return value. const0_rtx indicates
6689 the result is unused.
6690 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6691 CODE is the operation being performed (OP)
6692 MEMMODEL is the memory model variant to use.
6693 AFTER is true to return the result of the operation (OP_fetch).
6694 AFTER is false to return the value before the operation (fetch_OP).
6696 This function will *only* generate instructions if there is a direct
6697 optab. No compare and swap loops or libcalls will be generated. */
6699 static rtx
6700 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6701 enum rtx_code code, enum memmodel model,
6702 bool after)
6704 machine_mode mode = GET_MODE (mem);
6705 struct atomic_op_functions optab;
6706 rtx result;
6707 bool unused_result = (target == const0_rtx);
6709 get_atomic_op_for_code (&optab, code);
6711 /* Check to see if there are any better instructions. */
6712 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6713 if (result)
6714 return result;
6716 /* Check for the case where the result isn't used and try those patterns. */
6717 if (unused_result)
6719 /* Try the memory model variant first. */
6720 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6721 if (result)
6722 return result;
6724 /* Next try the old style withuot a memory model. */
6725 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6726 if (result)
6727 return result;
6729 /* There is no no-result pattern, so try patterns with a result. */
6730 target = NULL_RTX;
6733 /* Try the __atomic version. */
6734 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6735 if (result)
6736 return result;
6738 /* Try the older __sync version. */
6739 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6740 if (result)
6741 return result;
6743 /* If the fetch value can be calculated from the other variation of fetch,
6744 try that operation. */
6745 if (after || unused_result || optab.reverse_code != UNKNOWN)
6747 /* Try the __atomic version, then the older __sync version. */
6748 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6749 if (!result)
6750 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6752 if (result)
6754 /* If the result isn't used, no need to do compensation code. */
6755 if (unused_result)
6756 return result;
6758 /* Issue compensation code. Fetch_after == fetch_before OP val.
6759 Fetch_before == after REVERSE_OP val. */
6760 if (!after)
6761 code = optab.reverse_code;
6762 if (code == NOT)
6764 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6765 true, OPTAB_LIB_WIDEN);
6766 result = expand_simple_unop (mode, NOT, result, target, true);
6768 else
6769 result = expand_simple_binop (mode, code, result, val, target,
6770 true, OPTAB_LIB_WIDEN);
6771 return result;
6775 /* No direct opcode can be generated. */
6776 return NULL_RTX;
6781 /* This function expands an atomic fetch_OP or OP_fetch operation:
6782 TARGET is an option place to stick the return value. const0_rtx indicates
6783 the result is unused.
6784 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6785 CODE is the operation being performed (OP)
6786 MEMMODEL is the memory model variant to use.
6787 AFTER is true to return the result of the operation (OP_fetch).
6788 AFTER is false to return the value before the operation (fetch_OP). */
6790 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6791 enum memmodel model, bool after)
6793 machine_mode mode = GET_MODE (mem);
6794 rtx result;
6795 bool unused_result = (target == const0_rtx);
6797 /* If loads are not atomic for the required size and we are not called to
6798 provide a __sync builtin, do not do anything so that we stay consistent
6799 with atomic loads of the same size. */
6800 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6801 return NULL_RTX;
6803 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6804 after);
6806 if (result)
6807 return result;
6809 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6810 if (code == PLUS || code == MINUS)
6812 rtx tmp;
6813 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6815 start_sequence ();
6816 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6817 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6818 model, after);
6819 if (result)
6821 /* PLUS worked so emit the insns and return. */
6822 tmp = get_insns ();
6823 end_sequence ();
6824 emit_insn (tmp);
6825 return result;
6828 /* PLUS did not work, so throw away the negation code and continue. */
6829 end_sequence ();
6832 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6833 if (!can_compare_and_swap_p (mode, false))
6835 rtx libfunc;
6836 bool fixup = false;
6837 enum rtx_code orig_code = code;
6838 struct atomic_op_functions optab;
6840 get_atomic_op_for_code (&optab, code);
6841 libfunc = optab_libfunc (after ? optab.fetch_after
6842 : optab.fetch_before, mode);
6843 if (libfunc == NULL
6844 && (after || unused_result || optab.reverse_code != UNKNOWN))
6846 fixup = true;
6847 if (!after)
6848 code = optab.reverse_code;
6849 libfunc = optab_libfunc (after ? optab.fetch_before
6850 : optab.fetch_after, mode);
6852 if (libfunc != NULL)
6854 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6855 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
6856 addr, ptr_mode, val, mode);
6858 if (!unused_result && fixup)
6859 result = expand_simple_binop (mode, code, result, val, target,
6860 true, OPTAB_LIB_WIDEN);
6861 return result;
6864 /* We need the original code for any further attempts. */
6865 code = orig_code;
6868 /* If nothing else has succeeded, default to a compare and swap loop. */
6869 if (can_compare_and_swap_p (mode, true))
6871 rtx_insn *insn;
6872 rtx t0 = gen_reg_rtx (mode), t1;
6874 start_sequence ();
6876 /* If the result is used, get a register for it. */
6877 if (!unused_result)
6879 if (!target || !register_operand (target, mode))
6880 target = gen_reg_rtx (mode);
6881 /* If fetch_before, copy the value now. */
6882 if (!after)
6883 emit_move_insn (target, t0);
6885 else
6886 target = const0_rtx;
6888 t1 = t0;
6889 if (code == NOT)
6891 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
6892 true, OPTAB_LIB_WIDEN);
6893 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
6895 else
6896 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
6897 OPTAB_LIB_WIDEN);
6899 /* For after, copy the value now. */
6900 if (!unused_result && after)
6901 emit_move_insn (target, t1);
6902 insn = get_insns ();
6903 end_sequence ();
6905 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6906 return target;
6909 return NULL_RTX;
6912 /* Return true if OPERAND is suitable for operand number OPNO of
6913 instruction ICODE. */
6915 bool
6916 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
6918 return (!insn_data[(int) icode].operand[opno].predicate
6919 || (insn_data[(int) icode].operand[opno].predicate
6920 (operand, insn_data[(int) icode].operand[opno].mode)));
6923 /* TARGET is a target of a multiword operation that we are going to
6924 implement as a series of word-mode operations. Return true if
6925 TARGET is suitable for this purpose. */
6927 bool
6928 valid_multiword_target_p (rtx target)
6930 machine_mode mode;
6931 int i;
6933 mode = GET_MODE (target);
6934 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
6935 if (!validate_subreg (word_mode, mode, target, i))
6936 return false;
6937 return true;
6940 /* Like maybe_legitimize_operand, but do not change the code of the
6941 current rtx value. */
6943 static bool
6944 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
6945 struct expand_operand *op)
6947 /* See if the operand matches in its current form. */
6948 if (insn_operand_matches (icode, opno, op->value))
6949 return true;
6951 /* If the operand is a memory whose address has no side effects,
6952 try forcing the address into a non-virtual pseudo register.
6953 The check for side effects is important because copy_to_mode_reg
6954 cannot handle things like auto-modified addresses. */
6955 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
6957 rtx addr, mem;
6959 mem = op->value;
6960 addr = XEXP (mem, 0);
6961 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
6962 && !side_effects_p (addr))
6964 rtx_insn *last;
6965 machine_mode mode;
6967 last = get_last_insn ();
6968 mode = get_address_mode (mem);
6969 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
6970 if (insn_operand_matches (icode, opno, mem))
6972 op->value = mem;
6973 return true;
6975 delete_insns_since (last);
6979 return false;
6982 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6983 on success, storing the new operand value back in OP. */
6985 static bool
6986 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
6987 struct expand_operand *op)
6989 machine_mode mode, imode;
6990 bool old_volatile_ok, result;
6992 mode = op->mode;
6993 switch (op->type)
6995 case EXPAND_FIXED:
6996 old_volatile_ok = volatile_ok;
6997 volatile_ok = true;
6998 result = maybe_legitimize_operand_same_code (icode, opno, op);
6999 volatile_ok = old_volatile_ok;
7000 return result;
7002 case EXPAND_OUTPUT:
7003 gcc_assert (mode != VOIDmode);
7004 if (op->value
7005 && op->value != const0_rtx
7006 && GET_MODE (op->value) == mode
7007 && maybe_legitimize_operand_same_code (icode, opno, op))
7008 return true;
7010 op->value = gen_reg_rtx (mode);
7011 op->target = 0;
7012 break;
7014 case EXPAND_INPUT:
7015 input:
7016 gcc_assert (mode != VOIDmode);
7017 gcc_assert (GET_MODE (op->value) == VOIDmode
7018 || GET_MODE (op->value) == mode);
7019 if (maybe_legitimize_operand_same_code (icode, opno, op))
7020 return true;
7022 op->value = copy_to_mode_reg (mode, op->value);
7023 break;
7025 case EXPAND_CONVERT_TO:
7026 gcc_assert (mode != VOIDmode);
7027 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
7028 goto input;
7030 case EXPAND_CONVERT_FROM:
7031 if (GET_MODE (op->value) != VOIDmode)
7032 mode = GET_MODE (op->value);
7033 else
7034 /* The caller must tell us what mode this value has. */
7035 gcc_assert (mode != VOIDmode);
7037 imode = insn_data[(int) icode].operand[opno].mode;
7038 if (imode != VOIDmode && imode != mode)
7040 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
7041 mode = imode;
7043 goto input;
7045 case EXPAND_ADDRESS:
7046 op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
7047 op->value);
7048 goto input;
7050 case EXPAND_INTEGER:
7051 mode = insn_data[(int) icode].operand[opno].mode;
7052 if (mode != VOIDmode && const_int_operand (op->value, mode))
7053 goto input;
7054 break;
7056 return insn_operand_matches (icode, opno, op->value);
7059 /* Make OP describe an input operand that should have the same value
7060 as VALUE, after any mode conversion that the target might request.
7061 TYPE is the type of VALUE. */
7063 void
7064 create_convert_operand_from_type (struct expand_operand *op,
7065 rtx value, tree type)
7067 create_convert_operand_from (op, value, TYPE_MODE (type),
7068 TYPE_UNSIGNED (type));
7071 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7072 of instruction ICODE. Return true on success, leaving the new operand
7073 values in the OPS themselves. Emit no code on failure. */
7075 bool
7076 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
7077 unsigned int nops, struct expand_operand *ops)
7079 rtx_insn *last;
7080 unsigned int i;
7082 last = get_last_insn ();
7083 for (i = 0; i < nops; i++)
7084 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
7086 delete_insns_since (last);
7087 return false;
7089 return true;
7092 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7093 as its operands. Return the instruction pattern on success,
7094 and emit any necessary set-up code. Return null and emit no
7095 code on failure. */
7097 rtx_insn *
7098 maybe_gen_insn (enum insn_code icode, unsigned int nops,
7099 struct expand_operand *ops)
7101 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
7102 if (!maybe_legitimize_operands (icode, 0, nops, ops))
7103 return NULL;
7105 switch (nops)
7107 case 1:
7108 return GEN_FCN (icode) (ops[0].value);
7109 case 2:
7110 return GEN_FCN (icode) (ops[0].value, ops[1].value);
7111 case 3:
7112 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
7113 case 4:
7114 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7115 ops[3].value);
7116 case 5:
7117 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7118 ops[3].value, ops[4].value);
7119 case 6:
7120 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7121 ops[3].value, ops[4].value, ops[5].value);
7122 case 7:
7123 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7124 ops[3].value, ops[4].value, ops[5].value,
7125 ops[6].value);
7126 case 8:
7127 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7128 ops[3].value, ops[4].value, ops[5].value,
7129 ops[6].value, ops[7].value);
7130 case 9:
7131 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7132 ops[3].value, ops[4].value, ops[5].value,
7133 ops[6].value, ops[7].value, ops[8].value);
7135 gcc_unreachable ();
7138 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7139 as its operands. Return true on success and emit no code on failure. */
7141 bool
7142 maybe_expand_insn (enum insn_code icode, unsigned int nops,
7143 struct expand_operand *ops)
7145 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7146 if (pat)
7148 emit_insn (pat);
7149 return true;
7151 return false;
7154 /* Like maybe_expand_insn, but for jumps. */
7156 bool
7157 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
7158 struct expand_operand *ops)
7160 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7161 if (pat)
7163 emit_jump_insn (pat);
7164 return true;
7166 return false;
7169 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7170 as its operands. */
7172 void
7173 expand_insn (enum insn_code icode, unsigned int nops,
7174 struct expand_operand *ops)
7176 if (!maybe_expand_insn (icode, nops, ops))
7177 gcc_unreachable ();
7180 /* Like expand_insn, but for jumps. */
7182 void
7183 expand_jump_insn (enum insn_code icode, unsigned int nops,
7184 struct expand_operand *ops)
7186 if (!maybe_expand_jump_insn (icode, nops, ops))
7187 gcc_unreachable ();