d: Merge upstream dmd, druntime c8ae4adb2e, phobos 792c8b7c1.
[official-gcc.git] / gcc / optabs.cc
blobbbe3bd79ca105750af63d05058b61484ee653ccf
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2022 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 "optabs.h"
32 #include "expmed.h"
33 #include "emit-rtl.h"
34 #include "recog.h"
35 #include "diagnostic-core.h"
36 #include "rtx-vector-builder.h"
38 /* Include insn-config.h before expr.h so that HAVE_conditional_move
39 is properly defined. */
40 #include "stor-layout.h"
41 #include "except.h"
42 #include "dojump.h"
43 #include "explow.h"
44 #include "expr.h"
45 #include "optabs-tree.h"
46 #include "libfuncs.h"
47 #include "internal-fn.h"
48 #include "langhooks.h"
50 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
51 machine_mode *);
52 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
53 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
55 static rtx emit_conditional_move_1 (rtx, rtx, rtx, rtx, machine_mode);
57 /* Debug facility for use in GDB. */
58 void debug_optab_libfuncs (void);
60 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
61 the result of operation CODE applied to OP0 (and OP1 if it is a binary
62 operation). OP0_MODE is OP0's mode.
64 If the last insn does not set TARGET, don't do anything, but return 1.
66 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
67 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
68 try again, ensuring that TARGET is not one of the operands. */
70 static int
71 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
72 rtx op1, machine_mode op0_mode)
74 rtx_insn *last_insn;
75 rtx set;
76 rtx note;
78 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
80 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
81 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
82 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
83 && GET_RTX_CLASS (code) != RTX_COMPARE
84 && GET_RTX_CLASS (code) != RTX_UNARY)
85 return 1;
87 if (GET_CODE (target) == ZERO_EXTRACT)
88 return 1;
90 for (last_insn = insns;
91 NEXT_INSN (last_insn) != NULL_RTX;
92 last_insn = NEXT_INSN (last_insn))
95 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
96 a value changing in the insn, so the note would be invalid for CSE. */
97 if (reg_overlap_mentioned_p (target, op0)
98 || (op1 && reg_overlap_mentioned_p (target, op1)))
100 if (MEM_P (target)
101 && (rtx_equal_p (target, op0)
102 || (op1 && rtx_equal_p (target, op1))))
104 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
105 over expanding it as temp = MEM op X, MEM = temp. If the target
106 supports MEM = MEM op X instructions, it is sometimes too hard
107 to reconstruct that form later, especially if X is also a memory,
108 and due to multiple occurrences of addresses the address might
109 be forced into register unnecessarily.
110 Note that not emitting the REG_EQUIV note might inhibit
111 CSE in some cases. */
112 set = single_set (last_insn);
113 if (set
114 && GET_CODE (SET_SRC (set)) == code
115 && MEM_P (SET_DEST (set))
116 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
117 || (op1 && rtx_equal_p (SET_DEST (set),
118 XEXP (SET_SRC (set), 1)))))
119 return 1;
121 return 0;
124 set = set_for_reg_notes (last_insn);
125 if (set == NULL_RTX)
126 return 1;
128 if (! rtx_equal_p (SET_DEST (set), target)
129 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
130 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
131 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
132 return 1;
134 if (GET_RTX_CLASS (code) == RTX_UNARY)
135 switch (code)
137 case FFS:
138 case CLZ:
139 case CTZ:
140 case CLRSB:
141 case POPCOUNT:
142 case PARITY:
143 case BSWAP:
144 if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
146 note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
147 if (GET_MODE_UNIT_SIZE (op0_mode)
148 > GET_MODE_UNIT_SIZE (GET_MODE (target)))
149 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
150 note, op0_mode);
151 else
152 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
153 note, op0_mode);
154 break;
156 /* FALLTHRU */
157 default:
158 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
159 break;
161 else
162 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
164 set_unique_reg_note (last_insn, REG_EQUAL, note);
166 return 1;
169 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
170 for a widening operation would be. In most cases this would be OP0, but if
171 that's a constant it'll be VOIDmode, which isn't useful. */
173 static machine_mode
174 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
176 machine_mode m0 = GET_MODE (op0);
177 machine_mode m1 = GET_MODE (op1);
178 machine_mode result;
180 if (m0 == VOIDmode && m1 == VOIDmode)
181 return to_mode;
182 else if (m0 == VOIDmode || GET_MODE_UNIT_SIZE (m0) < GET_MODE_UNIT_SIZE (m1))
183 result = m1;
184 else
185 result = m0;
187 if (GET_MODE_UNIT_SIZE (result) > GET_MODE_UNIT_SIZE (to_mode))
188 return to_mode;
190 return result;
193 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
194 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
195 not actually do a sign-extend or zero-extend, but can leave the
196 higher-order bits of the result rtx undefined, for example, in the case
197 of logical operations, but not right shifts. */
199 static rtx
200 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
201 int unsignedp, int no_extend)
203 rtx result;
204 scalar_int_mode int_mode;
206 /* If we don't have to extend and this is a constant, return it. */
207 if (no_extend && GET_MODE (op) == VOIDmode)
208 return op;
210 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
211 extend since it will be more efficient to do so unless the signedness of
212 a promoted object differs from our extension. */
213 if (! no_extend
214 || !is_a <scalar_int_mode> (mode, &int_mode)
215 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
216 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
217 return convert_modes (mode, oldmode, op, unsignedp);
219 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
220 SUBREG. */
221 if (GET_MODE_SIZE (int_mode) <= UNITS_PER_WORD)
222 return gen_lowpart (int_mode, force_reg (GET_MODE (op), op));
224 /* Otherwise, get an object of MODE, clobber it, and set the low-order
225 part to OP. */
227 result = gen_reg_rtx (int_mode);
228 emit_clobber (result);
229 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
230 return result;
233 /* Expand vector widening operations.
235 There are two different classes of operations handled here:
236 1) Operations whose result is wider than all the arguments to the operation.
237 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
238 In this case OP0 and optionally OP1 would be initialized,
239 but WIDE_OP wouldn't (not relevant for this case).
240 2) Operations whose result is of the same size as the last argument to the
241 operation, but wider than all the other arguments to the operation.
242 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
243 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
245 E.g, when called to expand the following operations, this is how
246 the arguments will be initialized:
247 nops OP0 OP1 WIDE_OP
248 widening-sum 2 oprnd0 - oprnd1
249 widening-dot-product 3 oprnd0 oprnd1 oprnd2
250 widening-mult 2 oprnd0 oprnd1 -
251 type-promotion (vec-unpack) 1 oprnd0 - - */
254 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
255 rtx target, int unsignedp)
257 class expand_operand eops[4];
258 tree oprnd0, oprnd1, oprnd2;
259 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
260 optab widen_pattern_optab;
261 enum insn_code icode;
262 int nops = TREE_CODE_LENGTH (ops->code);
263 int op;
264 bool sbool = false;
266 oprnd0 = ops->op0;
267 oprnd1 = nops >= 2 ? ops->op1 : NULL_TREE;
268 oprnd2 = nops >= 3 ? ops->op2 : NULL_TREE;
270 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
271 if (ops->code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
272 || ops->code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
273 /* The sign is from the result type rather than operand's type
274 for these ops. */
275 widen_pattern_optab
276 = optab_for_tree_code (ops->code, ops->type, optab_default);
277 else if ((ops->code == VEC_UNPACK_HI_EXPR
278 || ops->code == VEC_UNPACK_LO_EXPR)
279 && VECTOR_BOOLEAN_TYPE_P (ops->type)
280 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (oprnd0))
281 && TYPE_MODE (ops->type) == TYPE_MODE (TREE_TYPE (oprnd0))
282 && SCALAR_INT_MODE_P (TYPE_MODE (ops->type)))
284 /* For VEC_UNPACK_{LO,HI}_EXPR if the mode of op0 and result is
285 the same scalar mode for VECTOR_BOOLEAN_TYPE_P vectors, use
286 vec_unpacks_sbool_{lo,hi}_optab, so that we can pass in
287 the pattern number of elements in the wider vector. */
288 widen_pattern_optab
289 = (ops->code == VEC_UNPACK_HI_EXPR
290 ? vec_unpacks_sbool_hi_optab : vec_unpacks_sbool_lo_optab);
291 sbool = true;
293 else if (ops->code == DOT_PROD_EXPR)
295 enum optab_subtype subtype = optab_default;
296 signop sign1 = TYPE_SIGN (TREE_TYPE (oprnd0));
297 signop sign2 = TYPE_SIGN (TREE_TYPE (oprnd1));
298 if (sign1 == sign2)
300 else if (sign1 == SIGNED && sign2 == UNSIGNED)
302 subtype = optab_vector_mixed_sign;
303 /* Same as optab_vector_mixed_sign but flip the operands. */
304 std::swap (op0, op1);
306 else if (sign1 == UNSIGNED && sign2 == SIGNED)
307 subtype = optab_vector_mixed_sign;
308 else
309 gcc_unreachable ();
311 widen_pattern_optab
312 = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), subtype);
314 else
315 widen_pattern_optab
316 = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
317 if (ops->code == WIDEN_MULT_PLUS_EXPR
318 || ops->code == WIDEN_MULT_MINUS_EXPR)
319 icode = find_widening_optab_handler (widen_pattern_optab,
320 TYPE_MODE (TREE_TYPE (ops->op2)),
321 tmode0);
322 else
323 icode = optab_handler (widen_pattern_optab, tmode0);
324 gcc_assert (icode != CODE_FOR_nothing);
326 if (nops >= 2)
327 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
328 else if (sbool)
330 nops = 2;
331 op1 = GEN_INT (TYPE_VECTOR_SUBPARTS (TREE_TYPE (oprnd0)).to_constant ());
332 tmode1 = tmode0;
335 /* The last operand is of a wider mode than the rest of the operands. */
336 if (nops == 2)
337 wmode = tmode1;
338 else if (nops == 3)
340 gcc_assert (tmode1 == tmode0);
341 gcc_assert (op1);
342 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
345 op = 0;
346 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
347 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
348 if (op1)
349 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
350 if (wide_op)
351 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
352 expand_insn (icode, op, eops);
353 return eops[0].value;
356 /* Generate code to perform an operation specified by TERNARY_OPTAB
357 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
359 UNSIGNEDP is for the case where we have to widen the operands
360 to perform the operation. It says to use zero-extension.
362 If TARGET is nonzero, the value
363 is generated there, if it is convenient to do so.
364 In all cases an rtx is returned for the locus of the value;
365 this may or may not be TARGET. */
368 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
369 rtx op1, rtx op2, rtx target, int unsignedp)
371 class expand_operand ops[4];
372 enum insn_code icode = optab_handler (ternary_optab, mode);
374 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
376 create_output_operand (&ops[0], target, mode);
377 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
378 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
379 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
380 expand_insn (icode, 4, ops);
381 return ops[0].value;
385 /* Like expand_binop, but return a constant rtx if the result can be
386 calculated at compile time. The arguments and return value are
387 otherwise the same as for expand_binop. */
390 simplify_expand_binop (machine_mode mode, optab binoptab,
391 rtx op0, rtx op1, rtx target, int unsignedp,
392 enum optab_methods methods)
394 if (CONSTANT_P (op0) && CONSTANT_P (op1))
396 rtx x = simplify_binary_operation (optab_to_code (binoptab),
397 mode, op0, op1);
398 if (x)
399 return x;
402 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
405 /* Like simplify_expand_binop, but always put the result in TARGET.
406 Return true if the expansion succeeded. */
408 bool
409 force_expand_binop (machine_mode mode, optab binoptab,
410 rtx op0, rtx op1, rtx target, int unsignedp,
411 enum optab_methods methods)
413 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
414 target, unsignedp, methods);
415 if (x == 0)
416 return false;
417 if (x != target)
418 emit_move_insn (target, x);
419 return true;
422 /* Create a new vector value in VMODE with all elements set to OP. The
423 mode of OP must be the element mode of VMODE. If OP is a constant,
424 then the return value will be a constant. */
427 expand_vector_broadcast (machine_mode vmode, rtx op)
429 int n;
430 rtvec vec;
432 gcc_checking_assert (VECTOR_MODE_P (vmode));
434 if (valid_for_const_vector_p (vmode, op))
435 return gen_const_vec_duplicate (vmode, op);
437 insn_code icode = optab_handler (vec_duplicate_optab, vmode);
438 if (icode != CODE_FOR_nothing)
440 class expand_operand ops[2];
441 create_output_operand (&ops[0], NULL_RTX, vmode);
442 create_input_operand (&ops[1], op, GET_MODE (op));
443 expand_insn (icode, 2, ops);
444 return ops[0].value;
447 if (!GET_MODE_NUNITS (vmode).is_constant (&n))
448 return NULL;
450 /* ??? If the target doesn't have a vec_init, then we have no easy way
451 of performing this operation. Most of this sort of generic support
452 is hidden away in the vector lowering support in gimple. */
453 icode = convert_optab_handler (vec_init_optab, vmode,
454 GET_MODE_INNER (vmode));
455 if (icode == CODE_FOR_nothing)
456 return NULL;
458 vec = rtvec_alloc (n);
459 for (int i = 0; i < n; ++i)
460 RTVEC_ELT (vec, i) = op;
461 rtx ret = gen_reg_rtx (vmode);
462 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
464 return ret;
467 /* This subroutine of expand_doubleword_shift handles the cases in which
468 the effective shift value is >= BITS_PER_WORD. The arguments and return
469 value are the same as for the parent routine, except that SUPERWORD_OP1
470 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
471 INTO_TARGET may be null if the caller has decided to calculate it. */
473 static bool
474 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
475 rtx outof_target, rtx into_target,
476 int unsignedp, enum optab_methods methods)
478 if (into_target != 0)
479 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
480 into_target, unsignedp, methods))
481 return false;
483 if (outof_target != 0)
485 /* For a signed right shift, we must fill OUTOF_TARGET with copies
486 of the sign bit, otherwise we must fill it with zeros. */
487 if (binoptab != ashr_optab)
488 emit_move_insn (outof_target, CONST0_RTX (word_mode));
489 else
490 if (!force_expand_binop (word_mode, binoptab, outof_input,
491 gen_int_shift_amount (word_mode,
492 BITS_PER_WORD - 1),
493 outof_target, unsignedp, methods))
494 return false;
496 return true;
499 /* This subroutine of expand_doubleword_shift handles the cases in which
500 the effective shift value is < BITS_PER_WORD. The arguments and return
501 value are the same as for the parent routine. */
503 static bool
504 expand_subword_shift (scalar_int_mode op1_mode, optab binoptab,
505 rtx outof_input, rtx into_input, rtx op1,
506 rtx outof_target, rtx into_target,
507 int unsignedp, enum optab_methods methods,
508 unsigned HOST_WIDE_INT shift_mask)
510 optab reverse_unsigned_shift, unsigned_shift;
511 rtx tmp, carries;
513 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
514 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
516 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
517 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
518 the opposite direction to BINOPTAB. */
519 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
521 carries = outof_input;
522 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
523 op1_mode), op1_mode);
524 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
525 0, true, methods);
527 else
529 /* We must avoid shifting by BITS_PER_WORD bits since that is either
530 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
531 has unknown behavior. Do a single shift first, then shift by the
532 remainder. It's OK to use ~OP1 as the remainder if shift counts
533 are truncated to the mode size. */
534 carries = expand_binop (word_mode, reverse_unsigned_shift,
535 outof_input, const1_rtx, 0, unsignedp, methods);
536 if (shift_mask == BITS_PER_WORD - 1)
538 tmp = immed_wide_int_const
539 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
540 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
541 0, true, methods);
543 else
545 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
546 op1_mode), op1_mode);
547 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
548 0, true, methods);
551 if (tmp == 0 || carries == 0)
552 return false;
553 carries = expand_binop (word_mode, reverse_unsigned_shift,
554 carries, tmp, 0, unsignedp, methods);
555 if (carries == 0)
556 return false;
558 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
559 so the result can go directly into INTO_TARGET if convenient. */
560 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
561 into_target, unsignedp, methods);
562 if (tmp == 0)
563 return false;
565 /* Now OR in the bits carried over from OUTOF_INPUT. */
566 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
567 into_target, unsignedp, methods))
568 return false;
570 /* Use a standard word_mode shift for the out-of half. */
571 if (outof_target != 0)
572 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
573 outof_target, unsignedp, methods))
574 return false;
576 return true;
580 /* Try implementing expand_doubleword_shift using conditional moves.
581 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
582 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
583 are the shift counts to use in the former and latter case. All other
584 arguments are the same as the parent routine. */
586 static bool
587 expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
588 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
589 rtx outof_input, rtx into_input,
590 rtx subword_op1, rtx superword_op1,
591 rtx outof_target, rtx into_target,
592 int unsignedp, enum optab_methods methods,
593 unsigned HOST_WIDE_INT shift_mask)
595 rtx outof_superword, into_superword;
597 /* Put the superword version of the output into OUTOF_SUPERWORD and
598 INTO_SUPERWORD. */
599 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
600 if (outof_target != 0 && subword_op1 == superword_op1)
602 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
603 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
604 into_superword = outof_target;
605 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
606 outof_superword, 0, unsignedp, methods))
607 return false;
609 else
611 into_superword = gen_reg_rtx (word_mode);
612 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
613 outof_superword, into_superword,
614 unsignedp, methods))
615 return false;
618 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
619 if (!expand_subword_shift (op1_mode, binoptab,
620 outof_input, into_input, subword_op1,
621 outof_target, into_target,
622 unsignedp, methods, shift_mask))
623 return false;
625 /* Select between them. Do the INTO half first because INTO_SUPERWORD
626 might be the current value of OUTOF_TARGET. */
627 if (!emit_conditional_move (into_target, { cmp_code, cmp1, cmp2, op1_mode },
628 into_target, into_superword, word_mode, false))
629 return false;
631 if (outof_target != 0)
632 if (!emit_conditional_move (outof_target,
633 { cmp_code, cmp1, cmp2, op1_mode },
634 outof_target, outof_superword,
635 word_mode, false))
636 return false;
638 return true;
641 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
642 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
643 input operand; the shift moves bits in the direction OUTOF_INPUT->
644 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
645 of the target. OP1 is the shift count and OP1_MODE is its mode.
646 If OP1 is constant, it will have been truncated as appropriate
647 and is known to be nonzero.
649 If SHIFT_MASK is zero, the result of word shifts is undefined when the
650 shift count is outside the range [0, BITS_PER_WORD). This routine must
651 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
653 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
654 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
655 fill with zeros or sign bits as appropriate.
657 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
658 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
659 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
660 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
661 are undefined.
663 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
664 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
665 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
666 function wants to calculate it itself.
668 Return true if the shift could be successfully synthesized. */
670 static bool
671 expand_doubleword_shift (scalar_int_mode op1_mode, optab binoptab,
672 rtx outof_input, rtx into_input, rtx op1,
673 rtx outof_target, rtx into_target,
674 int unsignedp, enum optab_methods methods,
675 unsigned HOST_WIDE_INT shift_mask)
677 rtx superword_op1, tmp, cmp1, cmp2;
678 enum rtx_code cmp_code;
680 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
681 fill the result with sign or zero bits as appropriate. If so, the value
682 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
683 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
684 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
686 This isn't worthwhile for constant shifts since the optimizers will
687 cope better with in-range shift counts. */
688 if (shift_mask >= BITS_PER_WORD
689 && outof_target != 0
690 && !CONSTANT_P (op1))
692 if (!expand_doubleword_shift (op1_mode, binoptab,
693 outof_input, into_input, op1,
694 0, into_target,
695 unsignedp, methods, shift_mask))
696 return false;
697 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
698 outof_target, unsignedp, methods))
699 return false;
700 return true;
703 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
704 is true when the effective shift value is less than BITS_PER_WORD.
705 Set SUPERWORD_OP1 to the shift count that should be used to shift
706 OUTOF_INPUT into INTO_TARGET when the condition is false. */
707 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
708 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
710 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
711 is a subword shift count. */
712 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
713 0, true, methods);
714 cmp2 = CONST0_RTX (op1_mode);
715 cmp_code = EQ;
716 superword_op1 = op1;
718 else
720 /* Set CMP1 to OP1 - BITS_PER_WORD. */
721 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
722 0, true, methods);
723 cmp2 = CONST0_RTX (op1_mode);
724 cmp_code = LT;
725 superword_op1 = cmp1;
727 if (cmp1 == 0)
728 return false;
730 /* If we can compute the condition at compile time, pick the
731 appropriate subroutine. */
732 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
733 if (tmp != 0 && CONST_INT_P (tmp))
735 if (tmp == const0_rtx)
736 return expand_superword_shift (binoptab, outof_input, superword_op1,
737 outof_target, into_target,
738 unsignedp, methods);
739 else
740 return expand_subword_shift (op1_mode, binoptab,
741 outof_input, into_input, op1,
742 outof_target, into_target,
743 unsignedp, methods, shift_mask);
746 /* Try using conditional moves to generate straight-line code. */
747 if (HAVE_conditional_move)
749 rtx_insn *start = get_last_insn ();
750 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
751 cmp_code, cmp1, cmp2,
752 outof_input, into_input,
753 op1, superword_op1,
754 outof_target, into_target,
755 unsignedp, methods, shift_mask))
756 return true;
757 delete_insns_since (start);
760 /* As a last resort, use branches to select the correct alternative. */
761 rtx_code_label *subword_label = gen_label_rtx ();
762 rtx_code_label *done_label = gen_label_rtx ();
764 NO_DEFER_POP;
765 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
766 0, 0, subword_label,
767 profile_probability::uninitialized ());
768 OK_DEFER_POP;
770 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
771 outof_target, into_target,
772 unsignedp, methods))
773 return false;
775 emit_jump_insn (targetm.gen_jump (done_label));
776 emit_barrier ();
777 emit_label (subword_label);
779 if (!expand_subword_shift (op1_mode, binoptab,
780 outof_input, into_input, op1,
781 outof_target, into_target,
782 unsignedp, methods, shift_mask))
783 return false;
785 emit_label (done_label);
786 return true;
789 /* Subroutine of expand_binop. Perform a double word multiplication of
790 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
791 as the target's word_mode. This function return NULL_RTX if anything
792 goes wrong, in which case it may have already emitted instructions
793 which need to be deleted.
795 If we want to multiply two two-word values and have normal and widening
796 multiplies of single-word values, we can do this with three smaller
797 multiplications.
799 The multiplication proceeds as follows:
800 _______________________
801 [__op0_high_|__op0_low__]
802 _______________________
803 * [__op1_high_|__op1_low__]
804 _______________________________________________
805 _______________________
806 (1) [__op0_low__*__op1_low__]
807 _______________________
808 (2a) [__op0_low__*__op1_high_]
809 _______________________
810 (2b) [__op0_high_*__op1_low__]
811 _______________________
812 (3) [__op0_high_*__op1_high_]
815 This gives a 4-word result. Since we are only interested in the
816 lower 2 words, partial result (3) and the upper words of (2a) and
817 (2b) don't need to be calculated. Hence (2a) and (2b) can be
818 calculated using non-widening multiplication.
820 (1), however, needs to be calculated with an unsigned widening
821 multiplication. If this operation is not directly supported we
822 try using a signed widening multiplication and adjust the result.
823 This adjustment works as follows:
825 If both operands are positive then no adjustment is needed.
827 If the operands have different signs, for example op0_low < 0 and
828 op1_low >= 0, the instruction treats the most significant bit of
829 op0_low as a sign bit instead of a bit with significance
830 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
831 with 2**BITS_PER_WORD - op0_low, and two's complements the
832 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
833 the result.
835 Similarly, if both operands are negative, we need to add
836 (op0_low + op1_low) * 2**BITS_PER_WORD.
838 We use a trick to adjust quickly. We logically shift op0_low right
839 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
840 op0_high (op1_high) before it is used to calculate 2b (2a). If no
841 logical shift exists, we do an arithmetic right shift and subtract
842 the 0 or -1. */
844 static rtx
845 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
846 bool umulp, enum optab_methods methods)
848 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
849 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
850 rtx wordm1 = (umulp ? NULL_RTX
851 : gen_int_shift_amount (word_mode, BITS_PER_WORD - 1));
852 rtx product, adjust, product_high, temp;
854 rtx op0_high = operand_subword_force (op0, high, mode);
855 rtx op0_low = operand_subword_force (op0, low, mode);
856 rtx op1_high = operand_subword_force (op1, high, mode);
857 rtx op1_low = operand_subword_force (op1, low, mode);
859 /* If we're using an unsigned multiply to directly compute the product
860 of the low-order words of the operands and perform any required
861 adjustments of the operands, we begin by trying two more multiplications
862 and then computing the appropriate sum.
864 We have checked above that the required addition is provided.
865 Full-word addition will normally always succeed, especially if
866 it is provided at all, so we don't worry about its failure. The
867 multiplication may well fail, however, so we do handle that. */
869 if (!umulp)
871 /* ??? This could be done with emit_store_flag where available. */
872 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
873 NULL_RTX, 1, methods);
874 if (temp)
875 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
876 NULL_RTX, 0, OPTAB_DIRECT);
877 else
879 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
880 NULL_RTX, 0, methods);
881 if (!temp)
882 return NULL_RTX;
883 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
884 NULL_RTX, 0, OPTAB_DIRECT);
887 if (!op0_high)
888 return NULL_RTX;
891 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
892 NULL_RTX, 0, OPTAB_DIRECT);
893 if (!adjust)
894 return NULL_RTX;
896 /* OP0_HIGH should now be dead. */
898 if (!umulp)
900 /* ??? This could be done with emit_store_flag where available. */
901 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
902 NULL_RTX, 1, methods);
903 if (temp)
904 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
905 NULL_RTX, 0, OPTAB_DIRECT);
906 else
908 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
909 NULL_RTX, 0, methods);
910 if (!temp)
911 return NULL_RTX;
912 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
913 NULL_RTX, 0, OPTAB_DIRECT);
916 if (!op1_high)
917 return NULL_RTX;
920 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
921 NULL_RTX, 0, OPTAB_DIRECT);
922 if (!temp)
923 return NULL_RTX;
925 /* OP1_HIGH should now be dead. */
927 adjust = expand_binop (word_mode, add_optab, adjust, temp,
928 NULL_RTX, 0, OPTAB_DIRECT);
930 if (target && !REG_P (target))
931 target = NULL_RTX;
933 /* *_widen_optab needs to determine operand mode, make sure at least
934 one operand has non-VOID mode. */
935 if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
936 op0_low = force_reg (word_mode, op0_low);
938 if (umulp)
939 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
940 target, 1, OPTAB_DIRECT);
941 else
942 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
943 target, 1, OPTAB_DIRECT);
945 if (!product)
946 return NULL_RTX;
948 product_high = operand_subword (product, high, 1, mode);
949 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
950 NULL_RTX, 0, OPTAB_DIRECT);
951 emit_move_insn (product_high, adjust);
952 return product;
955 /* Subroutine of expand_binop. Optimize unsigned double-word OP0 % OP1 for
956 constant OP1. If for some bit in [BITS_PER_WORD / 2, BITS_PER_WORD] range
957 (prefer higher bits) ((1w << bit) % OP1) == 1, then the modulo can be
958 computed in word-mode as ((OP0 & (bit - 1)) + ((OP0 >> bit) & (bit - 1))
959 + (OP0 >> (2 * bit))) % OP1. Whether we need to sum 2, 3 or 4 values
960 depends on the bit value, if 2, then carry from the addition needs to be
961 added too, i.e. like:
962 sum += __builtin_add_overflow (low, high, &sum)
964 Optimize signed double-word OP0 % OP1 similarly, just apply some correction
965 factor to the sum before doing unsigned remainder, in the form of
966 sum += (((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & const);
967 then perform unsigned
968 remainder = sum % OP1;
969 and finally
970 remainder += ((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1); */
972 static rtx
973 expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
975 if (INTVAL (op1) <= 1 || (INTVAL (op1) & 1) == 0)
976 return NULL_RTX;
978 rtx_insn *last = get_last_insn ();
979 for (int bit = BITS_PER_WORD; bit >= BITS_PER_WORD / 2; bit--)
981 wide_int w = wi::shifted_mask (bit, 1, false, 2 * BITS_PER_WORD);
982 if (wi::ne_p (wi::umod_trunc (w, INTVAL (op1)), 1))
983 continue;
984 rtx sum = NULL_RTX, mask = NULL_RTX;
985 if (bit == BITS_PER_WORD)
987 /* For signed modulo we need to add correction to the sum
988 and that might again overflow. */
989 if (!unsignedp)
990 continue;
991 if (optab_handler (uaddv4_optab, word_mode) == CODE_FOR_nothing)
992 continue;
993 tree wtype = lang_hooks.types.type_for_mode (word_mode, 1);
994 if (wtype == NULL_TREE)
995 continue;
996 tree ctype = build_complex_type (wtype);
997 if (TYPE_MODE (ctype) != GET_MODE_COMPLEX_MODE (word_mode))
998 continue;
999 machine_mode cmode = TYPE_MODE (ctype);
1000 rtx op00 = operand_subword_force (op0, 0, mode);
1001 rtx op01 = operand_subword_force (op0, 1, mode);
1002 rtx cres = gen_rtx_CONCAT (cmode, gen_reg_rtx (word_mode),
1003 gen_reg_rtx (word_mode));
1004 tree lhs = make_tree (ctype, cres);
1005 tree arg0 = make_tree (wtype, op00);
1006 tree arg1 = make_tree (wtype, op01);
1007 expand_addsub_overflow (UNKNOWN_LOCATION, PLUS_EXPR, lhs, arg0,
1008 arg1, true, true, true, false, NULL);
1009 sum = expand_simple_binop (word_mode, PLUS, XEXP (cres, 0),
1010 XEXP (cres, 1), NULL_RTX, 1,
1011 OPTAB_DIRECT);
1012 if (sum == NULL_RTX)
1013 return NULL_RTX;
1015 else
1017 /* Code below uses GEN_INT, so we need the masks to be representable
1018 in HOST_WIDE_INTs. */
1019 if (bit >= HOST_BITS_PER_WIDE_INT)
1020 continue;
1021 /* If op0 is e.g. -1 or -2 unsigned, then the 2 additions might
1022 overflow. Consider 64-bit -1ULL for word size 32, if we add
1023 0x7fffffffU + 0x7fffffffU + 3U, it wraps around to 1. */
1024 if (bit == BITS_PER_WORD - 1)
1025 continue;
1027 int count = (2 * BITS_PER_WORD + bit - 1) / bit;
1028 rtx sum_corr = NULL_RTX;
1030 if (!unsignedp)
1032 /* For signed modulo, compute it as unsigned modulo of
1033 sum with a correction added to it if OP0 is negative,
1034 such that the result can be computed as unsigned
1035 remainder + ((OP1 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1). */
1036 w = wi::min_value (2 * BITS_PER_WORD, SIGNED);
1037 wide_int wmod1 = wi::umod_trunc (w, INTVAL (op1));
1038 wide_int wmod2 = wi::smod_trunc (w, INTVAL (op1));
1039 /* wmod2 == -wmod1. */
1040 wmod2 = wmod2 + (INTVAL (op1) - 1);
1041 if (wi::ne_p (wmod1, wmod2))
1043 wide_int wcorr = wmod2 - wmod1;
1044 if (wi::neg_p (w))
1045 wcorr = wcorr + INTVAL (op1);
1046 /* Now verify if the count sums can't overflow, and punt
1047 if they could. */
1048 w = wi::mask (bit, false, 2 * BITS_PER_WORD);
1049 w = w * (count - 1);
1050 w = w + wi::mask (2 * BITS_PER_WORD - (count - 1) * bit,
1051 false, 2 * BITS_PER_WORD);
1052 w = w + wcorr;
1053 w = wi::lrshift (w, BITS_PER_WORD);
1054 if (wi::ne_p (w, 0))
1055 continue;
1057 mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
1058 mode);
1059 mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
1060 GEN_INT (BITS_PER_WORD - 1),
1061 NULL_RTX, 0, OPTAB_DIRECT);
1062 if (mask == NULL_RTX)
1063 return NULL_RTX;
1064 sum_corr = immed_wide_int_const (wcorr, word_mode);
1065 sum_corr = expand_simple_binop (word_mode, AND, mask,
1066 sum_corr, NULL_RTX, 1,
1067 OPTAB_DIRECT);
1068 if (sum_corr == NULL_RTX)
1069 return NULL_RTX;
1073 for (int i = 0; i < count; i++)
1075 rtx v = op0;
1076 if (i)
1077 v = expand_simple_binop (mode, LSHIFTRT, v, GEN_INT (i * bit),
1078 NULL_RTX, 1, OPTAB_DIRECT);
1079 if (v == NULL_RTX)
1080 return NULL_RTX;
1081 v = lowpart_subreg (word_mode, v, mode);
1082 if (v == NULL_RTX)
1083 return NULL_RTX;
1084 if (i != count - 1)
1085 v = expand_simple_binop (word_mode, AND, v,
1086 GEN_INT ((HOST_WIDE_INT_1U << bit)
1087 - 1), NULL_RTX, 1,
1088 OPTAB_DIRECT);
1089 if (v == NULL_RTX)
1090 return NULL_RTX;
1091 if (sum == NULL_RTX)
1092 sum = v;
1093 else
1094 sum = expand_simple_binop (word_mode, PLUS, sum, v, NULL_RTX,
1095 1, OPTAB_DIRECT);
1096 if (sum == NULL_RTX)
1097 return NULL_RTX;
1099 if (sum_corr)
1101 sum = expand_simple_binop (word_mode, PLUS, sum, sum_corr,
1102 NULL_RTX, 1, OPTAB_DIRECT);
1103 if (sum == NULL_RTX)
1104 return NULL_RTX;
1107 rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, NULL, NULL,
1108 sum, gen_int_mode (INTVAL (op1),
1109 word_mode),
1110 NULL_RTX, 1, OPTAB_DIRECT);
1111 if (remainder == NULL_RTX)
1112 return NULL_RTX;
1114 if (!unsignedp)
1116 if (mask == NULL_RTX)
1118 mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
1119 mode);
1120 mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
1121 GEN_INT (BITS_PER_WORD - 1),
1122 NULL_RTX, 0, OPTAB_DIRECT);
1123 if (mask == NULL_RTX)
1124 return NULL_RTX;
1126 mask = expand_simple_binop (word_mode, AND, mask,
1127 gen_int_mode (1 - INTVAL (op1),
1128 word_mode),
1129 NULL_RTX, 1, OPTAB_DIRECT);
1130 if (mask == NULL_RTX)
1131 return NULL_RTX;
1132 remainder = expand_simple_binop (word_mode, PLUS, remainder,
1133 mask, NULL_RTX, 1, OPTAB_DIRECT);
1134 if (remainder == NULL_RTX)
1135 return NULL_RTX;
1138 remainder = convert_modes (mode, word_mode, remainder, unsignedp);
1139 /* Punt if we need any library calls. */
1140 if (last)
1141 last = NEXT_INSN (last);
1142 else
1143 last = get_insns ();
1144 for (; last; last = NEXT_INSN (last))
1145 if (CALL_P (last))
1146 return NULL_RTX;
1147 return remainder;
1149 return NULL_RTX;
1152 /* Similarly to the above function, but compute both quotient and remainder.
1153 Quotient can be computed from the remainder as:
1154 rem = op0 % op1; // Handled using expand_doubleword_mod
1155 quot = (op0 - rem) * inv; // inv is multiplicative inverse of op1 modulo
1156 // 2 * BITS_PER_WORD
1158 We can also handle cases where op1 is a multiple of power of two constant
1159 and constant handled by expand_doubleword_mod.
1160 op11 = 1 << __builtin_ctz (op1);
1161 op12 = op1 / op11;
1162 rem1 = op0 % op12; // Handled using expand_doubleword_mod
1163 quot1 = (op0 - rem1) * inv; // inv is multiplicative inverse of op12 modulo
1164 // 2 * BITS_PER_WORD
1165 rem = (quot1 % op11) * op12 + rem1;
1166 quot = quot1 / op11; */
1169 expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem,
1170 bool unsignedp)
1172 *rem = NULL_RTX;
1174 /* Negative dividend should have been optimized into positive,
1175 similarly modulo by 1 and modulo by power of two is optimized
1176 differently too. */
1177 if (INTVAL (op1) <= 1 || pow2p_hwi (INTVAL (op1)))
1178 return NULL_RTX;
1180 rtx op11 = const1_rtx;
1181 rtx op12 = op1;
1182 if ((INTVAL (op1) & 1) == 0)
1184 int bit = ctz_hwi (INTVAL (op1));
1185 op11 = GEN_INT (HOST_WIDE_INT_1 << bit);
1186 op12 = GEN_INT (INTVAL (op1) >> bit);
1189 rtx rem1 = expand_doubleword_mod (mode, op0, op12, unsignedp);
1190 if (rem1 == NULL_RTX)
1191 return NULL_RTX;
1193 int prec = 2 * BITS_PER_WORD;
1194 wide_int a = wide_int::from (INTVAL (op12), prec + 1, UNSIGNED);
1195 wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
1196 wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
1197 rtx inv = immed_wide_int_const (m, mode);
1199 rtx_insn *last = get_last_insn ();
1200 rtx quot1 = expand_simple_binop (mode, MINUS, op0, rem1,
1201 NULL_RTX, unsignedp, OPTAB_DIRECT);
1202 if (quot1 == NULL_RTX)
1203 return NULL_RTX;
1205 quot1 = expand_simple_binop (mode, MULT, quot1, inv,
1206 NULL_RTX, unsignedp, OPTAB_DIRECT);
1207 if (quot1 == NULL_RTX)
1208 return NULL_RTX;
1210 if (op11 != const1_rtx)
1212 rtx rem2 = expand_divmod (1, TRUNC_MOD_EXPR, mode, NULL, NULL, quot1,
1213 op11, NULL_RTX, unsignedp, OPTAB_DIRECT);
1214 if (rem2 == NULL_RTX)
1215 return NULL_RTX;
1217 rem2 = expand_simple_binop (mode, MULT, rem2, op12, NULL_RTX,
1218 unsignedp, OPTAB_DIRECT);
1219 if (rem2 == NULL_RTX)
1220 return NULL_RTX;
1222 rem2 = expand_simple_binop (mode, PLUS, rem2, rem1, NULL_RTX,
1223 unsignedp, OPTAB_DIRECT);
1224 if (rem2 == NULL_RTX)
1225 return NULL_RTX;
1227 rtx quot2 = expand_divmod (0, TRUNC_DIV_EXPR, mode, NULL, NULL, quot1,
1228 op11, NULL_RTX, unsignedp, OPTAB_DIRECT);
1229 if (quot2 == NULL_RTX)
1230 return NULL_RTX;
1232 rem1 = rem2;
1233 quot1 = quot2;
1236 /* Punt if we need any library calls. */
1237 if (last)
1238 last = NEXT_INSN (last);
1239 else
1240 last = get_insns ();
1241 for (; last; last = NEXT_INSN (last))
1242 if (CALL_P (last))
1243 return NULL_RTX;
1245 *rem = rem1;
1246 return quot1;
1249 /* Wrapper around expand_binop which takes an rtx code to specify
1250 the operation to perform, not an optab pointer. All other
1251 arguments are the same. */
1253 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
1254 rtx op1, rtx target, int unsignedp,
1255 enum optab_methods methods)
1257 optab binop = code_to_optab (code);
1258 gcc_assert (binop);
1260 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1263 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1264 binop. Order them according to commutative_operand_precedence and, if
1265 possible, try to put TARGET or a pseudo first. */
1266 static bool
1267 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1269 int op0_prec = commutative_operand_precedence (op0);
1270 int op1_prec = commutative_operand_precedence (op1);
1272 if (op0_prec < op1_prec)
1273 return true;
1275 if (op0_prec > op1_prec)
1276 return false;
1278 /* With equal precedence, both orders are ok, but it is better if the
1279 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1280 if (target == 0 || REG_P (target))
1281 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1282 else
1283 return rtx_equal_p (op1, target);
1286 /* Return true if BINOPTAB implements a shift operation. */
1288 static bool
1289 shift_optab_p (optab binoptab)
1291 switch (optab_to_code (binoptab))
1293 case ASHIFT:
1294 case SS_ASHIFT:
1295 case US_ASHIFT:
1296 case ASHIFTRT:
1297 case LSHIFTRT:
1298 case ROTATE:
1299 case ROTATERT:
1300 return true;
1302 default:
1303 return false;
1307 /* Return true if BINOPTAB implements a commutative binary operation. */
1309 static bool
1310 commutative_optab_p (optab binoptab)
1312 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
1313 || binoptab == smul_widen_optab
1314 || binoptab == umul_widen_optab
1315 || binoptab == smul_highpart_optab
1316 || binoptab == umul_highpart_optab);
1319 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1320 optimizing, and if the operand is a constant that costs more than
1321 1 instruction, force the constant into a register and return that
1322 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1324 static rtx
1325 avoid_expensive_constant (machine_mode mode, optab binoptab,
1326 int opn, rtx x, bool unsignedp)
1328 bool speed = optimize_insn_for_speed_p ();
1330 if (mode != VOIDmode
1331 && optimize
1332 && CONSTANT_P (x)
1333 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
1334 > set_src_cost (x, mode, speed)))
1336 if (CONST_INT_P (x))
1338 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1339 if (intval != INTVAL (x))
1340 x = GEN_INT (intval);
1342 else
1343 x = convert_modes (mode, VOIDmode, x, unsignedp);
1344 x = force_reg (mode, x);
1346 return x;
1349 /* Helper function for expand_binop: handle the case where there
1350 is an insn ICODE that directly implements the indicated operation.
1351 Returns null if this is not possible. */
1352 static rtx
1353 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
1354 rtx op0, rtx op1,
1355 rtx target, int unsignedp, enum optab_methods methods,
1356 rtx_insn *last)
1358 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1359 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1360 machine_mode mode0, mode1, tmp_mode;
1361 class expand_operand ops[3];
1362 bool commutative_p;
1363 rtx_insn *pat;
1364 rtx xop0 = op0, xop1 = op1;
1365 bool canonicalize_op1 = false;
1367 /* If it is a commutative operator and the modes would match
1368 if we would swap the operands, we can save the conversions. */
1369 commutative_p = commutative_optab_p (binoptab);
1370 if (commutative_p
1371 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1372 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode0)
1373 std::swap (xop0, xop1);
1375 /* If we are optimizing, force expensive constants into a register. */
1376 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1377 if (!shift_optab_p (binoptab))
1378 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1379 else
1380 /* Shifts and rotates often use a different mode for op1 from op0;
1381 for VOIDmode constants we don't know the mode, so force it
1382 to be canonicalized using convert_modes. */
1383 canonicalize_op1 = true;
1385 /* In case the insn wants input operands in modes different from
1386 those of the actual operands, convert the operands. It would
1387 seem that we don't need to convert CONST_INTs, but we do, so
1388 that they're properly zero-extended, sign-extended or truncated
1389 for their mode. */
1391 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1392 if (xmode0 != VOIDmode && xmode0 != mode0)
1394 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1395 mode0 = xmode0;
1398 mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
1399 ? GET_MODE (xop1) : mode);
1400 if (xmode1 != VOIDmode && xmode1 != mode1)
1402 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1403 mode1 = xmode1;
1406 /* If operation is commutative,
1407 try to make the first operand a register.
1408 Even better, try to make it the same as the target.
1409 Also try to make the last operand a constant. */
1410 if (commutative_p
1411 && swap_commutative_operands_with_target (target, xop0, xop1))
1412 std::swap (xop0, xop1);
1414 /* Now, if insn's predicates don't allow our operands, put them into
1415 pseudo regs. */
1417 if (binoptab == vec_pack_trunc_optab
1418 || binoptab == vec_pack_usat_optab
1419 || binoptab == vec_pack_ssat_optab
1420 || binoptab == vec_pack_ufix_trunc_optab
1421 || binoptab == vec_pack_sfix_trunc_optab
1422 || binoptab == vec_packu_float_optab
1423 || binoptab == vec_packs_float_optab)
1425 /* The mode of the result is different then the mode of the
1426 arguments. */
1427 tmp_mode = insn_data[(int) icode].operand[0].mode;
1428 if (VECTOR_MODE_P (mode)
1429 && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
1431 delete_insns_since (last);
1432 return NULL_RTX;
1435 else
1436 tmp_mode = mode;
1438 create_output_operand (&ops[0], target, tmp_mode);
1439 create_input_operand (&ops[1], xop0, mode0);
1440 create_input_operand (&ops[2], xop1, mode1);
1441 pat = maybe_gen_insn (icode, 3, ops);
1442 if (pat)
1444 /* If PAT is composed of more than one insn, try to add an appropriate
1445 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1446 operand, call expand_binop again, this time without a target. */
1447 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1448 && ! add_equal_note (pat, ops[0].value,
1449 optab_to_code (binoptab),
1450 ops[1].value, ops[2].value, mode0))
1452 delete_insns_since (last);
1453 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1454 unsignedp, methods);
1457 emit_insn (pat);
1458 return ops[0].value;
1460 delete_insns_since (last);
1461 return NULL_RTX;
1464 /* Generate code to perform an operation specified by BINOPTAB
1465 on operands OP0 and OP1, with result having machine-mode MODE.
1467 UNSIGNEDP is for the case where we have to widen the operands
1468 to perform the operation. It says to use zero-extension.
1470 If TARGET is nonzero, the value
1471 is generated there, if it is convenient to do so.
1472 In all cases an rtx is returned for the locus of the value;
1473 this may or may not be TARGET. */
1476 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1477 rtx target, int unsignedp, enum optab_methods methods)
1479 enum optab_methods next_methods
1480 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1481 ? OPTAB_WIDEN : methods);
1482 enum mode_class mclass;
1483 enum insn_code icode;
1484 machine_mode wider_mode;
1485 scalar_int_mode int_mode;
1486 rtx libfunc;
1487 rtx temp;
1488 rtx_insn *entry_last = get_last_insn ();
1489 rtx_insn *last;
1491 mclass = GET_MODE_CLASS (mode);
1493 /* If subtracting an integer constant, convert this into an addition of
1494 the negated constant. */
1496 if (binoptab == sub_optab && CONST_INT_P (op1))
1498 op1 = negate_rtx (mode, op1);
1499 binoptab = add_optab;
1501 /* For shifts, constant invalid op1 might be expanded from different
1502 mode than MODE. As those are invalid, force them to a register
1503 to avoid further problems during expansion. */
1504 else if (CONST_INT_P (op1)
1505 && shift_optab_p (binoptab)
1506 && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode)))
1508 op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode));
1509 op1 = force_reg (GET_MODE_INNER (mode), op1);
1512 /* Record where to delete back to if we backtrack. */
1513 last = get_last_insn ();
1515 /* If we can do it with a three-operand insn, do so. */
1517 if (methods != OPTAB_MUST_WIDEN)
1519 if (convert_optab_p (binoptab))
1521 machine_mode from_mode = widened_mode (mode, op0, op1);
1522 icode = find_widening_optab_handler (binoptab, mode, from_mode);
1524 else
1525 icode = optab_handler (binoptab, mode);
1526 if (icode != CODE_FOR_nothing)
1528 temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
1529 target, unsignedp, methods, last);
1530 if (temp)
1531 return temp;
1535 /* If we were trying to rotate, and that didn't work, try rotating
1536 the other direction before falling back to shifts and bitwise-or. */
1537 if (((binoptab == rotl_optab
1538 && (icode = optab_handler (rotr_optab, mode)) != CODE_FOR_nothing)
1539 || (binoptab == rotr_optab
1540 && (icode = optab_handler (rotl_optab, mode)) != CODE_FOR_nothing))
1541 && is_int_mode (mode, &int_mode))
1543 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1544 rtx newop1;
1545 unsigned int bits = GET_MODE_PRECISION (int_mode);
1547 if (CONST_INT_P (op1))
1548 newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
1549 else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
1550 newop1 = negate_rtx (GET_MODE (op1), op1);
1551 else
1552 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1553 gen_int_mode (bits, GET_MODE (op1)), op1,
1554 NULL_RTX, unsignedp, OPTAB_DIRECT);
1556 temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
1557 target, unsignedp, methods, last);
1558 if (temp)
1559 return temp;
1562 /* If this is a multiply, see if we can do a widening operation that
1563 takes operands of this mode and makes a wider mode. */
1565 if (binoptab == smul_optab
1566 && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
1567 && (convert_optab_handler ((unsignedp
1568 ? umul_widen_optab
1569 : smul_widen_optab),
1570 wider_mode, mode) != CODE_FOR_nothing))
1572 /* *_widen_optab needs to determine operand mode, make sure at least
1573 one operand has non-VOID mode. */
1574 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
1575 op0 = force_reg (mode, op0);
1576 temp = expand_binop (wider_mode,
1577 unsignedp ? umul_widen_optab : smul_widen_optab,
1578 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1580 if (temp != 0)
1582 if (GET_MODE_CLASS (mode) == MODE_INT
1583 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1584 return gen_lowpart (mode, temp);
1585 else
1586 return convert_to_mode (mode, temp, unsignedp);
1590 /* If this is a vector shift by a scalar, see if we can do a vector
1591 shift by a vector. If so, broadcast the scalar into a vector. */
1592 if (mclass == MODE_VECTOR_INT)
1594 optab otheroptab = unknown_optab;
1596 if (binoptab == ashl_optab)
1597 otheroptab = vashl_optab;
1598 else if (binoptab == ashr_optab)
1599 otheroptab = vashr_optab;
1600 else if (binoptab == lshr_optab)
1601 otheroptab = vlshr_optab;
1602 else if (binoptab == rotl_optab)
1603 otheroptab = vrotl_optab;
1604 else if (binoptab == rotr_optab)
1605 otheroptab = vrotr_optab;
1607 if (otheroptab
1608 && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
1610 /* The scalar may have been extended to be too wide. Truncate
1611 it back to the proper size to fit in the broadcast vector. */
1612 scalar_mode inner_mode = GET_MODE_INNER (mode);
1613 if (!CONST_INT_P (op1)
1614 && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
1615 > GET_MODE_BITSIZE (inner_mode)))
1616 op1 = force_reg (inner_mode,
1617 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1618 GET_MODE (op1)));
1619 rtx vop1 = expand_vector_broadcast (mode, op1);
1620 if (vop1)
1622 temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
1623 target, unsignedp, methods, last);
1624 if (temp)
1625 return temp;
1630 /* Look for a wider mode of the same class for which we think we
1631 can open-code the operation. Check for a widening multiply at the
1632 wider mode as well. */
1634 if (CLASS_HAS_WIDER_MODES_P (mclass)
1635 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1636 FOR_EACH_WIDER_MODE (wider_mode, mode)
1638 machine_mode next_mode;
1639 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1640 || (binoptab == smul_optab
1641 && GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
1642 && (find_widening_optab_handler ((unsignedp
1643 ? umul_widen_optab
1644 : smul_widen_optab),
1645 next_mode, mode)
1646 != CODE_FOR_nothing)))
1648 rtx xop0 = op0, xop1 = op1;
1649 int no_extend = 0;
1651 /* For certain integer operations, we need not actually extend
1652 the narrow operands, as long as we will truncate
1653 the results to the same narrowness. */
1655 if ((binoptab == ior_optab || binoptab == and_optab
1656 || binoptab == xor_optab
1657 || binoptab == add_optab || binoptab == sub_optab
1658 || binoptab == smul_optab || binoptab == ashl_optab)
1659 && mclass == MODE_INT)
1661 no_extend = 1;
1662 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1663 xop0, unsignedp);
1664 if (binoptab != ashl_optab)
1665 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1666 xop1, unsignedp);
1669 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1671 /* The second operand of a shift must always be extended. */
1672 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1673 no_extend && binoptab != ashl_optab);
1675 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1676 unsignedp, OPTAB_DIRECT);
1677 if (temp)
1679 if (mclass != MODE_INT
1680 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1682 if (target == 0)
1683 target = gen_reg_rtx (mode);
1684 convert_move (target, temp, 0);
1685 return target;
1687 else
1688 return gen_lowpart (mode, temp);
1690 else
1691 delete_insns_since (last);
1695 /* If operation is commutative,
1696 try to make the first operand a register.
1697 Even better, try to make it the same as the target.
1698 Also try to make the last operand a constant. */
1699 if (commutative_optab_p (binoptab)
1700 && swap_commutative_operands_with_target (target, op0, op1))
1701 std::swap (op0, op1);
1703 /* These can be done a word at a time. */
1704 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1705 && is_int_mode (mode, &int_mode)
1706 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
1707 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1709 int i;
1710 rtx_insn *insns;
1712 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1713 won't be accurate, so use a new target. */
1714 if (target == 0
1715 || target == op0
1716 || target == op1
1717 || reg_overlap_mentioned_p (target, op0)
1718 || reg_overlap_mentioned_p (target, op1)
1719 || !valid_multiword_target_p (target))
1720 target = gen_reg_rtx (int_mode);
1722 start_sequence ();
1724 /* Do the actual arithmetic. */
1725 machine_mode op0_mode = GET_MODE (op0);
1726 machine_mode op1_mode = GET_MODE (op1);
1727 if (op0_mode == VOIDmode)
1728 op0_mode = int_mode;
1729 if (op1_mode == VOIDmode)
1730 op1_mode = int_mode;
1731 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
1733 rtx target_piece = operand_subword (target, i, 1, int_mode);
1734 rtx x = expand_binop (word_mode, binoptab,
1735 operand_subword_force (op0, i, op0_mode),
1736 operand_subword_force (op1, i, op1_mode),
1737 target_piece, unsignedp, next_methods);
1739 if (x == 0)
1740 break;
1742 if (target_piece != x)
1743 emit_move_insn (target_piece, x);
1746 insns = get_insns ();
1747 end_sequence ();
1749 if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
1751 emit_insn (insns);
1752 return target;
1756 /* Synthesize double word shifts from single word shifts. */
1757 if ((binoptab == lshr_optab || binoptab == ashl_optab
1758 || binoptab == ashr_optab)
1759 && is_int_mode (mode, &int_mode)
1760 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1761 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1762 && GET_MODE_PRECISION (int_mode) == GET_MODE_BITSIZE (int_mode)
1763 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1764 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1765 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1767 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1768 scalar_int_mode op1_mode;
1770 double_shift_mask = targetm.shift_truncation_mask (int_mode);
1771 shift_mask = targetm.shift_truncation_mask (word_mode);
1772 op1_mode = (GET_MODE (op1) != VOIDmode
1773 ? as_a <scalar_int_mode> (GET_MODE (op1))
1774 : word_mode);
1776 /* Apply the truncation to constant shifts. */
1777 if (double_shift_mask > 0 && CONST_INT_P (op1))
1778 op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode);
1780 if (op1 == CONST0_RTX (op1_mode))
1781 return op0;
1783 /* Make sure that this is a combination that expand_doubleword_shift
1784 can handle. See the comments there for details. */
1785 if (double_shift_mask == 0
1786 || (shift_mask == BITS_PER_WORD - 1
1787 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1789 rtx_insn *insns;
1790 rtx into_target, outof_target;
1791 rtx into_input, outof_input;
1792 int left_shift, outof_word;
1794 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1795 won't be accurate, so use a new target. */
1796 if (target == 0
1797 || target == op0
1798 || target == op1
1799 || reg_overlap_mentioned_p (target, op0)
1800 || reg_overlap_mentioned_p (target, op1)
1801 || !valid_multiword_target_p (target))
1802 target = gen_reg_rtx (int_mode);
1804 start_sequence ();
1806 /* OUTOF_* is the word we are shifting bits away from, and
1807 INTO_* is the word that we are shifting bits towards, thus
1808 they differ depending on the direction of the shift and
1809 WORDS_BIG_ENDIAN. */
1811 left_shift = binoptab == ashl_optab;
1812 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1814 outof_target = operand_subword (target, outof_word, 1, int_mode);
1815 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1817 outof_input = operand_subword_force (op0, outof_word, int_mode);
1818 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1820 if (expand_doubleword_shift (op1_mode, binoptab,
1821 outof_input, into_input, op1,
1822 outof_target, into_target,
1823 unsignedp, next_methods, shift_mask))
1825 insns = get_insns ();
1826 end_sequence ();
1828 emit_insn (insns);
1829 return target;
1831 end_sequence ();
1835 /* Synthesize double word rotates from single word shifts. */
1836 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1837 && is_int_mode (mode, &int_mode)
1838 && CONST_INT_P (op1)
1839 && GET_MODE_PRECISION (int_mode) == 2 * BITS_PER_WORD
1840 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1841 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1843 rtx_insn *insns;
1844 rtx into_target, outof_target;
1845 rtx into_input, outof_input;
1846 rtx inter;
1847 int shift_count, left_shift, outof_word;
1849 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1850 won't be accurate, so use a new target. Do this also if target is not
1851 a REG, first because having a register instead may open optimization
1852 opportunities, and second because if target and op0 happen to be MEMs
1853 designating the same location, we would risk clobbering it too early
1854 in the code sequence we generate below. */
1855 if (target == 0
1856 || target == op0
1857 || target == op1
1858 || !REG_P (target)
1859 || reg_overlap_mentioned_p (target, op0)
1860 || reg_overlap_mentioned_p (target, op1)
1861 || !valid_multiword_target_p (target))
1862 target = gen_reg_rtx (int_mode);
1864 start_sequence ();
1866 shift_count = INTVAL (op1);
1868 /* OUTOF_* is the word we are shifting bits away from, and
1869 INTO_* is the word that we are shifting bits towards, thus
1870 they differ depending on the direction of the shift and
1871 WORDS_BIG_ENDIAN. */
1873 left_shift = (binoptab == rotl_optab);
1874 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1876 outof_target = operand_subword (target, outof_word, 1, int_mode);
1877 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1879 outof_input = operand_subword_force (op0, outof_word, int_mode);
1880 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1882 if (shift_count == BITS_PER_WORD)
1884 /* This is just a word swap. */
1885 emit_move_insn (outof_target, into_input);
1886 emit_move_insn (into_target, outof_input);
1887 inter = const0_rtx;
1889 else
1891 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1892 HOST_WIDE_INT first_shift_count, second_shift_count;
1893 optab reverse_unsigned_shift, unsigned_shift;
1895 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1896 ? lshr_optab : ashl_optab);
1898 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1899 ? ashl_optab : lshr_optab);
1901 if (shift_count > BITS_PER_WORD)
1903 first_shift_count = shift_count - BITS_PER_WORD;
1904 second_shift_count = 2 * BITS_PER_WORD - shift_count;
1906 else
1908 first_shift_count = BITS_PER_WORD - shift_count;
1909 second_shift_count = shift_count;
1911 rtx first_shift_count_rtx
1912 = gen_int_shift_amount (word_mode, first_shift_count);
1913 rtx second_shift_count_rtx
1914 = gen_int_shift_amount (word_mode, second_shift_count);
1916 into_temp1 = expand_binop (word_mode, unsigned_shift,
1917 outof_input, first_shift_count_rtx,
1918 NULL_RTX, unsignedp, next_methods);
1919 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1920 into_input, second_shift_count_rtx,
1921 NULL_RTX, unsignedp, next_methods);
1923 if (into_temp1 != 0 && into_temp2 != 0)
1924 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1925 into_target, unsignedp, next_methods);
1926 else
1927 inter = 0;
1929 if (inter != 0 && inter != into_target)
1930 emit_move_insn (into_target, inter);
1932 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1933 into_input, first_shift_count_rtx,
1934 NULL_RTX, unsignedp, next_methods);
1935 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1936 outof_input, second_shift_count_rtx,
1937 NULL_RTX, unsignedp, next_methods);
1939 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1940 inter = expand_binop (word_mode, ior_optab,
1941 outof_temp1, outof_temp2,
1942 outof_target, unsignedp, next_methods);
1944 if (inter != 0 && inter != outof_target)
1945 emit_move_insn (outof_target, inter);
1948 insns = get_insns ();
1949 end_sequence ();
1951 if (inter != 0)
1953 emit_insn (insns);
1954 return target;
1958 /* These can be done a word at a time by propagating carries. */
1959 if ((binoptab == add_optab || binoptab == sub_optab)
1960 && is_int_mode (mode, &int_mode)
1961 && GET_MODE_SIZE (int_mode) >= 2 * UNITS_PER_WORD
1962 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1964 unsigned int i;
1965 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1966 const unsigned int nwords = GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD;
1967 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1968 rtx xop0, xop1, xtarget;
1970 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1971 value is one of those, use it. Otherwise, use 1 since it is the
1972 one easiest to get. */
1973 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1974 int normalizep = STORE_FLAG_VALUE;
1975 #else
1976 int normalizep = 1;
1977 #endif
1979 /* Prepare the operands. */
1980 xop0 = force_reg (int_mode, op0);
1981 xop1 = force_reg (int_mode, op1);
1983 xtarget = gen_reg_rtx (int_mode);
1985 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1986 target = xtarget;
1988 /* Indicate for flow that the entire target reg is being set. */
1989 if (REG_P (target))
1990 emit_clobber (xtarget);
1992 /* Do the actual arithmetic. */
1993 for (i = 0; i < nwords; i++)
1995 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1996 rtx target_piece = operand_subword (xtarget, index, 1, int_mode);
1997 rtx op0_piece = operand_subword_force (xop0, index, int_mode);
1998 rtx op1_piece = operand_subword_force (xop1, index, int_mode);
1999 rtx x;
2001 /* Main add/subtract of the input operands. */
2002 x = expand_binop (word_mode, binoptab,
2003 op0_piece, op1_piece,
2004 target_piece, unsignedp, next_methods);
2005 if (x == 0)
2006 break;
2008 if (i + 1 < nwords)
2010 /* Store carry from main add/subtract. */
2011 carry_out = gen_reg_rtx (word_mode);
2012 carry_out = emit_store_flag_force (carry_out,
2013 (binoptab == add_optab
2014 ? LT : GT),
2015 x, op0_piece,
2016 word_mode, 1, normalizep);
2019 if (i > 0)
2021 rtx newx;
2023 /* Add/subtract previous carry to main result. */
2024 newx = expand_binop (word_mode,
2025 normalizep == 1 ? binoptab : otheroptab,
2026 x, carry_in,
2027 NULL_RTX, 1, next_methods);
2029 if (i + 1 < nwords)
2031 /* Get out carry from adding/subtracting carry in. */
2032 rtx carry_tmp = gen_reg_rtx (word_mode);
2033 carry_tmp = emit_store_flag_force (carry_tmp,
2034 (binoptab == add_optab
2035 ? LT : GT),
2036 newx, x,
2037 word_mode, 1, normalizep);
2039 /* Logical-ior the two poss. carry together. */
2040 carry_out = expand_binop (word_mode, ior_optab,
2041 carry_out, carry_tmp,
2042 carry_out, 0, next_methods);
2043 if (carry_out == 0)
2044 break;
2046 emit_move_insn (target_piece, newx);
2048 else
2050 if (x != target_piece)
2051 emit_move_insn (target_piece, x);
2054 carry_in = carry_out;
2057 if (i == GET_MODE_BITSIZE (int_mode) / (unsigned) BITS_PER_WORD)
2059 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing
2060 || ! rtx_equal_p (target, xtarget))
2062 rtx_insn *temp = emit_move_insn (target, xtarget);
2064 set_dst_reg_note (temp, REG_EQUAL,
2065 gen_rtx_fmt_ee (optab_to_code (binoptab),
2066 int_mode, copy_rtx (xop0),
2067 copy_rtx (xop1)),
2068 target);
2070 else
2071 target = xtarget;
2073 return target;
2076 else
2077 delete_insns_since (last);
2080 /* Attempt to synthesize double word multiplies using a sequence of word
2081 mode multiplications. We first attempt to generate a sequence using a
2082 more efficient unsigned widening multiply, and if that fails we then
2083 try using a signed widening multiply. */
2085 if (binoptab == smul_optab
2086 && is_int_mode (mode, &int_mode)
2087 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2088 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
2089 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
2091 rtx product = NULL_RTX;
2092 if (convert_optab_handler (umul_widen_optab, int_mode, word_mode)
2093 != CODE_FOR_nothing)
2095 product = expand_doubleword_mult (int_mode, op0, op1, target,
2096 true, methods);
2097 if (!product)
2098 delete_insns_since (last);
2101 if (product == NULL_RTX
2102 && (convert_optab_handler (smul_widen_optab, int_mode, word_mode)
2103 != CODE_FOR_nothing))
2105 product = expand_doubleword_mult (int_mode, op0, op1, target,
2106 false, methods);
2107 if (!product)
2108 delete_insns_since (last);
2111 if (product != NULL_RTX)
2113 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
2115 rtx_insn *move = emit_move_insn (target ? target : product,
2116 product);
2117 set_dst_reg_note (move,
2118 REG_EQUAL,
2119 gen_rtx_fmt_ee (MULT, int_mode,
2120 copy_rtx (op0),
2121 copy_rtx (op1)),
2122 target ? target : product);
2124 return product;
2128 /* Attempt to synthetize double word modulo by constant divisor. */
2129 if ((binoptab == umod_optab
2130 || binoptab == smod_optab
2131 || binoptab == udiv_optab
2132 || binoptab == sdiv_optab)
2133 && optimize
2134 && CONST_INT_P (op1)
2135 && is_int_mode (mode, &int_mode)
2136 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2137 && optab_handler ((binoptab == umod_optab || binoptab == udiv_optab)
2138 ? udivmod_optab : sdivmod_optab,
2139 int_mode) == CODE_FOR_nothing
2140 && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
2141 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
2142 && optimize_insn_for_speed_p ())
2144 rtx res = NULL_RTX;
2145 if ((binoptab == umod_optab || binoptab == smod_optab)
2146 && (INTVAL (op1) & 1) == 0)
2147 res = expand_doubleword_mod (int_mode, op0, op1,
2148 binoptab == umod_optab);
2149 else
2151 rtx quot = expand_doubleword_divmod (int_mode, op0, op1, &res,
2152 binoptab == umod_optab
2153 || binoptab == udiv_optab);
2154 if (quot == NULL_RTX)
2155 res = NULL_RTX;
2156 else if (binoptab == udiv_optab || binoptab == sdiv_optab)
2157 res = quot;
2159 if (res != NULL_RTX)
2161 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
2163 rtx_insn *move = emit_move_insn (target ? target : res,
2164 res);
2165 set_dst_reg_note (move, REG_EQUAL,
2166 gen_rtx_fmt_ee (optab_to_code (binoptab),
2167 int_mode, copy_rtx (op0), op1),
2168 target ? target : res);
2170 return res;
2172 else
2173 delete_insns_since (last);
2176 /* It can't be open-coded in this mode.
2177 Use a library call if one is available and caller says that's ok. */
2179 libfunc = optab_libfunc (binoptab, mode);
2180 if (libfunc
2181 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2183 rtx_insn *insns;
2184 rtx op1x = op1;
2185 machine_mode op1_mode = mode;
2186 rtx value;
2188 start_sequence ();
2190 if (shift_optab_p (binoptab))
2192 op1_mode = targetm.libgcc_shift_count_mode ();
2193 /* Specify unsigned here,
2194 since negative shift counts are meaningless. */
2195 op1x = convert_to_mode (op1_mode, op1, 1);
2198 if (GET_MODE (op0) != VOIDmode
2199 && GET_MODE (op0) != mode)
2200 op0 = convert_to_mode (mode, op0, unsignedp);
2202 /* Pass 1 for NO_QUEUE so we don't lose any increments
2203 if the libcall is cse'd or moved. */
2204 value = emit_library_call_value (libfunc,
2205 NULL_RTX, LCT_CONST, mode,
2206 op0, mode, op1x, op1_mode);
2208 insns = get_insns ();
2209 end_sequence ();
2211 bool trapv = trapv_binoptab_p (binoptab);
2212 target = gen_reg_rtx (mode);
2213 emit_libcall_block_1 (insns, target, value,
2214 trapv ? NULL_RTX
2215 : gen_rtx_fmt_ee (optab_to_code (binoptab),
2216 mode, op0, op1), trapv);
2218 return target;
2221 delete_insns_since (last);
2223 /* It can't be done in this mode. Can we do it in a wider mode? */
2225 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2226 || methods == OPTAB_MUST_WIDEN))
2228 /* Caller says, don't even try. */
2229 delete_insns_since (entry_last);
2230 return 0;
2233 /* Compute the value of METHODS to pass to recursive calls.
2234 Don't allow widening to be tried recursively. */
2236 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2238 /* Look for a wider mode of the same class for which it appears we can do
2239 the operation. */
2241 if (CLASS_HAS_WIDER_MODES_P (mclass))
2243 /* This code doesn't make sense for conversion optabs, since we
2244 wouldn't then want to extend the operands to be the same size
2245 as the result. */
2246 gcc_assert (!convert_optab_p (binoptab));
2247 FOR_EACH_WIDER_MODE (wider_mode, mode)
2249 if (optab_handler (binoptab, wider_mode)
2250 || (methods == OPTAB_LIB
2251 && optab_libfunc (binoptab, wider_mode)))
2253 rtx xop0 = op0, xop1 = op1;
2254 int no_extend = 0;
2256 /* For certain integer operations, we need not actually extend
2257 the narrow operands, as long as we will truncate
2258 the results to the same narrowness. */
2260 if ((binoptab == ior_optab || binoptab == and_optab
2261 || binoptab == xor_optab
2262 || binoptab == add_optab || binoptab == sub_optab
2263 || binoptab == smul_optab || binoptab == ashl_optab)
2264 && mclass == MODE_INT)
2265 no_extend = 1;
2267 xop0 = widen_operand (xop0, wider_mode, mode,
2268 unsignedp, no_extend);
2270 /* The second operand of a shift must always be extended. */
2271 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2272 no_extend && binoptab != ashl_optab);
2274 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2275 unsignedp, methods);
2276 if (temp)
2278 if (mclass != MODE_INT
2279 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2281 if (target == 0)
2282 target = gen_reg_rtx (mode);
2283 convert_move (target, temp, 0);
2284 return target;
2286 else
2287 return gen_lowpart (mode, temp);
2289 else
2290 delete_insns_since (last);
2295 delete_insns_since (entry_last);
2296 return 0;
2299 /* Expand a binary operator which has both signed and unsigned forms.
2300 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2301 signed operations.
2303 If we widen unsigned operands, we may use a signed wider operation instead
2304 of an unsigned wider operation, since the result would be the same. */
2307 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
2308 rtx op0, rtx op1, rtx target, int unsignedp,
2309 enum optab_methods methods)
2311 rtx temp;
2312 optab direct_optab = unsignedp ? uoptab : soptab;
2313 bool save_enable;
2315 /* Do it without widening, if possible. */
2316 temp = expand_binop (mode, direct_optab, op0, op1, target,
2317 unsignedp, OPTAB_DIRECT);
2318 if (temp || methods == OPTAB_DIRECT)
2319 return temp;
2321 /* Try widening to a signed int. Disable any direct use of any
2322 signed insn in the current mode. */
2323 save_enable = swap_optab_enable (soptab, mode, false);
2325 temp = expand_binop (mode, soptab, op0, op1, target,
2326 unsignedp, OPTAB_WIDEN);
2328 /* For unsigned operands, try widening to an unsigned int. */
2329 if (!temp && unsignedp)
2330 temp = expand_binop (mode, uoptab, op0, op1, target,
2331 unsignedp, OPTAB_WIDEN);
2332 if (temp || methods == OPTAB_WIDEN)
2333 goto egress;
2335 /* Use the right width libcall if that exists. */
2336 temp = expand_binop (mode, direct_optab, op0, op1, target,
2337 unsignedp, OPTAB_LIB);
2338 if (temp || methods == OPTAB_LIB)
2339 goto egress;
2341 /* Must widen and use a libcall, use either signed or unsigned. */
2342 temp = expand_binop (mode, soptab, op0, op1, target,
2343 unsignedp, methods);
2344 if (!temp && unsignedp)
2345 temp = expand_binop (mode, uoptab, op0, op1, target,
2346 unsignedp, methods);
2348 egress:
2349 /* Undo the fiddling above. */
2350 if (save_enable)
2351 swap_optab_enable (soptab, mode, true);
2352 return temp;
2355 /* Generate code to perform an operation specified by UNOPPTAB
2356 on operand OP0, with two results to TARG0 and TARG1.
2357 We assume that the order of the operands for the instruction
2358 is TARG0, TARG1, OP0.
2360 Either TARG0 or TARG1 may be zero, but what that means is that
2361 the result is not actually wanted. We will generate it into
2362 a dummy pseudo-reg and discard it. They may not both be zero.
2364 Returns 1 if this operation can be performed; 0 if not. */
2367 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2368 int unsignedp)
2370 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2371 enum mode_class mclass;
2372 machine_mode wider_mode;
2373 rtx_insn *entry_last = get_last_insn ();
2374 rtx_insn *last;
2376 mclass = GET_MODE_CLASS (mode);
2378 if (!targ0)
2379 targ0 = gen_reg_rtx (mode);
2380 if (!targ1)
2381 targ1 = gen_reg_rtx (mode);
2383 /* Record where to go back to if we fail. */
2384 last = get_last_insn ();
2386 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2388 class expand_operand ops[3];
2389 enum insn_code icode = optab_handler (unoptab, mode);
2391 create_fixed_operand (&ops[0], targ0);
2392 create_fixed_operand (&ops[1], targ1);
2393 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2394 if (maybe_expand_insn (icode, 3, ops))
2395 return 1;
2398 /* It can't be done in this mode. Can we do it in a wider mode? */
2400 if (CLASS_HAS_WIDER_MODES_P (mclass))
2402 FOR_EACH_WIDER_MODE (wider_mode, mode)
2404 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2406 rtx t0 = gen_reg_rtx (wider_mode);
2407 rtx t1 = gen_reg_rtx (wider_mode);
2408 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2410 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2412 convert_move (targ0, t0, unsignedp);
2413 convert_move (targ1, t1, unsignedp);
2414 return 1;
2416 else
2417 delete_insns_since (last);
2422 delete_insns_since (entry_last);
2423 return 0;
2426 /* Generate code to perform an operation specified by BINOPTAB
2427 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2428 We assume that the order of the operands for the instruction
2429 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2430 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2432 Either TARG0 or TARG1 may be zero, but what that means is that
2433 the result is not actually wanted. We will generate it into
2434 a dummy pseudo-reg and discard it. They may not both be zero.
2436 Returns 1 if this operation can be performed; 0 if not. */
2439 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2440 int unsignedp)
2442 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2443 enum mode_class mclass;
2444 machine_mode wider_mode;
2445 rtx_insn *entry_last = get_last_insn ();
2446 rtx_insn *last;
2448 mclass = GET_MODE_CLASS (mode);
2450 if (!targ0)
2451 targ0 = gen_reg_rtx (mode);
2452 if (!targ1)
2453 targ1 = gen_reg_rtx (mode);
2455 /* Record where to go back to if we fail. */
2456 last = get_last_insn ();
2458 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2460 class expand_operand ops[4];
2461 enum insn_code icode = optab_handler (binoptab, mode);
2462 machine_mode mode0 = insn_data[icode].operand[1].mode;
2463 machine_mode mode1 = insn_data[icode].operand[2].mode;
2464 rtx xop0 = op0, xop1 = op1;
2466 /* If we are optimizing, force expensive constants into a register. */
2467 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2468 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2470 create_fixed_operand (&ops[0], targ0);
2471 create_convert_operand_from (&ops[1], xop0, mode, unsignedp);
2472 create_convert_operand_from (&ops[2], xop1, mode, unsignedp);
2473 create_fixed_operand (&ops[3], targ1);
2474 if (maybe_expand_insn (icode, 4, ops))
2475 return 1;
2476 delete_insns_since (last);
2479 /* It can't be done in this mode. Can we do it in a wider mode? */
2481 if (CLASS_HAS_WIDER_MODES_P (mclass))
2483 FOR_EACH_WIDER_MODE (wider_mode, mode)
2485 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2487 rtx t0 = gen_reg_rtx (wider_mode);
2488 rtx t1 = gen_reg_rtx (wider_mode);
2489 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2490 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2492 if (expand_twoval_binop (binoptab, cop0, cop1,
2493 t0, t1, unsignedp))
2495 convert_move (targ0, t0, unsignedp);
2496 convert_move (targ1, t1, unsignedp);
2497 return 1;
2499 else
2500 delete_insns_since (last);
2505 delete_insns_since (entry_last);
2506 return 0;
2509 /* Expand the two-valued library call indicated by BINOPTAB, but
2510 preserve only one of the values. If TARG0 is non-NULL, the first
2511 value is placed into TARG0; otherwise the second value is placed
2512 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2513 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2514 This routine assumes that the value returned by the library call is
2515 as if the return value was of an integral mode twice as wide as the
2516 mode of OP0. Returns 1 if the call was successful. */
2518 bool
2519 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2520 rtx targ0, rtx targ1, enum rtx_code code)
2522 machine_mode mode;
2523 machine_mode libval_mode;
2524 rtx libval;
2525 rtx_insn *insns;
2526 rtx libfunc;
2528 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2529 gcc_assert (!targ0 != !targ1);
2531 mode = GET_MODE (op0);
2532 libfunc = optab_libfunc (binoptab, mode);
2533 if (!libfunc)
2534 return false;
2536 /* The value returned by the library function will have twice as
2537 many bits as the nominal MODE. */
2538 libval_mode = smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode));
2539 start_sequence ();
2540 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2541 libval_mode,
2542 op0, mode,
2543 op1, mode);
2544 /* Get the part of VAL containing the value that we want. */
2545 libval = simplify_gen_subreg (mode, libval, libval_mode,
2546 targ0 ? 0 : GET_MODE_SIZE (mode));
2547 insns = get_insns ();
2548 end_sequence ();
2549 /* Move the into the desired location. */
2550 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2551 gen_rtx_fmt_ee (code, mode, op0, op1));
2553 return true;
2557 /* Wrapper around expand_unop which takes an rtx code to specify
2558 the operation to perform, not an optab pointer. All other
2559 arguments are the same. */
2561 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2562 rtx target, int unsignedp)
2564 optab unop = code_to_optab (code);
2565 gcc_assert (unop);
2567 return expand_unop (mode, unop, op0, target, unsignedp);
2570 /* Try calculating
2571 (clz:narrow x)
2573 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2575 A similar operation can be used for clrsb. UNOPTAB says which operation
2576 we are trying to expand. */
2577 static rtx
2578 widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
2580 opt_scalar_int_mode wider_mode_iter;
2581 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2583 scalar_int_mode wider_mode = wider_mode_iter.require ();
2584 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2586 rtx xop0, temp;
2587 rtx_insn *last;
2589 last = get_last_insn ();
2591 if (target == 0)
2592 target = gen_reg_rtx (mode);
2593 xop0 = widen_operand (op0, wider_mode, mode,
2594 unoptab != clrsb_optab, false);
2595 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2596 unoptab != clrsb_optab);
2597 if (temp != 0)
2598 temp = expand_binop
2599 (wider_mode, sub_optab, temp,
2600 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2601 - GET_MODE_PRECISION (mode),
2602 wider_mode),
2603 target, true, OPTAB_DIRECT);
2604 if (temp == 0)
2605 delete_insns_since (last);
2607 return temp;
2610 return 0;
2613 /* Attempt to emit (clrsb:mode op0) as
2614 (plus:mode (clz:mode (xor:mode op0 (ashr:mode op0 (const_int prec-1))))
2615 (const_int -1))
2616 if CLZ_DEFINED_VALUE_AT_ZERO (mode, val) is 2 and val is prec,
2617 or as
2618 (clz:mode (ior:mode (xor:mode (ashl:mode op0 (const_int 1))
2619 (ashr:mode op0 (const_int prec-1)))
2620 (const_int 1)))
2621 otherwise. */
2623 static rtx
2624 expand_clrsb_using_clz (scalar_int_mode mode, rtx op0, rtx target)
2626 if (optimize_insn_for_size_p ()
2627 || optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2628 return NULL_RTX;
2630 start_sequence ();
2631 HOST_WIDE_INT val = 0;
2632 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) != 2
2633 || val != GET_MODE_PRECISION (mode))
2634 val = 0;
2635 else
2636 val = 1;
2638 rtx temp2 = op0;
2639 if (!val)
2641 temp2 = expand_binop (mode, ashl_optab, op0, const1_rtx,
2642 NULL_RTX, 0, OPTAB_DIRECT);
2643 if (!temp2)
2645 fail:
2646 end_sequence ();
2647 return NULL_RTX;
2651 rtx temp = expand_binop (mode, ashr_optab, op0,
2652 GEN_INT (GET_MODE_PRECISION (mode) - 1),
2653 NULL_RTX, 0, OPTAB_DIRECT);
2654 if (!temp)
2655 goto fail;
2657 temp = expand_binop (mode, xor_optab, temp2, temp, NULL_RTX, 0,
2658 OPTAB_DIRECT);
2659 if (!temp)
2660 goto fail;
2662 if (!val)
2664 temp = expand_binop (mode, ior_optab, temp, const1_rtx,
2665 NULL_RTX, 0, OPTAB_DIRECT);
2666 if (!temp)
2667 goto fail;
2669 temp = expand_unop_direct (mode, clz_optab, temp, val ? NULL_RTX : target,
2670 true);
2671 if (!temp)
2672 goto fail;
2673 if (val)
2675 temp = expand_binop (mode, add_optab, temp, constm1_rtx,
2676 target, 0, OPTAB_DIRECT);
2677 if (!temp)
2678 goto fail;
2681 rtx_insn *seq = get_insns ();
2682 end_sequence ();
2684 add_equal_note (seq, temp, CLRSB, op0, NULL_RTX, mode);
2685 emit_insn (seq);
2686 return temp;
2689 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2690 quantities, choosing which based on whether the high word is nonzero. */
2691 static rtx
2692 expand_doubleword_clz (scalar_int_mode mode, rtx op0, rtx target)
2694 rtx xop0 = force_reg (mode, op0);
2695 rtx subhi = gen_highpart (word_mode, xop0);
2696 rtx sublo = gen_lowpart (word_mode, xop0);
2697 rtx_code_label *hi0_label = gen_label_rtx ();
2698 rtx_code_label *after_label = gen_label_rtx ();
2699 rtx_insn *seq;
2700 rtx temp, result;
2702 /* If we were not given a target, use a word_mode register, not a
2703 'mode' register. The result will fit, and nobody is expecting
2704 anything bigger (the return type of __builtin_clz* is int). */
2705 if (!target)
2706 target = gen_reg_rtx (word_mode);
2708 /* In any case, write to a word_mode scratch in both branches of the
2709 conditional, so we can ensure there is a single move insn setting
2710 'target' to tag a REG_EQUAL note on. */
2711 result = gen_reg_rtx (word_mode);
2713 start_sequence ();
2715 /* If the high word is not equal to zero,
2716 then clz of the full value is clz of the high word. */
2717 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2718 word_mode, true, hi0_label);
2720 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2721 if (!temp)
2722 goto fail;
2724 if (temp != result)
2725 convert_move (result, temp, true);
2727 emit_jump_insn (targetm.gen_jump (after_label));
2728 emit_barrier ();
2730 /* Else clz of the full value is clz of the low word plus the number
2731 of bits in the high word. */
2732 emit_label (hi0_label);
2734 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2735 if (!temp)
2736 goto fail;
2737 temp = expand_binop (word_mode, add_optab, temp,
2738 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2739 result, true, OPTAB_DIRECT);
2740 if (!temp)
2741 goto fail;
2742 if (temp != result)
2743 convert_move (result, temp, true);
2745 emit_label (after_label);
2746 convert_move (target, result, true);
2748 seq = get_insns ();
2749 end_sequence ();
2751 add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
2752 emit_insn (seq);
2753 return target;
2755 fail:
2756 end_sequence ();
2757 return 0;
2760 /* Try calculating popcount of a double-word quantity as two popcount's of
2761 word-sized quantities and summing up the results. */
2762 static rtx
2763 expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
2765 rtx t0, t1, t;
2766 rtx_insn *seq;
2768 start_sequence ();
2770 t0 = expand_unop_direct (word_mode, popcount_optab,
2771 operand_subword_force (op0, 0, mode), NULL_RTX,
2772 true);
2773 t1 = expand_unop_direct (word_mode, popcount_optab,
2774 operand_subword_force (op0, 1, mode), NULL_RTX,
2775 true);
2776 if (!t0 || !t1)
2778 end_sequence ();
2779 return NULL_RTX;
2782 /* If we were not given a target, use a word_mode register, not a
2783 'mode' register. The result will fit, and nobody is expecting
2784 anything bigger (the return type of __builtin_popcount* is int). */
2785 if (!target)
2786 target = gen_reg_rtx (word_mode);
2788 t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
2790 seq = get_insns ();
2791 end_sequence ();
2793 add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
2794 emit_insn (seq);
2795 return t;
2798 /* Try calculating
2799 (parity:wide x)
2801 (parity:narrow (low (x) ^ high (x))) */
2802 static rtx
2803 expand_doubleword_parity (scalar_int_mode mode, rtx op0, rtx target)
2805 rtx t = expand_binop (word_mode, xor_optab,
2806 operand_subword_force (op0, 0, mode),
2807 operand_subword_force (op0, 1, mode),
2808 NULL_RTX, 0, OPTAB_DIRECT);
2809 return expand_unop (word_mode, parity_optab, t, target, true);
2812 /* Try calculating
2813 (bswap:narrow x)
2815 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2816 static rtx
2817 widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
2819 rtx x;
2820 rtx_insn *last;
2821 opt_scalar_int_mode wider_mode_iter;
2823 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2824 if (optab_handler (bswap_optab, wider_mode_iter.require ())
2825 != CODE_FOR_nothing)
2826 break;
2828 if (!wider_mode_iter.exists ())
2829 return NULL_RTX;
2831 scalar_int_mode wider_mode = wider_mode_iter.require ();
2832 last = get_last_insn ();
2834 x = widen_operand (op0, wider_mode, mode, true, true);
2835 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2837 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2838 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2839 if (x != 0)
2840 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2841 GET_MODE_BITSIZE (wider_mode)
2842 - GET_MODE_BITSIZE (mode),
2843 NULL_RTX, true);
2845 if (x != 0)
2847 if (target == 0)
2848 target = gen_reg_rtx (mode);
2849 emit_move_insn (target, gen_lowpart (mode, x));
2851 else
2852 delete_insns_since (last);
2854 return target;
2857 /* Try calculating bswap as two bswaps of two word-sized operands. */
2859 static rtx
2860 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2862 rtx t0, t1;
2864 t1 = expand_unop (word_mode, bswap_optab,
2865 operand_subword_force (op, 0, mode), NULL_RTX, true);
2866 t0 = expand_unop (word_mode, bswap_optab,
2867 operand_subword_force (op, 1, mode), NULL_RTX, true);
2869 if (target == 0 || !valid_multiword_target_p (target))
2870 target = gen_reg_rtx (mode);
2871 if (REG_P (target))
2872 emit_clobber (target);
2873 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2874 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2876 return target;
2879 /* Try calculating (parity x) as (and (popcount x) 1), where
2880 popcount can also be done in a wider mode. */
2881 static rtx
2882 expand_parity (scalar_int_mode mode, rtx op0, rtx target)
2884 enum mode_class mclass = GET_MODE_CLASS (mode);
2885 opt_scalar_int_mode wider_mode_iter;
2886 FOR_EACH_MODE_FROM (wider_mode_iter, mode)
2888 scalar_int_mode wider_mode = wider_mode_iter.require ();
2889 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2891 rtx xop0, temp;
2892 rtx_insn *last;
2894 last = get_last_insn ();
2896 if (target == 0 || GET_MODE (target) != wider_mode)
2897 target = gen_reg_rtx (wider_mode);
2899 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2900 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2901 true);
2902 if (temp != 0)
2903 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2904 target, true, OPTAB_DIRECT);
2906 if (temp)
2908 if (mclass != MODE_INT
2909 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2910 return convert_to_mode (mode, temp, 0);
2911 else
2912 return gen_lowpart (mode, temp);
2914 else
2915 delete_insns_since (last);
2918 return 0;
2921 /* Try calculating ctz(x) as K - clz(x & -x) ,
2922 where K is GET_MODE_PRECISION(mode) - 1.
2924 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2925 don't have to worry about what the hardware does in that case. (If
2926 the clz instruction produces the usual value at 0, which is K, the
2927 result of this code sequence will be -1; expand_ffs, below, relies
2928 on this. It might be nice to have it be K instead, for consistency
2929 with the (very few) processors that provide a ctz with a defined
2930 value, but that would take one more instruction, and it would be
2931 less convenient for expand_ffs anyway. */
2933 static rtx
2934 expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
2936 rtx_insn *seq;
2937 rtx temp;
2939 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2940 return 0;
2942 start_sequence ();
2944 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2945 if (temp)
2946 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2947 true, OPTAB_DIRECT);
2948 if (temp)
2949 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2950 if (temp)
2951 temp = expand_binop (mode, sub_optab,
2952 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2953 temp, target,
2954 true, OPTAB_DIRECT);
2955 if (temp == 0)
2957 end_sequence ();
2958 return 0;
2961 seq = get_insns ();
2962 end_sequence ();
2964 add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
2965 emit_insn (seq);
2966 return temp;
2970 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2971 else with the sequence used by expand_clz.
2973 The ffs builtin promises to return zero for a zero value and ctz/clz
2974 may have an undefined value in that case. If they do not give us a
2975 convenient value, we have to generate a test and branch. */
2976 static rtx
2977 expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
2979 HOST_WIDE_INT val = 0;
2980 bool defined_at_zero = false;
2981 rtx temp;
2982 rtx_insn *seq;
2984 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2986 start_sequence ();
2988 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2989 if (!temp)
2990 goto fail;
2992 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2994 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2996 start_sequence ();
2997 temp = expand_ctz (mode, op0, 0);
2998 if (!temp)
2999 goto fail;
3001 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
3003 defined_at_zero = true;
3004 val = (GET_MODE_PRECISION (mode) - 1) - val;
3007 else
3008 return 0;
3010 if (defined_at_zero && val == -1)
3011 /* No correction needed at zero. */;
3012 else
3014 /* We don't try to do anything clever with the situation found
3015 on some processors (eg Alpha) where ctz(0:mode) ==
3016 bitsize(mode). If someone can think of a way to send N to -1
3017 and leave alone all values in the range 0..N-1 (where N is a
3018 power of two), cheaper than this test-and-branch, please add it.
3020 The test-and-branch is done after the operation itself, in case
3021 the operation sets condition codes that can be recycled for this.
3022 (This is true on i386, for instance.) */
3024 rtx_code_label *nonzero_label = gen_label_rtx ();
3025 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
3026 mode, true, nonzero_label);
3028 convert_move (temp, GEN_INT (-1), false);
3029 emit_label (nonzero_label);
3032 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
3033 to produce a value in the range 0..bitsize. */
3034 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
3035 target, false, OPTAB_DIRECT);
3036 if (!temp)
3037 goto fail;
3039 seq = get_insns ();
3040 end_sequence ();
3042 add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
3043 emit_insn (seq);
3044 return temp;
3046 fail:
3047 end_sequence ();
3048 return 0;
3051 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
3052 conditions, VAL may already be a SUBREG against which we cannot generate
3053 a further SUBREG. In this case, we expect forcing the value into a
3054 register will work around the situation. */
3056 static rtx
3057 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
3058 machine_mode imode)
3060 rtx ret;
3061 ret = lowpart_subreg (omode, val, imode);
3062 if (ret == NULL)
3064 val = force_reg (imode, val);
3065 ret = lowpart_subreg (omode, val, imode);
3066 gcc_assert (ret != NULL);
3068 return ret;
3071 /* Expand a floating point absolute value or negation operation via a
3072 logical operation on the sign bit. */
3074 static rtx
3075 expand_absneg_bit (enum rtx_code code, scalar_float_mode mode,
3076 rtx op0, rtx target)
3078 const struct real_format *fmt;
3079 int bitpos, word, nwords, i;
3080 scalar_int_mode imode;
3081 rtx temp;
3082 rtx_insn *insns;
3084 /* The format has to have a simple sign bit. */
3085 fmt = REAL_MODE_FORMAT (mode);
3086 if (fmt == NULL)
3087 return NULL_RTX;
3089 bitpos = fmt->signbit_rw;
3090 if (bitpos < 0)
3091 return NULL_RTX;
3093 /* Don't create negative zeros if the format doesn't support them. */
3094 if (code == NEG && !fmt->has_signed_zero)
3095 return NULL_RTX;
3097 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3099 if (!int_mode_for_mode (mode).exists (&imode))
3100 return NULL_RTX;
3101 word = 0;
3102 nwords = 1;
3104 else
3106 imode = word_mode;
3108 if (FLOAT_WORDS_BIG_ENDIAN)
3109 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3110 else
3111 word = bitpos / BITS_PER_WORD;
3112 bitpos = bitpos % BITS_PER_WORD;
3113 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3116 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3117 if (code == ABS)
3118 mask = ~mask;
3120 if (target == 0
3121 || target == op0
3122 || reg_overlap_mentioned_p (target, op0)
3123 || (nwords > 1 && !valid_multiword_target_p (target)))
3124 target = gen_reg_rtx (mode);
3126 if (nwords > 1)
3128 start_sequence ();
3130 for (i = 0; i < nwords; ++i)
3132 rtx targ_piece = operand_subword (target, i, 1, mode);
3133 rtx op0_piece = operand_subword_force (op0, i, mode);
3135 if (i == word)
3137 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3138 op0_piece,
3139 immed_wide_int_const (mask, imode),
3140 targ_piece, 1, OPTAB_LIB_WIDEN);
3141 if (temp != targ_piece)
3142 emit_move_insn (targ_piece, temp);
3144 else
3145 emit_move_insn (targ_piece, op0_piece);
3148 insns = get_insns ();
3149 end_sequence ();
3151 emit_insn (insns);
3153 else
3155 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3156 gen_lowpart (imode, op0),
3157 immed_wide_int_const (mask, imode),
3158 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3159 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3161 set_dst_reg_note (get_last_insn (), REG_EQUAL,
3162 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
3163 target);
3166 return target;
3169 /* As expand_unop, but will fail rather than attempt the operation in a
3170 different mode or with a libcall. */
3171 static rtx
3172 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
3173 int unsignedp)
3175 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
3177 class expand_operand ops[2];
3178 enum insn_code icode = optab_handler (unoptab, mode);
3179 rtx_insn *last = get_last_insn ();
3180 rtx_insn *pat;
3182 create_output_operand (&ops[0], target, mode);
3183 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
3184 pat = maybe_gen_insn (icode, 2, ops);
3185 if (pat)
3187 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3188 && ! add_equal_note (pat, ops[0].value,
3189 optab_to_code (unoptab),
3190 ops[1].value, NULL_RTX, mode))
3192 delete_insns_since (last);
3193 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
3196 emit_insn (pat);
3198 return ops[0].value;
3201 return 0;
3204 /* Generate code to perform an operation specified by UNOPTAB
3205 on operand OP0, with result having machine-mode MODE.
3207 UNSIGNEDP is for the case where we have to widen the operands
3208 to perform the operation. It says to use zero-extension.
3210 If TARGET is nonzero, the value
3211 is generated there, if it is convenient to do so.
3212 In all cases an rtx is returned for the locus of the value;
3213 this may or may not be TARGET. */
3216 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
3217 int unsignedp)
3219 enum mode_class mclass = GET_MODE_CLASS (mode);
3220 machine_mode wider_mode;
3221 scalar_int_mode int_mode;
3222 scalar_float_mode float_mode;
3223 rtx temp;
3224 rtx libfunc;
3226 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3227 if (temp)
3228 return temp;
3230 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3232 /* Widening (or narrowing) clz needs special treatment. */
3233 if (unoptab == clz_optab)
3235 if (is_a <scalar_int_mode> (mode, &int_mode))
3237 temp = widen_leading (int_mode, op0, target, unoptab);
3238 if (temp)
3239 return temp;
3241 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3242 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3244 temp = expand_doubleword_clz (int_mode, op0, target);
3245 if (temp)
3246 return temp;
3250 goto try_libcall;
3253 if (unoptab == clrsb_optab)
3255 if (is_a <scalar_int_mode> (mode, &int_mode))
3257 temp = widen_leading (int_mode, op0, target, unoptab);
3258 if (temp)
3259 return temp;
3260 temp = expand_clrsb_using_clz (int_mode, op0, target);
3261 if (temp)
3262 return temp;
3264 goto try_libcall;
3267 if (unoptab == popcount_optab
3268 && is_a <scalar_int_mode> (mode, &int_mode)
3269 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3270 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
3271 && optimize_insn_for_speed_p ())
3273 temp = expand_doubleword_popcount (int_mode, op0, target);
3274 if (temp)
3275 return temp;
3278 if (unoptab == parity_optab
3279 && is_a <scalar_int_mode> (mode, &int_mode)
3280 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3281 && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
3282 || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
3283 && optimize_insn_for_speed_p ())
3285 temp = expand_doubleword_parity (int_mode, op0, target);
3286 if (temp)
3287 return temp;
3290 /* Widening (or narrowing) bswap needs special treatment. */
3291 if (unoptab == bswap_optab)
3293 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3294 or ROTATERT. First try these directly; if this fails, then try the
3295 obvious pair of shifts with allowed widening, as this will probably
3296 be always more efficient than the other fallback methods. */
3297 if (mode == HImode)
3299 rtx_insn *last;
3300 rtx temp1, temp2;
3302 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
3304 temp = expand_binop (mode, rotl_optab, op0,
3305 gen_int_shift_amount (mode, 8),
3306 target, unsignedp, OPTAB_DIRECT);
3307 if (temp)
3308 return temp;
3311 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
3313 temp = expand_binop (mode, rotr_optab, op0,
3314 gen_int_shift_amount (mode, 8),
3315 target, unsignedp, OPTAB_DIRECT);
3316 if (temp)
3317 return temp;
3320 last = get_last_insn ();
3322 temp1 = expand_binop (mode, ashl_optab, op0,
3323 gen_int_shift_amount (mode, 8), NULL_RTX,
3324 unsignedp, OPTAB_WIDEN);
3325 temp2 = expand_binop (mode, lshr_optab, op0,
3326 gen_int_shift_amount (mode, 8), NULL_RTX,
3327 unsignedp, OPTAB_WIDEN);
3328 if (temp1 && temp2)
3330 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
3331 unsignedp, OPTAB_WIDEN);
3332 if (temp)
3333 return temp;
3336 delete_insns_since (last);
3339 if (is_a <scalar_int_mode> (mode, &int_mode))
3341 temp = widen_bswap (int_mode, op0, target);
3342 if (temp)
3343 return temp;
3345 /* We do not provide a 128-bit bswap in libgcc so force the use of
3346 a double bswap for 64-bit targets. */
3347 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3348 && (UNITS_PER_WORD == 8
3349 || optab_handler (unoptab, word_mode) != CODE_FOR_nothing))
3351 temp = expand_doubleword_bswap (mode, op0, target);
3352 if (temp)
3353 return temp;
3357 goto try_libcall;
3360 if (CLASS_HAS_WIDER_MODES_P (mclass))
3361 FOR_EACH_WIDER_MODE (wider_mode, mode)
3363 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
3365 rtx xop0 = op0;
3366 rtx_insn *last = get_last_insn ();
3368 /* For certain operations, we need not actually extend
3369 the narrow operand, as long as we will truncate the
3370 results to the same narrowness. */
3372 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3373 (unoptab == neg_optab
3374 || unoptab == one_cmpl_optab)
3375 && mclass == MODE_INT);
3377 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3378 unsignedp);
3380 if (temp)
3382 if (mclass != MODE_INT
3383 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
3385 if (target == 0)
3386 target = gen_reg_rtx (mode);
3387 convert_move (target, temp, 0);
3388 return target;
3390 else
3391 return gen_lowpart (mode, temp);
3393 else
3394 delete_insns_since (last);
3398 /* These can be done a word at a time. */
3399 if (unoptab == one_cmpl_optab
3400 && is_int_mode (mode, &int_mode)
3401 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
3402 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3404 int i;
3405 rtx_insn *insns;
3407 if (target == 0
3408 || target == op0
3409 || reg_overlap_mentioned_p (target, op0)
3410 || !valid_multiword_target_p (target))
3411 target = gen_reg_rtx (int_mode);
3413 start_sequence ();
3415 /* Do the actual arithmetic. */
3416 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
3418 rtx target_piece = operand_subword (target, i, 1, int_mode);
3419 rtx x = expand_unop (word_mode, unoptab,
3420 operand_subword_force (op0, i, int_mode),
3421 target_piece, unsignedp);
3423 if (target_piece != x)
3424 emit_move_insn (target_piece, x);
3427 insns = get_insns ();
3428 end_sequence ();
3430 emit_insn (insns);
3431 return target;
3434 /* Emit ~op0 as op0 ^ -1. */
3435 if (unoptab == one_cmpl_optab
3436 && (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3437 && optab_handler (xor_optab, mode) != CODE_FOR_nothing)
3439 temp = expand_binop (mode, xor_optab, op0, CONSTM1_RTX (mode),
3440 target, unsignedp, OPTAB_DIRECT);
3441 if (temp)
3442 return temp;
3445 if (optab_to_code (unoptab) == NEG)
3447 /* Try negating floating point values by flipping the sign bit. */
3448 if (is_a <scalar_float_mode> (mode, &float_mode))
3450 temp = expand_absneg_bit (NEG, float_mode, op0, target);
3451 if (temp)
3452 return temp;
3455 /* If there is no negation pattern, and we have no negative zero,
3456 try subtracting from zero. */
3457 if (!HONOR_SIGNED_ZEROS (mode))
3459 temp = expand_binop (mode, (unoptab == negv_optab
3460 ? subv_optab : sub_optab),
3461 CONST0_RTX (mode), op0, target,
3462 unsignedp, OPTAB_DIRECT);
3463 if (temp)
3464 return temp;
3468 /* Try calculating parity (x) as popcount (x) % 2. */
3469 if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
3471 temp = expand_parity (int_mode, op0, target);
3472 if (temp)
3473 return temp;
3476 /* Try implementing ffs (x) in terms of clz (x). */
3477 if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
3479 temp = expand_ffs (int_mode, op0, target);
3480 if (temp)
3481 return temp;
3484 /* Try implementing ctz (x) in terms of clz (x). */
3485 if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
3487 temp = expand_ctz (int_mode, op0, target);
3488 if (temp)
3489 return temp;
3492 try_libcall:
3493 /* Now try a library call in this mode. */
3494 libfunc = optab_libfunc (unoptab, mode);
3495 if (libfunc)
3497 rtx_insn *insns;
3498 rtx value;
3499 rtx eq_value;
3500 machine_mode outmode = mode;
3502 /* All of these functions return small values. Thus we choose to
3503 have them return something that isn't a double-word. */
3504 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3505 || unoptab == clrsb_optab || unoptab == popcount_optab
3506 || unoptab == parity_optab)
3507 outmode
3508 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3509 optab_libfunc (unoptab, mode)));
3511 start_sequence ();
3513 /* Pass 1 for NO_QUEUE so we don't lose any increments
3514 if the libcall is cse'd or moved. */
3515 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3516 op0, mode);
3517 insns = get_insns ();
3518 end_sequence ();
3520 target = gen_reg_rtx (outmode);
3521 bool trapv = trapv_unoptab_p (unoptab);
3522 if (trapv)
3523 eq_value = NULL_RTX;
3524 else
3526 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3527 if (GET_MODE_UNIT_SIZE (outmode) < GET_MODE_UNIT_SIZE (mode))
3528 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3529 else if (GET_MODE_UNIT_SIZE (outmode) > GET_MODE_UNIT_SIZE (mode))
3530 eq_value = simplify_gen_unary (ZERO_EXTEND,
3531 outmode, eq_value, mode);
3533 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
3535 return target;
3538 /* It can't be done in this mode. Can we do it in a wider mode? */
3540 if (CLASS_HAS_WIDER_MODES_P (mclass))
3542 FOR_EACH_WIDER_MODE (wider_mode, mode)
3544 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3545 || optab_libfunc (unoptab, wider_mode))
3547 rtx xop0 = op0;
3548 rtx_insn *last = get_last_insn ();
3550 /* For certain operations, we need not actually extend
3551 the narrow operand, as long as we will truncate the
3552 results to the same narrowness. */
3553 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3554 (unoptab == neg_optab
3555 || unoptab == one_cmpl_optab
3556 || unoptab == bswap_optab)
3557 && mclass == MODE_INT);
3559 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3560 unsignedp);
3562 /* If we are generating clz using wider mode, adjust the
3563 result. Similarly for clrsb. */
3564 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3565 && temp != 0)
3567 scalar_int_mode wider_int_mode
3568 = as_a <scalar_int_mode> (wider_mode);
3569 int_mode = as_a <scalar_int_mode> (mode);
3570 temp = expand_binop
3571 (wider_mode, sub_optab, temp,
3572 gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
3573 - GET_MODE_PRECISION (int_mode),
3574 wider_int_mode),
3575 target, true, OPTAB_DIRECT);
3578 /* Likewise for bswap. */
3579 if (unoptab == bswap_optab && temp != 0)
3581 scalar_int_mode wider_int_mode
3582 = as_a <scalar_int_mode> (wider_mode);
3583 int_mode = as_a <scalar_int_mode> (mode);
3584 gcc_assert (GET_MODE_PRECISION (wider_int_mode)
3585 == GET_MODE_BITSIZE (wider_int_mode)
3586 && GET_MODE_PRECISION (int_mode)
3587 == GET_MODE_BITSIZE (int_mode));
3589 temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
3590 GET_MODE_BITSIZE (wider_int_mode)
3591 - GET_MODE_BITSIZE (int_mode),
3592 NULL_RTX, true);
3595 if (temp)
3597 if (mclass != MODE_INT)
3599 if (target == 0)
3600 target = gen_reg_rtx (mode);
3601 convert_move (target, temp, 0);
3602 return target;
3604 else
3605 return gen_lowpart (mode, temp);
3607 else
3608 delete_insns_since (last);
3613 /* One final attempt at implementing negation via subtraction,
3614 this time allowing widening of the operand. */
3615 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3617 rtx temp;
3618 temp = expand_binop (mode,
3619 unoptab == negv_optab ? subv_optab : sub_optab,
3620 CONST0_RTX (mode), op0,
3621 target, unsignedp, OPTAB_LIB_WIDEN);
3622 if (temp)
3623 return temp;
3626 return 0;
3629 /* Emit code to compute the absolute value of OP0, with result to
3630 TARGET if convenient. (TARGET may be 0.) The return value says
3631 where the result actually is to be found.
3633 MODE is the mode of the operand; the mode of the result is
3634 different but can be deduced from MODE.
3639 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3640 int result_unsignedp)
3642 rtx temp;
3644 if (GET_MODE_CLASS (mode) != MODE_INT
3645 || ! flag_trapv)
3646 result_unsignedp = 1;
3648 /* First try to do it with a special abs instruction. */
3649 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3650 op0, target, 0);
3651 if (temp != 0)
3652 return temp;
3654 /* For floating point modes, try clearing the sign bit. */
3655 scalar_float_mode float_mode;
3656 if (is_a <scalar_float_mode> (mode, &float_mode))
3658 temp = expand_absneg_bit (ABS, float_mode, op0, target);
3659 if (temp)
3660 return temp;
3663 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3664 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3665 && !HONOR_SIGNED_ZEROS (mode))
3667 rtx_insn *last = get_last_insn ();
3669 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3670 op0, NULL_RTX, 0);
3671 if (temp != 0)
3672 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3673 OPTAB_WIDEN);
3675 if (temp != 0)
3676 return temp;
3678 delete_insns_since (last);
3681 /* If this machine has expensive jumps, we can do integer absolute
3682 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3683 where W is the width of MODE. */
3685 scalar_int_mode int_mode;
3686 if (is_int_mode (mode, &int_mode)
3687 && BRANCH_COST (optimize_insn_for_speed_p (),
3688 false) >= 2)
3690 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3691 GET_MODE_PRECISION (int_mode) - 1,
3692 NULL_RTX, 0);
3694 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3695 OPTAB_LIB_WIDEN);
3696 if (temp != 0)
3697 temp = expand_binop (int_mode,
3698 result_unsignedp ? sub_optab : subv_optab,
3699 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3701 if (temp != 0)
3702 return temp;
3705 return NULL_RTX;
3709 expand_abs (machine_mode mode, rtx op0, rtx target,
3710 int result_unsignedp, int safe)
3712 rtx temp;
3713 rtx_code_label *op1;
3715 if (GET_MODE_CLASS (mode) != MODE_INT
3716 || ! flag_trapv)
3717 result_unsignedp = 1;
3719 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3720 if (temp != 0)
3721 return temp;
3723 /* If that does not win, use conditional jump and negate. */
3725 /* It is safe to use the target if it is the same
3726 as the source if this is also a pseudo register */
3727 if (op0 == target && REG_P (op0)
3728 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3729 safe = 1;
3731 op1 = gen_label_rtx ();
3732 if (target == 0 || ! safe
3733 || GET_MODE (target) != mode
3734 || (MEM_P (target) && MEM_VOLATILE_P (target))
3735 || (REG_P (target)
3736 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3737 target = gen_reg_rtx (mode);
3739 emit_move_insn (target, op0);
3740 NO_DEFER_POP;
3742 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3743 NULL_RTX, NULL, op1,
3744 profile_probability::uninitialized ());
3746 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3747 target, target, 0);
3748 if (op0 != target)
3749 emit_move_insn (target, op0);
3750 emit_label (op1);
3751 OK_DEFER_POP;
3752 return target;
3755 /* Emit code to compute the one's complement absolute value of OP0
3756 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3757 (TARGET may be NULL_RTX.) The return value says where the result
3758 actually is to be found.
3760 MODE is the mode of the operand; the mode of the result is
3761 different but can be deduced from MODE. */
3764 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3766 rtx temp;
3768 /* Not applicable for floating point modes. */
3769 if (FLOAT_MODE_P (mode))
3770 return NULL_RTX;
3772 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3773 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3775 rtx_insn *last = get_last_insn ();
3777 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3778 if (temp != 0)
3779 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3780 OPTAB_WIDEN);
3782 if (temp != 0)
3783 return temp;
3785 delete_insns_since (last);
3788 /* If this machine has expensive jumps, we can do one's complement
3789 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3791 scalar_int_mode int_mode;
3792 if (is_int_mode (mode, &int_mode)
3793 && BRANCH_COST (optimize_insn_for_speed_p (),
3794 false) >= 2)
3796 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3797 GET_MODE_PRECISION (int_mode) - 1,
3798 NULL_RTX, 0);
3800 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3801 OPTAB_LIB_WIDEN);
3803 if (temp != 0)
3804 return temp;
3807 return NULL_RTX;
3810 /* A subroutine of expand_copysign, perform the copysign operation using the
3811 abs and neg primitives advertised to exist on the target. The assumption
3812 is that we have a split register file, and leaving op0 in fp registers,
3813 and not playing with subregs so much, will help the register allocator. */
3815 static rtx
3816 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3817 int bitpos, bool op0_is_abs)
3819 scalar_int_mode imode;
3820 enum insn_code icode;
3821 rtx sign;
3822 rtx_code_label *label;
3824 if (target == op1)
3825 target = NULL_RTX;
3827 /* Check if the back end provides an insn that handles signbit for the
3828 argument's mode. */
3829 icode = optab_handler (signbit_optab, mode);
3830 if (icode != CODE_FOR_nothing)
3832 imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
3833 sign = gen_reg_rtx (imode);
3834 emit_unop_insn (icode, sign, op1, UNKNOWN);
3836 else
3838 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3840 if (!int_mode_for_mode (mode).exists (&imode))
3841 return NULL_RTX;
3842 op1 = gen_lowpart (imode, op1);
3844 else
3846 int word;
3848 imode = word_mode;
3849 if (FLOAT_WORDS_BIG_ENDIAN)
3850 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3851 else
3852 word = bitpos / BITS_PER_WORD;
3853 bitpos = bitpos % BITS_PER_WORD;
3854 op1 = operand_subword_force (op1, word, mode);
3857 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3858 sign = expand_binop (imode, and_optab, op1,
3859 immed_wide_int_const (mask, imode),
3860 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3863 if (!op0_is_abs)
3865 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3866 if (op0 == NULL)
3867 return NULL_RTX;
3868 target = op0;
3870 else
3872 if (target == NULL_RTX)
3873 target = copy_to_reg (op0);
3874 else
3875 emit_move_insn (target, op0);
3878 label = gen_label_rtx ();
3879 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3881 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3882 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3883 else
3884 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3885 if (op0 != target)
3886 emit_move_insn (target, op0);
3888 emit_label (label);
3890 return target;
3894 /* A subroutine of expand_copysign, perform the entire copysign operation
3895 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3896 is true if op0 is known to have its sign bit clear. */
3898 static rtx
3899 expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3900 int bitpos, bool op0_is_abs)
3902 scalar_int_mode imode;
3903 int word, nwords, i;
3904 rtx temp;
3905 rtx_insn *insns;
3907 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3909 if (!int_mode_for_mode (mode).exists (&imode))
3910 return NULL_RTX;
3911 word = 0;
3912 nwords = 1;
3914 else
3916 imode = word_mode;
3918 if (FLOAT_WORDS_BIG_ENDIAN)
3919 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3920 else
3921 word = bitpos / BITS_PER_WORD;
3922 bitpos = bitpos % BITS_PER_WORD;
3923 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3926 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3928 if (target == 0
3929 || target == op0
3930 || target == op1
3931 || reg_overlap_mentioned_p (target, op0)
3932 || reg_overlap_mentioned_p (target, op1)
3933 || (nwords > 1 && !valid_multiword_target_p (target)))
3934 target = gen_reg_rtx (mode);
3936 if (nwords > 1)
3938 start_sequence ();
3940 for (i = 0; i < nwords; ++i)
3942 rtx targ_piece = operand_subword (target, i, 1, mode);
3943 rtx op0_piece = operand_subword_force (op0, i, mode);
3945 if (i == word)
3947 if (!op0_is_abs)
3948 op0_piece
3949 = expand_binop (imode, and_optab, op0_piece,
3950 immed_wide_int_const (~mask, imode),
3951 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3952 op1 = expand_binop (imode, and_optab,
3953 operand_subword_force (op1, i, mode),
3954 immed_wide_int_const (mask, imode),
3955 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3957 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3958 targ_piece, 1, OPTAB_LIB_WIDEN);
3959 if (temp != targ_piece)
3960 emit_move_insn (targ_piece, temp);
3962 else
3963 emit_move_insn (targ_piece, op0_piece);
3966 insns = get_insns ();
3967 end_sequence ();
3969 emit_insn (insns);
3971 else
3973 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3974 immed_wide_int_const (mask, imode),
3975 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3977 op0 = gen_lowpart (imode, op0);
3978 if (!op0_is_abs)
3979 op0 = expand_binop (imode, and_optab, op0,
3980 immed_wide_int_const (~mask, imode),
3981 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3983 temp = expand_binop (imode, ior_optab, op0, op1,
3984 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3985 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3988 return target;
3991 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3992 scalar floating point mode. Return NULL if we do not know how to
3993 expand the operation inline. */
3996 expand_copysign (rtx op0, rtx op1, rtx target)
3998 scalar_float_mode mode;
3999 const struct real_format *fmt;
4000 bool op0_is_abs;
4001 rtx temp;
4003 mode = as_a <scalar_float_mode> (GET_MODE (op0));
4004 gcc_assert (GET_MODE (op1) == mode);
4006 /* First try to do it with a special instruction. */
4007 temp = expand_binop (mode, copysign_optab, op0, op1,
4008 target, 0, OPTAB_DIRECT);
4009 if (temp)
4010 return temp;
4012 fmt = REAL_MODE_FORMAT (mode);
4013 if (fmt == NULL || !fmt->has_signed_zero)
4014 return NULL_RTX;
4016 op0_is_abs = false;
4017 if (CONST_DOUBLE_AS_FLOAT_P (op0))
4019 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
4020 op0 = simplify_unary_operation (ABS, mode, op0, mode);
4021 op0_is_abs = true;
4024 if (fmt->signbit_ro >= 0
4025 && (CONST_DOUBLE_AS_FLOAT_P (op0)
4026 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
4027 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
4029 temp = expand_copysign_absneg (mode, op0, op1, target,
4030 fmt->signbit_ro, op0_is_abs);
4031 if (temp)
4032 return temp;
4035 if (fmt->signbit_rw < 0)
4036 return NULL_RTX;
4037 return expand_copysign_bit (mode, op0, op1, target,
4038 fmt->signbit_rw, op0_is_abs);
4041 /* Generate an instruction whose insn-code is INSN_CODE,
4042 with two operands: an output TARGET and an input OP0.
4043 TARGET *must* be nonzero, and the output is always stored there.
4044 CODE is an rtx code such that (CODE OP0) is an rtx that describes
4045 the value that is stored into TARGET.
4047 Return false if expansion failed. */
4049 bool
4050 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
4051 enum rtx_code code)
4053 class expand_operand ops[2];
4054 rtx_insn *pat;
4056 create_output_operand (&ops[0], target, GET_MODE (target));
4057 create_input_operand (&ops[1], op0, GET_MODE (op0));
4058 pat = maybe_gen_insn (icode, 2, ops);
4059 if (!pat)
4060 return false;
4062 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
4063 && code != UNKNOWN)
4064 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
4065 GET_MODE (op0));
4067 emit_insn (pat);
4069 if (ops[0].value != target)
4070 emit_move_insn (target, ops[0].value);
4071 return true;
4073 /* Generate an instruction whose insn-code is INSN_CODE,
4074 with two operands: an output TARGET and an input OP0.
4075 TARGET *must* be nonzero, and the output is always stored there.
4076 CODE is an rtx code such that (CODE OP0) is an rtx that describes
4077 the value that is stored into TARGET. */
4079 void
4080 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
4082 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
4083 gcc_assert (ok);
4086 struct no_conflict_data
4088 rtx target;
4089 rtx_insn *first, *insn;
4090 bool must_stay;
4093 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
4094 the currently examined clobber / store has to stay in the list of
4095 insns that constitute the actual libcall block. */
4096 static void
4097 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
4099 struct no_conflict_data *p= (struct no_conflict_data *) p0;
4101 /* If this inns directly contributes to setting the target, it must stay. */
4102 if (reg_overlap_mentioned_p (p->target, dest))
4103 p->must_stay = true;
4104 /* If we haven't committed to keeping any other insns in the list yet,
4105 there is nothing more to check. */
4106 else if (p->insn == p->first)
4107 return;
4108 /* If this insn sets / clobbers a register that feeds one of the insns
4109 already in the list, this insn has to stay too. */
4110 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
4111 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
4112 || reg_used_between_p (dest, p->first, p->insn)
4113 /* Likewise if this insn depends on a register set by a previous
4114 insn in the list, or if it sets a result (presumably a hard
4115 register) that is set or clobbered by a previous insn.
4116 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
4117 SET_DEST perform the former check on the address, and the latter
4118 check on the MEM. */
4119 || (GET_CODE (set) == SET
4120 && (modified_in_p (SET_SRC (set), p->first)
4121 || modified_in_p (SET_DEST (set), p->first)
4122 || modified_between_p (SET_SRC (set), p->first, p->insn)
4123 || modified_between_p (SET_DEST (set), p->first, p->insn))))
4124 p->must_stay = true;
4128 /* Emit code to make a call to a constant function or a library call.
4130 INSNS is a list containing all insns emitted in the call.
4131 These insns leave the result in RESULT. Our block is to copy RESULT
4132 to TARGET, which is logically equivalent to EQUIV.
4134 We first emit any insns that set a pseudo on the assumption that these are
4135 loading constants into registers; doing so allows them to be safely cse'ed
4136 between blocks. Then we emit all the other insns in the block, followed by
4137 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
4138 note with an operand of EQUIV. */
4140 static void
4141 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
4142 bool equiv_may_trap)
4144 rtx final_dest = target;
4145 rtx_insn *next, *last, *insn;
4147 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
4148 into a MEM later. Protect the libcall block from this change. */
4149 if (! REG_P (target) || REG_USERVAR_P (target))
4150 target = gen_reg_rtx (GET_MODE (target));
4152 /* If we're using non-call exceptions, a libcall corresponding to an
4153 operation that may trap may also trap. */
4154 /* ??? See the comment in front of make_reg_eh_region_note. */
4155 if (cfun->can_throw_non_call_exceptions
4156 && (equiv_may_trap || may_trap_p (equiv)))
4158 for (insn = insns; insn; insn = NEXT_INSN (insn))
4159 if (CALL_P (insn))
4161 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
4162 if (note)
4164 int lp_nr = INTVAL (XEXP (note, 0));
4165 if (lp_nr == 0 || lp_nr == INT_MIN)
4166 remove_note (insn, note);
4170 else
4172 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
4173 reg note to indicate that this call cannot throw or execute a nonlocal
4174 goto (unless there is already a REG_EH_REGION note, in which case
4175 we update it). */
4176 for (insn = insns; insn; insn = NEXT_INSN (insn))
4177 if (CALL_P (insn))
4178 make_reg_eh_region_note_nothrow_nononlocal (insn);
4181 /* First emit all insns that set pseudos. Remove them from the list as
4182 we go. Avoid insns that set pseudos which were referenced in previous
4183 insns. These can be generated by move_by_pieces, for example,
4184 to update an address. Similarly, avoid insns that reference things
4185 set in previous insns. */
4187 for (insn = insns; insn; insn = next)
4189 rtx set = single_set (insn);
4191 next = NEXT_INSN (insn);
4193 if (set != 0 && REG_P (SET_DEST (set))
4194 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
4196 struct no_conflict_data data;
4198 data.target = const0_rtx;
4199 data.first = insns;
4200 data.insn = insn;
4201 data.must_stay = 0;
4202 note_stores (insn, no_conflict_move_test, &data);
4203 if (! data.must_stay)
4205 if (PREV_INSN (insn))
4206 SET_NEXT_INSN (PREV_INSN (insn)) = next;
4207 else
4208 insns = next;
4210 if (next)
4211 SET_PREV_INSN (next) = PREV_INSN (insn);
4213 add_insn (insn);
4217 /* Some ports use a loop to copy large arguments onto the stack.
4218 Don't move anything outside such a loop. */
4219 if (LABEL_P (insn))
4220 break;
4223 /* Write the remaining insns followed by the final copy. */
4224 for (insn = insns; insn; insn = next)
4226 next = NEXT_INSN (insn);
4228 add_insn (insn);
4231 last = emit_move_insn (target, result);
4232 if (equiv)
4233 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
4235 if (final_dest != target)
4236 emit_move_insn (final_dest, target);
4239 void
4240 emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
4242 emit_libcall_block_1 (insns, target, result, equiv, false);
4245 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4246 PURPOSE describes how this comparison will be used. CODE is the rtx
4247 comparison code we will be using.
4249 ??? Actually, CODE is slightly weaker than that. A target is still
4250 required to implement all of the normal bcc operations, but not
4251 required to implement all (or any) of the unordered bcc operations. */
4254 can_compare_p (enum rtx_code code, machine_mode mode,
4255 enum can_compare_purpose purpose)
4257 rtx test;
4258 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
4261 enum insn_code icode;
4263 if (purpose == ccp_jump
4264 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
4265 && insn_operand_matches (icode, 0, test))
4266 return 1;
4267 if (purpose == ccp_store_flag
4268 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
4269 && insn_operand_matches (icode, 1, test))
4270 return 1;
4271 if (purpose == ccp_cmov
4272 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
4273 return 1;
4275 mode = GET_MODE_WIDER_MODE (mode).else_void ();
4276 PUT_MODE (test, mode);
4278 while (mode != VOIDmode);
4280 return 0;
4283 /* Return whether RTL code CODE corresponds to an unsigned optab. */
4285 static bool
4286 unsigned_optab_p (enum rtx_code code)
4288 return code == LTU || code == LEU || code == GTU || code == GEU;
4291 /* Return whether the backend-emitted comparison for code CODE, comparing
4292 operands of mode VALUE_MODE and producing a result with MASK_MODE, matches
4293 operand OPNO of pattern ICODE. */
4295 static bool
4296 insn_predicate_matches_p (enum insn_code icode, unsigned int opno,
4297 enum rtx_code code, machine_mode mask_mode,
4298 machine_mode value_mode)
4300 rtx reg1 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 1);
4301 rtx reg2 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 2);
4302 rtx test = alloca_rtx_fmt_ee (code, mask_mode, reg1, reg2);
4303 return insn_operand_matches (icode, opno, test);
4306 /* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
4307 for code CODE, comparing operands of mode VALUE_MODE and producing a result
4308 with MASK_MODE. */
4310 bool
4311 can_vec_cmp_compare_p (enum rtx_code code, machine_mode value_mode,
4312 machine_mode mask_mode)
4314 enum insn_code icode
4315 = get_vec_cmp_icode (value_mode, mask_mode, unsigned_optab_p (code));
4316 if (icode == CODE_FOR_nothing)
4317 return false;
4319 return insn_predicate_matches_p (icode, 1, code, mask_mode, value_mode);
4322 /* Return whether the backend can emit a vector comparison (vcond/vcondu) for
4323 code CODE, comparing operands of mode CMP_OP_MODE and producing a result
4324 with VALUE_MODE. */
4326 bool
4327 can_vcond_compare_p (enum rtx_code code, machine_mode value_mode,
4328 machine_mode cmp_op_mode)
4330 enum insn_code icode
4331 = get_vcond_icode (value_mode, cmp_op_mode, unsigned_optab_p (code));
4332 if (icode == CODE_FOR_nothing)
4333 return false;
4335 return insn_predicate_matches_p (icode, 3, code, value_mode, cmp_op_mode);
4338 /* Return whether the backend can emit vector set instructions for inserting
4339 element into vector at variable index position. */
4341 bool
4342 can_vec_set_var_idx_p (machine_mode vec_mode)
4344 if (!VECTOR_MODE_P (vec_mode))
4345 return false;
4347 machine_mode inner_mode = GET_MODE_INNER (vec_mode);
4349 rtx reg1 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 1);
4350 rtx reg2 = alloca_raw_REG (inner_mode, LAST_VIRTUAL_REGISTER + 2);
4352 enum insn_code icode = optab_handler (vec_set_optab, vec_mode);
4354 const struct insn_data_d *data = &insn_data[icode];
4355 machine_mode idx_mode = data->operand[2].mode;
4357 rtx reg3 = alloca_raw_REG (idx_mode, LAST_VIRTUAL_REGISTER + 3);
4359 return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1)
4360 && insn_operand_matches (icode, 1, reg2)
4361 && insn_operand_matches (icode, 2, reg3);
4364 /* This function is called when we are going to emit a compare instruction that
4365 compares the values found in X and Y, using the rtl operator COMPARISON.
4367 If they have mode BLKmode, then SIZE specifies the size of both operands.
4369 UNSIGNEDP nonzero says that the operands are unsigned;
4370 this matters if they need to be widened (as given by METHODS).
4372 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
4373 if we failed to produce one.
4375 *PMODE is the mode of the inputs (in case they are const_int).
4377 This function performs all the setup necessary so that the caller only has
4378 to emit a single comparison insn. This setup can involve doing a BLKmode
4379 comparison or emitting a library call to perform the comparison if no insn
4380 is available to handle it.
4381 The values which are passed in through pointers can be modified; the caller
4382 should perform the comparison on the modified values. Constant
4383 comparisons must have already been folded. */
4385 static void
4386 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4387 int unsignedp, enum optab_methods methods,
4388 rtx *ptest, machine_mode *pmode)
4390 machine_mode mode = *pmode;
4391 rtx libfunc, test;
4392 machine_mode cmp_mode;
4394 /* The other methods are not needed. */
4395 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
4396 || methods == OPTAB_LIB_WIDEN);
4398 if (CONST_SCALAR_INT_P (y))
4399 canonicalize_comparison (mode, &comparison, &y);
4401 /* If we are optimizing, force expensive constants into a register. */
4402 if (CONSTANT_P (x) && optimize
4403 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
4404 > COSTS_N_INSNS (1))
4405 && can_create_pseudo_p ())
4406 x = force_reg (mode, x);
4408 if (CONSTANT_P (y) && optimize
4409 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
4410 > COSTS_N_INSNS (1))
4411 && can_create_pseudo_p ())
4412 y = force_reg (mode, y);
4414 /* Don't let both operands fail to indicate the mode. */
4415 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4416 x = force_reg (mode, x);
4417 if (mode == VOIDmode)
4418 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
4420 /* Handle all BLKmode compares. */
4422 if (mode == BLKmode)
4424 machine_mode result_mode;
4425 enum insn_code cmp_code;
4426 rtx result;
4427 rtx opalign
4428 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4430 gcc_assert (size);
4432 /* Try to use a memory block compare insn - either cmpstr
4433 or cmpmem will do. */
4434 opt_scalar_int_mode cmp_mode_iter;
4435 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT)
4437 scalar_int_mode cmp_mode = cmp_mode_iter.require ();
4438 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
4439 if (cmp_code == CODE_FOR_nothing)
4440 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
4441 if (cmp_code == CODE_FOR_nothing)
4442 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
4443 if (cmp_code == CODE_FOR_nothing)
4444 continue;
4446 /* Must make sure the size fits the insn's mode. */
4447 if (CONST_INT_P (size)
4448 ? UINTVAL (size) > GET_MODE_MASK (cmp_mode)
4449 : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
4450 > GET_MODE_BITSIZE (cmp_mode)))
4451 continue;
4453 result_mode = insn_data[cmp_code].operand[0].mode;
4454 result = gen_reg_rtx (result_mode);
4455 size = convert_to_mode (cmp_mode, size, 1);
4456 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4458 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4459 *pmode = result_mode;
4460 return;
4463 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
4464 goto fail;
4466 /* Otherwise call a library function. */
4467 result = emit_block_comp_via_libcall (x, y, size);
4469 x = result;
4470 y = const0_rtx;
4471 mode = TYPE_MODE (integer_type_node);
4472 methods = OPTAB_LIB_WIDEN;
4473 unsignedp = false;
4476 /* Don't allow operands to the compare to trap, as that can put the
4477 compare and branch in different basic blocks. */
4478 if (cfun->can_throw_non_call_exceptions)
4480 if (!can_create_pseudo_p () && (may_trap_p (x) || may_trap_p (y)))
4481 goto fail;
4482 if (may_trap_p (x))
4483 x = copy_to_reg (x);
4484 if (may_trap_p (y))
4485 y = copy_to_reg (y);
4488 if (GET_MODE_CLASS (mode) == MODE_CC)
4490 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
4491 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4492 gcc_assert (icode != CODE_FOR_nothing
4493 && insn_operand_matches (icode, 0, test));
4494 *ptest = test;
4495 return;
4498 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4499 FOR_EACH_WIDER_MODE_FROM (cmp_mode, mode)
4501 enum insn_code icode;
4502 icode = optab_handler (cbranch_optab, cmp_mode);
4503 if (icode != CODE_FOR_nothing
4504 && insn_operand_matches (icode, 0, test))
4506 rtx_insn *last = get_last_insn ();
4507 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
4508 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
4509 if (op0 && op1
4510 && insn_operand_matches (icode, 1, op0)
4511 && insn_operand_matches (icode, 2, op1))
4513 XEXP (test, 0) = op0;
4514 XEXP (test, 1) = op1;
4515 *ptest = test;
4516 *pmode = cmp_mode;
4517 return;
4519 delete_insns_since (last);
4522 if (methods == OPTAB_DIRECT)
4523 break;
4526 if (methods != OPTAB_LIB_WIDEN)
4527 goto fail;
4529 if (SCALAR_FLOAT_MODE_P (mode))
4531 /* Small trick if UNORDERED isn't implemented by the hardware. */
4532 if (comparison == UNORDERED && rtx_equal_p (x, y))
4534 prepare_cmp_insn (x, y, UNLT, NULL_RTX, unsignedp, OPTAB_WIDEN,
4535 ptest, pmode);
4536 if (*ptest)
4537 return;
4540 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4542 else
4544 rtx result;
4545 machine_mode ret_mode;
4547 /* Handle a libcall just for the mode we are using. */
4548 libfunc = optab_libfunc (cmp_optab, mode);
4549 gcc_assert (libfunc);
4551 /* If we want unsigned, and this mode has a distinct unsigned
4552 comparison routine, use that. */
4553 if (unsignedp)
4555 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4556 if (ulibfunc)
4557 libfunc = ulibfunc;
4560 ret_mode = targetm.libgcc_cmp_return_mode ();
4561 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4562 ret_mode, x, mode, y, mode);
4564 /* There are two kinds of comparison routines. Biased routines
4565 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4566 of gcc expect that the comparison operation is equivalent
4567 to the modified comparison. For signed comparisons compare the
4568 result against 1 in the biased case, and zero in the unbiased
4569 case. For unsigned comparisons always compare against 1 after
4570 biasing the unbiased result by adding 1. This gives us a way to
4571 represent LTU.
4572 The comparisons in the fixed-point helper library are always
4573 biased. */
4574 x = result;
4575 y = const1_rtx;
4577 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4579 if (unsignedp)
4580 x = plus_constant (ret_mode, result, 1);
4581 else
4582 y = const0_rtx;
4585 *pmode = ret_mode;
4586 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4587 ptest, pmode);
4590 return;
4592 fail:
4593 *ptest = NULL_RTX;
4596 /* Before emitting an insn with code ICODE, make sure that X, which is going
4597 to be used for operand OPNUM of the insn, is converted from mode MODE to
4598 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4599 that it is accepted by the operand predicate. Return the new value. */
4602 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
4603 machine_mode wider_mode, int unsignedp)
4605 if (mode != wider_mode)
4606 x = convert_modes (wider_mode, mode, x, unsignedp);
4608 if (!insn_operand_matches (icode, opnum, x))
4610 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
4611 if (reload_completed)
4612 return NULL_RTX;
4613 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
4614 return NULL_RTX;
4615 x = copy_to_mode_reg (op_mode, x);
4618 return x;
4621 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4622 we can do the branch. */
4624 static void
4625 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
4626 profile_probability prob)
4628 machine_mode optab_mode;
4629 enum mode_class mclass;
4630 enum insn_code icode;
4631 rtx_insn *insn;
4633 mclass = GET_MODE_CLASS (mode);
4634 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4635 icode = optab_handler (cbranch_optab, optab_mode);
4637 gcc_assert (icode != CODE_FOR_nothing);
4638 gcc_assert (insn_operand_matches (icode, 0, test));
4639 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4640 XEXP (test, 1), label));
4641 if (prob.initialized_p ()
4642 && profile_status_for_fn (cfun) != PROFILE_ABSENT
4643 && insn
4644 && JUMP_P (insn)
4645 && any_condjump_p (insn)
4646 && !find_reg_note (insn, REG_BR_PROB, 0))
4647 add_reg_br_prob_note (insn, prob);
4650 /* Generate code to compare X with Y so that the condition codes are
4651 set and to jump to LABEL if the condition is true. If X is a
4652 constant and Y is not a constant, then the comparison is swapped to
4653 ensure that the comparison RTL has the canonical form.
4655 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4656 need to be widened. UNSIGNEDP is also used to select the proper
4657 branch condition code.
4659 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4661 MODE is the mode of the inputs (in case they are const_int).
4663 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4664 It will be potentially converted into an unsigned variant based on
4665 UNSIGNEDP to select a proper jump instruction.
4667 PROB is the probability of jumping to LABEL. */
4669 void
4670 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4671 machine_mode mode, int unsignedp, rtx label,
4672 profile_probability prob)
4674 rtx op0 = x, op1 = y;
4675 rtx test;
4677 /* Swap operands and condition to ensure canonical RTL. */
4678 if (swap_commutative_operands_p (x, y)
4679 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4681 op0 = y, op1 = x;
4682 comparison = swap_condition (comparison);
4685 /* If OP0 is still a constant, then both X and Y must be constants
4686 or the opposite comparison is not supported. Force X into a register
4687 to create canonical RTL. */
4688 if (CONSTANT_P (op0))
4689 op0 = force_reg (mode, op0);
4691 if (unsignedp)
4692 comparison = unsigned_condition (comparison);
4694 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4695 &test, &mode);
4696 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4700 /* Emit a library call comparison between floating point X and Y.
4701 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4703 static void
4704 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4705 rtx *ptest, machine_mode *pmode)
4707 enum rtx_code swapped = swap_condition (comparison);
4708 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4709 machine_mode orig_mode = GET_MODE (x);
4710 machine_mode mode;
4711 rtx true_rtx, false_rtx;
4712 rtx value, target, equiv;
4713 rtx_insn *insns;
4714 rtx libfunc = 0;
4715 bool reversed_p = false;
4716 scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
4718 FOR_EACH_WIDER_MODE_FROM (mode, orig_mode)
4720 if (code_to_optab (comparison)
4721 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4722 break;
4724 if (code_to_optab (swapped)
4725 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4727 std::swap (x, y);
4728 comparison = swapped;
4729 break;
4732 if (code_to_optab (reversed)
4733 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4735 comparison = reversed;
4736 reversed_p = true;
4737 break;
4741 gcc_assert (mode != VOIDmode);
4743 if (mode != orig_mode)
4745 x = convert_to_mode (mode, x, 0);
4746 y = convert_to_mode (mode, y, 0);
4749 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4750 the RTL. The allows the RTL optimizers to delete the libcall if the
4751 condition can be determined at compile-time. */
4752 if (comparison == UNORDERED
4753 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4755 true_rtx = const_true_rtx;
4756 false_rtx = const0_rtx;
4758 else
4760 switch (comparison)
4762 case EQ:
4763 true_rtx = const0_rtx;
4764 false_rtx = const_true_rtx;
4765 break;
4767 case NE:
4768 true_rtx = const_true_rtx;
4769 false_rtx = const0_rtx;
4770 break;
4772 case GT:
4773 true_rtx = const1_rtx;
4774 false_rtx = const0_rtx;
4775 break;
4777 case GE:
4778 true_rtx = const0_rtx;
4779 false_rtx = constm1_rtx;
4780 break;
4782 case LT:
4783 true_rtx = constm1_rtx;
4784 false_rtx = const0_rtx;
4785 break;
4787 case LE:
4788 true_rtx = const0_rtx;
4789 false_rtx = const1_rtx;
4790 break;
4792 default:
4793 gcc_unreachable ();
4797 if (comparison == UNORDERED)
4799 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4800 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4801 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4802 temp, const_true_rtx, equiv);
4804 else
4806 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4807 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4808 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4809 equiv, true_rtx, false_rtx);
4812 start_sequence ();
4813 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4814 cmp_mode, x, mode, y, mode);
4815 insns = get_insns ();
4816 end_sequence ();
4818 target = gen_reg_rtx (cmp_mode);
4819 emit_libcall_block (insns, target, value, equiv);
4821 if (comparison == UNORDERED
4822 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4823 || reversed_p)
4824 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4825 else
4826 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4828 *pmode = cmp_mode;
4831 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4833 void
4834 emit_indirect_jump (rtx loc)
4836 if (!targetm.have_indirect_jump ())
4837 sorry ("indirect jumps are not available on this target");
4838 else
4840 class expand_operand ops[1];
4841 create_address_operand (&ops[0], loc);
4842 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4843 emit_barrier ();
4848 /* Emit a conditional move instruction if the machine supports one for that
4849 condition and machine mode.
4851 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4852 the mode to use should they be constants. If it is VOIDmode, they cannot
4853 both be constants.
4855 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4856 should be stored there. MODE is the mode to use should they be constants.
4857 If it is VOIDmode, they cannot both be constants.
4859 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4860 is not supported. */
4863 emit_conditional_move (rtx target, struct rtx_comparison comp,
4864 rtx op2, rtx op3,
4865 machine_mode mode, int unsignedp)
4867 rtx comparison;
4868 rtx_insn *last;
4869 enum insn_code icode;
4870 enum rtx_code reversed;
4872 /* If the two source operands are identical, that's just a move. */
4874 if (rtx_equal_p (op2, op3))
4876 if (!target)
4877 target = gen_reg_rtx (mode);
4879 emit_move_insn (target, op3);
4880 return target;
4883 /* If one operand is constant, make it the second one. Only do this
4884 if the other operand is not constant as well. */
4886 if (swap_commutative_operands_p (comp.op0, comp.op1))
4888 std::swap (comp.op0, comp.op1);
4889 comp.code = swap_condition (comp.code);
4892 /* get_condition will prefer to generate LT and GT even if the old
4893 comparison was against zero, so undo that canonicalization here since
4894 comparisons against zero are cheaper. */
4896 if (comp.code == LT && comp.op1 == const1_rtx)
4897 comp.code = LE, comp.op1 = const0_rtx;
4898 else if (comp.code == GT && comp.op1 == constm1_rtx)
4899 comp.code = GE, comp.op1 = const0_rtx;
4901 if (comp.mode == VOIDmode)
4902 comp.mode = GET_MODE (comp.op0);
4904 enum rtx_code orig_code = comp.code;
4905 bool swapped = false;
4906 if (swap_commutative_operands_p (op2, op3)
4907 && ((reversed =
4908 reversed_comparison_code_parts (comp.code, comp.op0, comp.op1, NULL))
4909 != UNKNOWN))
4911 std::swap (op2, op3);
4912 comp.code = reversed;
4913 swapped = true;
4916 if (mode == VOIDmode)
4917 mode = GET_MODE (op2);
4919 icode = direct_optab_handler (movcc_optab, mode);
4921 if (icode == CODE_FOR_nothing)
4922 return NULL_RTX;
4924 if (!target)
4925 target = gen_reg_rtx (mode);
4927 for (int pass = 0; ; pass++)
4929 comp.code = unsignedp ? unsigned_condition (comp.code) : comp.code;
4930 comparison =
4931 simplify_gen_relational (comp.code, VOIDmode,
4932 comp.mode, comp.op0, comp.op1);
4934 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4935 punt and let the caller figure out how best to deal with this
4936 situation. */
4937 if (COMPARISON_P (comparison))
4939 saved_pending_stack_adjust save;
4940 save_pending_stack_adjust (&save);
4941 last = get_last_insn ();
4942 do_pending_stack_adjust ();
4943 machine_mode cmpmode = comp.mode;
4944 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4945 GET_CODE (comparison), NULL_RTX, unsignedp,
4946 OPTAB_WIDEN, &comparison, &cmpmode);
4947 if (comparison)
4949 rtx res = emit_conditional_move_1 (target, comparison,
4950 op2, op3, mode);
4951 if (res != NULL_RTX)
4952 return res;
4954 delete_insns_since (last);
4955 restore_pending_stack_adjust (&save);
4958 if (pass == 1)
4959 return NULL_RTX;
4961 /* If the preferred op2/op3 order is not usable, retry with other
4962 operand order, perhaps it will expand successfully. */
4963 if (swapped)
4964 comp.code = orig_code;
4965 else if ((reversed =
4966 reversed_comparison_code_parts (orig_code, comp.op0, comp.op1,
4967 NULL))
4968 != UNKNOWN)
4969 comp.code = reversed;
4970 else
4971 return NULL_RTX;
4972 std::swap (op2, op3);
4976 /* Helper function that, in addition to COMPARISON, also tries
4977 the reversed REV_COMPARISON with swapped OP2 and OP3. As opposed
4978 to when we pass the specific constituents of a comparison, no
4979 additional insns are emitted for it. It might still be necessary
4980 to emit more than one insn for the final conditional move, though. */
4983 emit_conditional_move (rtx target, rtx comparison, rtx rev_comparison,
4984 rtx op2, rtx op3, machine_mode mode)
4986 rtx res = emit_conditional_move_1 (target, comparison, op2, op3, mode);
4988 if (res != NULL_RTX)
4989 return res;
4991 return emit_conditional_move_1 (target, rev_comparison, op3, op2, mode);
4994 /* Helper for emitting a conditional move. */
4996 static rtx
4997 emit_conditional_move_1 (rtx target, rtx comparison,
4998 rtx op2, rtx op3, machine_mode mode)
5000 enum insn_code icode;
5002 if (comparison == NULL_RTX || !COMPARISON_P (comparison))
5003 return NULL_RTX;
5005 /* If the two source operands are identical, that's just a move.
5006 As the comparison comes in non-canonicalized, we must make
5007 sure not to discard any possible side effects. If there are
5008 side effects, just let the target handle it. */
5009 if (!side_effects_p (comparison) && rtx_equal_p (op2, op3))
5011 if (!target)
5012 target = gen_reg_rtx (mode);
5014 emit_move_insn (target, op3);
5015 return target;
5018 if (mode == VOIDmode)
5019 mode = GET_MODE (op2);
5021 icode = direct_optab_handler (movcc_optab, mode);
5023 if (icode == CODE_FOR_nothing)
5024 return NULL_RTX;
5026 if (!target)
5027 target = gen_reg_rtx (mode);
5029 class expand_operand ops[4];
5031 create_output_operand (&ops[0], target, mode);
5032 create_fixed_operand (&ops[1], comparison);
5033 create_input_operand (&ops[2], op2, mode);
5034 create_input_operand (&ops[3], op3, mode);
5036 if (maybe_expand_insn (icode, 4, ops))
5038 if (ops[0].value != target)
5039 convert_move (target, ops[0].value, false);
5040 return target;
5043 return NULL_RTX;
5047 /* Emit a conditional negate or bitwise complement using the
5048 negcc or notcc optabs if available. Return NULL_RTX if such operations
5049 are not available. Otherwise return the RTX holding the result.
5050 TARGET is the desired destination of the result. COMP is the comparison
5051 on which to negate. If COND is true move into TARGET the negation
5052 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
5053 CODE is either NEG or NOT. MODE is the machine mode in which the
5054 operation is performed. */
5057 emit_conditional_neg_or_complement (rtx target, rtx_code code,
5058 machine_mode mode, rtx cond, rtx op1,
5059 rtx op2)
5061 optab op = unknown_optab;
5062 if (code == NEG)
5063 op = negcc_optab;
5064 else if (code == NOT)
5065 op = notcc_optab;
5066 else
5067 gcc_unreachable ();
5069 insn_code icode = direct_optab_handler (op, mode);
5071 if (icode == CODE_FOR_nothing)
5072 return NULL_RTX;
5074 if (!target)
5075 target = gen_reg_rtx (mode);
5077 rtx_insn *last = get_last_insn ();
5078 class expand_operand ops[4];
5080 create_output_operand (&ops[0], target, mode);
5081 create_fixed_operand (&ops[1], cond);
5082 create_input_operand (&ops[2], op1, mode);
5083 create_input_operand (&ops[3], op2, mode);
5085 if (maybe_expand_insn (icode, 4, ops))
5087 if (ops[0].value != target)
5088 convert_move (target, ops[0].value, false);
5090 return target;
5092 delete_insns_since (last);
5093 return NULL_RTX;
5096 /* Emit a conditional addition instruction if the machine supports one for that
5097 condition and machine mode.
5099 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
5100 the mode to use should they be constants. If it is VOIDmode, they cannot
5101 both be constants.
5103 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
5104 should be stored there. MODE is the mode to use should they be constants.
5105 If it is VOIDmode, they cannot both be constants.
5107 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
5108 is not supported. */
5111 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
5112 machine_mode cmode, rtx op2, rtx op3,
5113 machine_mode mode, int unsignedp)
5115 rtx comparison;
5116 rtx_insn *last;
5117 enum insn_code icode;
5119 /* If one operand is constant, make it the second one. Only do this
5120 if the other operand is not constant as well. */
5122 if (swap_commutative_operands_p (op0, op1))
5124 std::swap (op0, op1);
5125 code = swap_condition (code);
5128 /* get_condition will prefer to generate LT and GT even if the old
5129 comparison was against zero, so undo that canonicalization here since
5130 comparisons against zero are cheaper. */
5131 if (code == LT && op1 == const1_rtx)
5132 code = LE, op1 = const0_rtx;
5133 else if (code == GT && op1 == constm1_rtx)
5134 code = GE, op1 = const0_rtx;
5136 if (cmode == VOIDmode)
5137 cmode = GET_MODE (op0);
5139 if (mode == VOIDmode)
5140 mode = GET_MODE (op2);
5142 icode = optab_handler (addcc_optab, mode);
5144 if (icode == CODE_FOR_nothing)
5145 return 0;
5147 if (!target)
5148 target = gen_reg_rtx (mode);
5150 code = unsignedp ? unsigned_condition (code) : code;
5151 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
5153 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
5154 return NULL and let the caller figure out how best to deal with this
5155 situation. */
5156 if (!COMPARISON_P (comparison))
5157 return NULL_RTX;
5159 do_pending_stack_adjust ();
5160 last = get_last_insn ();
5161 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
5162 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
5163 &comparison, &cmode);
5164 if (comparison)
5166 class expand_operand ops[4];
5168 create_output_operand (&ops[0], target, mode);
5169 create_fixed_operand (&ops[1], comparison);
5170 create_input_operand (&ops[2], op2, mode);
5171 create_input_operand (&ops[3], op3, mode);
5172 if (maybe_expand_insn (icode, 4, ops))
5174 if (ops[0].value != target)
5175 convert_move (target, ops[0].value, false);
5176 return target;
5179 delete_insns_since (last);
5180 return NULL_RTX;
5183 /* These functions attempt to generate an insn body, rather than
5184 emitting the insn, but if the gen function already emits them, we
5185 make no attempt to turn them back into naked patterns. */
5187 /* Generate and return an insn body to add Y to X. */
5189 rtx_insn *
5190 gen_add2_insn (rtx x, rtx y)
5192 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
5194 gcc_assert (insn_operand_matches (icode, 0, x));
5195 gcc_assert (insn_operand_matches (icode, 1, x));
5196 gcc_assert (insn_operand_matches (icode, 2, y));
5198 return GEN_FCN (icode) (x, x, y);
5201 /* Generate and return an insn body to add r1 and c,
5202 storing the result in r0. */
5204 rtx_insn *
5205 gen_add3_insn (rtx r0, rtx r1, rtx c)
5207 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
5209 if (icode == CODE_FOR_nothing
5210 || !insn_operand_matches (icode, 0, r0)
5211 || !insn_operand_matches (icode, 1, r1)
5212 || !insn_operand_matches (icode, 2, c))
5213 return NULL;
5215 return GEN_FCN (icode) (r0, r1, c);
5219 have_add2_insn (rtx x, rtx y)
5221 enum insn_code icode;
5223 gcc_assert (GET_MODE (x) != VOIDmode);
5225 icode = optab_handler (add_optab, GET_MODE (x));
5227 if (icode == CODE_FOR_nothing)
5228 return 0;
5230 if (!insn_operand_matches (icode, 0, x)
5231 || !insn_operand_matches (icode, 1, x)
5232 || !insn_operand_matches (icode, 2, y))
5233 return 0;
5235 return 1;
5238 /* Generate and return an insn body to add Y to X. */
5240 rtx_insn *
5241 gen_addptr3_insn (rtx x, rtx y, rtx z)
5243 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
5245 gcc_assert (insn_operand_matches (icode, 0, x));
5246 gcc_assert (insn_operand_matches (icode, 1, y));
5247 gcc_assert (insn_operand_matches (icode, 2, z));
5249 return GEN_FCN (icode) (x, y, z);
5252 /* Return true if the target implements an addptr pattern and X, Y,
5253 and Z are valid for the pattern predicates. */
5256 have_addptr3_insn (rtx x, rtx y, rtx z)
5258 enum insn_code icode;
5260 gcc_assert (GET_MODE (x) != VOIDmode);
5262 icode = optab_handler (addptr3_optab, GET_MODE (x));
5264 if (icode == CODE_FOR_nothing)
5265 return 0;
5267 if (!insn_operand_matches (icode, 0, x)
5268 || !insn_operand_matches (icode, 1, y)
5269 || !insn_operand_matches (icode, 2, z))
5270 return 0;
5272 return 1;
5275 /* Generate and return an insn body to subtract Y from X. */
5277 rtx_insn *
5278 gen_sub2_insn (rtx x, rtx y)
5280 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
5282 gcc_assert (insn_operand_matches (icode, 0, x));
5283 gcc_assert (insn_operand_matches (icode, 1, x));
5284 gcc_assert (insn_operand_matches (icode, 2, y));
5286 return GEN_FCN (icode) (x, x, y);
5289 /* Generate and return an insn body to subtract r1 and c,
5290 storing the result in r0. */
5292 rtx_insn *
5293 gen_sub3_insn (rtx r0, rtx r1, rtx c)
5295 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
5297 if (icode == CODE_FOR_nothing
5298 || !insn_operand_matches (icode, 0, r0)
5299 || !insn_operand_matches (icode, 1, r1)
5300 || !insn_operand_matches (icode, 2, c))
5301 return NULL;
5303 return GEN_FCN (icode) (r0, r1, c);
5307 have_sub2_insn (rtx x, rtx y)
5309 enum insn_code icode;
5311 gcc_assert (GET_MODE (x) != VOIDmode);
5313 icode = optab_handler (sub_optab, GET_MODE (x));
5315 if (icode == CODE_FOR_nothing)
5316 return 0;
5318 if (!insn_operand_matches (icode, 0, x)
5319 || !insn_operand_matches (icode, 1, x)
5320 || !insn_operand_matches (icode, 2, y))
5321 return 0;
5323 return 1;
5326 /* Generate the body of an insn to extend Y (with mode MFROM)
5327 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
5329 rtx_insn *
5330 gen_extend_insn (rtx x, rtx y, machine_mode mto,
5331 machine_mode mfrom, int unsignedp)
5333 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
5334 return GEN_FCN (icode) (x, y);
5337 /* Generate code to convert FROM to floating point
5338 and store in TO. FROM must be fixed point and not VOIDmode.
5339 UNSIGNEDP nonzero means regard FROM as unsigned.
5340 Normally this is done by correcting the final value
5341 if it is negative. */
5343 void
5344 expand_float (rtx to, rtx from, int unsignedp)
5346 enum insn_code icode;
5347 rtx target = to;
5348 scalar_mode from_mode, to_mode;
5349 machine_mode fmode, imode;
5350 bool can_do_signed = false;
5352 /* Crash now, because we won't be able to decide which mode to use. */
5353 gcc_assert (GET_MODE (from) != VOIDmode);
5355 /* Look for an insn to do the conversion. Do it in the specified
5356 modes if possible; otherwise convert either input, output or both to
5357 wider mode. If the integer mode is wider than the mode of FROM,
5358 we can do the conversion signed even if the input is unsigned. */
5360 FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
5361 FOR_EACH_MODE_FROM (imode, GET_MODE (from))
5363 int doing_unsigned = unsignedp;
5365 if (fmode != GET_MODE (to)
5366 && (significand_size (fmode)
5367 < GET_MODE_UNIT_PRECISION (GET_MODE (from))))
5368 continue;
5370 icode = can_float_p (fmode, imode, unsignedp);
5371 if (icode == CODE_FOR_nothing && unsignedp)
5373 enum insn_code scode = can_float_p (fmode, imode, 0);
5374 if (scode != CODE_FOR_nothing)
5375 can_do_signed = true;
5376 if (imode != GET_MODE (from))
5377 icode = scode, doing_unsigned = 0;
5380 if (icode != CODE_FOR_nothing)
5382 if (imode != GET_MODE (from))
5383 from = convert_to_mode (imode, from, unsignedp);
5385 if (fmode != GET_MODE (to))
5386 target = gen_reg_rtx (fmode);
5388 emit_unop_insn (icode, target, from,
5389 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5391 if (target != to)
5392 convert_move (to, target, 0);
5393 return;
5397 /* Unsigned integer, and no way to convert directly. Convert as signed,
5398 then unconditionally adjust the result. */
5399 if (unsignedp
5400 && can_do_signed
5401 && is_a <scalar_mode> (GET_MODE (to), &to_mode)
5402 && is_a <scalar_mode> (GET_MODE (from), &from_mode))
5404 opt_scalar_mode fmode_iter;
5405 rtx_code_label *label = gen_label_rtx ();
5406 rtx temp;
5407 REAL_VALUE_TYPE offset;
5409 /* Look for a usable floating mode FMODE wider than the source and at
5410 least as wide as the target. Using FMODE will avoid rounding woes
5411 with unsigned values greater than the signed maximum value. */
5413 FOR_EACH_MODE_FROM (fmode_iter, to_mode)
5415 scalar_mode fmode = fmode_iter.require ();
5416 if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
5417 && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
5418 break;
5421 if (!fmode_iter.exists (&fmode))
5423 /* There is no such mode. Pretend the target is wide enough. */
5424 fmode = to_mode;
5426 /* Avoid double-rounding when TO is narrower than FROM. */
5427 if ((significand_size (fmode) + 1)
5428 < GET_MODE_PRECISION (from_mode))
5430 rtx temp1;
5431 rtx_code_label *neglabel = gen_label_rtx ();
5433 /* Don't use TARGET if it isn't a register, is a hard register,
5434 or is the wrong mode. */
5435 if (!REG_P (target)
5436 || REGNO (target) < FIRST_PSEUDO_REGISTER
5437 || GET_MODE (target) != fmode)
5438 target = gen_reg_rtx (fmode);
5440 imode = from_mode;
5441 do_pending_stack_adjust ();
5443 /* Test whether the sign bit is set. */
5444 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5445 0, neglabel);
5447 /* The sign bit is not set. Convert as signed. */
5448 expand_float (target, from, 0);
5449 emit_jump_insn (targetm.gen_jump (label));
5450 emit_barrier ();
5452 /* The sign bit is set.
5453 Convert to a usable (positive signed) value by shifting right
5454 one bit, while remembering if a nonzero bit was shifted
5455 out; i.e., compute (from & 1) | (from >> 1). */
5457 emit_label (neglabel);
5458 temp = expand_binop (imode, and_optab, from, const1_rtx,
5459 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5460 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
5461 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5462 OPTAB_LIB_WIDEN);
5463 expand_float (target, temp, 0);
5465 /* Multiply by 2 to undo the shift above. */
5466 temp = expand_binop (fmode, add_optab, target, target,
5467 target, 0, OPTAB_LIB_WIDEN);
5468 if (temp != target)
5469 emit_move_insn (target, temp);
5471 do_pending_stack_adjust ();
5472 emit_label (label);
5473 goto done;
5477 /* If we are about to do some arithmetic to correct for an
5478 unsigned operand, do it in a pseudo-register. */
5480 if (to_mode != fmode
5481 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5482 target = gen_reg_rtx (fmode);
5484 /* Convert as signed integer to floating. */
5485 expand_float (target, from, 0);
5487 /* If FROM is negative (and therefore TO is negative),
5488 correct its value by 2**bitwidth. */
5490 do_pending_stack_adjust ();
5491 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
5492 0, label);
5495 real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
5496 temp = expand_binop (fmode, add_optab, target,
5497 const_double_from_real_value (offset, fmode),
5498 target, 0, OPTAB_LIB_WIDEN);
5499 if (temp != target)
5500 emit_move_insn (target, temp);
5502 do_pending_stack_adjust ();
5503 emit_label (label);
5504 goto done;
5507 /* No hardware instruction available; call a library routine. */
5509 rtx libfunc;
5510 rtx_insn *insns;
5511 rtx value;
5512 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5514 if (is_narrower_int_mode (GET_MODE (from), SImode))
5515 from = convert_to_mode (SImode, from, unsignedp);
5517 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5518 gcc_assert (libfunc);
5520 start_sequence ();
5522 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5523 GET_MODE (to), from, GET_MODE (from));
5524 insns = get_insns ();
5525 end_sequence ();
5527 emit_libcall_block (insns, target, value,
5528 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
5529 GET_MODE (to), from));
5532 done:
5534 /* Copy result to requested destination
5535 if we have been computing in a temp location. */
5537 if (target != to)
5539 if (GET_MODE (target) == GET_MODE (to))
5540 emit_move_insn (to, target);
5541 else
5542 convert_move (to, target, 0);
5546 /* Generate code to convert FROM to fixed point and store in TO. FROM
5547 must be floating point. */
5549 void
5550 expand_fix (rtx to, rtx from, int unsignedp)
5552 enum insn_code icode;
5553 rtx target = to;
5554 machine_mode fmode, imode;
5555 opt_scalar_mode fmode_iter;
5556 bool must_trunc = false;
5558 /* We first try to find a pair of modes, one real and one integer, at
5559 least as wide as FROM and TO, respectively, in which we can open-code
5560 this conversion. If the integer mode is wider than the mode of TO,
5561 we can do the conversion either signed or unsigned. */
5563 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5564 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5566 int doing_unsigned = unsignedp;
5568 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5569 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5570 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5572 if (icode != CODE_FOR_nothing)
5574 rtx_insn *last = get_last_insn ();
5575 rtx from1 = from;
5576 if (fmode != GET_MODE (from))
5577 from1 = convert_to_mode (fmode, from, 0);
5579 if (must_trunc)
5581 rtx temp = gen_reg_rtx (GET_MODE (from1));
5582 from1 = expand_unop (GET_MODE (from1), ftrunc_optab, from1,
5583 temp, 0);
5586 if (imode != GET_MODE (to))
5587 target = gen_reg_rtx (imode);
5589 if (maybe_emit_unop_insn (icode, target, from1,
5590 doing_unsigned ? UNSIGNED_FIX : FIX))
5592 if (target != to)
5593 convert_move (to, target, unsignedp);
5594 return;
5596 delete_insns_since (last);
5600 /* For an unsigned conversion, there is one more way to do it.
5601 If we have a signed conversion, we generate code that compares
5602 the real value to the largest representable positive number. If if
5603 is smaller, the conversion is done normally. Otherwise, subtract
5604 one plus the highest signed number, convert, and add it back.
5606 We only need to check all real modes, since we know we didn't find
5607 anything with a wider integer mode.
5609 This code used to extend FP value into mode wider than the destination.
5610 This is needed for decimal float modes which cannot accurately
5611 represent one plus the highest signed number of the same size, but
5612 not for binary modes. Consider, for instance conversion from SFmode
5613 into DImode.
5615 The hot path through the code is dealing with inputs smaller than 2^63
5616 and doing just the conversion, so there is no bits to lose.
5618 In the other path we know the value is positive in the range 2^63..2^64-1
5619 inclusive. (as for other input overflow happens and result is undefined)
5620 So we know that the most important bit set in mantissa corresponds to
5621 2^63. The subtraction of 2^63 should not generate any rounding as it
5622 simply clears out that bit. The rest is trivial. */
5624 scalar_int_mode to_mode;
5625 if (unsignedp
5626 && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
5627 && HWI_COMPUTABLE_MODE_P (to_mode))
5628 FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
5630 scalar_mode fmode = fmode_iter.require ();
5631 if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
5632 0, &must_trunc)
5633 && (!DECIMAL_FLOAT_MODE_P (fmode)
5634 || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
5636 int bitsize;
5637 REAL_VALUE_TYPE offset;
5638 rtx limit;
5639 rtx_code_label *lab1, *lab2;
5640 rtx_insn *insn;
5642 bitsize = GET_MODE_PRECISION (to_mode);
5643 real_2expN (&offset, bitsize - 1, fmode);
5644 limit = const_double_from_real_value (offset, fmode);
5645 lab1 = gen_label_rtx ();
5646 lab2 = gen_label_rtx ();
5648 if (fmode != GET_MODE (from))
5649 from = convert_to_mode (fmode, from, 0);
5651 /* See if we need to do the subtraction. */
5652 do_pending_stack_adjust ();
5653 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
5654 GET_MODE (from), 0, lab1);
5656 /* If not, do the signed "fix" and branch around fixup code. */
5657 expand_fix (to, from, 0);
5658 emit_jump_insn (targetm.gen_jump (lab2));
5659 emit_barrier ();
5661 /* Otherwise, subtract 2**(N-1), convert to signed number,
5662 then add 2**(N-1). Do the addition using XOR since this
5663 will often generate better code. */
5664 emit_label (lab1);
5665 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5666 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5667 expand_fix (to, target, 0);
5668 target = expand_binop (to_mode, xor_optab, to,
5669 gen_int_mode
5670 (HOST_WIDE_INT_1 << (bitsize - 1),
5671 to_mode),
5672 to, 1, OPTAB_LIB_WIDEN);
5674 if (target != to)
5675 emit_move_insn (to, target);
5677 emit_label (lab2);
5679 if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
5681 /* Make a place for a REG_NOTE and add it. */
5682 insn = emit_move_insn (to, to);
5683 set_dst_reg_note (insn, REG_EQUAL,
5684 gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
5685 copy_rtx (from)),
5686 to);
5689 return;
5693 /* We can't do it with an insn, so use a library call. But first ensure
5694 that the mode of TO is at least as wide as SImode, since those are the
5695 only library calls we know about. */
5697 if (is_narrower_int_mode (GET_MODE (to), SImode))
5699 target = gen_reg_rtx (SImode);
5701 expand_fix (target, from, unsignedp);
5703 else
5705 rtx_insn *insns;
5706 rtx value;
5707 rtx libfunc;
5709 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5710 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5711 gcc_assert (libfunc);
5713 start_sequence ();
5715 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5716 GET_MODE (to), from, GET_MODE (from));
5717 insns = get_insns ();
5718 end_sequence ();
5720 emit_libcall_block (insns, target, value,
5721 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5722 GET_MODE (to), from));
5725 if (target != to)
5727 if (GET_MODE (to) == GET_MODE (target))
5728 emit_move_insn (to, target);
5729 else
5730 convert_move (to, target, 0);
5735 /* Promote integer arguments for a libcall if necessary.
5736 emit_library_call_value cannot do the promotion because it does not
5737 know if it should do a signed or unsigned promotion. This is because
5738 there are no tree types defined for libcalls. */
5740 static rtx
5741 prepare_libcall_arg (rtx arg, int uintp)
5743 scalar_int_mode mode;
5744 machine_mode arg_mode;
5745 if (is_a <scalar_int_mode> (GET_MODE (arg), &mode))
5747 /* If we need to promote the integer function argument we need to do
5748 it here instead of inside emit_library_call_value because in
5749 emit_library_call_value we don't know if we should do a signed or
5750 unsigned promotion. */
5752 int unsigned_p = 0;
5753 arg_mode = promote_function_mode (NULL_TREE, mode,
5754 &unsigned_p, NULL_TREE, 0);
5755 if (arg_mode != mode)
5756 return convert_to_mode (arg_mode, arg, uintp);
5758 return arg;
5761 /* Generate code to convert FROM or TO a fixed-point.
5762 If UINTP is true, either TO or FROM is an unsigned integer.
5763 If SATP is true, we need to saturate the result. */
5765 void
5766 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5768 machine_mode to_mode = GET_MODE (to);
5769 machine_mode from_mode = GET_MODE (from);
5770 convert_optab tab;
5771 enum rtx_code this_code;
5772 enum insn_code code;
5773 rtx_insn *insns;
5774 rtx value;
5775 rtx libfunc;
5777 if (to_mode == from_mode)
5779 emit_move_insn (to, from);
5780 return;
5783 if (uintp)
5785 tab = satp ? satfractuns_optab : fractuns_optab;
5786 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5788 else
5790 tab = satp ? satfract_optab : fract_optab;
5791 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5793 code = convert_optab_handler (tab, to_mode, from_mode);
5794 if (code != CODE_FOR_nothing)
5796 emit_unop_insn (code, to, from, this_code);
5797 return;
5800 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5801 gcc_assert (libfunc);
5803 from = prepare_libcall_arg (from, uintp);
5804 from_mode = GET_MODE (from);
5806 start_sequence ();
5807 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5808 from, from_mode);
5809 insns = get_insns ();
5810 end_sequence ();
5812 emit_libcall_block (insns, to, value,
5813 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5816 /* Generate code to convert FROM to fixed point and store in TO. FROM
5817 must be floating point, TO must be signed. Use the conversion optab
5818 TAB to do the conversion. */
5820 bool
5821 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5823 enum insn_code icode;
5824 rtx target = to;
5825 machine_mode fmode, imode;
5827 /* We first try to find a pair of modes, one real and one integer, at
5828 least as wide as FROM and TO, respectively, in which we can open-code
5829 this conversion. If the integer mode is wider than the mode of TO,
5830 we can do the conversion either signed or unsigned. */
5832 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5833 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5835 icode = convert_optab_handler (tab, imode, fmode,
5836 insn_optimization_type ());
5837 if (icode != CODE_FOR_nothing)
5839 rtx_insn *last = get_last_insn ();
5840 if (fmode != GET_MODE (from))
5841 from = convert_to_mode (fmode, from, 0);
5843 if (imode != GET_MODE (to))
5844 target = gen_reg_rtx (imode);
5846 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5848 delete_insns_since (last);
5849 continue;
5851 if (target != to)
5852 convert_move (to, target, 0);
5853 return true;
5857 return false;
5860 /* Report whether we have an instruction to perform the operation
5861 specified by CODE on operands of mode MODE. */
5863 have_insn_for (enum rtx_code code, machine_mode mode)
5865 return (code_to_optab (code)
5866 && (optab_handler (code_to_optab (code), mode)
5867 != CODE_FOR_nothing));
5870 /* Print information about the current contents of the optabs on
5871 STDERR. */
5873 DEBUG_FUNCTION void
5874 debug_optab_libfuncs (void)
5876 int i, j, k;
5878 /* Dump the arithmetic optabs. */
5879 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5880 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5882 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5883 if (l)
5885 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5886 fprintf (stderr, "%s\t%s:\t%s\n",
5887 GET_RTX_NAME (optab_to_code ((optab) i)),
5888 GET_MODE_NAME (j),
5889 XSTR (l, 0));
5893 /* Dump the conversion optabs. */
5894 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5895 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5896 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5898 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5899 (machine_mode) k);
5900 if (l)
5902 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5903 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5904 GET_RTX_NAME (optab_to_code ((optab) i)),
5905 GET_MODE_NAME (j),
5906 GET_MODE_NAME (k),
5907 XSTR (l, 0));
5912 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5913 CODE. Return 0 on failure. */
5915 rtx_insn *
5916 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5918 machine_mode mode = GET_MODE (op1);
5919 enum insn_code icode;
5920 rtx_insn *insn;
5921 rtx trap_rtx;
5923 if (mode == VOIDmode)
5924 return 0;
5926 icode = optab_handler (ctrap_optab, mode);
5927 if (icode == CODE_FOR_nothing)
5928 return 0;
5930 /* Some targets only accept a zero trap code. */
5931 if (!insn_operand_matches (icode, 3, tcode))
5932 return 0;
5934 do_pending_stack_adjust ();
5935 start_sequence ();
5936 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5937 &trap_rtx, &mode);
5938 if (!trap_rtx)
5939 insn = NULL;
5940 else
5941 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5942 tcode);
5944 /* If that failed, then give up. */
5945 if (insn == 0)
5947 end_sequence ();
5948 return 0;
5951 emit_insn (insn);
5952 insn = get_insns ();
5953 end_sequence ();
5954 return insn;
5957 /* Return rtx code for TCODE or UNKNOWN. Use UNSIGNEDP to select signed
5958 or unsigned operation code. */
5960 enum rtx_code
5961 get_rtx_code_1 (enum tree_code tcode, bool unsignedp)
5963 enum rtx_code code;
5964 switch (tcode)
5966 case EQ_EXPR:
5967 code = EQ;
5968 break;
5969 case NE_EXPR:
5970 code = NE;
5971 break;
5972 case LT_EXPR:
5973 code = unsignedp ? LTU : LT;
5974 break;
5975 case LE_EXPR:
5976 code = unsignedp ? LEU : LE;
5977 break;
5978 case GT_EXPR:
5979 code = unsignedp ? GTU : GT;
5980 break;
5981 case GE_EXPR:
5982 code = unsignedp ? GEU : GE;
5983 break;
5985 case UNORDERED_EXPR:
5986 code = UNORDERED;
5987 break;
5988 case ORDERED_EXPR:
5989 code = ORDERED;
5990 break;
5991 case UNLT_EXPR:
5992 code = UNLT;
5993 break;
5994 case UNLE_EXPR:
5995 code = UNLE;
5996 break;
5997 case UNGT_EXPR:
5998 code = UNGT;
5999 break;
6000 case UNGE_EXPR:
6001 code = UNGE;
6002 break;
6003 case UNEQ_EXPR:
6004 code = UNEQ;
6005 break;
6006 case LTGT_EXPR:
6007 code = LTGT;
6008 break;
6010 case BIT_AND_EXPR:
6011 code = AND;
6012 break;
6014 case BIT_IOR_EXPR:
6015 code = IOR;
6016 break;
6018 default:
6019 code = UNKNOWN;
6020 break;
6022 return code;
6025 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6026 or unsigned operation code. */
6028 enum rtx_code
6029 get_rtx_code (enum tree_code tcode, bool unsignedp)
6031 enum rtx_code code = get_rtx_code_1 (tcode, unsignedp);
6032 gcc_assert (code != UNKNOWN);
6033 return code;
6036 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
6037 select signed or unsigned operators. OPNO holds the index of the
6038 first comparison operand for insn ICODE. Do not generate the
6039 compare instruction itself. */
6042 vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
6043 tree t_op0, tree t_op1, bool unsignedp,
6044 enum insn_code icode, unsigned int opno)
6046 class expand_operand ops[2];
6047 rtx rtx_op0, rtx_op1;
6048 machine_mode m0, m1;
6049 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
6051 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
6053 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
6054 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
6055 cases, use the original mode. */
6056 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6057 EXPAND_STACK_PARM);
6058 m0 = GET_MODE (rtx_op0);
6059 if (m0 == VOIDmode)
6060 m0 = TYPE_MODE (TREE_TYPE (t_op0));
6062 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6063 EXPAND_STACK_PARM);
6064 m1 = GET_MODE (rtx_op1);
6065 if (m1 == VOIDmode)
6066 m1 = TYPE_MODE (TREE_TYPE (t_op1));
6068 create_input_operand (&ops[0], rtx_op0, m0);
6069 create_input_operand (&ops[1], rtx_op1, m1);
6070 if (!maybe_legitimize_operands (icode, opno, 2, ops))
6071 gcc_unreachable ();
6072 return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
6075 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
6076 the first vec_perm operand, assuming the second operand (for left shift
6077 first operand) is a constant vector of zeros. Return the shift distance
6078 in bits if so, or NULL_RTX if the vec_perm is not a shift. MODE is the
6079 mode of the value being shifted. SHIFT_OPTAB is vec_shr_optab for right
6080 shift or vec_shl_optab for left shift. */
6081 static rtx
6082 shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel,
6083 optab shift_optab)
6085 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
6086 poly_int64 first = sel[0];
6087 if (maybe_ge (sel[0], GET_MODE_NUNITS (mode)))
6088 return NULL_RTX;
6090 if (shift_optab == vec_shl_optab)
6092 unsigned int nelt;
6093 if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
6094 return NULL_RTX;
6095 unsigned firstidx = 0;
6096 for (unsigned int i = 0; i < nelt; i++)
6098 if (known_eq (sel[i], nelt))
6100 if (i == 0 || firstidx)
6101 return NULL_RTX;
6102 firstidx = i;
6104 else if (firstidx
6105 ? maybe_ne (sel[i], nelt + i - firstidx)
6106 : maybe_ge (sel[i], nelt))
6107 return NULL_RTX;
6110 if (firstidx == 0)
6111 return NULL_RTX;
6112 first = firstidx;
6114 else if (!sel.series_p (0, 1, first, 1))
6116 unsigned int nelt;
6117 if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
6118 return NULL_RTX;
6119 for (unsigned int i = 1; i < nelt; i++)
6121 poly_int64 expected = i + first;
6122 /* Indices into the second vector are all equivalent. */
6123 if (maybe_lt (sel[i], nelt)
6124 ? maybe_ne (sel[i], expected)
6125 : maybe_lt (expected, nelt))
6126 return NULL_RTX;
6130 return gen_int_shift_amount (mode, first * bitsize);
6133 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn. */
6135 static rtx
6136 expand_vec_perm_1 (enum insn_code icode, rtx target,
6137 rtx v0, rtx v1, rtx sel)
6139 machine_mode tmode = GET_MODE (target);
6140 machine_mode smode = GET_MODE (sel);
6141 class expand_operand ops[4];
6143 gcc_assert (GET_MODE_CLASS (smode) == MODE_VECTOR_INT
6144 || related_int_vector_mode (tmode).require () == smode);
6145 create_output_operand (&ops[0], target, tmode);
6146 create_input_operand (&ops[3], sel, smode);
6148 /* Make an effort to preserve v0 == v1. The target expander is able to
6149 rely on this to determine if we're permuting a single input operand. */
6150 if (rtx_equal_p (v0, v1))
6152 if (!insn_operand_matches (icode, 1, v0))
6153 v0 = force_reg (tmode, v0);
6154 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
6155 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
6157 create_fixed_operand (&ops[1], v0);
6158 create_fixed_operand (&ops[2], v0);
6160 else
6162 create_input_operand (&ops[1], v0, tmode);
6163 create_input_operand (&ops[2], v1, tmode);
6166 if (maybe_expand_insn (icode, 4, ops))
6167 return ops[0].value;
6168 return NULL_RTX;
6171 /* Implement a permutation of vectors v0 and v1 using the permutation
6172 vector in SEL and return the result. Use TARGET to hold the result
6173 if nonnull and convenient.
6175 MODE is the mode of the vectors being permuted (V0 and V1). SEL_MODE
6176 is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
6177 to have a particular mode. */
6180 expand_vec_perm_const (machine_mode mode, rtx v0, rtx v1,
6181 const vec_perm_builder &sel, machine_mode sel_mode,
6182 rtx target)
6184 if (!target || !register_operand (target, mode))
6185 target = gen_reg_rtx (mode);
6187 /* Set QIMODE to a different vector mode with byte elements.
6188 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6189 machine_mode qimode;
6190 if (!qimode_for_vec_perm (mode).exists (&qimode))
6191 qimode = VOIDmode;
6193 rtx_insn *last = get_last_insn ();
6195 bool single_arg_p = rtx_equal_p (v0, v1);
6196 /* Always specify two input vectors here and leave the target to handle
6197 cases in which the inputs are equal. Not all backends can cope with
6198 the single-input representation when testing for a double-input
6199 target instruction. */
6200 vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode));
6202 /* See if this can be handled with a vec_shr or vec_shl. We only do this
6203 if the second (for vec_shr) or first (for vec_shl) vector is all
6204 zeroes. */
6205 insn_code shift_code = CODE_FOR_nothing;
6206 insn_code shift_code_qi = CODE_FOR_nothing;
6207 optab shift_optab = unknown_optab;
6208 rtx v2 = v0;
6209 if (v1 == CONST0_RTX (GET_MODE (v1)))
6210 shift_optab = vec_shr_optab;
6211 else if (v0 == CONST0_RTX (GET_MODE (v0)))
6213 shift_optab = vec_shl_optab;
6214 v2 = v1;
6216 if (shift_optab != unknown_optab)
6218 shift_code = optab_handler (shift_optab, mode);
6219 shift_code_qi = ((qimode != VOIDmode && qimode != mode)
6220 ? optab_handler (shift_optab, qimode)
6221 : CODE_FOR_nothing);
6223 if (shift_code != CODE_FOR_nothing || shift_code_qi != CODE_FOR_nothing)
6225 rtx shift_amt = shift_amt_for_vec_perm_mask (mode, indices, shift_optab);
6226 if (shift_amt)
6228 class expand_operand ops[3];
6229 if (shift_amt == const0_rtx)
6230 return v2;
6231 if (shift_code != CODE_FOR_nothing)
6233 create_output_operand (&ops[0], target, mode);
6234 create_input_operand (&ops[1], v2, mode);
6235 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
6236 if (maybe_expand_insn (shift_code, 3, ops))
6237 return ops[0].value;
6239 if (shift_code_qi != CODE_FOR_nothing)
6241 rtx tmp = gen_reg_rtx (qimode);
6242 create_output_operand (&ops[0], tmp, qimode);
6243 create_input_operand (&ops[1], gen_lowpart (qimode, v2), qimode);
6244 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
6245 if (maybe_expand_insn (shift_code_qi, 3, ops))
6246 return gen_lowpart (mode, ops[0].value);
6251 if (targetm.vectorize.vec_perm_const != NULL)
6253 if (single_arg_p)
6254 v1 = v0;
6256 gcc_checking_assert (GET_MODE (v0) == GET_MODE (v1));
6257 machine_mode op_mode = GET_MODE (v0);
6258 if (targetm.vectorize.vec_perm_const (mode, op_mode, target, v0, v1,
6259 indices))
6260 return target;
6263 /* Fall back to a constant byte-based permutation. */
6264 vec_perm_indices qimode_indices;
6265 rtx target_qi = NULL_RTX, v0_qi = NULL_RTX, v1_qi = NULL_RTX;
6266 if (qimode != VOIDmode)
6268 qimode_indices.new_expanded_vector (indices, GET_MODE_UNIT_SIZE (mode));
6269 target_qi = gen_reg_rtx (qimode);
6270 v0_qi = gen_lowpart (qimode, v0);
6271 v1_qi = gen_lowpart (qimode, v1);
6272 if (targetm.vectorize.vec_perm_const != NULL
6273 && targetm.vectorize.vec_perm_const (qimode, qimode, target_qi, v0_qi,
6274 v1_qi, qimode_indices))
6275 return gen_lowpart (mode, target_qi);
6278 v0 = force_reg (mode, v0);
6279 if (single_arg_p)
6280 v1 = v0;
6281 v1 = force_reg (mode, v1);
6283 /* Otherwise expand as a fully variable permuation. */
6285 /* The optabs are only defined for selectors with the same width
6286 as the values being permuted. */
6287 machine_mode required_sel_mode;
6288 if (!related_int_vector_mode (mode).exists (&required_sel_mode))
6290 delete_insns_since (last);
6291 return NULL_RTX;
6294 /* We know that it is semantically valid to treat SEL as having SEL_MODE.
6295 If that isn't the mode we want then we need to prove that using
6296 REQUIRED_SEL_MODE is OK. */
6297 if (sel_mode != required_sel_mode)
6299 if (!selector_fits_mode_p (required_sel_mode, indices))
6301 delete_insns_since (last);
6302 return NULL_RTX;
6304 sel_mode = required_sel_mode;
6307 insn_code icode = direct_optab_handler (vec_perm_optab, mode);
6308 if (icode != CODE_FOR_nothing)
6310 rtx sel_rtx = vec_perm_indices_to_rtx (sel_mode, indices);
6311 rtx tmp = expand_vec_perm_1 (icode, target, v0, v1, sel_rtx);
6312 if (tmp)
6313 return tmp;
6316 if (qimode != VOIDmode
6317 && selector_fits_mode_p (qimode, qimode_indices))
6319 icode = direct_optab_handler (vec_perm_optab, qimode);
6320 if (icode != CODE_FOR_nothing)
6322 rtx sel_qi = vec_perm_indices_to_rtx (qimode, qimode_indices);
6323 rtx tmp = expand_vec_perm_1 (icode, target_qi, v0_qi, v1_qi, sel_qi);
6324 if (tmp)
6325 return gen_lowpart (mode, tmp);
6329 delete_insns_since (last);
6330 return NULL_RTX;
6333 /* Implement a permutation of vectors v0 and v1 using the permutation
6334 vector in SEL and return the result. Use TARGET to hold the result
6335 if nonnull and convenient.
6337 MODE is the mode of the vectors being permuted (V0 and V1).
6338 SEL must have the integer equivalent of MODE and is known to be
6339 unsuitable for permutes with a constant permutation vector. */
6342 expand_vec_perm_var (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
6344 enum insn_code icode;
6345 unsigned int i, u;
6346 rtx tmp, sel_qi;
6348 u = GET_MODE_UNIT_SIZE (mode);
6350 if (!target || GET_MODE (target) != mode)
6351 target = gen_reg_rtx (mode);
6353 icode = direct_optab_handler (vec_perm_optab, mode);
6354 if (icode != CODE_FOR_nothing)
6356 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6357 if (tmp)
6358 return tmp;
6361 /* As a special case to aid several targets, lower the element-based
6362 permutation to a byte-based permutation and try again. */
6363 machine_mode qimode;
6364 if (!qimode_for_vec_perm (mode).exists (&qimode)
6365 || maybe_gt (GET_MODE_NUNITS (qimode), GET_MODE_MASK (QImode) + 1))
6366 return NULL_RTX;
6367 icode = direct_optab_handler (vec_perm_optab, qimode);
6368 if (icode == CODE_FOR_nothing)
6369 return NULL_RTX;
6371 /* Multiply each element by its byte size. */
6372 machine_mode selmode = GET_MODE (sel);
6373 if (u == 2)
6374 sel = expand_simple_binop (selmode, PLUS, sel, sel,
6375 NULL, 0, OPTAB_DIRECT);
6376 else
6377 sel = expand_simple_binop (selmode, ASHIFT, sel,
6378 gen_int_shift_amount (selmode, exact_log2 (u)),
6379 NULL, 0, OPTAB_DIRECT);
6380 gcc_assert (sel != NULL);
6382 /* Broadcast the low byte each element into each of its bytes.
6383 The encoding has U interleaved stepped patterns, one for each
6384 byte of an element. */
6385 vec_perm_builder const_sel (GET_MODE_SIZE (mode), u, 3);
6386 unsigned int low_byte_in_u = BYTES_BIG_ENDIAN ? u - 1 : 0;
6387 for (i = 0; i < 3; ++i)
6388 for (unsigned int j = 0; j < u; ++j)
6389 const_sel.quick_push (i * u + low_byte_in_u);
6390 sel = gen_lowpart (qimode, sel);
6391 sel = expand_vec_perm_const (qimode, sel, sel, const_sel, qimode, NULL);
6392 gcc_assert (sel != NULL);
6394 /* Add the byte offset to each byte element. */
6395 /* Note that the definition of the indicies here is memory ordering,
6396 so there should be no difference between big and little endian. */
6397 rtx_vector_builder byte_indices (qimode, u, 1);
6398 for (i = 0; i < u; ++i)
6399 byte_indices.quick_push (GEN_INT (i));
6400 tmp = byte_indices.build ();
6401 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
6402 sel, 0, OPTAB_DIRECT);
6403 gcc_assert (sel_qi != NULL);
6405 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
6406 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
6407 gen_lowpart (qimode, v1), sel_qi);
6408 if (tmp)
6409 tmp = gen_lowpart (mode, tmp);
6410 return tmp;
6413 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
6414 Use TARGET for the result if nonnull and convenient. */
6417 expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
6419 class expand_operand ops[3];
6420 enum insn_code icode;
6421 machine_mode emode = GET_MODE_INNER (vmode);
6423 icode = direct_optab_handler (vec_series_optab, vmode);
6424 gcc_assert (icode != CODE_FOR_nothing);
6426 create_output_operand (&ops[0], target, vmode);
6427 create_input_operand (&ops[1], op0, emode);
6428 create_input_operand (&ops[2], op1, emode);
6430 expand_insn (icode, 3, ops);
6431 return ops[0].value;
6434 /* Generate insns for a vector comparison into a mask. */
6437 expand_vec_cmp_expr (tree type, tree exp, rtx target)
6439 class expand_operand ops[4];
6440 enum insn_code icode;
6441 rtx comparison;
6442 machine_mode mask_mode = TYPE_MODE (type);
6443 machine_mode vmode;
6444 bool unsignedp;
6445 tree op0a, op0b;
6446 enum tree_code tcode;
6448 op0a = TREE_OPERAND (exp, 0);
6449 op0b = TREE_OPERAND (exp, 1);
6450 tcode = TREE_CODE (exp);
6452 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
6453 vmode = TYPE_MODE (TREE_TYPE (op0a));
6455 icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
6456 if (icode == CODE_FOR_nothing)
6458 if (tcode == EQ_EXPR || tcode == NE_EXPR)
6459 icode = get_vec_cmp_eq_icode (vmode, mask_mode);
6460 if (icode == CODE_FOR_nothing)
6461 return 0;
6464 comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
6465 unsignedp, icode, 2);
6466 create_output_operand (&ops[0], target, mask_mode);
6467 create_fixed_operand (&ops[1], comparison);
6468 create_fixed_operand (&ops[2], XEXP (comparison, 0));
6469 create_fixed_operand (&ops[3], XEXP (comparison, 1));
6470 expand_insn (icode, 4, ops);
6471 return ops[0].value;
6474 /* Expand a highpart multiply. */
6477 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
6478 rtx target, bool uns_p)
6480 class expand_operand eops[3];
6481 enum insn_code icode;
6482 int method, i;
6483 machine_mode wmode;
6484 rtx m1, m2;
6485 optab tab1, tab2;
6487 method = can_mult_highpart_p (mode, uns_p);
6488 switch (method)
6490 case 0:
6491 return NULL_RTX;
6492 case 1:
6493 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
6494 return expand_binop (mode, tab1, op0, op1, target, uns_p,
6495 OPTAB_LIB_WIDEN);
6496 case 2:
6497 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6498 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6499 break;
6500 case 3:
6501 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6502 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6503 if (BYTES_BIG_ENDIAN)
6504 std::swap (tab1, tab2);
6505 break;
6506 default:
6507 gcc_unreachable ();
6510 icode = optab_handler (tab1, mode);
6511 wmode = insn_data[icode].operand[0].mode;
6512 gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode),
6513 GET_MODE_NUNITS (mode)));
6514 gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode), GET_MODE_SIZE (mode)));
6516 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6517 create_input_operand (&eops[1], op0, mode);
6518 create_input_operand (&eops[2], op1, mode);
6519 expand_insn (icode, 3, eops);
6520 m1 = gen_lowpart (mode, eops[0].value);
6522 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6523 create_input_operand (&eops[1], op0, mode);
6524 create_input_operand (&eops[2], op1, mode);
6525 expand_insn (optab_handler (tab2, mode), 3, eops);
6526 m2 = gen_lowpart (mode, eops[0].value);
6528 vec_perm_builder sel;
6529 if (method == 2)
6531 /* The encoding has 2 interleaved stepped patterns. */
6532 sel.new_vector (GET_MODE_NUNITS (mode), 2, 3);
6533 for (i = 0; i < 6; ++i)
6534 sel.quick_push (!BYTES_BIG_ENDIAN + (i & ~1)
6535 + ((i & 1) ? GET_MODE_NUNITS (mode) : 0));
6537 else
6539 /* The encoding has a single interleaved stepped pattern. */
6540 sel.new_vector (GET_MODE_NUNITS (mode), 1, 3);
6541 for (i = 0; i < 3; ++i)
6542 sel.quick_push (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
6545 return expand_vec_perm_const (mode, m1, m2, sel, BLKmode, target);
6548 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6549 pattern. */
6551 static void
6552 find_cc_set (rtx x, const_rtx pat, void *data)
6554 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
6555 && GET_CODE (pat) == SET)
6557 rtx *p_cc_reg = (rtx *) data;
6558 gcc_assert (!*p_cc_reg);
6559 *p_cc_reg = x;
6563 /* This is a helper function for the other atomic operations. This function
6564 emits a loop that contains SEQ that iterates until a compare-and-swap
6565 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6566 a set of instructions that takes a value from OLD_REG as an input and
6567 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6568 set to the current contents of MEM. After SEQ, a compare-and-swap will
6569 attempt to update MEM with NEW_REG. The function returns true when the
6570 loop was generated successfully. */
6572 static bool
6573 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6575 machine_mode mode = GET_MODE (mem);
6576 rtx_code_label *label;
6577 rtx cmp_reg, success, oldval;
6579 /* The loop we want to generate looks like
6581 cmp_reg = mem;
6582 label:
6583 old_reg = cmp_reg;
6584 seq;
6585 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6586 if (success)
6587 goto label;
6589 Note that we only do the plain load from memory once. Subsequent
6590 iterations use the value loaded by the compare-and-swap pattern. */
6592 label = gen_label_rtx ();
6593 cmp_reg = gen_reg_rtx (mode);
6595 emit_move_insn (cmp_reg, mem);
6596 emit_label (label);
6597 emit_move_insn (old_reg, cmp_reg);
6598 if (seq)
6599 emit_insn (seq);
6601 success = NULL_RTX;
6602 oldval = cmp_reg;
6603 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
6604 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
6605 MEMMODEL_RELAXED))
6606 return false;
6608 if (oldval != cmp_reg)
6609 emit_move_insn (cmp_reg, oldval);
6611 /* Mark this jump predicted not taken. */
6612 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
6613 GET_MODE (success), 1, label,
6614 profile_probability::guessed_never ());
6615 return true;
6619 /* This function tries to emit an atomic_exchange intruction. VAL is written
6620 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6621 using TARGET if possible. */
6623 static rtx
6624 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6626 machine_mode mode = GET_MODE (mem);
6627 enum insn_code icode;
6629 /* If the target supports the exchange directly, great. */
6630 icode = direct_optab_handler (atomic_exchange_optab, mode);
6631 if (icode != CODE_FOR_nothing)
6633 class expand_operand ops[4];
6635 create_output_operand (&ops[0], target, mode);
6636 create_fixed_operand (&ops[1], mem);
6637 create_input_operand (&ops[2], val, mode);
6638 create_integer_operand (&ops[3], model);
6639 if (maybe_expand_insn (icode, 4, ops))
6640 return ops[0].value;
6643 return NULL_RTX;
6646 /* This function tries to implement an atomic exchange operation using
6647 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6648 The previous contents of *MEM are returned, using TARGET if possible.
6649 Since this instructionn is an acquire barrier only, stronger memory
6650 models may require additional barriers to be emitted. */
6652 static rtx
6653 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
6654 enum memmodel model)
6656 machine_mode mode = GET_MODE (mem);
6657 enum insn_code icode;
6658 rtx_insn *last_insn = get_last_insn ();
6660 icode = optab_handler (sync_lock_test_and_set_optab, mode);
6662 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
6663 exists, and the memory model is stronger than acquire, add a release
6664 barrier before the instruction. */
6666 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
6667 expand_mem_thread_fence (model);
6669 if (icode != CODE_FOR_nothing)
6671 class expand_operand ops[3];
6672 create_output_operand (&ops[0], target, mode);
6673 create_fixed_operand (&ops[1], mem);
6674 create_input_operand (&ops[2], val, mode);
6675 if (maybe_expand_insn (icode, 3, ops))
6676 return ops[0].value;
6679 /* If an external test-and-set libcall is provided, use that instead of
6680 any external compare-and-swap that we might get from the compare-and-
6681 swap-loop expansion later. */
6682 if (!can_compare_and_swap_p (mode, false))
6684 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
6685 if (libfunc != NULL)
6687 rtx addr;
6689 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6690 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6691 mode, addr, ptr_mode,
6692 val, mode);
6696 /* If the test_and_set can't be emitted, eliminate any barrier that might
6697 have been emitted. */
6698 delete_insns_since (last_insn);
6699 return NULL_RTX;
6702 /* This function tries to implement an atomic exchange operation using a
6703 compare_and_swap loop. VAL is written to *MEM. The previous contents of
6704 *MEM are returned, using TARGET if possible. No memory model is required
6705 since a compare_and_swap loop is seq-cst. */
6707 static rtx
6708 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
6710 machine_mode mode = GET_MODE (mem);
6712 if (can_compare_and_swap_p (mode, true))
6714 if (!target || !register_operand (target, mode))
6715 target = gen_reg_rtx (mode);
6716 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6717 return target;
6720 return NULL_RTX;
6723 /* This function tries to implement an atomic test-and-set operation
6724 using the atomic_test_and_set instruction pattern. A boolean value
6725 is returned from the operation, using TARGET if possible. */
6727 static rtx
6728 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6730 machine_mode pat_bool_mode;
6731 class expand_operand ops[3];
6733 if (!targetm.have_atomic_test_and_set ())
6734 return NULL_RTX;
6736 /* While we always get QImode from __atomic_test_and_set, we get
6737 other memory modes from __sync_lock_test_and_set. Note that we
6738 use no endian adjustment here. This matches the 4.6 behavior
6739 in the Sparc backend. */
6740 enum insn_code icode = targetm.code_for_atomic_test_and_set;
6741 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
6742 if (GET_MODE (mem) != QImode)
6743 mem = adjust_address_nv (mem, QImode, 0);
6745 pat_bool_mode = insn_data[icode].operand[0].mode;
6746 create_output_operand (&ops[0], target, pat_bool_mode);
6747 create_fixed_operand (&ops[1], mem);
6748 create_integer_operand (&ops[2], model);
6750 if (maybe_expand_insn (icode, 3, ops))
6751 return ops[0].value;
6752 return NULL_RTX;
6755 /* This function expands the legacy _sync_lock test_and_set operation which is
6756 generally an atomic exchange. Some limited targets only allow the
6757 constant 1 to be stored. This is an ACQUIRE operation.
6759 TARGET is an optional place to stick the return value.
6760 MEM is where VAL is stored. */
6763 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
6765 rtx ret;
6767 /* Try an atomic_exchange first. */
6768 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
6769 if (ret)
6770 return ret;
6772 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
6773 MEMMODEL_SYNC_ACQUIRE);
6774 if (ret)
6775 return ret;
6777 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6778 if (ret)
6779 return ret;
6781 /* If there are no other options, try atomic_test_and_set if the value
6782 being stored is 1. */
6783 if (val == const1_rtx)
6784 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
6786 return ret;
6789 /* This function expands the atomic test_and_set operation:
6790 atomically store a boolean TRUE into MEM and return the previous value.
6792 MEMMODEL is the memory model variant to use.
6793 TARGET is an optional place to stick the return value. */
6796 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6798 machine_mode mode = GET_MODE (mem);
6799 rtx ret, trueval, subtarget;
6801 ret = maybe_emit_atomic_test_and_set (target, mem, model);
6802 if (ret)
6803 return ret;
6805 /* Be binary compatible with non-default settings of trueval, and different
6806 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6807 another only has atomic-exchange. */
6808 if (targetm.atomic_test_and_set_trueval == 1)
6810 trueval = const1_rtx;
6811 subtarget = target ? target : gen_reg_rtx (mode);
6813 else
6815 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
6816 subtarget = gen_reg_rtx (mode);
6819 /* Try the atomic-exchange optab... */
6820 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
6822 /* ... then an atomic-compare-and-swap loop ... */
6823 if (!ret)
6824 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
6826 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6827 if (!ret)
6828 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
6830 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6831 things with the value 1. Thus we try again without trueval. */
6832 if (!ret && targetm.atomic_test_and_set_trueval != 1)
6833 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
6835 /* Failing all else, assume a single threaded environment and simply
6836 perform the operation. */
6837 if (!ret)
6839 /* If the result is ignored skip the move to target. */
6840 if (subtarget != const0_rtx)
6841 emit_move_insn (subtarget, mem);
6843 emit_move_insn (mem, trueval);
6844 ret = subtarget;
6847 /* Recall that have to return a boolean value; rectify if trueval
6848 is not exactly one. */
6849 if (targetm.atomic_test_and_set_trueval != 1)
6850 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
6852 return ret;
6855 /* This function expands the atomic exchange operation:
6856 atomically store VAL in MEM and return the previous value in MEM.
6858 MEMMODEL is the memory model variant to use.
6859 TARGET is an optional place to stick the return value. */
6862 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6864 machine_mode mode = GET_MODE (mem);
6865 rtx ret;
6867 /* If loads are not atomic for the required size and we are not called to
6868 provide a __sync builtin, do not do anything so that we stay consistent
6869 with atomic loads of the same size. */
6870 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6871 return NULL_RTX;
6873 ret = maybe_emit_atomic_exchange (target, mem, val, model);
6875 /* Next try a compare-and-swap loop for the exchange. */
6876 if (!ret)
6877 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6879 return ret;
6882 /* This function expands the atomic compare exchange operation:
6884 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6885 *PTARGET_OVAL is an optional place to store the old value from memory.
6886 Both target parameters may be NULL or const0_rtx to indicate that we do
6887 not care about that return value. Both target parameters are updated on
6888 success to the actual location of the corresponding result.
6890 MEMMODEL is the memory model variant to use.
6892 The return value of the function is true for success. */
6894 bool
6895 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
6896 rtx mem, rtx expected, rtx desired,
6897 bool is_weak, enum memmodel succ_model,
6898 enum memmodel fail_model)
6900 machine_mode mode = GET_MODE (mem);
6901 class expand_operand ops[8];
6902 enum insn_code icode;
6903 rtx target_oval, target_bool = NULL_RTX;
6904 rtx libfunc;
6906 /* If loads are not atomic for the required size and we are not called to
6907 provide a __sync builtin, do not do anything so that we stay consistent
6908 with atomic loads of the same size. */
6909 if (!can_atomic_load_p (mode) && !is_mm_sync (succ_model))
6910 return false;
6912 /* Load expected into a register for the compare and swap. */
6913 if (MEM_P (expected))
6914 expected = copy_to_reg (expected);
6916 /* Make sure we always have some place to put the return oldval.
6917 Further, make sure that place is distinct from the input expected,
6918 just in case we need that path down below. */
6919 if (ptarget_oval && *ptarget_oval == const0_rtx)
6920 ptarget_oval = NULL;
6922 if (ptarget_oval == NULL
6923 || (target_oval = *ptarget_oval) == NULL
6924 || reg_overlap_mentioned_p (expected, target_oval))
6925 target_oval = gen_reg_rtx (mode);
6927 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6928 if (icode != CODE_FOR_nothing)
6930 machine_mode bool_mode = insn_data[icode].operand[0].mode;
6932 if (ptarget_bool && *ptarget_bool == const0_rtx)
6933 ptarget_bool = NULL;
6935 /* Make sure we always have a place for the bool operand. */
6936 if (ptarget_bool == NULL
6937 || (target_bool = *ptarget_bool) == NULL
6938 || GET_MODE (target_bool) != bool_mode)
6939 target_bool = gen_reg_rtx (bool_mode);
6941 /* Emit the compare_and_swap. */
6942 create_output_operand (&ops[0], target_bool, bool_mode);
6943 create_output_operand (&ops[1], target_oval, mode);
6944 create_fixed_operand (&ops[2], mem);
6945 create_input_operand (&ops[3], expected, mode);
6946 create_input_operand (&ops[4], desired, mode);
6947 create_integer_operand (&ops[5], is_weak);
6948 create_integer_operand (&ops[6], succ_model);
6949 create_integer_operand (&ops[7], fail_model);
6950 if (maybe_expand_insn (icode, 8, ops))
6952 /* Return success/failure. */
6953 target_bool = ops[0].value;
6954 target_oval = ops[1].value;
6955 goto success;
6959 /* Otherwise fall back to the original __sync_val_compare_and_swap
6960 which is always seq-cst. */
6961 icode = optab_handler (sync_compare_and_swap_optab, mode);
6962 if (icode != CODE_FOR_nothing)
6964 rtx cc_reg;
6966 create_output_operand (&ops[0], target_oval, mode);
6967 create_fixed_operand (&ops[1], mem);
6968 create_input_operand (&ops[2], expected, mode);
6969 create_input_operand (&ops[3], desired, mode);
6970 if (!maybe_expand_insn (icode, 4, ops))
6971 return false;
6973 target_oval = ops[0].value;
6975 /* If the caller isn't interested in the boolean return value,
6976 skip the computation of it. */
6977 if (ptarget_bool == NULL)
6978 goto success;
6980 /* Otherwise, work out if the compare-and-swap succeeded. */
6981 cc_reg = NULL_RTX;
6982 if (have_insn_for (COMPARE, CCmode))
6983 note_stores (get_last_insn (), find_cc_set, &cc_reg);
6984 if (cc_reg)
6986 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6987 const0_rtx, VOIDmode, 0, 1);
6988 goto success;
6990 goto success_bool_from_val;
6993 /* Also check for library support for __sync_val_compare_and_swap. */
6994 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6995 if (libfunc != NULL)
6997 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6998 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6999 mode, addr, ptr_mode,
7000 expected, mode, desired, mode);
7001 emit_move_insn (target_oval, target);
7003 /* Compute the boolean return value only if requested. */
7004 if (ptarget_bool)
7005 goto success_bool_from_val;
7006 else
7007 goto success;
7010 /* Failure. */
7011 return false;
7013 success_bool_from_val:
7014 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
7015 expected, VOIDmode, 1, 1);
7016 success:
7017 /* Make sure that the oval output winds up where the caller asked. */
7018 if (ptarget_oval)
7019 *ptarget_oval = target_oval;
7020 if (ptarget_bool)
7021 *ptarget_bool = target_bool;
7022 return true;
7025 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
7027 static void
7028 expand_asm_memory_blockage (void)
7030 rtx asm_op, clob;
7032 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
7033 rtvec_alloc (0), rtvec_alloc (0),
7034 rtvec_alloc (0), UNKNOWN_LOCATION);
7035 MEM_VOLATILE_P (asm_op) = 1;
7037 clob = gen_rtx_SCRATCH (VOIDmode);
7038 clob = gen_rtx_MEM (BLKmode, clob);
7039 clob = gen_rtx_CLOBBER (VOIDmode, clob);
7041 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
7044 /* Do not propagate memory accesses across this point. */
7046 static void
7047 expand_memory_blockage (void)
7049 if (targetm.have_memory_blockage ())
7050 emit_insn (targetm.gen_memory_blockage ());
7051 else
7052 expand_asm_memory_blockage ();
7055 /* Generate asm volatile("" : : : "memory") as a memory blockage, at the
7056 same time clobbering the register set specified by REGS. */
7058 void
7059 expand_asm_reg_clobber_mem_blockage (HARD_REG_SET regs)
7061 rtx asm_op, clob_mem;
7063 unsigned int num_of_regs = 0;
7064 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7065 if (TEST_HARD_REG_BIT (regs, i))
7066 num_of_regs++;
7068 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
7069 rtvec_alloc (0), rtvec_alloc (0),
7070 rtvec_alloc (0), UNKNOWN_LOCATION);
7071 MEM_VOLATILE_P (asm_op) = 1;
7073 rtvec v = rtvec_alloc (num_of_regs + 2);
7075 clob_mem = gen_rtx_SCRATCH (VOIDmode);
7076 clob_mem = gen_rtx_MEM (BLKmode, clob_mem);
7077 clob_mem = gen_rtx_CLOBBER (VOIDmode, clob_mem);
7079 RTVEC_ELT (v, 0) = asm_op;
7080 RTVEC_ELT (v, 1) = clob_mem;
7082 if (num_of_regs > 0)
7084 unsigned int j = 2;
7085 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
7086 if (TEST_HARD_REG_BIT (regs, i))
7088 RTVEC_ELT (v, j) = gen_rtx_CLOBBER (VOIDmode, regno_reg_rtx[i]);
7089 j++;
7091 gcc_assert (j == (num_of_regs + 2));
7094 emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
7097 /* This routine will either emit the mem_thread_fence pattern or issue a
7098 sync_synchronize to generate a fence for memory model MEMMODEL. */
7100 void
7101 expand_mem_thread_fence (enum memmodel model)
7103 if (is_mm_relaxed (model))
7104 return;
7105 if (targetm.have_mem_thread_fence ())
7107 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
7108 expand_memory_blockage ();
7110 else if (targetm.have_memory_barrier ())
7111 emit_insn (targetm.gen_memory_barrier ());
7112 else if (synchronize_libfunc != NULL_RTX)
7113 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode);
7114 else
7115 expand_memory_blockage ();
7118 /* Emit a signal fence with given memory model. */
7120 void
7121 expand_mem_signal_fence (enum memmodel model)
7123 /* No machine barrier is required to implement a signal fence, but
7124 a compiler memory barrier must be issued, except for relaxed MM. */
7125 if (!is_mm_relaxed (model))
7126 expand_memory_blockage ();
7129 /* This function expands the atomic load operation:
7130 return the atomically loaded value in MEM.
7132 MEMMODEL is the memory model variant to use.
7133 TARGET is an option place to stick the return value. */
7136 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
7138 machine_mode mode = GET_MODE (mem);
7139 enum insn_code icode;
7141 /* If the target supports the load directly, great. */
7142 icode = direct_optab_handler (atomic_load_optab, mode);
7143 if (icode != CODE_FOR_nothing)
7145 class expand_operand ops[3];
7146 rtx_insn *last = get_last_insn ();
7147 if (is_mm_seq_cst (model))
7148 expand_memory_blockage ();
7150 create_output_operand (&ops[0], target, mode);
7151 create_fixed_operand (&ops[1], mem);
7152 create_integer_operand (&ops[2], model);
7153 if (maybe_expand_insn (icode, 3, ops))
7155 if (!is_mm_relaxed (model))
7156 expand_memory_blockage ();
7157 return ops[0].value;
7159 delete_insns_since (last);
7162 /* If the size of the object is greater than word size on this target,
7163 then we assume that a load will not be atomic. We could try to
7164 emulate a load with a compare-and-swap operation, but the store that
7165 doing this could result in would be incorrect if this is a volatile
7166 atomic load or targetting read-only-mapped memory. */
7167 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
7168 /* If there is no atomic load, leave the library call. */
7169 return NULL_RTX;
7171 /* Otherwise assume loads are atomic, and emit the proper barriers. */
7172 if (!target || target == const0_rtx)
7173 target = gen_reg_rtx (mode);
7175 /* For SEQ_CST, emit a barrier before the load. */
7176 if (is_mm_seq_cst (model))
7177 expand_mem_thread_fence (model);
7179 emit_move_insn (target, mem);
7181 /* Emit the appropriate barrier after the load. */
7182 expand_mem_thread_fence (model);
7184 return target;
7187 /* This function expands the atomic store operation:
7188 Atomically store VAL in MEM.
7189 MEMMODEL is the memory model variant to use.
7190 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7191 function returns const0_rtx if a pattern was emitted. */
7194 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
7196 machine_mode mode = GET_MODE (mem);
7197 enum insn_code icode;
7198 class expand_operand ops[3];
7200 /* If the target supports the store directly, great. */
7201 icode = direct_optab_handler (atomic_store_optab, mode);
7202 if (icode != CODE_FOR_nothing)
7204 rtx_insn *last = get_last_insn ();
7205 if (!is_mm_relaxed (model))
7206 expand_memory_blockage ();
7207 create_fixed_operand (&ops[0], mem);
7208 create_input_operand (&ops[1], val, mode);
7209 create_integer_operand (&ops[2], model);
7210 if (maybe_expand_insn (icode, 3, ops))
7212 if (is_mm_seq_cst (model))
7213 expand_memory_blockage ();
7214 return const0_rtx;
7216 delete_insns_since (last);
7219 /* If using __sync_lock_release is a viable alternative, try it.
7220 Note that this will not be set to true if we are expanding a generic
7221 __atomic_store_n. */
7222 if (use_release)
7224 icode = direct_optab_handler (sync_lock_release_optab, mode);
7225 if (icode != CODE_FOR_nothing)
7227 create_fixed_operand (&ops[0], mem);
7228 create_input_operand (&ops[1], const0_rtx, mode);
7229 if (maybe_expand_insn (icode, 2, ops))
7231 /* lock_release is only a release barrier. */
7232 if (is_mm_seq_cst (model))
7233 expand_mem_thread_fence (model);
7234 return const0_rtx;
7239 /* If the size of the object is greater than word size on this target,
7240 a default store will not be atomic. */
7241 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
7243 /* If loads are atomic or we are called to provide a __sync builtin,
7244 we can try a atomic_exchange and throw away the result. Otherwise,
7245 don't do anything so that we do not create an inconsistency between
7246 loads and stores. */
7247 if (can_atomic_load_p (mode) || is_mm_sync (model))
7249 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
7250 if (!target)
7251 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem,
7252 val);
7253 if (target)
7254 return const0_rtx;
7256 return NULL_RTX;
7259 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7260 expand_mem_thread_fence (model);
7262 emit_move_insn (mem, val);
7264 /* For SEQ_CST, also emit a barrier after the store. */
7265 if (is_mm_seq_cst (model))
7266 expand_mem_thread_fence (model);
7268 return const0_rtx;
7272 /* Structure containing the pointers and values required to process the
7273 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7275 struct atomic_op_functions
7277 direct_optab mem_fetch_before;
7278 direct_optab mem_fetch_after;
7279 direct_optab mem_no_result;
7280 optab fetch_before;
7281 optab fetch_after;
7282 direct_optab no_result;
7283 enum rtx_code reverse_code;
7287 /* Fill in structure pointed to by OP with the various optab entries for an
7288 operation of type CODE. */
7290 static void
7291 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
7293 gcc_assert (op!= NULL);
7295 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7296 in the source code during compilation, and the optab entries are not
7297 computable until runtime. Fill in the values at runtime. */
7298 switch (code)
7300 case PLUS:
7301 op->mem_fetch_before = atomic_fetch_add_optab;
7302 op->mem_fetch_after = atomic_add_fetch_optab;
7303 op->mem_no_result = atomic_add_optab;
7304 op->fetch_before = sync_old_add_optab;
7305 op->fetch_after = sync_new_add_optab;
7306 op->no_result = sync_add_optab;
7307 op->reverse_code = MINUS;
7308 break;
7309 case MINUS:
7310 op->mem_fetch_before = atomic_fetch_sub_optab;
7311 op->mem_fetch_after = atomic_sub_fetch_optab;
7312 op->mem_no_result = atomic_sub_optab;
7313 op->fetch_before = sync_old_sub_optab;
7314 op->fetch_after = sync_new_sub_optab;
7315 op->no_result = sync_sub_optab;
7316 op->reverse_code = PLUS;
7317 break;
7318 case XOR:
7319 op->mem_fetch_before = atomic_fetch_xor_optab;
7320 op->mem_fetch_after = atomic_xor_fetch_optab;
7321 op->mem_no_result = atomic_xor_optab;
7322 op->fetch_before = sync_old_xor_optab;
7323 op->fetch_after = sync_new_xor_optab;
7324 op->no_result = sync_xor_optab;
7325 op->reverse_code = XOR;
7326 break;
7327 case AND:
7328 op->mem_fetch_before = atomic_fetch_and_optab;
7329 op->mem_fetch_after = atomic_and_fetch_optab;
7330 op->mem_no_result = atomic_and_optab;
7331 op->fetch_before = sync_old_and_optab;
7332 op->fetch_after = sync_new_and_optab;
7333 op->no_result = sync_and_optab;
7334 op->reverse_code = UNKNOWN;
7335 break;
7336 case IOR:
7337 op->mem_fetch_before = atomic_fetch_or_optab;
7338 op->mem_fetch_after = atomic_or_fetch_optab;
7339 op->mem_no_result = atomic_or_optab;
7340 op->fetch_before = sync_old_ior_optab;
7341 op->fetch_after = sync_new_ior_optab;
7342 op->no_result = sync_ior_optab;
7343 op->reverse_code = UNKNOWN;
7344 break;
7345 case NOT:
7346 op->mem_fetch_before = atomic_fetch_nand_optab;
7347 op->mem_fetch_after = atomic_nand_fetch_optab;
7348 op->mem_no_result = atomic_nand_optab;
7349 op->fetch_before = sync_old_nand_optab;
7350 op->fetch_after = sync_new_nand_optab;
7351 op->no_result = sync_nand_optab;
7352 op->reverse_code = UNKNOWN;
7353 break;
7354 default:
7355 gcc_unreachable ();
7359 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7360 using memory order MODEL. If AFTER is true the operation needs to return
7361 the value of *MEM after the operation, otherwise the previous value.
7362 TARGET is an optional place to place the result. The result is unused if
7363 it is const0_rtx.
7364 Return the result if there is a better sequence, otherwise NULL_RTX. */
7366 static rtx
7367 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7368 enum memmodel model, bool after)
7370 /* If the value is prefetched, or not used, it may be possible to replace
7371 the sequence with a native exchange operation. */
7372 if (!after || target == const0_rtx)
7374 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7375 if (code == AND && val == const0_rtx)
7377 if (target == const0_rtx)
7378 target = gen_reg_rtx (GET_MODE (mem));
7379 return maybe_emit_atomic_exchange (target, mem, val, model);
7382 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7383 if (code == IOR && val == constm1_rtx)
7385 if (target == const0_rtx)
7386 target = gen_reg_rtx (GET_MODE (mem));
7387 return maybe_emit_atomic_exchange (target, mem, val, model);
7391 return NULL_RTX;
7394 /* Try to emit an instruction for a specific operation varaition.
7395 OPTAB contains the OP functions.
7396 TARGET is an optional place to return the result. const0_rtx means unused.
7397 MEM is the memory location to operate on.
7398 VAL is the value to use in the operation.
7399 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7400 MODEL is the memory model, if used.
7401 AFTER is true if the returned result is the value after the operation. */
7403 static rtx
7404 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
7405 rtx val, bool use_memmodel, enum memmodel model, bool after)
7407 machine_mode mode = GET_MODE (mem);
7408 class expand_operand ops[4];
7409 enum insn_code icode;
7410 int op_counter = 0;
7411 int num_ops;
7413 /* Check to see if there is a result returned. */
7414 if (target == const0_rtx)
7416 if (use_memmodel)
7418 icode = direct_optab_handler (optab->mem_no_result, mode);
7419 create_integer_operand (&ops[2], model);
7420 num_ops = 3;
7422 else
7424 icode = direct_optab_handler (optab->no_result, mode);
7425 num_ops = 2;
7428 /* Otherwise, we need to generate a result. */
7429 else
7431 if (use_memmodel)
7433 icode = direct_optab_handler (after ? optab->mem_fetch_after
7434 : optab->mem_fetch_before, mode);
7435 create_integer_operand (&ops[3], model);
7436 num_ops = 4;
7438 else
7440 icode = optab_handler (after ? optab->fetch_after
7441 : optab->fetch_before, mode);
7442 num_ops = 3;
7444 create_output_operand (&ops[op_counter++], target, mode);
7446 if (icode == CODE_FOR_nothing)
7447 return NULL_RTX;
7449 create_fixed_operand (&ops[op_counter++], mem);
7450 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7451 create_convert_operand_to (&ops[op_counter++], val, mode, true);
7453 if (maybe_expand_insn (icode, num_ops, ops))
7454 return (target == const0_rtx ? const0_rtx : ops[0].value);
7456 return NULL_RTX;
7460 /* This function expands an atomic fetch_OP or OP_fetch operation:
7461 TARGET is an option place to stick the return value. const0_rtx indicates
7462 the result is unused.
7463 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7464 CODE is the operation being performed (OP)
7465 MEMMODEL is the memory model variant to use.
7466 AFTER is true to return the result of the operation (OP_fetch).
7467 AFTER is false to return the value before the operation (fetch_OP).
7469 This function will *only* generate instructions if there is a direct
7470 optab. No compare and swap loops or libcalls will be generated. */
7472 static rtx
7473 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
7474 enum rtx_code code, enum memmodel model,
7475 bool after)
7477 machine_mode mode = GET_MODE (mem);
7478 struct atomic_op_functions optab;
7479 rtx result;
7480 bool unused_result = (target == const0_rtx);
7482 get_atomic_op_for_code (&optab, code);
7484 /* Check to see if there are any better instructions. */
7485 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
7486 if (result)
7487 return result;
7489 /* Check for the case where the result isn't used and try those patterns. */
7490 if (unused_result)
7492 /* Try the memory model variant first. */
7493 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
7494 if (result)
7495 return result;
7497 /* Next try the old style withuot a memory model. */
7498 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
7499 if (result)
7500 return result;
7502 /* There is no no-result pattern, so try patterns with a result. */
7503 target = NULL_RTX;
7506 /* Try the __atomic version. */
7507 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
7508 if (result)
7509 return result;
7511 /* Try the older __sync version. */
7512 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
7513 if (result)
7514 return result;
7516 /* If the fetch value can be calculated from the other variation of fetch,
7517 try that operation. */
7518 if (after || unused_result || optab.reverse_code != UNKNOWN)
7520 /* Try the __atomic version, then the older __sync version. */
7521 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
7522 if (!result)
7523 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
7525 if (result)
7527 /* If the result isn't used, no need to do compensation code. */
7528 if (unused_result)
7529 return result;
7531 /* Issue compensation code. Fetch_after == fetch_before OP val.
7532 Fetch_before == after REVERSE_OP val. */
7533 if (!after)
7534 code = optab.reverse_code;
7535 if (code == NOT)
7537 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
7538 true, OPTAB_LIB_WIDEN);
7539 result = expand_simple_unop (mode, NOT, result, target, true);
7541 else
7542 result = expand_simple_binop (mode, code, result, val, target,
7543 true, OPTAB_LIB_WIDEN);
7544 return result;
7548 /* No direct opcode can be generated. */
7549 return NULL_RTX;
7554 /* This function expands an atomic fetch_OP or OP_fetch operation:
7555 TARGET is an option place to stick the return value. const0_rtx indicates
7556 the result is unused.
7557 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7558 CODE is the operation being performed (OP)
7559 MEMMODEL is the memory model variant to use.
7560 AFTER is true to return the result of the operation (OP_fetch).
7561 AFTER is false to return the value before the operation (fetch_OP). */
7563 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7564 enum memmodel model, bool after)
7566 machine_mode mode = GET_MODE (mem);
7567 rtx result;
7568 bool unused_result = (target == const0_rtx);
7570 /* If loads are not atomic for the required size and we are not called to
7571 provide a __sync builtin, do not do anything so that we stay consistent
7572 with atomic loads of the same size. */
7573 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
7574 return NULL_RTX;
7576 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
7577 after);
7579 if (result)
7580 return result;
7582 /* Add/sub can be implemented by doing the reverse operation with -(val). */
7583 if (code == PLUS || code == MINUS)
7585 rtx tmp;
7586 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
7588 start_sequence ();
7589 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
7590 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
7591 model, after);
7592 if (result)
7594 /* PLUS worked so emit the insns and return. */
7595 tmp = get_insns ();
7596 end_sequence ();
7597 emit_insn (tmp);
7598 return result;
7601 /* PLUS did not work, so throw away the negation code and continue. */
7602 end_sequence ();
7605 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
7606 if (!can_compare_and_swap_p (mode, false))
7608 rtx libfunc;
7609 bool fixup = false;
7610 enum rtx_code orig_code = code;
7611 struct atomic_op_functions optab;
7613 get_atomic_op_for_code (&optab, code);
7614 libfunc = optab_libfunc (after ? optab.fetch_after
7615 : optab.fetch_before, mode);
7616 if (libfunc == NULL
7617 && (after || unused_result || optab.reverse_code != UNKNOWN))
7619 fixup = true;
7620 if (!after)
7621 code = optab.reverse_code;
7622 libfunc = optab_libfunc (after ? optab.fetch_before
7623 : optab.fetch_after, mode);
7625 if (libfunc != NULL)
7627 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7628 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
7629 addr, ptr_mode, val, mode);
7631 if (!unused_result && fixup)
7632 result = expand_simple_binop (mode, code, result, val, target,
7633 true, OPTAB_LIB_WIDEN);
7634 return result;
7637 /* We need the original code for any further attempts. */
7638 code = orig_code;
7641 /* If nothing else has succeeded, default to a compare and swap loop. */
7642 if (can_compare_and_swap_p (mode, true))
7644 rtx_insn *insn;
7645 rtx t0 = gen_reg_rtx (mode), t1;
7647 start_sequence ();
7649 /* If the result is used, get a register for it. */
7650 if (!unused_result)
7652 if (!target || !register_operand (target, mode))
7653 target = gen_reg_rtx (mode);
7654 /* If fetch_before, copy the value now. */
7655 if (!after)
7656 emit_move_insn (target, t0);
7658 else
7659 target = const0_rtx;
7661 t1 = t0;
7662 if (code == NOT)
7664 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7665 true, OPTAB_LIB_WIDEN);
7666 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7668 else
7669 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
7670 OPTAB_LIB_WIDEN);
7672 /* For after, copy the value now. */
7673 if (!unused_result && after)
7674 emit_move_insn (target, t1);
7675 insn = get_insns ();
7676 end_sequence ();
7678 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7679 return target;
7682 return NULL_RTX;
7685 /* Return true if OPERAND is suitable for operand number OPNO of
7686 instruction ICODE. */
7688 bool
7689 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
7691 return (!insn_data[(int) icode].operand[opno].predicate
7692 || (insn_data[(int) icode].operand[opno].predicate
7693 (operand, insn_data[(int) icode].operand[opno].mode)));
7696 /* TARGET is a target of a multiword operation that we are going to
7697 implement as a series of word-mode operations. Return true if
7698 TARGET is suitable for this purpose. */
7700 bool
7701 valid_multiword_target_p (rtx target)
7703 machine_mode mode;
7704 int i, size;
7706 mode = GET_MODE (target);
7707 if (!GET_MODE_SIZE (mode).is_constant (&size))
7708 return false;
7709 for (i = 0; i < size; i += UNITS_PER_WORD)
7710 if (!validate_subreg (word_mode, mode, target, i))
7711 return false;
7712 return true;
7715 /* Make OP describe an input operand that has value INTVAL and that has
7716 no inherent mode. This function should only be used for operands that
7717 are always expand-time constants. The backend may request that INTVAL
7718 be copied into a different kind of rtx, but it must specify the mode
7719 of that rtx if so. */
7721 void
7722 create_integer_operand (class expand_operand *op, poly_int64 intval)
7724 create_expand_operand (op, EXPAND_INTEGER,
7725 gen_int_mode (intval, MAX_MODE_INT),
7726 VOIDmode, false, intval);
7729 /* Like maybe_legitimize_operand, but do not change the code of the
7730 current rtx value. */
7732 static bool
7733 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
7734 class expand_operand *op)
7736 /* See if the operand matches in its current form. */
7737 if (insn_operand_matches (icode, opno, op->value))
7738 return true;
7740 /* If the operand is a memory whose address has no side effects,
7741 try forcing the address into a non-virtual pseudo register.
7742 The check for side effects is important because copy_to_mode_reg
7743 cannot handle things like auto-modified addresses. */
7744 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
7746 rtx addr, mem;
7748 mem = op->value;
7749 addr = XEXP (mem, 0);
7750 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
7751 && !side_effects_p (addr))
7753 rtx_insn *last;
7754 machine_mode mode;
7756 last = get_last_insn ();
7757 mode = get_address_mode (mem);
7758 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
7759 if (insn_operand_matches (icode, opno, mem))
7761 op->value = mem;
7762 return true;
7764 delete_insns_since (last);
7768 return false;
7771 /* Try to make OP match operand OPNO of instruction ICODE. Return true
7772 on success, storing the new operand value back in OP. */
7774 static bool
7775 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
7776 class expand_operand *op)
7778 machine_mode mode, imode, tmode;
7780 mode = op->mode;
7781 switch (op->type)
7783 case EXPAND_FIXED:
7785 temporary_volatile_ok v (true);
7786 return maybe_legitimize_operand_same_code (icode, opno, op);
7789 case EXPAND_OUTPUT:
7790 gcc_assert (mode != VOIDmode);
7791 if (op->value
7792 && op->value != const0_rtx
7793 && GET_MODE (op->value) == mode
7794 && maybe_legitimize_operand_same_code (icode, opno, op))
7795 return true;
7797 op->value = gen_reg_rtx (mode);
7798 op->target = 0;
7799 break;
7801 case EXPAND_INPUT:
7802 input:
7803 gcc_assert (mode != VOIDmode);
7804 gcc_assert (GET_MODE (op->value) == VOIDmode
7805 || GET_MODE (op->value) == mode);
7806 if (maybe_legitimize_operand_same_code (icode, opno, op))
7807 return true;
7809 op->value = copy_to_mode_reg (mode, op->value);
7810 break;
7812 case EXPAND_CONVERT_TO:
7813 gcc_assert (mode != VOIDmode);
7814 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
7815 goto input;
7817 case EXPAND_CONVERT_FROM:
7818 if (GET_MODE (op->value) != VOIDmode)
7819 mode = GET_MODE (op->value);
7820 else
7821 /* The caller must tell us what mode this value has. */
7822 gcc_assert (mode != VOIDmode);
7824 imode = insn_data[(int) icode].operand[opno].mode;
7825 tmode = (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode)
7826 ? GET_MODE_INNER (imode) : imode);
7827 if (tmode != VOIDmode && tmode != mode)
7829 op->value = convert_modes (tmode, mode, op->value, op->unsigned_p);
7830 mode = tmode;
7832 if (imode != VOIDmode && imode != mode)
7834 gcc_assert (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode));
7835 op->value = expand_vector_broadcast (imode, op->value);
7836 mode = imode;
7838 goto input;
7840 case EXPAND_ADDRESS:
7841 op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
7842 op->value);
7843 goto input;
7845 case EXPAND_INTEGER:
7846 mode = insn_data[(int) icode].operand[opno].mode;
7847 if (mode != VOIDmode
7848 && known_eq (trunc_int_for_mode (op->int_value, mode),
7849 op->int_value))
7851 op->value = gen_int_mode (op->int_value, mode);
7852 goto input;
7854 break;
7856 return insn_operand_matches (icode, opno, op->value);
7859 /* Make OP describe an input operand that should have the same value
7860 as VALUE, after any mode conversion that the target might request.
7861 TYPE is the type of VALUE. */
7863 void
7864 create_convert_operand_from_type (class expand_operand *op,
7865 rtx value, tree type)
7867 create_convert_operand_from (op, value, TYPE_MODE (type),
7868 TYPE_UNSIGNED (type));
7871 /* Return true if the requirements on operands OP1 and OP2 of instruction
7872 ICODE are similar enough for the result of legitimizing OP1 to be
7873 reusable for OP2. OPNO1 and OPNO2 are the operand numbers associated
7874 with OP1 and OP2 respectively. */
7876 static inline bool
7877 can_reuse_operands_p (enum insn_code icode,
7878 unsigned int opno1, unsigned int opno2,
7879 const class expand_operand *op1,
7880 const class expand_operand *op2)
7882 /* Check requirements that are common to all types. */
7883 if (op1->type != op2->type
7884 || op1->mode != op2->mode
7885 || (insn_data[(int) icode].operand[opno1].mode
7886 != insn_data[(int) icode].operand[opno2].mode))
7887 return false;
7889 /* Check the requirements for specific types. */
7890 switch (op1->type)
7892 case EXPAND_OUTPUT:
7893 /* Outputs must remain distinct. */
7894 return false;
7896 case EXPAND_FIXED:
7897 case EXPAND_INPUT:
7898 case EXPAND_ADDRESS:
7899 case EXPAND_INTEGER:
7900 return true;
7902 case EXPAND_CONVERT_TO:
7903 case EXPAND_CONVERT_FROM:
7904 return op1->unsigned_p == op2->unsigned_p;
7906 gcc_unreachable ();
7909 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7910 of instruction ICODE. Return true on success, leaving the new operand
7911 values in the OPS themselves. Emit no code on failure. */
7913 bool
7914 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
7915 unsigned int nops, class expand_operand *ops)
7917 rtx_insn *last = get_last_insn ();
7918 rtx *orig_values = XALLOCAVEC (rtx, nops);
7919 for (unsigned int i = 0; i < nops; i++)
7921 orig_values[i] = ops[i].value;
7923 /* First try reusing the result of an earlier legitimization.
7924 This avoids duplicate rtl and ensures that tied operands
7925 remain tied.
7927 This search is linear, but NOPS is bounded at compile time
7928 to a small number (current a single digit). */
7929 unsigned int j = 0;
7930 for (; j < i; ++j)
7931 if (can_reuse_operands_p (icode, opno + j, opno + i, &ops[j], &ops[i])
7932 && rtx_equal_p (orig_values[j], orig_values[i])
7933 && ops[j].value
7934 && insn_operand_matches (icode, opno + i, ops[j].value))
7936 ops[i].value = copy_rtx (ops[j].value);
7937 break;
7940 /* Otherwise try legitimizing the operand on its own. */
7941 if (j == i && !maybe_legitimize_operand (icode, opno + i, &ops[i]))
7943 delete_insns_since (last);
7944 return false;
7947 return true;
7950 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7951 as its operands. Return the instruction pattern on success,
7952 and emit any necessary set-up code. Return null and emit no
7953 code on failure. */
7955 rtx_insn *
7956 maybe_gen_insn (enum insn_code icode, unsigned int nops,
7957 class expand_operand *ops)
7959 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
7960 if (!maybe_legitimize_operands (icode, 0, nops, ops))
7961 return NULL;
7963 switch (nops)
7965 case 0:
7966 return GEN_FCN (icode) ();
7967 case 1:
7968 return GEN_FCN (icode) (ops[0].value);
7969 case 2:
7970 return GEN_FCN (icode) (ops[0].value, ops[1].value);
7971 case 3:
7972 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
7973 case 4:
7974 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7975 ops[3].value);
7976 case 5:
7977 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7978 ops[3].value, ops[4].value);
7979 case 6:
7980 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7981 ops[3].value, ops[4].value, ops[5].value);
7982 case 7:
7983 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7984 ops[3].value, ops[4].value, ops[5].value,
7985 ops[6].value);
7986 case 8:
7987 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7988 ops[3].value, ops[4].value, ops[5].value,
7989 ops[6].value, ops[7].value);
7990 case 9:
7991 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7992 ops[3].value, ops[4].value, ops[5].value,
7993 ops[6].value, ops[7].value, ops[8].value);
7995 gcc_unreachable ();
7998 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7999 as its operands. Return true on success and emit no code on failure. */
8001 bool
8002 maybe_expand_insn (enum insn_code icode, unsigned int nops,
8003 class expand_operand *ops)
8005 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
8006 if (pat)
8008 emit_insn (pat);
8009 return true;
8011 return false;
8014 /* Like maybe_expand_insn, but for jumps. */
8016 bool
8017 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
8018 class expand_operand *ops)
8020 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
8021 if (pat)
8023 emit_jump_insn (pat);
8024 return true;
8026 return false;
8029 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
8030 as its operands. */
8032 void
8033 expand_insn (enum insn_code icode, unsigned int nops,
8034 class expand_operand *ops)
8036 if (!maybe_expand_insn (icode, nops, ops))
8037 gcc_unreachable ();
8040 /* Like expand_insn, but for jumps. */
8042 void
8043 expand_jump_insn (enum insn_code icode, unsigned int nops,
8044 class expand_operand *ops)
8046 if (!maybe_expand_jump_insn (icode, nops, ops))
8047 gcc_unreachable ();