fix __builtin___clear_cache overrider fallout
[official-gcc.git] / gcc / optabs.c
blobbdc692bbc73503def6df9ced302a2cb880b01f56
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2020 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 /* Debug facility for use in GDB. */
56 void debug_optab_libfuncs (void);
58 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
59 the result of operation CODE applied to OP0 (and OP1 if it is a binary
60 operation). OP0_MODE is OP0's mode.
62 If the last insn does not set TARGET, don't do anything, but return 1.
64 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
65 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
66 try again, ensuring that TARGET is not one of the operands. */
68 static int
69 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0,
70 rtx op1, machine_mode op0_mode)
72 rtx_insn *last_insn;
73 rtx set;
74 rtx note;
76 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
78 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
79 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
80 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
81 && GET_RTX_CLASS (code) != RTX_COMPARE
82 && GET_RTX_CLASS (code) != RTX_UNARY)
83 return 1;
85 if (GET_CODE (target) == ZERO_EXTRACT)
86 return 1;
88 for (last_insn = insns;
89 NEXT_INSN (last_insn) != NULL_RTX;
90 last_insn = NEXT_INSN (last_insn))
93 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
94 a value changing in the insn, so the note would be invalid for CSE. */
95 if (reg_overlap_mentioned_p (target, op0)
96 || (op1 && reg_overlap_mentioned_p (target, op1)))
98 if (MEM_P (target)
99 && (rtx_equal_p (target, op0)
100 || (op1 && rtx_equal_p (target, op1))))
102 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
103 over expanding it as temp = MEM op X, MEM = temp. If the target
104 supports MEM = MEM op X instructions, it is sometimes too hard
105 to reconstruct that form later, especially if X is also a memory,
106 and due to multiple occurrences of addresses the address might
107 be forced into register unnecessarily.
108 Note that not emitting the REG_EQUIV note might inhibit
109 CSE in some cases. */
110 set = single_set (last_insn);
111 if (set
112 && GET_CODE (SET_SRC (set)) == code
113 && MEM_P (SET_DEST (set))
114 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
115 || (op1 && rtx_equal_p (SET_DEST (set),
116 XEXP (SET_SRC (set), 1)))))
117 return 1;
119 return 0;
122 set = set_for_reg_notes (last_insn);
123 if (set == NULL_RTX)
124 return 1;
126 if (! rtx_equal_p (SET_DEST (set), target)
127 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
128 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
129 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
130 return 1;
132 if (GET_RTX_CLASS (code) == RTX_UNARY)
133 switch (code)
135 case FFS:
136 case CLZ:
137 case CTZ:
138 case CLRSB:
139 case POPCOUNT:
140 case PARITY:
141 case BSWAP:
142 if (op0_mode != VOIDmode && GET_MODE (target) != op0_mode)
144 note = gen_rtx_fmt_e (code, op0_mode, copy_rtx (op0));
145 if (GET_MODE_UNIT_SIZE (op0_mode)
146 > GET_MODE_UNIT_SIZE (GET_MODE (target)))
147 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
148 note, op0_mode);
149 else
150 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
151 note, op0_mode);
152 break;
154 /* FALLTHRU */
155 default:
156 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
157 break;
159 else
160 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
162 set_unique_reg_note (last_insn, REG_EQUAL, note);
164 return 1;
167 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
168 for a widening operation would be. In most cases this would be OP0, but if
169 that's a constant it'll be VOIDmode, which isn't useful. */
171 static machine_mode
172 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
174 machine_mode m0 = GET_MODE (op0);
175 machine_mode m1 = GET_MODE (op1);
176 machine_mode result;
178 if (m0 == VOIDmode && m1 == VOIDmode)
179 return to_mode;
180 else if (m0 == VOIDmode || GET_MODE_UNIT_SIZE (m0) < GET_MODE_UNIT_SIZE (m1))
181 result = m1;
182 else
183 result = m0;
185 if (GET_MODE_UNIT_SIZE (result) > GET_MODE_UNIT_SIZE (to_mode))
186 return to_mode;
188 return result;
191 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
192 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
193 not actually do a sign-extend or zero-extend, but can leave the
194 higher-order bits of the result rtx undefined, for example, in the case
195 of logical operations, but not right shifts. */
197 static rtx
198 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
199 int unsignedp, int no_extend)
201 rtx result;
202 scalar_int_mode int_mode;
204 /* If we don't have to extend and this is a constant, return it. */
205 if (no_extend && GET_MODE (op) == VOIDmode)
206 return op;
208 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
209 extend since it will be more efficient to do so unless the signedness of
210 a promoted object differs from our extension. */
211 if (! no_extend
212 || !is_a <scalar_int_mode> (mode, &int_mode)
213 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
214 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
215 return convert_modes (mode, oldmode, op, unsignedp);
217 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
218 SUBREG. */
219 if (GET_MODE_SIZE (int_mode) <= UNITS_PER_WORD)
220 return gen_lowpart (int_mode, force_reg (GET_MODE (op), op));
222 /* Otherwise, get an object of MODE, clobber it, and set the low-order
223 part to OP. */
225 result = gen_reg_rtx (int_mode);
226 emit_clobber (result);
227 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
228 return result;
231 /* Expand vector widening operations.
233 There are two different classes of operations handled here:
234 1) Operations whose result is wider than all the arguments to the operation.
235 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
236 In this case OP0 and optionally OP1 would be initialized,
237 but WIDE_OP wouldn't (not relevant for this case).
238 2) Operations whose result is of the same size as the last argument to the
239 operation, but wider than all the other arguments to the operation.
240 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
241 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
243 E.g, when called to expand the following operations, this is how
244 the arguments will be initialized:
245 nops OP0 OP1 WIDE_OP
246 widening-sum 2 oprnd0 - oprnd1
247 widening-dot-product 3 oprnd0 oprnd1 oprnd2
248 widening-mult 2 oprnd0 oprnd1 -
249 type-promotion (vec-unpack) 1 oprnd0 - - */
252 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
253 rtx target, int unsignedp)
255 class expand_operand eops[4];
256 tree oprnd0, oprnd1, oprnd2;
257 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
258 optab widen_pattern_optab;
259 enum insn_code icode;
260 int nops = TREE_CODE_LENGTH (ops->code);
261 int op;
262 bool sbool = false;
264 oprnd0 = ops->op0;
265 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
266 if (ops->code == VEC_UNPACK_FIX_TRUNC_HI_EXPR
267 || ops->code == VEC_UNPACK_FIX_TRUNC_LO_EXPR)
268 /* The sign is from the result type rather than operand's type
269 for these ops. */
270 widen_pattern_optab
271 = optab_for_tree_code (ops->code, ops->type, optab_default);
272 else if ((ops->code == VEC_UNPACK_HI_EXPR
273 || ops->code == VEC_UNPACK_LO_EXPR)
274 && VECTOR_BOOLEAN_TYPE_P (ops->type)
275 && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (oprnd0))
276 && TYPE_MODE (ops->type) == TYPE_MODE (TREE_TYPE (oprnd0))
277 && SCALAR_INT_MODE_P (TYPE_MODE (ops->type)))
279 /* For VEC_UNPACK_{LO,HI}_EXPR if the mode of op0 and result is
280 the same scalar mode for VECTOR_BOOLEAN_TYPE_P vectors, use
281 vec_unpacks_sbool_{lo,hi}_optab, so that we can pass in
282 the pattern number of elements in the wider vector. */
283 widen_pattern_optab
284 = (ops->code == VEC_UNPACK_HI_EXPR
285 ? vec_unpacks_sbool_hi_optab : vec_unpacks_sbool_lo_optab);
286 sbool = true;
288 else
289 widen_pattern_optab
290 = optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
291 if (ops->code == WIDEN_MULT_PLUS_EXPR
292 || ops->code == WIDEN_MULT_MINUS_EXPR)
293 icode = find_widening_optab_handler (widen_pattern_optab,
294 TYPE_MODE (TREE_TYPE (ops->op2)),
295 tmode0);
296 else
297 icode = optab_handler (widen_pattern_optab, tmode0);
298 gcc_assert (icode != CODE_FOR_nothing);
300 if (nops >= 2)
302 oprnd1 = ops->op1;
303 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
305 else if (sbool)
307 nops = 2;
308 op1 = GEN_INT (TYPE_VECTOR_SUBPARTS (TREE_TYPE (oprnd0)).to_constant ());
309 tmode1 = tmode0;
312 /* The last operand is of a wider mode than the rest of the operands. */
313 if (nops == 2)
314 wmode = tmode1;
315 else if (nops == 3)
317 gcc_assert (tmode1 == tmode0);
318 gcc_assert (op1);
319 oprnd2 = ops->op2;
320 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
323 op = 0;
324 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
325 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
326 if (op1)
327 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
328 if (wide_op)
329 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
330 expand_insn (icode, op, eops);
331 return eops[0].value;
334 /* Generate code to perform an operation specified by TERNARY_OPTAB
335 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
337 UNSIGNEDP is for the case where we have to widen the operands
338 to perform the operation. It says to use zero-extension.
340 If TARGET is nonzero, the value
341 is generated there, if it is convenient to do so.
342 In all cases an rtx is returned for the locus of the value;
343 this may or may not be TARGET. */
346 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
347 rtx op1, rtx op2, rtx target, int unsignedp)
349 class expand_operand ops[4];
350 enum insn_code icode = optab_handler (ternary_optab, mode);
352 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
354 create_output_operand (&ops[0], target, mode);
355 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
356 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
357 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
358 expand_insn (icode, 4, ops);
359 return ops[0].value;
363 /* Like expand_binop, but return a constant rtx if the result can be
364 calculated at compile time. The arguments and return value are
365 otherwise the same as for expand_binop. */
368 simplify_expand_binop (machine_mode mode, optab binoptab,
369 rtx op0, rtx op1, rtx target, int unsignedp,
370 enum optab_methods methods)
372 if (CONSTANT_P (op0) && CONSTANT_P (op1))
374 rtx x = simplify_binary_operation (optab_to_code (binoptab),
375 mode, op0, op1);
376 if (x)
377 return x;
380 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
383 /* Like simplify_expand_binop, but always put the result in TARGET.
384 Return true if the expansion succeeded. */
386 bool
387 force_expand_binop (machine_mode mode, optab binoptab,
388 rtx op0, rtx op1, rtx target, int unsignedp,
389 enum optab_methods methods)
391 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
392 target, unsignedp, methods);
393 if (x == 0)
394 return false;
395 if (x != target)
396 emit_move_insn (target, x);
397 return true;
400 /* Create a new vector value in VMODE with all elements set to OP. The
401 mode of OP must be the element mode of VMODE. If OP is a constant,
402 then the return value will be a constant. */
405 expand_vector_broadcast (machine_mode vmode, rtx op)
407 int n;
408 rtvec vec;
410 gcc_checking_assert (VECTOR_MODE_P (vmode));
412 if (valid_for_const_vector_p (vmode, op))
413 return gen_const_vec_duplicate (vmode, op);
415 insn_code icode = optab_handler (vec_duplicate_optab, vmode);
416 if (icode != CODE_FOR_nothing)
418 class expand_operand ops[2];
419 create_output_operand (&ops[0], NULL_RTX, vmode);
420 create_input_operand (&ops[1], op, GET_MODE (op));
421 expand_insn (icode, 2, ops);
422 return ops[0].value;
425 if (!GET_MODE_NUNITS (vmode).is_constant (&n))
426 return NULL;
428 /* ??? If the target doesn't have a vec_init, then we have no easy way
429 of performing this operation. Most of this sort of generic support
430 is hidden away in the vector lowering support in gimple. */
431 icode = convert_optab_handler (vec_init_optab, vmode,
432 GET_MODE_INNER (vmode));
433 if (icode == CODE_FOR_nothing)
434 return NULL;
436 vec = rtvec_alloc (n);
437 for (int i = 0; i < n; ++i)
438 RTVEC_ELT (vec, i) = op;
439 rtx ret = gen_reg_rtx (vmode);
440 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
442 return ret;
445 /* This subroutine of expand_doubleword_shift handles the cases in which
446 the effective shift value is >= BITS_PER_WORD. The arguments and return
447 value are the same as for the parent routine, except that SUPERWORD_OP1
448 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
449 INTO_TARGET may be null if the caller has decided to calculate it. */
451 static bool
452 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
453 rtx outof_target, rtx into_target,
454 int unsignedp, enum optab_methods methods)
456 if (into_target != 0)
457 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
458 into_target, unsignedp, methods))
459 return false;
461 if (outof_target != 0)
463 /* For a signed right shift, we must fill OUTOF_TARGET with copies
464 of the sign bit, otherwise we must fill it with zeros. */
465 if (binoptab != ashr_optab)
466 emit_move_insn (outof_target, CONST0_RTX (word_mode));
467 else
468 if (!force_expand_binop (word_mode, binoptab, outof_input,
469 gen_int_shift_amount (word_mode,
470 BITS_PER_WORD - 1),
471 outof_target, unsignedp, methods))
472 return false;
474 return true;
477 /* This subroutine of expand_doubleword_shift handles the cases in which
478 the effective shift value is < BITS_PER_WORD. The arguments and return
479 value are the same as for the parent routine. */
481 static bool
482 expand_subword_shift (scalar_int_mode op1_mode, optab binoptab,
483 rtx outof_input, rtx into_input, rtx op1,
484 rtx outof_target, rtx into_target,
485 int unsignedp, enum optab_methods methods,
486 unsigned HOST_WIDE_INT shift_mask)
488 optab reverse_unsigned_shift, unsigned_shift;
489 rtx tmp, carries;
491 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
492 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
494 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
495 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
496 the opposite direction to BINOPTAB. */
497 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
499 carries = outof_input;
500 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
501 op1_mode), op1_mode);
502 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
503 0, true, methods);
505 else
507 /* We must avoid shifting by BITS_PER_WORD bits since that is either
508 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
509 has unknown behavior. Do a single shift first, then shift by the
510 remainder. It's OK to use ~OP1 as the remainder if shift counts
511 are truncated to the mode size. */
512 carries = expand_binop (word_mode, reverse_unsigned_shift,
513 outof_input, const1_rtx, 0, unsignedp, methods);
514 if (shift_mask == BITS_PER_WORD - 1)
516 tmp = immed_wide_int_const
517 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
518 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
519 0, true, methods);
521 else
523 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
524 op1_mode), op1_mode);
525 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
526 0, true, methods);
529 if (tmp == 0 || carries == 0)
530 return false;
531 carries = expand_binop (word_mode, reverse_unsigned_shift,
532 carries, tmp, 0, unsignedp, methods);
533 if (carries == 0)
534 return false;
536 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
537 so the result can go directly into INTO_TARGET if convenient. */
538 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
539 into_target, unsignedp, methods);
540 if (tmp == 0)
541 return false;
543 /* Now OR in the bits carried over from OUTOF_INPUT. */
544 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
545 into_target, unsignedp, methods))
546 return false;
548 /* Use a standard word_mode shift for the out-of half. */
549 if (outof_target != 0)
550 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
551 outof_target, unsignedp, methods))
552 return false;
554 return true;
558 /* Try implementing expand_doubleword_shift using conditional moves.
559 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
560 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
561 are the shift counts to use in the former and latter case. All other
562 arguments are the same as the parent routine. */
564 static bool
565 expand_doubleword_shift_condmove (scalar_int_mode op1_mode, optab binoptab,
566 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
567 rtx outof_input, rtx into_input,
568 rtx subword_op1, rtx superword_op1,
569 rtx outof_target, rtx into_target,
570 int unsignedp, enum optab_methods methods,
571 unsigned HOST_WIDE_INT shift_mask)
573 rtx outof_superword, into_superword;
575 /* Put the superword version of the output into OUTOF_SUPERWORD and
576 INTO_SUPERWORD. */
577 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
578 if (outof_target != 0 && subword_op1 == superword_op1)
580 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
581 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
582 into_superword = outof_target;
583 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
584 outof_superword, 0, unsignedp, methods))
585 return false;
587 else
589 into_superword = gen_reg_rtx (word_mode);
590 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
591 outof_superword, into_superword,
592 unsignedp, methods))
593 return false;
596 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
597 if (!expand_subword_shift (op1_mode, binoptab,
598 outof_input, into_input, subword_op1,
599 outof_target, into_target,
600 unsignedp, methods, shift_mask))
601 return false;
603 /* Select between them. Do the INTO half first because INTO_SUPERWORD
604 might be the current value of OUTOF_TARGET. */
605 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
606 into_target, into_superword, word_mode, false))
607 return false;
609 if (outof_target != 0)
610 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
611 outof_target, outof_superword,
612 word_mode, false))
613 return false;
615 return true;
618 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
619 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
620 input operand; the shift moves bits in the direction OUTOF_INPUT->
621 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
622 of the target. OP1 is the shift count and OP1_MODE is its mode.
623 If OP1 is constant, it will have been truncated as appropriate
624 and is known to be nonzero.
626 If SHIFT_MASK is zero, the result of word shifts is undefined when the
627 shift count is outside the range [0, BITS_PER_WORD). This routine must
628 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
630 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
631 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
632 fill with zeros or sign bits as appropriate.
634 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
635 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
636 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
637 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
638 are undefined.
640 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
641 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
642 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
643 function wants to calculate it itself.
645 Return true if the shift could be successfully synthesized. */
647 static bool
648 expand_doubleword_shift (scalar_int_mode op1_mode, optab binoptab,
649 rtx outof_input, rtx into_input, rtx op1,
650 rtx outof_target, rtx into_target,
651 int unsignedp, enum optab_methods methods,
652 unsigned HOST_WIDE_INT shift_mask)
654 rtx superword_op1, tmp, cmp1, cmp2;
655 enum rtx_code cmp_code;
657 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
658 fill the result with sign or zero bits as appropriate. If so, the value
659 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
660 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
661 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
663 This isn't worthwhile for constant shifts since the optimizers will
664 cope better with in-range shift counts. */
665 if (shift_mask >= BITS_PER_WORD
666 && outof_target != 0
667 && !CONSTANT_P (op1))
669 if (!expand_doubleword_shift (op1_mode, binoptab,
670 outof_input, into_input, op1,
671 0, into_target,
672 unsignedp, methods, shift_mask))
673 return false;
674 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
675 outof_target, unsignedp, methods))
676 return false;
677 return true;
680 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
681 is true when the effective shift value is less than BITS_PER_WORD.
682 Set SUPERWORD_OP1 to the shift count that should be used to shift
683 OUTOF_INPUT into INTO_TARGET when the condition is false. */
684 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
685 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
687 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
688 is a subword shift count. */
689 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
690 0, true, methods);
691 cmp2 = CONST0_RTX (op1_mode);
692 cmp_code = EQ;
693 superword_op1 = op1;
695 else
697 /* Set CMP1 to OP1 - BITS_PER_WORD. */
698 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
699 0, true, methods);
700 cmp2 = CONST0_RTX (op1_mode);
701 cmp_code = LT;
702 superword_op1 = cmp1;
704 if (cmp1 == 0)
705 return false;
707 /* If we can compute the condition at compile time, pick the
708 appropriate subroutine. */
709 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
710 if (tmp != 0 && CONST_INT_P (tmp))
712 if (tmp == const0_rtx)
713 return expand_superword_shift (binoptab, outof_input, superword_op1,
714 outof_target, into_target,
715 unsignedp, methods);
716 else
717 return expand_subword_shift (op1_mode, binoptab,
718 outof_input, into_input, op1,
719 outof_target, into_target,
720 unsignedp, methods, shift_mask);
723 /* Try using conditional moves to generate straight-line code. */
724 if (HAVE_conditional_move)
726 rtx_insn *start = get_last_insn ();
727 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
728 cmp_code, cmp1, cmp2,
729 outof_input, into_input,
730 op1, superword_op1,
731 outof_target, into_target,
732 unsignedp, methods, shift_mask))
733 return true;
734 delete_insns_since (start);
737 /* As a last resort, use branches to select the correct alternative. */
738 rtx_code_label *subword_label = gen_label_rtx ();
739 rtx_code_label *done_label = gen_label_rtx ();
741 NO_DEFER_POP;
742 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
743 0, 0, subword_label,
744 profile_probability::uninitialized ());
745 OK_DEFER_POP;
747 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
748 outof_target, into_target,
749 unsignedp, methods))
750 return false;
752 emit_jump_insn (targetm.gen_jump (done_label));
753 emit_barrier ();
754 emit_label (subword_label);
756 if (!expand_subword_shift (op1_mode, binoptab,
757 outof_input, into_input, op1,
758 outof_target, into_target,
759 unsignedp, methods, shift_mask))
760 return false;
762 emit_label (done_label);
763 return true;
766 /* Subroutine of expand_binop. Perform a double word multiplication of
767 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
768 as the target's word_mode. This function return NULL_RTX if anything
769 goes wrong, in which case it may have already emitted instructions
770 which need to be deleted.
772 If we want to multiply two two-word values and have normal and widening
773 multiplies of single-word values, we can do this with three smaller
774 multiplications.
776 The multiplication proceeds as follows:
777 _______________________
778 [__op0_high_|__op0_low__]
779 _______________________
780 * [__op1_high_|__op1_low__]
781 _______________________________________________
782 _______________________
783 (1) [__op0_low__*__op1_low__]
784 _______________________
785 (2a) [__op0_low__*__op1_high_]
786 _______________________
787 (2b) [__op0_high_*__op1_low__]
788 _______________________
789 (3) [__op0_high_*__op1_high_]
792 This gives a 4-word result. Since we are only interested in the
793 lower 2 words, partial result (3) and the upper words of (2a) and
794 (2b) don't need to be calculated. Hence (2a) and (2b) can be
795 calculated using non-widening multiplication.
797 (1), however, needs to be calculated with an unsigned widening
798 multiplication. If this operation is not directly supported we
799 try using a signed widening multiplication and adjust the result.
800 This adjustment works as follows:
802 If both operands are positive then no adjustment is needed.
804 If the operands have different signs, for example op0_low < 0 and
805 op1_low >= 0, the instruction treats the most significant bit of
806 op0_low as a sign bit instead of a bit with significance
807 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
808 with 2**BITS_PER_WORD - op0_low, and two's complements the
809 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
810 the result.
812 Similarly, if both operands are negative, we need to add
813 (op0_low + op1_low) * 2**BITS_PER_WORD.
815 We use a trick to adjust quickly. We logically shift op0_low right
816 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
817 op0_high (op1_high) before it is used to calculate 2b (2a). If no
818 logical shift exists, we do an arithmetic right shift and subtract
819 the 0 or -1. */
821 static rtx
822 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
823 bool umulp, enum optab_methods methods)
825 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
826 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
827 rtx wordm1 = (umulp ? NULL_RTX
828 : gen_int_shift_amount (word_mode, BITS_PER_WORD - 1));
829 rtx product, adjust, product_high, temp;
831 rtx op0_high = operand_subword_force (op0, high, mode);
832 rtx op0_low = operand_subword_force (op0, low, mode);
833 rtx op1_high = operand_subword_force (op1, high, mode);
834 rtx op1_low = operand_subword_force (op1, low, mode);
836 /* If we're using an unsigned multiply to directly compute the product
837 of the low-order words of the operands and perform any required
838 adjustments of the operands, we begin by trying two more multiplications
839 and then computing the appropriate sum.
841 We have checked above that the required addition is provided.
842 Full-word addition will normally always succeed, especially if
843 it is provided at all, so we don't worry about its failure. The
844 multiplication may well fail, however, so we do handle that. */
846 if (!umulp)
848 /* ??? This could be done with emit_store_flag where available. */
849 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
850 NULL_RTX, 1, methods);
851 if (temp)
852 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
853 NULL_RTX, 0, OPTAB_DIRECT);
854 else
856 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
857 NULL_RTX, 0, methods);
858 if (!temp)
859 return NULL_RTX;
860 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
861 NULL_RTX, 0, OPTAB_DIRECT);
864 if (!op0_high)
865 return NULL_RTX;
868 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
869 NULL_RTX, 0, OPTAB_DIRECT);
870 if (!adjust)
871 return NULL_RTX;
873 /* OP0_HIGH should now be dead. */
875 if (!umulp)
877 /* ??? This could be done with emit_store_flag where available. */
878 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
879 NULL_RTX, 1, methods);
880 if (temp)
881 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
882 NULL_RTX, 0, OPTAB_DIRECT);
883 else
885 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
886 NULL_RTX, 0, methods);
887 if (!temp)
888 return NULL_RTX;
889 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
890 NULL_RTX, 0, OPTAB_DIRECT);
893 if (!op1_high)
894 return NULL_RTX;
897 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
898 NULL_RTX, 0, OPTAB_DIRECT);
899 if (!temp)
900 return NULL_RTX;
902 /* OP1_HIGH should now be dead. */
904 adjust = expand_binop (word_mode, add_optab, adjust, temp,
905 NULL_RTX, 0, OPTAB_DIRECT);
907 if (target && !REG_P (target))
908 target = NULL_RTX;
910 /* *_widen_optab needs to determine operand mode, make sure at least
911 one operand has non-VOID mode. */
912 if (GET_MODE (op0_low) == VOIDmode && GET_MODE (op1_low) == VOIDmode)
913 op0_low = force_reg (word_mode, op0_low);
915 if (umulp)
916 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
917 target, 1, OPTAB_DIRECT);
918 else
919 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
920 target, 1, OPTAB_DIRECT);
922 if (!product)
923 return NULL_RTX;
925 product_high = operand_subword (product, high, 1, mode);
926 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
927 NULL_RTX, 0, OPTAB_DIRECT);
928 emit_move_insn (product_high, adjust);
929 return product;
932 /* Subroutine of expand_binop. Optimize unsigned double-word OP0 % OP1 for
933 constant OP1. If for some bit in [BITS_PER_WORD / 2, BITS_PER_WORD] range
934 (prefer higher bits) ((1w << bit) % OP1) == 1, then the modulo can be
935 computed in word-mode as ((OP0 & (bit - 1)) + ((OP0 >> bit) & (bit - 1))
936 + (OP0 >> (2 * bit))) % OP1. Whether we need to sum 2, 3 or 4 values
937 depends on the bit value, if 2, then carry from the addition needs to be
938 added too, i.e. like:
939 sum += __builtin_add_overflow (low, high, &sum)
941 Optimize signed double-word OP0 % OP1 similarly, just apply some correction
942 factor to the sum before doing unsigned remainder, in the form of
943 sum += (((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & const);
944 then perform unsigned
945 remainder = sum % OP1;
946 and finally
947 remainder += ((signed) OP0 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1); */
949 static rtx
950 expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
952 if (INTVAL (op1) <= 1 || (INTVAL (op1) & 1) == 0)
953 return NULL_RTX;
955 rtx_insn *last = get_last_insn ();
956 for (int bit = BITS_PER_WORD; bit >= BITS_PER_WORD / 2; bit--)
958 wide_int w = wi::shifted_mask (bit, 1, false, 2 * BITS_PER_WORD);
959 if (wi::ne_p (wi::umod_trunc (w, INTVAL (op1)), 1))
960 continue;
961 rtx sum = NULL_RTX, mask = NULL_RTX;
962 if (bit == BITS_PER_WORD)
964 /* For signed modulo we need to add correction to the sum
965 and that might again overflow. */
966 if (!unsignedp)
967 continue;
968 if (optab_handler (uaddv4_optab, word_mode) == CODE_FOR_nothing)
969 continue;
970 tree wtype = lang_hooks.types.type_for_mode (word_mode, 1);
971 if (wtype == NULL_TREE)
972 continue;
973 tree ctype = build_complex_type (wtype);
974 if (TYPE_MODE (ctype) != GET_MODE_COMPLEX_MODE (word_mode))
975 continue;
976 machine_mode cmode = TYPE_MODE (ctype);
977 rtx op00 = operand_subword_force (op0, 0, mode);
978 rtx op01 = operand_subword_force (op0, 1, mode);
979 rtx cres = gen_rtx_CONCAT (cmode, gen_reg_rtx (word_mode),
980 gen_reg_rtx (word_mode));
981 tree lhs = make_tree (ctype, cres);
982 tree arg0 = make_tree (wtype, op00);
983 tree arg1 = make_tree (wtype, op01);
984 expand_addsub_overflow (UNKNOWN_LOCATION, PLUS_EXPR, lhs, arg0,
985 arg1, true, true, true, false, NULL);
986 sum = expand_simple_binop (word_mode, PLUS, XEXP (cres, 0),
987 XEXP (cres, 1), NULL_RTX, 1,
988 OPTAB_DIRECT);
989 if (sum == NULL_RTX)
990 return NULL_RTX;
992 else
994 /* Code below uses GEN_INT, so we need the masks to be representable
995 in HOST_WIDE_INTs. */
996 if (bit >= HOST_BITS_PER_WIDE_INT)
997 continue;
998 /* If op0 is e.g. -1 or -2 unsigned, then the 2 additions might
999 overflow. Consider 64-bit -1ULL for word size 32, if we add
1000 0x7fffffffU + 0x7fffffffU + 3U, it wraps around to 1. */
1001 if (bit == BITS_PER_WORD - 1)
1002 continue;
1004 int count = (2 * BITS_PER_WORD + bit - 1) / bit;
1005 rtx sum_corr = NULL_RTX;
1007 if (!unsignedp)
1009 /* For signed modulo, compute it as unsigned modulo of
1010 sum with a correction added to it if OP0 is negative,
1011 such that the result can be computed as unsigned
1012 remainder + ((OP1 >> (2 * BITS_PER_WORD - 1)) & (1 - OP1). */
1013 w = wi::min_value (2 * BITS_PER_WORD, SIGNED);
1014 wide_int wmod1 = wi::umod_trunc (w, INTVAL (op1));
1015 wide_int wmod2 = wi::smod_trunc (w, INTVAL (op1));
1016 /* wmod2 == -wmod1. */
1017 wmod2 = wmod2 + (INTVAL (op1) - 1);
1018 if (wi::ne_p (wmod1, wmod2))
1020 wide_int wcorr = wmod2 - wmod1;
1021 if (wi::neg_p (w))
1022 wcorr = wcorr + INTVAL (op1);
1023 /* Now verify if the count sums can't overflow, and punt
1024 if they could. */
1025 w = wi::mask (bit, false, 2 * BITS_PER_WORD);
1026 w = w * (count - 1);
1027 w = w + wi::mask (2 * BITS_PER_WORD - (count - 1) * bit,
1028 false, 2 * BITS_PER_WORD);
1029 w = w + wcorr;
1030 w = wi::lrshift (w, BITS_PER_WORD);
1031 if (wi::ne_p (w, 0))
1032 continue;
1034 mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
1035 mode);
1036 mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
1037 GEN_INT (BITS_PER_WORD - 1),
1038 NULL_RTX, 0, OPTAB_DIRECT);
1039 if (mask == NULL_RTX)
1040 return NULL_RTX;
1041 sum_corr = immed_wide_int_const (wcorr, word_mode);
1042 sum_corr = expand_simple_binop (word_mode, AND, mask,
1043 sum_corr, NULL_RTX, 1,
1044 OPTAB_DIRECT);
1045 if (sum_corr == NULL_RTX)
1046 return NULL_RTX;
1050 for (int i = 0; i < count; i++)
1052 rtx v = op0;
1053 if (i)
1054 v = expand_simple_binop (mode, LSHIFTRT, v, GEN_INT (i * bit),
1055 NULL_RTX, 1, OPTAB_DIRECT);
1056 if (v == NULL_RTX)
1057 return NULL_RTX;
1058 v = lowpart_subreg (word_mode, v, mode);
1059 if (v == NULL_RTX)
1060 return NULL_RTX;
1061 if (i != count - 1)
1062 v = expand_simple_binop (word_mode, AND, v,
1063 GEN_INT ((HOST_WIDE_INT_1U << bit)
1064 - 1), NULL_RTX, 1,
1065 OPTAB_DIRECT);
1066 if (v == NULL_RTX)
1067 return NULL_RTX;
1068 if (sum == NULL_RTX)
1069 sum = v;
1070 else
1071 sum = expand_simple_binop (word_mode, PLUS, sum, v, NULL_RTX,
1072 1, OPTAB_DIRECT);
1073 if (sum == NULL_RTX)
1074 return NULL_RTX;
1076 if (sum_corr)
1078 sum = expand_simple_binop (word_mode, PLUS, sum, sum_corr,
1079 NULL_RTX, 1, OPTAB_DIRECT);
1080 if (sum == NULL_RTX)
1081 return NULL_RTX;
1084 rtx remainder = expand_divmod (1, TRUNC_MOD_EXPR, word_mode, sum, op1,
1085 NULL_RTX, 1, OPTAB_DIRECT);
1086 if (remainder == NULL_RTX)
1087 return NULL_RTX;
1089 if (!unsignedp)
1091 if (mask == NULL_RTX)
1093 mask = operand_subword_force (op0, WORDS_BIG_ENDIAN ? 0 : 1,
1094 mode);
1095 mask = expand_simple_binop (word_mode, ASHIFTRT, mask,
1096 GEN_INT (BITS_PER_WORD - 1),
1097 NULL_RTX, 0, OPTAB_DIRECT);
1098 if (mask == NULL_RTX)
1099 return NULL_RTX;
1101 mask = expand_simple_binop (word_mode, AND, mask,
1102 GEN_INT (1 - INTVAL (op1)),
1103 NULL_RTX, 1, OPTAB_DIRECT);
1104 if (mask == NULL_RTX)
1105 return NULL_RTX;
1106 remainder = expand_simple_binop (word_mode, PLUS, remainder,
1107 mask, NULL_RTX, 1, OPTAB_DIRECT);
1108 if (remainder == NULL_RTX)
1109 return NULL_RTX;
1112 remainder = convert_modes (mode, word_mode, remainder, unsignedp);
1113 /* Punt if we need any library calls. */
1114 for (; last; last = NEXT_INSN (last))
1115 if (CALL_P (last))
1116 return NULL_RTX;
1117 return remainder;
1119 return NULL_RTX;
1122 /* Similarly to the above function, but compute both quotient and remainder.
1123 Quotient can be computed from the remainder as:
1124 rem = op0 % op1; // Handled using expand_doubleword_mod
1125 quot = (op0 - rem) * inv; // inv is multiplicative inverse of op1 modulo
1126 // 2 * BITS_PER_WORD
1128 We can also handle cases where op1 is a multiple of power of two constant
1129 and constant handled by expand_doubleword_mod.
1130 op11 = 1 << __builtin_ctz (op1);
1131 op12 = op1 / op11;
1132 rem1 = op0 % op12; // Handled using expand_doubleword_mod
1133 quot1 = (op0 - rem1) * inv; // inv is multiplicative inverse of op12 modulo
1134 // 2 * BITS_PER_WORD
1135 rem = (quot1 % op11) * op12 + rem1;
1136 quot = quot1 / op11; */
1139 expand_doubleword_divmod (machine_mode mode, rtx op0, rtx op1, rtx *rem,
1140 bool unsignedp)
1142 *rem = NULL_RTX;
1144 /* Negative dividend should have been optimized into positive,
1145 similarly modulo by 1 and modulo by power of two is optimized
1146 differently too. */
1147 if (INTVAL (op1) <= 1 || pow2p_hwi (INTVAL (op1)))
1148 return NULL_RTX;
1150 rtx op11 = const1_rtx;
1151 rtx op12 = op1;
1152 if ((INTVAL (op1) & 1) == 0)
1154 int bit = ctz_hwi (INTVAL (op1));
1155 op11 = GEN_INT (HOST_WIDE_INT_1 << bit);
1156 op12 = GEN_INT (INTVAL (op1) >> bit);
1159 rtx rem1 = expand_doubleword_mod (mode, op0, op12, unsignedp);
1160 if (rem1 == NULL_RTX)
1161 return NULL_RTX;
1163 int prec = 2 * BITS_PER_WORD;
1164 wide_int a = wide_int::from (INTVAL (op12), prec + 1, UNSIGNED);
1165 wide_int b = wi::shifted_mask (prec, 1, false, prec + 1);
1166 wide_int m = wide_int::from (wi::mod_inv (a, b), prec, UNSIGNED);
1167 rtx inv = immed_wide_int_const (m, mode);
1169 rtx_insn *last = get_last_insn ();
1170 rtx quot1 = expand_simple_binop (mode, MINUS, op0, rem1,
1171 NULL_RTX, unsignedp, OPTAB_DIRECT);
1172 if (quot1 == NULL_RTX)
1173 return NULL_RTX;
1175 quot1 = expand_simple_binop (mode, MULT, quot1, inv,
1176 NULL_RTX, unsignedp, OPTAB_DIRECT);
1177 if (quot1 == NULL_RTX)
1178 return NULL_RTX;
1180 if (op11 != const1_rtx)
1182 rtx rem2 = expand_divmod (1, TRUNC_MOD_EXPR, mode, quot1, op11,
1183 NULL_RTX, unsignedp, OPTAB_DIRECT);
1184 if (rem2 == NULL_RTX)
1185 return NULL_RTX;
1187 rem2 = expand_simple_binop (mode, MULT, rem2, op12, NULL_RTX,
1188 unsignedp, OPTAB_DIRECT);
1189 if (rem2 == NULL_RTX)
1190 return NULL_RTX;
1192 rem2 = expand_simple_binop (mode, PLUS, rem2, rem1, NULL_RTX,
1193 unsignedp, OPTAB_DIRECT);
1194 if (rem2 == NULL_RTX)
1195 return NULL_RTX;
1197 rtx quot2 = expand_divmod (0, TRUNC_DIV_EXPR, mode, quot1, op11,
1198 NULL_RTX, unsignedp, OPTAB_DIRECT);
1199 if (quot2 == NULL_RTX)
1200 return NULL_RTX;
1202 rem1 = rem2;
1203 quot1 = quot2;
1206 /* Punt if we need any library calls. */
1207 for (; last; last = NEXT_INSN (last))
1208 if (CALL_P (last))
1209 return NULL_RTX;
1211 *rem = rem1;
1212 return quot1;
1215 /* Wrapper around expand_binop which takes an rtx code to specify
1216 the operation to perform, not an optab pointer. All other
1217 arguments are the same. */
1219 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
1220 rtx op1, rtx target, int unsignedp,
1221 enum optab_methods methods)
1223 optab binop = code_to_optab (code);
1224 gcc_assert (binop);
1226 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1229 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1230 binop. Order them according to commutative_operand_precedence and, if
1231 possible, try to put TARGET or a pseudo first. */
1232 static bool
1233 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1235 int op0_prec = commutative_operand_precedence (op0);
1236 int op1_prec = commutative_operand_precedence (op1);
1238 if (op0_prec < op1_prec)
1239 return true;
1241 if (op0_prec > op1_prec)
1242 return false;
1244 /* With equal precedence, both orders are ok, but it is better if the
1245 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1246 if (target == 0 || REG_P (target))
1247 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1248 else
1249 return rtx_equal_p (op1, target);
1252 /* Return true if BINOPTAB implements a shift operation. */
1254 static bool
1255 shift_optab_p (optab binoptab)
1257 switch (optab_to_code (binoptab))
1259 case ASHIFT:
1260 case SS_ASHIFT:
1261 case US_ASHIFT:
1262 case ASHIFTRT:
1263 case LSHIFTRT:
1264 case ROTATE:
1265 case ROTATERT:
1266 return true;
1268 default:
1269 return false;
1273 /* Return true if BINOPTAB implements a commutative binary operation. */
1275 static bool
1276 commutative_optab_p (optab binoptab)
1278 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
1279 || binoptab == smul_widen_optab
1280 || binoptab == umul_widen_optab
1281 || binoptab == smul_highpart_optab
1282 || binoptab == umul_highpart_optab);
1285 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
1286 optimizing, and if the operand is a constant that costs more than
1287 1 instruction, force the constant into a register and return that
1288 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1290 static rtx
1291 avoid_expensive_constant (machine_mode mode, optab binoptab,
1292 int opn, rtx x, bool unsignedp)
1294 bool speed = optimize_insn_for_speed_p ();
1296 if (mode != VOIDmode
1297 && optimize
1298 && CONSTANT_P (x)
1299 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
1300 > set_src_cost (x, mode, speed)))
1302 if (CONST_INT_P (x))
1304 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1305 if (intval != INTVAL (x))
1306 x = GEN_INT (intval);
1308 else
1309 x = convert_modes (mode, VOIDmode, x, unsignedp);
1310 x = force_reg (mode, x);
1312 return x;
1315 /* Helper function for expand_binop: handle the case where there
1316 is an insn ICODE that directly implements the indicated operation.
1317 Returns null if this is not possible. */
1318 static rtx
1319 expand_binop_directly (enum insn_code icode, machine_mode mode, optab binoptab,
1320 rtx op0, rtx op1,
1321 rtx target, int unsignedp, enum optab_methods methods,
1322 rtx_insn *last)
1324 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
1325 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
1326 machine_mode mode0, mode1, tmp_mode;
1327 class expand_operand ops[3];
1328 bool commutative_p;
1329 rtx_insn *pat;
1330 rtx xop0 = op0, xop1 = op1;
1331 bool canonicalize_op1 = false;
1333 /* If it is a commutative operator and the modes would match
1334 if we would swap the operands, we can save the conversions. */
1335 commutative_p = commutative_optab_p (binoptab);
1336 if (commutative_p
1337 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1338 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode0)
1339 std::swap (xop0, xop1);
1341 /* If we are optimizing, force expensive constants into a register. */
1342 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1343 if (!shift_optab_p (binoptab))
1344 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1345 else
1346 /* Shifts and rotates often use a different mode for op1 from op0;
1347 for VOIDmode constants we don't know the mode, so force it
1348 to be canonicalized using convert_modes. */
1349 canonicalize_op1 = true;
1351 /* In case the insn wants input operands in modes different from
1352 those of the actual operands, convert the operands. It would
1353 seem that we don't need to convert CONST_INTs, but we do, so
1354 that they're properly zero-extended, sign-extended or truncated
1355 for their mode. */
1357 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1358 if (xmode0 != VOIDmode && xmode0 != mode0)
1360 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1361 mode0 = xmode0;
1364 mode1 = ((GET_MODE (xop1) != VOIDmode || canonicalize_op1)
1365 ? GET_MODE (xop1) : mode);
1366 if (xmode1 != VOIDmode && xmode1 != mode1)
1368 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1369 mode1 = xmode1;
1372 /* If operation is commutative,
1373 try to make the first operand a register.
1374 Even better, try to make it the same as the target.
1375 Also try to make the last operand a constant. */
1376 if (commutative_p
1377 && swap_commutative_operands_with_target (target, xop0, xop1))
1378 std::swap (xop0, xop1);
1380 /* Now, if insn's predicates don't allow our operands, put them into
1381 pseudo regs. */
1383 if (binoptab == vec_pack_trunc_optab
1384 || binoptab == vec_pack_usat_optab
1385 || binoptab == vec_pack_ssat_optab
1386 || binoptab == vec_pack_ufix_trunc_optab
1387 || binoptab == vec_pack_sfix_trunc_optab
1388 || binoptab == vec_packu_float_optab
1389 || binoptab == vec_packs_float_optab)
1391 /* The mode of the result is different then the mode of the
1392 arguments. */
1393 tmp_mode = insn_data[(int) icode].operand[0].mode;
1394 if (VECTOR_MODE_P (mode)
1395 && maybe_ne (GET_MODE_NUNITS (tmp_mode), 2 * GET_MODE_NUNITS (mode)))
1397 delete_insns_since (last);
1398 return NULL_RTX;
1401 else
1402 tmp_mode = mode;
1404 create_output_operand (&ops[0], target, tmp_mode);
1405 create_input_operand (&ops[1], xop0, mode0);
1406 create_input_operand (&ops[2], xop1, mode1);
1407 pat = maybe_gen_insn (icode, 3, ops);
1408 if (pat)
1410 /* If PAT is composed of more than one insn, try to add an appropriate
1411 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1412 operand, call expand_binop again, this time without a target. */
1413 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1414 && ! add_equal_note (pat, ops[0].value,
1415 optab_to_code (binoptab),
1416 ops[1].value, ops[2].value, mode0))
1418 delete_insns_since (last);
1419 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1420 unsignedp, methods);
1423 emit_insn (pat);
1424 return ops[0].value;
1426 delete_insns_since (last);
1427 return NULL_RTX;
1430 /* Generate code to perform an operation specified by BINOPTAB
1431 on operands OP0 and OP1, with result having machine-mode MODE.
1433 UNSIGNEDP is for the case where we have to widen the operands
1434 to perform the operation. It says to use zero-extension.
1436 If TARGET is nonzero, the value
1437 is generated there, if it is convenient to do so.
1438 In all cases an rtx is returned for the locus of the value;
1439 this may or may not be TARGET. */
1442 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1443 rtx target, int unsignedp, enum optab_methods methods)
1445 enum optab_methods next_methods
1446 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1447 ? OPTAB_WIDEN : methods);
1448 enum mode_class mclass;
1449 enum insn_code icode;
1450 machine_mode wider_mode;
1451 scalar_int_mode int_mode;
1452 rtx libfunc;
1453 rtx temp;
1454 rtx_insn *entry_last = get_last_insn ();
1455 rtx_insn *last;
1457 mclass = GET_MODE_CLASS (mode);
1459 /* If subtracting an integer constant, convert this into an addition of
1460 the negated constant. */
1462 if (binoptab == sub_optab && CONST_INT_P (op1))
1464 op1 = negate_rtx (mode, op1);
1465 binoptab = add_optab;
1467 /* For shifts, constant invalid op1 might be expanded from different
1468 mode than MODE. As those are invalid, force them to a register
1469 to avoid further problems during expansion. */
1470 else if (CONST_INT_P (op1)
1471 && shift_optab_p (binoptab)
1472 && UINTVAL (op1) >= GET_MODE_BITSIZE (GET_MODE_INNER (mode)))
1474 op1 = gen_int_mode (INTVAL (op1), GET_MODE_INNER (mode));
1475 op1 = force_reg (GET_MODE_INNER (mode), op1);
1478 /* Record where to delete back to if we backtrack. */
1479 last = get_last_insn ();
1481 /* If we can do it with a three-operand insn, do so. */
1483 if (methods != OPTAB_MUST_WIDEN)
1485 if (convert_optab_p (binoptab))
1487 machine_mode from_mode = widened_mode (mode, op0, op1);
1488 icode = find_widening_optab_handler (binoptab, mode, from_mode);
1490 else
1491 icode = optab_handler (binoptab, mode);
1492 if (icode != CODE_FOR_nothing)
1494 temp = expand_binop_directly (icode, mode, binoptab, op0, op1,
1495 target, unsignedp, methods, last);
1496 if (temp)
1497 return temp;
1501 /* If we were trying to rotate, and that didn't work, try rotating
1502 the other direction before falling back to shifts and bitwise-or. */
1503 if (((binoptab == rotl_optab
1504 && (icode = optab_handler (rotr_optab, mode)) != CODE_FOR_nothing)
1505 || (binoptab == rotr_optab
1506 && (icode = optab_handler (rotl_optab, mode)) != CODE_FOR_nothing))
1507 && is_int_mode (mode, &int_mode))
1509 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1510 rtx newop1;
1511 unsigned int bits = GET_MODE_PRECISION (int_mode);
1513 if (CONST_INT_P (op1))
1514 newop1 = gen_int_shift_amount (int_mode, bits - INTVAL (op1));
1515 else if (targetm.shift_truncation_mask (int_mode) == bits - 1)
1516 newop1 = negate_rtx (GET_MODE (op1), op1);
1517 else
1518 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1519 gen_int_mode (bits, GET_MODE (op1)), op1,
1520 NULL_RTX, unsignedp, OPTAB_DIRECT);
1522 temp = expand_binop_directly (icode, int_mode, otheroptab, op0, newop1,
1523 target, unsignedp, methods, last);
1524 if (temp)
1525 return temp;
1528 /* If this is a multiply, see if we can do a widening operation that
1529 takes operands of this mode and makes a wider mode. */
1531 if (binoptab == smul_optab
1532 && GET_MODE_2XWIDER_MODE (mode).exists (&wider_mode)
1533 && (convert_optab_handler ((unsignedp
1534 ? umul_widen_optab
1535 : smul_widen_optab),
1536 wider_mode, mode) != CODE_FOR_nothing))
1538 /* *_widen_optab needs to determine operand mode, make sure at least
1539 one operand has non-VOID mode. */
1540 if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
1541 op0 = force_reg (mode, op0);
1542 temp = expand_binop (wider_mode,
1543 unsignedp ? umul_widen_optab : smul_widen_optab,
1544 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1546 if (temp != 0)
1548 if (GET_MODE_CLASS (mode) == MODE_INT
1549 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1550 return gen_lowpart (mode, temp);
1551 else
1552 return convert_to_mode (mode, temp, unsignedp);
1556 /* If this is a vector shift by a scalar, see if we can do a vector
1557 shift by a vector. If so, broadcast the scalar into a vector. */
1558 if (mclass == MODE_VECTOR_INT)
1560 optab otheroptab = unknown_optab;
1562 if (binoptab == ashl_optab)
1563 otheroptab = vashl_optab;
1564 else if (binoptab == ashr_optab)
1565 otheroptab = vashr_optab;
1566 else if (binoptab == lshr_optab)
1567 otheroptab = vlshr_optab;
1568 else if (binoptab == rotl_optab)
1569 otheroptab = vrotl_optab;
1570 else if (binoptab == rotr_optab)
1571 otheroptab = vrotr_optab;
1573 if (otheroptab
1574 && (icode = optab_handler (otheroptab, mode)) != CODE_FOR_nothing)
1576 /* The scalar may have been extended to be too wide. Truncate
1577 it back to the proper size to fit in the broadcast vector. */
1578 scalar_mode inner_mode = GET_MODE_INNER (mode);
1579 if (!CONST_INT_P (op1)
1580 && (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (op1)))
1581 > GET_MODE_BITSIZE (inner_mode)))
1582 op1 = force_reg (inner_mode,
1583 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1584 GET_MODE (op1)));
1585 rtx vop1 = expand_vector_broadcast (mode, op1);
1586 if (vop1)
1588 temp = expand_binop_directly (icode, mode, otheroptab, op0, vop1,
1589 target, unsignedp, methods, last);
1590 if (temp)
1591 return temp;
1596 /* Look for a wider mode of the same class for which we think we
1597 can open-code the operation. Check for a widening multiply at the
1598 wider mode as well. */
1600 if (CLASS_HAS_WIDER_MODES_P (mclass)
1601 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1602 FOR_EACH_WIDER_MODE (wider_mode, mode)
1604 machine_mode next_mode;
1605 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1606 || (binoptab == smul_optab
1607 && GET_MODE_WIDER_MODE (wider_mode).exists (&next_mode)
1608 && (find_widening_optab_handler ((unsignedp
1609 ? umul_widen_optab
1610 : smul_widen_optab),
1611 next_mode, mode)
1612 != CODE_FOR_nothing)))
1614 rtx xop0 = op0, xop1 = op1;
1615 int no_extend = 0;
1617 /* For certain integer operations, we need not actually extend
1618 the narrow operands, as long as we will truncate
1619 the results to the same narrowness. */
1621 if ((binoptab == ior_optab || binoptab == and_optab
1622 || binoptab == xor_optab
1623 || binoptab == add_optab || binoptab == sub_optab
1624 || binoptab == smul_optab || binoptab == ashl_optab)
1625 && mclass == MODE_INT)
1627 no_extend = 1;
1628 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1629 xop0, unsignedp);
1630 if (binoptab != ashl_optab)
1631 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1632 xop1, unsignedp);
1635 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1637 /* The second operand of a shift must always be extended. */
1638 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1639 no_extend && binoptab != ashl_optab);
1641 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1642 unsignedp, OPTAB_DIRECT);
1643 if (temp)
1645 if (mclass != MODE_INT
1646 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1648 if (target == 0)
1649 target = gen_reg_rtx (mode);
1650 convert_move (target, temp, 0);
1651 return target;
1653 else
1654 return gen_lowpart (mode, temp);
1656 else
1657 delete_insns_since (last);
1661 /* If operation is commutative,
1662 try to make the first operand a register.
1663 Even better, try to make it the same as the target.
1664 Also try to make the last operand a constant. */
1665 if (commutative_optab_p (binoptab)
1666 && swap_commutative_operands_with_target (target, op0, op1))
1667 std::swap (op0, op1);
1669 /* These can be done a word at a time. */
1670 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1671 && is_int_mode (mode, &int_mode)
1672 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
1673 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1675 int i;
1676 rtx_insn *insns;
1678 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1679 won't be accurate, so use a new target. */
1680 if (target == 0
1681 || target == op0
1682 || target == op1
1683 || reg_overlap_mentioned_p (target, op0)
1684 || reg_overlap_mentioned_p (target, op1)
1685 || !valid_multiword_target_p (target))
1686 target = gen_reg_rtx (int_mode);
1688 start_sequence ();
1690 /* Do the actual arithmetic. */
1691 machine_mode op0_mode = GET_MODE (op0);
1692 machine_mode op1_mode = GET_MODE (op1);
1693 if (op0_mode == VOIDmode)
1694 op0_mode = int_mode;
1695 if (op1_mode == VOIDmode)
1696 op1_mode = int_mode;
1697 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
1699 rtx target_piece = operand_subword (target, i, 1, int_mode);
1700 rtx x = expand_binop (word_mode, binoptab,
1701 operand_subword_force (op0, i, op0_mode),
1702 operand_subword_force (op1, i, op1_mode),
1703 target_piece, unsignedp, next_methods);
1705 if (x == 0)
1706 break;
1708 if (target_piece != x)
1709 emit_move_insn (target_piece, x);
1712 insns = get_insns ();
1713 end_sequence ();
1715 if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
1717 emit_insn (insns);
1718 return target;
1722 /* Synthesize double word shifts from single word shifts. */
1723 if ((binoptab == lshr_optab || binoptab == ashl_optab
1724 || binoptab == ashr_optab)
1725 && is_int_mode (mode, &int_mode)
1726 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1727 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
1728 && GET_MODE_PRECISION (int_mode) == GET_MODE_BITSIZE (int_mode)
1729 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1730 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1731 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1733 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1734 scalar_int_mode op1_mode;
1736 double_shift_mask = targetm.shift_truncation_mask (int_mode);
1737 shift_mask = targetm.shift_truncation_mask (word_mode);
1738 op1_mode = (GET_MODE (op1) != VOIDmode
1739 ? as_a <scalar_int_mode> (GET_MODE (op1))
1740 : word_mode);
1742 /* Apply the truncation to constant shifts. */
1743 if (double_shift_mask > 0 && CONST_INT_P (op1))
1744 op1 = gen_int_mode (INTVAL (op1) & double_shift_mask, op1_mode);
1746 if (op1 == CONST0_RTX (op1_mode))
1747 return op0;
1749 /* Make sure that this is a combination that expand_doubleword_shift
1750 can handle. See the comments there for details. */
1751 if (double_shift_mask == 0
1752 || (shift_mask == BITS_PER_WORD - 1
1753 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1755 rtx_insn *insns;
1756 rtx into_target, outof_target;
1757 rtx into_input, outof_input;
1758 int left_shift, outof_word;
1760 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1761 won't be accurate, so use a new target. */
1762 if (target == 0
1763 || target == op0
1764 || target == op1
1765 || reg_overlap_mentioned_p (target, op0)
1766 || reg_overlap_mentioned_p (target, op1)
1767 || !valid_multiword_target_p (target))
1768 target = gen_reg_rtx (int_mode);
1770 start_sequence ();
1772 /* OUTOF_* is the word we are shifting bits away from, and
1773 INTO_* is the word that we are shifting bits towards, thus
1774 they differ depending on the direction of the shift and
1775 WORDS_BIG_ENDIAN. */
1777 left_shift = binoptab == ashl_optab;
1778 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1780 outof_target = operand_subword (target, outof_word, 1, int_mode);
1781 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1783 outof_input = operand_subword_force (op0, outof_word, int_mode);
1784 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1786 if (expand_doubleword_shift (op1_mode, binoptab,
1787 outof_input, into_input, op1,
1788 outof_target, into_target,
1789 unsignedp, next_methods, shift_mask))
1791 insns = get_insns ();
1792 end_sequence ();
1794 emit_insn (insns);
1795 return target;
1797 end_sequence ();
1801 /* Synthesize double word rotates from single word shifts. */
1802 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1803 && is_int_mode (mode, &int_mode)
1804 && CONST_INT_P (op1)
1805 && GET_MODE_PRECISION (int_mode) == 2 * BITS_PER_WORD
1806 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1807 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1809 rtx_insn *insns;
1810 rtx into_target, outof_target;
1811 rtx into_input, outof_input;
1812 rtx inter;
1813 int shift_count, left_shift, outof_word;
1815 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1816 won't be accurate, so use a new target. Do this also if target is not
1817 a REG, first because having a register instead may open optimization
1818 opportunities, and second because if target and op0 happen to be MEMs
1819 designating the same location, we would risk clobbering it too early
1820 in the code sequence we generate below. */
1821 if (target == 0
1822 || target == op0
1823 || target == op1
1824 || !REG_P (target)
1825 || reg_overlap_mentioned_p (target, op0)
1826 || reg_overlap_mentioned_p (target, op1)
1827 || !valid_multiword_target_p (target))
1828 target = gen_reg_rtx (int_mode);
1830 start_sequence ();
1832 shift_count = INTVAL (op1);
1834 /* OUTOF_* is the word we are shifting bits away from, and
1835 INTO_* is the word that we are shifting bits towards, thus
1836 they differ depending on the direction of the shift and
1837 WORDS_BIG_ENDIAN. */
1839 left_shift = (binoptab == rotl_optab);
1840 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1842 outof_target = operand_subword (target, outof_word, 1, int_mode);
1843 into_target = operand_subword (target, 1 - outof_word, 1, int_mode);
1845 outof_input = operand_subword_force (op0, outof_word, int_mode);
1846 into_input = operand_subword_force (op0, 1 - outof_word, int_mode);
1848 if (shift_count == BITS_PER_WORD)
1850 /* This is just a word swap. */
1851 emit_move_insn (outof_target, into_input);
1852 emit_move_insn (into_target, outof_input);
1853 inter = const0_rtx;
1855 else
1857 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1858 HOST_WIDE_INT first_shift_count, second_shift_count;
1859 optab reverse_unsigned_shift, unsigned_shift;
1861 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1862 ? lshr_optab : ashl_optab);
1864 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1865 ? ashl_optab : lshr_optab);
1867 if (shift_count > BITS_PER_WORD)
1869 first_shift_count = shift_count - BITS_PER_WORD;
1870 second_shift_count = 2 * BITS_PER_WORD - shift_count;
1872 else
1874 first_shift_count = BITS_PER_WORD - shift_count;
1875 second_shift_count = shift_count;
1877 rtx first_shift_count_rtx
1878 = gen_int_shift_amount (word_mode, first_shift_count);
1879 rtx second_shift_count_rtx
1880 = gen_int_shift_amount (word_mode, second_shift_count);
1882 into_temp1 = expand_binop (word_mode, unsigned_shift,
1883 outof_input, first_shift_count_rtx,
1884 NULL_RTX, unsignedp, next_methods);
1885 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1886 into_input, second_shift_count_rtx,
1887 NULL_RTX, unsignedp, next_methods);
1889 if (into_temp1 != 0 && into_temp2 != 0)
1890 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1891 into_target, unsignedp, next_methods);
1892 else
1893 inter = 0;
1895 if (inter != 0 && inter != into_target)
1896 emit_move_insn (into_target, inter);
1898 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1899 into_input, first_shift_count_rtx,
1900 NULL_RTX, unsignedp, next_methods);
1901 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1902 outof_input, second_shift_count_rtx,
1903 NULL_RTX, unsignedp, next_methods);
1905 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1906 inter = expand_binop (word_mode, ior_optab,
1907 outof_temp1, outof_temp2,
1908 outof_target, unsignedp, next_methods);
1910 if (inter != 0 && inter != outof_target)
1911 emit_move_insn (outof_target, inter);
1914 insns = get_insns ();
1915 end_sequence ();
1917 if (inter != 0)
1919 emit_insn (insns);
1920 return target;
1924 /* These can be done a word at a time by propagating carries. */
1925 if ((binoptab == add_optab || binoptab == sub_optab)
1926 && is_int_mode (mode, &int_mode)
1927 && GET_MODE_SIZE (int_mode) >= 2 * UNITS_PER_WORD
1928 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1930 unsigned int i;
1931 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1932 const unsigned int nwords = GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD;
1933 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1934 rtx xop0, xop1, xtarget;
1936 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1937 value is one of those, use it. Otherwise, use 1 since it is the
1938 one easiest to get. */
1939 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1940 int normalizep = STORE_FLAG_VALUE;
1941 #else
1942 int normalizep = 1;
1943 #endif
1945 /* Prepare the operands. */
1946 xop0 = force_reg (int_mode, op0);
1947 xop1 = force_reg (int_mode, op1);
1949 xtarget = gen_reg_rtx (int_mode);
1951 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1952 target = xtarget;
1954 /* Indicate for flow that the entire target reg is being set. */
1955 if (REG_P (target))
1956 emit_clobber (xtarget);
1958 /* Do the actual arithmetic. */
1959 for (i = 0; i < nwords; i++)
1961 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1962 rtx target_piece = operand_subword (xtarget, index, 1, int_mode);
1963 rtx op0_piece = operand_subword_force (xop0, index, int_mode);
1964 rtx op1_piece = operand_subword_force (xop1, index, int_mode);
1965 rtx x;
1967 /* Main add/subtract of the input operands. */
1968 x = expand_binop (word_mode, binoptab,
1969 op0_piece, op1_piece,
1970 target_piece, unsignedp, next_methods);
1971 if (x == 0)
1972 break;
1974 if (i + 1 < nwords)
1976 /* Store carry from main add/subtract. */
1977 carry_out = gen_reg_rtx (word_mode);
1978 carry_out = emit_store_flag_force (carry_out,
1979 (binoptab == add_optab
1980 ? LT : GT),
1981 x, op0_piece,
1982 word_mode, 1, normalizep);
1985 if (i > 0)
1987 rtx newx;
1989 /* Add/subtract previous carry to main result. */
1990 newx = expand_binop (word_mode,
1991 normalizep == 1 ? binoptab : otheroptab,
1992 x, carry_in,
1993 NULL_RTX, 1, next_methods);
1995 if (i + 1 < nwords)
1997 /* Get out carry from adding/subtracting carry in. */
1998 rtx carry_tmp = gen_reg_rtx (word_mode);
1999 carry_tmp = emit_store_flag_force (carry_tmp,
2000 (binoptab == add_optab
2001 ? LT : GT),
2002 newx, x,
2003 word_mode, 1, normalizep);
2005 /* Logical-ior the two poss. carry together. */
2006 carry_out = expand_binop (word_mode, ior_optab,
2007 carry_out, carry_tmp,
2008 carry_out, 0, next_methods);
2009 if (carry_out == 0)
2010 break;
2012 emit_move_insn (target_piece, newx);
2014 else
2016 if (x != target_piece)
2017 emit_move_insn (target_piece, x);
2020 carry_in = carry_out;
2023 if (i == GET_MODE_BITSIZE (int_mode) / (unsigned) BITS_PER_WORD)
2025 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing
2026 || ! rtx_equal_p (target, xtarget))
2028 rtx_insn *temp = emit_move_insn (target, xtarget);
2030 set_dst_reg_note (temp, REG_EQUAL,
2031 gen_rtx_fmt_ee (optab_to_code (binoptab),
2032 int_mode, copy_rtx (xop0),
2033 copy_rtx (xop1)),
2034 target);
2036 else
2037 target = xtarget;
2039 return target;
2042 else
2043 delete_insns_since (last);
2046 /* Attempt to synthesize double word multiplies using a sequence of word
2047 mode multiplications. We first attempt to generate a sequence using a
2048 more efficient unsigned widening multiply, and if that fails we then
2049 try using a signed widening multiply. */
2051 if (binoptab == smul_optab
2052 && is_int_mode (mode, &int_mode)
2053 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2054 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
2055 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
2057 rtx product = NULL_RTX;
2058 if (convert_optab_handler (umul_widen_optab, int_mode, word_mode)
2059 != CODE_FOR_nothing)
2061 product = expand_doubleword_mult (int_mode, op0, op1, target,
2062 true, methods);
2063 if (!product)
2064 delete_insns_since (last);
2067 if (product == NULL_RTX
2068 && (convert_optab_handler (smul_widen_optab, int_mode, word_mode)
2069 != CODE_FOR_nothing))
2071 product = expand_doubleword_mult (int_mode, op0, op1, target,
2072 false, methods);
2073 if (!product)
2074 delete_insns_since (last);
2077 if (product != NULL_RTX)
2079 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
2081 rtx_insn *move = emit_move_insn (target ? target : product,
2082 product);
2083 set_dst_reg_note (move,
2084 REG_EQUAL,
2085 gen_rtx_fmt_ee (MULT, int_mode,
2086 copy_rtx (op0),
2087 copy_rtx (op1)),
2088 target ? target : product);
2090 return product;
2094 /* Attempt to synthetize double word modulo by constant divisor. */
2095 if ((binoptab == umod_optab
2096 || binoptab == smod_optab
2097 || binoptab == udiv_optab
2098 || binoptab == sdiv_optab)
2099 && optimize
2100 && CONST_INT_P (op1)
2101 && is_int_mode (mode, &int_mode)
2102 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
2103 && optab_handler ((binoptab == umod_optab || binoptab == udiv_optab)
2104 ? udivmod_optab : sdivmod_optab,
2105 int_mode) == CODE_FOR_nothing
2106 && optab_handler (and_optab, word_mode) != CODE_FOR_nothing
2107 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing
2108 && optimize_insn_for_speed_p ())
2110 rtx res = NULL_RTX;
2111 if ((binoptab == umod_optab || binoptab == smod_optab)
2112 && (INTVAL (op1) & 1) == 0)
2113 res = expand_doubleword_mod (int_mode, op0, op1,
2114 binoptab == umod_optab);
2115 else
2117 rtx quot = expand_doubleword_divmod (int_mode, op0, op1, &res,
2118 binoptab == umod_optab
2119 || binoptab == udiv_optab);
2120 if (quot == NULL_RTX)
2121 res = NULL_RTX;
2122 else if (binoptab == udiv_optab || binoptab == sdiv_optab)
2123 res = quot;
2125 if (res != NULL_RTX)
2127 if (optab_handler (mov_optab, int_mode) != CODE_FOR_nothing)
2129 rtx_insn *move = emit_move_insn (target ? target : res,
2130 res);
2131 set_dst_reg_note (move, REG_EQUAL,
2132 gen_rtx_fmt_ee (optab_to_code (binoptab),
2133 int_mode, copy_rtx (op0), op1),
2134 target ? target : res);
2136 return res;
2138 else
2139 delete_insns_since (last);
2142 /* It can't be open-coded in this mode.
2143 Use a library call if one is available and caller says that's ok. */
2145 libfunc = optab_libfunc (binoptab, mode);
2146 if (libfunc
2147 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
2149 rtx_insn *insns;
2150 rtx op1x = op1;
2151 machine_mode op1_mode = mode;
2152 rtx value;
2154 start_sequence ();
2156 if (shift_optab_p (binoptab))
2158 op1_mode = targetm.libgcc_shift_count_mode ();
2159 /* Specify unsigned here,
2160 since negative shift counts are meaningless. */
2161 op1x = convert_to_mode (op1_mode, op1, 1);
2164 if (GET_MODE (op0) != VOIDmode
2165 && GET_MODE (op0) != mode)
2166 op0 = convert_to_mode (mode, op0, unsignedp);
2168 /* Pass 1 for NO_QUEUE so we don't lose any increments
2169 if the libcall is cse'd or moved. */
2170 value = emit_library_call_value (libfunc,
2171 NULL_RTX, LCT_CONST, mode,
2172 op0, mode, op1x, op1_mode);
2174 insns = get_insns ();
2175 end_sequence ();
2177 bool trapv = trapv_binoptab_p (binoptab);
2178 target = gen_reg_rtx (mode);
2179 emit_libcall_block_1 (insns, target, value,
2180 trapv ? NULL_RTX
2181 : gen_rtx_fmt_ee (optab_to_code (binoptab),
2182 mode, op0, op1), trapv);
2184 return target;
2187 delete_insns_since (last);
2189 /* It can't be done in this mode. Can we do it in a wider mode? */
2191 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2192 || methods == OPTAB_MUST_WIDEN))
2194 /* Caller says, don't even try. */
2195 delete_insns_since (entry_last);
2196 return 0;
2199 /* Compute the value of METHODS to pass to recursive calls.
2200 Don't allow widening to be tried recursively. */
2202 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2204 /* Look for a wider mode of the same class for which it appears we can do
2205 the operation. */
2207 if (CLASS_HAS_WIDER_MODES_P (mclass))
2209 /* This code doesn't make sense for conversion optabs, since we
2210 wouldn't then want to extend the operands to be the same size
2211 as the result. */
2212 gcc_assert (!convert_optab_p (binoptab));
2213 FOR_EACH_WIDER_MODE (wider_mode, mode)
2215 if (optab_handler (binoptab, wider_mode)
2216 || (methods == OPTAB_LIB
2217 && optab_libfunc (binoptab, wider_mode)))
2219 rtx xop0 = op0, xop1 = op1;
2220 int no_extend = 0;
2222 /* For certain integer operations, we need not actually extend
2223 the narrow operands, as long as we will truncate
2224 the results to the same narrowness. */
2226 if ((binoptab == ior_optab || binoptab == and_optab
2227 || binoptab == xor_optab
2228 || binoptab == add_optab || binoptab == sub_optab
2229 || binoptab == smul_optab || binoptab == ashl_optab)
2230 && mclass == MODE_INT)
2231 no_extend = 1;
2233 xop0 = widen_operand (xop0, wider_mode, mode,
2234 unsignedp, no_extend);
2236 /* The second operand of a shift must always be extended. */
2237 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2238 no_extend && binoptab != ashl_optab);
2240 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2241 unsignedp, methods);
2242 if (temp)
2244 if (mclass != MODE_INT
2245 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2247 if (target == 0)
2248 target = gen_reg_rtx (mode);
2249 convert_move (target, temp, 0);
2250 return target;
2252 else
2253 return gen_lowpart (mode, temp);
2255 else
2256 delete_insns_since (last);
2261 delete_insns_since (entry_last);
2262 return 0;
2265 /* Expand a binary operator which has both signed and unsigned forms.
2266 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2267 signed operations.
2269 If we widen unsigned operands, we may use a signed wider operation instead
2270 of an unsigned wider operation, since the result would be the same. */
2273 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
2274 rtx op0, rtx op1, rtx target, int unsignedp,
2275 enum optab_methods methods)
2277 rtx temp;
2278 optab direct_optab = unsignedp ? uoptab : soptab;
2279 bool save_enable;
2281 /* Do it without widening, if possible. */
2282 temp = expand_binop (mode, direct_optab, op0, op1, target,
2283 unsignedp, OPTAB_DIRECT);
2284 if (temp || methods == OPTAB_DIRECT)
2285 return temp;
2287 /* Try widening to a signed int. Disable any direct use of any
2288 signed insn in the current mode. */
2289 save_enable = swap_optab_enable (soptab, mode, false);
2291 temp = expand_binop (mode, soptab, op0, op1, target,
2292 unsignedp, OPTAB_WIDEN);
2294 /* For unsigned operands, try widening to an unsigned int. */
2295 if (!temp && unsignedp)
2296 temp = expand_binop (mode, uoptab, op0, op1, target,
2297 unsignedp, OPTAB_WIDEN);
2298 if (temp || methods == OPTAB_WIDEN)
2299 goto egress;
2301 /* Use the right width libcall if that exists. */
2302 temp = expand_binop (mode, direct_optab, op0, op1, target,
2303 unsignedp, OPTAB_LIB);
2304 if (temp || methods == OPTAB_LIB)
2305 goto egress;
2307 /* Must widen and use a libcall, use either signed or unsigned. */
2308 temp = expand_binop (mode, soptab, op0, op1, target,
2309 unsignedp, methods);
2310 if (!temp && unsignedp)
2311 temp = expand_binop (mode, uoptab, op0, op1, target,
2312 unsignedp, methods);
2314 egress:
2315 /* Undo the fiddling above. */
2316 if (save_enable)
2317 swap_optab_enable (soptab, mode, true);
2318 return temp;
2321 /* Generate code to perform an operation specified by UNOPPTAB
2322 on operand OP0, with two results to TARG0 and TARG1.
2323 We assume that the order of the operands for the instruction
2324 is TARG0, TARG1, OP0.
2326 Either TARG0 or TARG1 may be zero, but what that means is that
2327 the result is not actually wanted. We will generate it into
2328 a dummy pseudo-reg and discard it. They may not both be zero.
2330 Returns 1 if this operation can be performed; 0 if not. */
2333 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2334 int unsignedp)
2336 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2337 enum mode_class mclass;
2338 machine_mode wider_mode;
2339 rtx_insn *entry_last = get_last_insn ();
2340 rtx_insn *last;
2342 mclass = GET_MODE_CLASS (mode);
2344 if (!targ0)
2345 targ0 = gen_reg_rtx (mode);
2346 if (!targ1)
2347 targ1 = gen_reg_rtx (mode);
2349 /* Record where to go back to if we fail. */
2350 last = get_last_insn ();
2352 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2354 class expand_operand ops[3];
2355 enum insn_code icode = optab_handler (unoptab, mode);
2357 create_fixed_operand (&ops[0], targ0);
2358 create_fixed_operand (&ops[1], targ1);
2359 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
2360 if (maybe_expand_insn (icode, 3, ops))
2361 return 1;
2364 /* It can't be done in this mode. Can we do it in a wider mode? */
2366 if (CLASS_HAS_WIDER_MODES_P (mclass))
2368 FOR_EACH_WIDER_MODE (wider_mode, mode)
2370 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2372 rtx t0 = gen_reg_rtx (wider_mode);
2373 rtx t1 = gen_reg_rtx (wider_mode);
2374 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2376 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2378 convert_move (targ0, t0, unsignedp);
2379 convert_move (targ1, t1, unsignedp);
2380 return 1;
2382 else
2383 delete_insns_since (last);
2388 delete_insns_since (entry_last);
2389 return 0;
2392 /* Generate code to perform an operation specified by BINOPTAB
2393 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2394 We assume that the order of the operands for the instruction
2395 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2396 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2398 Either TARG0 or TARG1 may be zero, but what that means is that
2399 the result is not actually wanted. We will generate it into
2400 a dummy pseudo-reg and discard it. They may not both be zero.
2402 Returns 1 if this operation can be performed; 0 if not. */
2405 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2406 int unsignedp)
2408 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2409 enum mode_class mclass;
2410 machine_mode wider_mode;
2411 rtx_insn *entry_last = get_last_insn ();
2412 rtx_insn *last;
2414 mclass = GET_MODE_CLASS (mode);
2416 if (!targ0)
2417 targ0 = gen_reg_rtx (mode);
2418 if (!targ1)
2419 targ1 = gen_reg_rtx (mode);
2421 /* Record where to go back to if we fail. */
2422 last = get_last_insn ();
2424 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2426 class expand_operand ops[4];
2427 enum insn_code icode = optab_handler (binoptab, mode);
2428 machine_mode mode0 = insn_data[icode].operand[1].mode;
2429 machine_mode mode1 = insn_data[icode].operand[2].mode;
2430 rtx xop0 = op0, xop1 = op1;
2432 /* If we are optimizing, force expensive constants into a register. */
2433 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2434 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2436 create_fixed_operand (&ops[0], targ0);
2437 create_convert_operand_from (&ops[1], xop0, mode, unsignedp);
2438 create_convert_operand_from (&ops[2], xop1, mode, unsignedp);
2439 create_fixed_operand (&ops[3], targ1);
2440 if (maybe_expand_insn (icode, 4, ops))
2441 return 1;
2442 delete_insns_since (last);
2445 /* It can't be done in this mode. Can we do it in a wider mode? */
2447 if (CLASS_HAS_WIDER_MODES_P (mclass))
2449 FOR_EACH_WIDER_MODE (wider_mode, mode)
2451 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2453 rtx t0 = gen_reg_rtx (wider_mode);
2454 rtx t1 = gen_reg_rtx (wider_mode);
2455 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2456 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2458 if (expand_twoval_binop (binoptab, cop0, cop1,
2459 t0, t1, unsignedp))
2461 convert_move (targ0, t0, unsignedp);
2462 convert_move (targ1, t1, unsignedp);
2463 return 1;
2465 else
2466 delete_insns_since (last);
2471 delete_insns_since (entry_last);
2472 return 0;
2475 /* Expand the two-valued library call indicated by BINOPTAB, but
2476 preserve only one of the values. If TARG0 is non-NULL, the first
2477 value is placed into TARG0; otherwise the second value is placed
2478 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2479 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2480 This routine assumes that the value returned by the library call is
2481 as if the return value was of an integral mode twice as wide as the
2482 mode of OP0. Returns 1 if the call was successful. */
2484 bool
2485 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2486 rtx targ0, rtx targ1, enum rtx_code code)
2488 machine_mode mode;
2489 machine_mode libval_mode;
2490 rtx libval;
2491 rtx_insn *insns;
2492 rtx libfunc;
2494 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2495 gcc_assert (!targ0 != !targ1);
2497 mode = GET_MODE (op0);
2498 libfunc = optab_libfunc (binoptab, mode);
2499 if (!libfunc)
2500 return false;
2502 /* The value returned by the library function will have twice as
2503 many bits as the nominal MODE. */
2504 libval_mode = smallest_int_mode_for_size (2 * GET_MODE_BITSIZE (mode));
2505 start_sequence ();
2506 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2507 libval_mode,
2508 op0, mode,
2509 op1, mode);
2510 /* Get the part of VAL containing the value that we want. */
2511 libval = simplify_gen_subreg (mode, libval, libval_mode,
2512 targ0 ? 0 : GET_MODE_SIZE (mode));
2513 insns = get_insns ();
2514 end_sequence ();
2515 /* Move the into the desired location. */
2516 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2517 gen_rtx_fmt_ee (code, mode, op0, op1));
2519 return true;
2523 /* Wrapper around expand_unop which takes an rtx code to specify
2524 the operation to perform, not an optab pointer. All other
2525 arguments are the same. */
2527 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2528 rtx target, int unsignedp)
2530 optab unop = code_to_optab (code);
2531 gcc_assert (unop);
2533 return expand_unop (mode, unop, op0, target, unsignedp);
2536 /* Try calculating
2537 (clz:narrow x)
2539 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2541 A similar operation can be used for clrsb. UNOPTAB says which operation
2542 we are trying to expand. */
2543 static rtx
2544 widen_leading (scalar_int_mode mode, rtx op0, rtx target, optab unoptab)
2546 opt_scalar_int_mode wider_mode_iter;
2547 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2549 scalar_int_mode wider_mode = wider_mode_iter.require ();
2550 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2552 rtx xop0, temp;
2553 rtx_insn *last;
2555 last = get_last_insn ();
2557 if (target == 0)
2558 target = gen_reg_rtx (mode);
2559 xop0 = widen_operand (op0, wider_mode, mode,
2560 unoptab != clrsb_optab, false);
2561 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2562 unoptab != clrsb_optab);
2563 if (temp != 0)
2564 temp = expand_binop
2565 (wider_mode, sub_optab, temp,
2566 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2567 - GET_MODE_PRECISION (mode),
2568 wider_mode),
2569 target, true, OPTAB_DIRECT);
2570 if (temp == 0)
2571 delete_insns_since (last);
2573 return temp;
2576 return 0;
2579 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2580 quantities, choosing which based on whether the high word is nonzero. */
2581 static rtx
2582 expand_doubleword_clz (scalar_int_mode mode, rtx op0, rtx target)
2584 rtx xop0 = force_reg (mode, op0);
2585 rtx subhi = gen_highpart (word_mode, xop0);
2586 rtx sublo = gen_lowpart (word_mode, xop0);
2587 rtx_code_label *hi0_label = gen_label_rtx ();
2588 rtx_code_label *after_label = gen_label_rtx ();
2589 rtx_insn *seq;
2590 rtx temp, result;
2592 /* If we were not given a target, use a word_mode register, not a
2593 'mode' register. The result will fit, and nobody is expecting
2594 anything bigger (the return type of __builtin_clz* is int). */
2595 if (!target)
2596 target = gen_reg_rtx (word_mode);
2598 /* In any case, write to a word_mode scratch in both branches of the
2599 conditional, so we can ensure there is a single move insn setting
2600 'target' to tag a REG_EQUAL note on. */
2601 result = gen_reg_rtx (word_mode);
2603 start_sequence ();
2605 /* If the high word is not equal to zero,
2606 then clz of the full value is clz of the high word. */
2607 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2608 word_mode, true, hi0_label);
2610 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2611 if (!temp)
2612 goto fail;
2614 if (temp != result)
2615 convert_move (result, temp, true);
2617 emit_jump_insn (targetm.gen_jump (after_label));
2618 emit_barrier ();
2620 /* Else clz of the full value is clz of the low word plus the number
2621 of bits in the high word. */
2622 emit_label (hi0_label);
2624 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2625 if (!temp)
2626 goto fail;
2627 temp = expand_binop (word_mode, add_optab, temp,
2628 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2629 result, true, OPTAB_DIRECT);
2630 if (!temp)
2631 goto fail;
2632 if (temp != result)
2633 convert_move (result, temp, true);
2635 emit_label (after_label);
2636 convert_move (target, result, true);
2638 seq = get_insns ();
2639 end_sequence ();
2641 add_equal_note (seq, target, CLZ, xop0, NULL_RTX, mode);
2642 emit_insn (seq);
2643 return target;
2645 fail:
2646 end_sequence ();
2647 return 0;
2650 /* Try calculating popcount of a double-word quantity as two popcount's of
2651 word-sized quantities and summing up the results. */
2652 static rtx
2653 expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
2655 rtx t0, t1, t;
2656 rtx_insn *seq;
2658 start_sequence ();
2660 t0 = expand_unop_direct (word_mode, popcount_optab,
2661 operand_subword_force (op0, 0, mode), NULL_RTX,
2662 true);
2663 t1 = expand_unop_direct (word_mode, popcount_optab,
2664 operand_subword_force (op0, 1, mode), NULL_RTX,
2665 true);
2666 if (!t0 || !t1)
2668 end_sequence ();
2669 return NULL_RTX;
2672 /* If we were not given a target, use a word_mode register, not a
2673 'mode' register. The result will fit, and nobody is expecting
2674 anything bigger (the return type of __builtin_popcount* is int). */
2675 if (!target)
2676 target = gen_reg_rtx (word_mode);
2678 t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
2680 seq = get_insns ();
2681 end_sequence ();
2683 add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
2684 emit_insn (seq);
2685 return t;
2688 /* Try calculating
2689 (parity:wide x)
2691 (parity:narrow (low (x) ^ high (x))) */
2692 static rtx
2693 expand_doubleword_parity (scalar_int_mode mode, rtx op0, rtx target)
2695 rtx t = expand_binop (word_mode, xor_optab,
2696 operand_subword_force (op0, 0, mode),
2697 operand_subword_force (op0, 1, mode),
2698 NULL_RTX, 0, OPTAB_DIRECT);
2699 return expand_unop (word_mode, parity_optab, t, target, true);
2702 /* Try calculating
2703 (bswap:narrow x)
2705 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2706 static rtx
2707 widen_bswap (scalar_int_mode mode, rtx op0, rtx target)
2709 rtx x;
2710 rtx_insn *last;
2711 opt_scalar_int_mode wider_mode_iter;
2713 FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
2714 if (optab_handler (bswap_optab, wider_mode_iter.require ())
2715 != CODE_FOR_nothing)
2716 break;
2718 if (!wider_mode_iter.exists ())
2719 return NULL_RTX;
2721 scalar_int_mode wider_mode = wider_mode_iter.require ();
2722 last = get_last_insn ();
2724 x = widen_operand (op0, wider_mode, mode, true, true);
2725 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2727 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2728 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2729 if (x != 0)
2730 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2731 GET_MODE_BITSIZE (wider_mode)
2732 - GET_MODE_BITSIZE (mode),
2733 NULL_RTX, true);
2735 if (x != 0)
2737 if (target == 0)
2738 target = gen_reg_rtx (mode);
2739 emit_move_insn (target, gen_lowpart (mode, x));
2741 else
2742 delete_insns_since (last);
2744 return target;
2747 /* Try calculating bswap as two bswaps of two word-sized operands. */
2749 static rtx
2750 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2752 rtx t0, t1;
2754 t1 = expand_unop (word_mode, bswap_optab,
2755 operand_subword_force (op, 0, mode), NULL_RTX, true);
2756 t0 = expand_unop (word_mode, bswap_optab,
2757 operand_subword_force (op, 1, mode), NULL_RTX, true);
2759 if (target == 0 || !valid_multiword_target_p (target))
2760 target = gen_reg_rtx (mode);
2761 if (REG_P (target))
2762 emit_clobber (target);
2763 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2764 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2766 return target;
2769 /* Try calculating (parity x) as (and (popcount x) 1), where
2770 popcount can also be done in a wider mode. */
2771 static rtx
2772 expand_parity (scalar_int_mode mode, rtx op0, rtx target)
2774 enum mode_class mclass = GET_MODE_CLASS (mode);
2775 opt_scalar_int_mode wider_mode_iter;
2776 FOR_EACH_MODE_FROM (wider_mode_iter, mode)
2778 scalar_int_mode wider_mode = wider_mode_iter.require ();
2779 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2781 rtx xop0, temp;
2782 rtx_insn *last;
2784 last = get_last_insn ();
2786 if (target == 0 || GET_MODE (target) != wider_mode)
2787 target = gen_reg_rtx (wider_mode);
2789 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2790 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2791 true);
2792 if (temp != 0)
2793 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2794 target, true, OPTAB_DIRECT);
2796 if (temp)
2798 if (mclass != MODE_INT
2799 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2800 return convert_to_mode (mode, temp, 0);
2801 else
2802 return gen_lowpart (mode, temp);
2804 else
2805 delete_insns_since (last);
2808 return 0;
2811 /* Try calculating ctz(x) as K - clz(x & -x) ,
2812 where K is GET_MODE_PRECISION(mode) - 1.
2814 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2815 don't have to worry about what the hardware does in that case. (If
2816 the clz instruction produces the usual value at 0, which is K, the
2817 result of this code sequence will be -1; expand_ffs, below, relies
2818 on this. It might be nice to have it be K instead, for consistency
2819 with the (very few) processors that provide a ctz with a defined
2820 value, but that would take one more instruction, and it would be
2821 less convenient for expand_ffs anyway. */
2823 static rtx
2824 expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
2826 rtx_insn *seq;
2827 rtx temp;
2829 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2830 return 0;
2832 start_sequence ();
2834 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2835 if (temp)
2836 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2837 true, OPTAB_DIRECT);
2838 if (temp)
2839 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2840 if (temp)
2841 temp = expand_binop (mode, sub_optab,
2842 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2843 temp, target,
2844 true, OPTAB_DIRECT);
2845 if (temp == 0)
2847 end_sequence ();
2848 return 0;
2851 seq = get_insns ();
2852 end_sequence ();
2854 add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
2855 emit_insn (seq);
2856 return temp;
2860 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2861 else with the sequence used by expand_clz.
2863 The ffs builtin promises to return zero for a zero value and ctz/clz
2864 may have an undefined value in that case. If they do not give us a
2865 convenient value, we have to generate a test and branch. */
2866 static rtx
2867 expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
2869 HOST_WIDE_INT val = 0;
2870 bool defined_at_zero = false;
2871 rtx temp;
2872 rtx_insn *seq;
2874 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2876 start_sequence ();
2878 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2879 if (!temp)
2880 goto fail;
2882 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2884 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2886 start_sequence ();
2887 temp = expand_ctz (mode, op0, 0);
2888 if (!temp)
2889 goto fail;
2891 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2893 defined_at_zero = true;
2894 val = (GET_MODE_PRECISION (mode) - 1) - val;
2897 else
2898 return 0;
2900 if (defined_at_zero && val == -1)
2901 /* No correction needed at zero. */;
2902 else
2904 /* We don't try to do anything clever with the situation found
2905 on some processors (eg Alpha) where ctz(0:mode) ==
2906 bitsize(mode). If someone can think of a way to send N to -1
2907 and leave alone all values in the range 0..N-1 (where N is a
2908 power of two), cheaper than this test-and-branch, please add it.
2910 The test-and-branch is done after the operation itself, in case
2911 the operation sets condition codes that can be recycled for this.
2912 (This is true on i386, for instance.) */
2914 rtx_code_label *nonzero_label = gen_label_rtx ();
2915 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2916 mode, true, nonzero_label);
2918 convert_move (temp, GEN_INT (-1), false);
2919 emit_label (nonzero_label);
2922 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2923 to produce a value in the range 0..bitsize. */
2924 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2925 target, false, OPTAB_DIRECT);
2926 if (!temp)
2927 goto fail;
2929 seq = get_insns ();
2930 end_sequence ();
2932 add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
2933 emit_insn (seq);
2934 return temp;
2936 fail:
2937 end_sequence ();
2938 return 0;
2941 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2942 conditions, VAL may already be a SUBREG against which we cannot generate
2943 a further SUBREG. In this case, we expect forcing the value into a
2944 register will work around the situation. */
2946 static rtx
2947 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2948 machine_mode imode)
2950 rtx ret;
2951 ret = lowpart_subreg (omode, val, imode);
2952 if (ret == NULL)
2954 val = force_reg (imode, val);
2955 ret = lowpart_subreg (omode, val, imode);
2956 gcc_assert (ret != NULL);
2958 return ret;
2961 /* Expand a floating point absolute value or negation operation via a
2962 logical operation on the sign bit. */
2964 static rtx
2965 expand_absneg_bit (enum rtx_code code, scalar_float_mode mode,
2966 rtx op0, rtx target)
2968 const struct real_format *fmt;
2969 int bitpos, word, nwords, i;
2970 scalar_int_mode imode;
2971 rtx temp;
2972 rtx_insn *insns;
2974 /* The format has to have a simple sign bit. */
2975 fmt = REAL_MODE_FORMAT (mode);
2976 if (fmt == NULL)
2977 return NULL_RTX;
2979 bitpos = fmt->signbit_rw;
2980 if (bitpos < 0)
2981 return NULL_RTX;
2983 /* Don't create negative zeros if the format doesn't support them. */
2984 if (code == NEG && !fmt->has_signed_zero)
2985 return NULL_RTX;
2987 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2989 if (!int_mode_for_mode (mode).exists (&imode))
2990 return NULL_RTX;
2991 word = 0;
2992 nwords = 1;
2994 else
2996 imode = word_mode;
2998 if (FLOAT_WORDS_BIG_ENDIAN)
2999 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3000 else
3001 word = bitpos / BITS_PER_WORD;
3002 bitpos = bitpos % BITS_PER_WORD;
3003 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3006 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3007 if (code == ABS)
3008 mask = ~mask;
3010 if (target == 0
3011 || target == op0
3012 || reg_overlap_mentioned_p (target, op0)
3013 || (nwords > 1 && !valid_multiword_target_p (target)))
3014 target = gen_reg_rtx (mode);
3016 if (nwords > 1)
3018 start_sequence ();
3020 for (i = 0; i < nwords; ++i)
3022 rtx targ_piece = operand_subword (target, i, 1, mode);
3023 rtx op0_piece = operand_subword_force (op0, i, mode);
3025 if (i == word)
3027 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3028 op0_piece,
3029 immed_wide_int_const (mask, imode),
3030 targ_piece, 1, OPTAB_LIB_WIDEN);
3031 if (temp != targ_piece)
3032 emit_move_insn (targ_piece, temp);
3034 else
3035 emit_move_insn (targ_piece, op0_piece);
3038 insns = get_insns ();
3039 end_sequence ();
3041 emit_insn (insns);
3043 else
3045 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
3046 gen_lowpart (imode, op0),
3047 immed_wide_int_const (mask, imode),
3048 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3049 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3051 set_dst_reg_note (get_last_insn (), REG_EQUAL,
3052 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
3053 target);
3056 return target;
3059 /* As expand_unop, but will fail rather than attempt the operation in a
3060 different mode or with a libcall. */
3061 static rtx
3062 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
3063 int unsignedp)
3065 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
3067 class expand_operand ops[2];
3068 enum insn_code icode = optab_handler (unoptab, mode);
3069 rtx_insn *last = get_last_insn ();
3070 rtx_insn *pat;
3072 create_output_operand (&ops[0], target, mode);
3073 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
3074 pat = maybe_gen_insn (icode, 2, ops);
3075 if (pat)
3077 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3078 && ! add_equal_note (pat, ops[0].value,
3079 optab_to_code (unoptab),
3080 ops[1].value, NULL_RTX, mode))
3082 delete_insns_since (last);
3083 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
3086 emit_insn (pat);
3088 return ops[0].value;
3091 return 0;
3094 /* Generate code to perform an operation specified by UNOPTAB
3095 on operand OP0, with result having machine-mode MODE.
3097 UNSIGNEDP is for the case where we have to widen the operands
3098 to perform the operation. It says to use zero-extension.
3100 If TARGET is nonzero, the value
3101 is generated there, if it is convenient to do so.
3102 In all cases an rtx is returned for the locus of the value;
3103 this may or may not be TARGET. */
3106 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
3107 int unsignedp)
3109 enum mode_class mclass = GET_MODE_CLASS (mode);
3110 machine_mode wider_mode;
3111 scalar_int_mode int_mode;
3112 scalar_float_mode float_mode;
3113 rtx temp;
3114 rtx libfunc;
3116 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
3117 if (temp)
3118 return temp;
3120 /* It can't be done in this mode. Can we open-code it in a wider mode? */
3122 /* Widening (or narrowing) clz needs special treatment. */
3123 if (unoptab == clz_optab)
3125 if (is_a <scalar_int_mode> (mode, &int_mode))
3127 temp = widen_leading (int_mode, op0, target, unoptab);
3128 if (temp)
3129 return temp;
3131 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3132 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3134 temp = expand_doubleword_clz (int_mode, op0, target);
3135 if (temp)
3136 return temp;
3140 goto try_libcall;
3143 if (unoptab == clrsb_optab)
3145 if (is_a <scalar_int_mode> (mode, &int_mode))
3147 temp = widen_leading (int_mode, op0, target, unoptab);
3148 if (temp)
3149 return temp;
3151 goto try_libcall;
3154 if (unoptab == popcount_optab
3155 && is_a <scalar_int_mode> (mode, &int_mode)
3156 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3157 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
3158 && optimize_insn_for_speed_p ())
3160 temp = expand_doubleword_popcount (int_mode, op0, target);
3161 if (temp)
3162 return temp;
3165 if (unoptab == parity_optab
3166 && is_a <scalar_int_mode> (mode, &int_mode)
3167 && GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3168 && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
3169 || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
3170 && optimize_insn_for_speed_p ())
3172 temp = expand_doubleword_parity (int_mode, op0, target);
3173 if (temp)
3174 return temp;
3177 /* Widening (or narrowing) bswap needs special treatment. */
3178 if (unoptab == bswap_optab)
3180 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
3181 or ROTATERT. First try these directly; if this fails, then try the
3182 obvious pair of shifts with allowed widening, as this will probably
3183 be always more efficient than the other fallback methods. */
3184 if (mode == HImode)
3186 rtx_insn *last;
3187 rtx temp1, temp2;
3189 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
3191 temp = expand_binop (mode, rotl_optab, op0,
3192 gen_int_shift_amount (mode, 8),
3193 target, unsignedp, OPTAB_DIRECT);
3194 if (temp)
3195 return temp;
3198 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
3200 temp = expand_binop (mode, rotr_optab, op0,
3201 gen_int_shift_amount (mode, 8),
3202 target, unsignedp, OPTAB_DIRECT);
3203 if (temp)
3204 return temp;
3207 last = get_last_insn ();
3209 temp1 = expand_binop (mode, ashl_optab, op0,
3210 gen_int_shift_amount (mode, 8), NULL_RTX,
3211 unsignedp, OPTAB_WIDEN);
3212 temp2 = expand_binop (mode, lshr_optab, op0,
3213 gen_int_shift_amount (mode, 8), NULL_RTX,
3214 unsignedp, OPTAB_WIDEN);
3215 if (temp1 && temp2)
3217 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
3218 unsignedp, OPTAB_WIDEN);
3219 if (temp)
3220 return temp;
3223 delete_insns_since (last);
3226 if (is_a <scalar_int_mode> (mode, &int_mode))
3228 temp = widen_bswap (int_mode, op0, target);
3229 if (temp)
3230 return temp;
3232 /* We do not provide a 128-bit bswap in libgcc so force the use of
3233 a double bswap for 64-bit targets. */
3234 if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
3235 && (UNITS_PER_WORD == 8
3236 || optab_handler (unoptab, word_mode) != CODE_FOR_nothing))
3238 temp = expand_doubleword_bswap (mode, op0, target);
3239 if (temp)
3240 return temp;
3244 goto try_libcall;
3247 if (CLASS_HAS_WIDER_MODES_P (mclass))
3248 FOR_EACH_WIDER_MODE (wider_mode, mode)
3250 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
3252 rtx xop0 = op0;
3253 rtx_insn *last = get_last_insn ();
3255 /* For certain operations, we need not actually extend
3256 the narrow operand, as long as we will truncate the
3257 results to the same narrowness. */
3259 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3260 (unoptab == neg_optab
3261 || unoptab == one_cmpl_optab)
3262 && mclass == MODE_INT);
3264 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3265 unsignedp);
3267 if (temp)
3269 if (mclass != MODE_INT
3270 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
3272 if (target == 0)
3273 target = gen_reg_rtx (mode);
3274 convert_move (target, temp, 0);
3275 return target;
3277 else
3278 return gen_lowpart (mode, temp);
3280 else
3281 delete_insns_since (last);
3285 /* These can be done a word at a time. */
3286 if (unoptab == one_cmpl_optab
3287 && is_int_mode (mode, &int_mode)
3288 && GET_MODE_SIZE (int_mode) > UNITS_PER_WORD
3289 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
3291 int i;
3292 rtx_insn *insns;
3294 if (target == 0
3295 || target == op0
3296 || reg_overlap_mentioned_p (target, op0)
3297 || !valid_multiword_target_p (target))
3298 target = gen_reg_rtx (int_mode);
3300 start_sequence ();
3302 /* Do the actual arithmetic. */
3303 for (i = 0; i < GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD; i++)
3305 rtx target_piece = operand_subword (target, i, 1, int_mode);
3306 rtx x = expand_unop (word_mode, unoptab,
3307 operand_subword_force (op0, i, int_mode),
3308 target_piece, unsignedp);
3310 if (target_piece != x)
3311 emit_move_insn (target_piece, x);
3314 insns = get_insns ();
3315 end_sequence ();
3317 emit_insn (insns);
3318 return target;
3321 /* Emit ~op0 as op0 ^ -1. */
3322 if (unoptab == one_cmpl_optab
3323 && (SCALAR_INT_MODE_P (mode) || GET_MODE_CLASS (mode) == MODE_VECTOR_INT)
3324 && optab_handler (xor_optab, mode) != CODE_FOR_nothing)
3326 temp = expand_binop (mode, xor_optab, op0, CONSTM1_RTX (mode),
3327 target, unsignedp, OPTAB_DIRECT);
3328 if (temp)
3329 return temp;
3332 if (optab_to_code (unoptab) == NEG)
3334 /* Try negating floating point values by flipping the sign bit. */
3335 if (is_a <scalar_float_mode> (mode, &float_mode))
3337 temp = expand_absneg_bit (NEG, float_mode, op0, target);
3338 if (temp)
3339 return temp;
3342 /* If there is no negation pattern, and we have no negative zero,
3343 try subtracting from zero. */
3344 if (!HONOR_SIGNED_ZEROS (mode))
3346 temp = expand_binop (mode, (unoptab == negv_optab
3347 ? subv_optab : sub_optab),
3348 CONST0_RTX (mode), op0, target,
3349 unsignedp, OPTAB_DIRECT);
3350 if (temp)
3351 return temp;
3355 /* Try calculating parity (x) as popcount (x) % 2. */
3356 if (unoptab == parity_optab && is_a <scalar_int_mode> (mode, &int_mode))
3358 temp = expand_parity (int_mode, op0, target);
3359 if (temp)
3360 return temp;
3363 /* Try implementing ffs (x) in terms of clz (x). */
3364 if (unoptab == ffs_optab && is_a <scalar_int_mode> (mode, &int_mode))
3366 temp = expand_ffs (int_mode, op0, target);
3367 if (temp)
3368 return temp;
3371 /* Try implementing ctz (x) in terms of clz (x). */
3372 if (unoptab == ctz_optab && is_a <scalar_int_mode> (mode, &int_mode))
3374 temp = expand_ctz (int_mode, op0, target);
3375 if (temp)
3376 return temp;
3379 try_libcall:
3380 /* Now try a library call in this mode. */
3381 libfunc = optab_libfunc (unoptab, mode);
3382 if (libfunc)
3384 rtx_insn *insns;
3385 rtx value;
3386 rtx eq_value;
3387 machine_mode outmode = mode;
3389 /* All of these functions return small values. Thus we choose to
3390 have them return something that isn't a double-word. */
3391 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3392 || unoptab == clrsb_optab || unoptab == popcount_optab
3393 || unoptab == parity_optab)
3394 outmode
3395 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
3396 optab_libfunc (unoptab, mode)));
3398 start_sequence ();
3400 /* Pass 1 for NO_QUEUE so we don't lose any increments
3401 if the libcall is cse'd or moved. */
3402 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
3403 op0, mode);
3404 insns = get_insns ();
3405 end_sequence ();
3407 target = gen_reg_rtx (outmode);
3408 bool trapv = trapv_unoptab_p (unoptab);
3409 if (trapv)
3410 eq_value = NULL_RTX;
3411 else
3413 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
3414 if (GET_MODE_UNIT_SIZE (outmode) < GET_MODE_UNIT_SIZE (mode))
3415 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
3416 else if (GET_MODE_UNIT_SIZE (outmode) > GET_MODE_UNIT_SIZE (mode))
3417 eq_value = simplify_gen_unary (ZERO_EXTEND,
3418 outmode, eq_value, mode);
3420 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
3422 return target;
3425 /* It can't be done in this mode. Can we do it in a wider mode? */
3427 if (CLASS_HAS_WIDER_MODES_P (mclass))
3429 FOR_EACH_WIDER_MODE (wider_mode, mode)
3431 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
3432 || optab_libfunc (unoptab, wider_mode))
3434 rtx xop0 = op0;
3435 rtx_insn *last = get_last_insn ();
3437 /* For certain operations, we need not actually extend
3438 the narrow operand, as long as we will truncate the
3439 results to the same narrowness. */
3440 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3441 (unoptab == neg_optab
3442 || unoptab == one_cmpl_optab
3443 || unoptab == bswap_optab)
3444 && mclass == MODE_INT);
3446 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3447 unsignedp);
3449 /* If we are generating clz using wider mode, adjust the
3450 result. Similarly for clrsb. */
3451 if ((unoptab == clz_optab || unoptab == clrsb_optab)
3452 && temp != 0)
3454 scalar_int_mode wider_int_mode
3455 = as_a <scalar_int_mode> (wider_mode);
3456 int_mode = as_a <scalar_int_mode> (mode);
3457 temp = expand_binop
3458 (wider_mode, sub_optab, temp,
3459 gen_int_mode (GET_MODE_PRECISION (wider_int_mode)
3460 - GET_MODE_PRECISION (int_mode),
3461 wider_int_mode),
3462 target, true, OPTAB_DIRECT);
3465 /* Likewise for bswap. */
3466 if (unoptab == bswap_optab && temp != 0)
3468 scalar_int_mode wider_int_mode
3469 = as_a <scalar_int_mode> (wider_mode);
3470 int_mode = as_a <scalar_int_mode> (mode);
3471 gcc_assert (GET_MODE_PRECISION (wider_int_mode)
3472 == GET_MODE_BITSIZE (wider_int_mode)
3473 && GET_MODE_PRECISION (int_mode)
3474 == GET_MODE_BITSIZE (int_mode));
3476 temp = expand_shift (RSHIFT_EXPR, wider_int_mode, temp,
3477 GET_MODE_BITSIZE (wider_int_mode)
3478 - GET_MODE_BITSIZE (int_mode),
3479 NULL_RTX, true);
3482 if (temp)
3484 if (mclass != MODE_INT)
3486 if (target == 0)
3487 target = gen_reg_rtx (mode);
3488 convert_move (target, temp, 0);
3489 return target;
3491 else
3492 return gen_lowpart (mode, temp);
3494 else
3495 delete_insns_since (last);
3500 /* One final attempt at implementing negation via subtraction,
3501 this time allowing widening of the operand. */
3502 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3504 rtx temp;
3505 temp = expand_binop (mode,
3506 unoptab == negv_optab ? subv_optab : sub_optab,
3507 CONST0_RTX (mode), op0,
3508 target, unsignedp, OPTAB_LIB_WIDEN);
3509 if (temp)
3510 return temp;
3513 return 0;
3516 /* Emit code to compute the absolute value of OP0, with result to
3517 TARGET if convenient. (TARGET may be 0.) The return value says
3518 where the result actually is to be found.
3520 MODE is the mode of the operand; the mode of the result is
3521 different but can be deduced from MODE.
3526 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3527 int result_unsignedp)
3529 rtx temp;
3531 if (GET_MODE_CLASS (mode) != MODE_INT
3532 || ! flag_trapv)
3533 result_unsignedp = 1;
3535 /* First try to do it with a special abs instruction. */
3536 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3537 op0, target, 0);
3538 if (temp != 0)
3539 return temp;
3541 /* For floating point modes, try clearing the sign bit. */
3542 scalar_float_mode float_mode;
3543 if (is_a <scalar_float_mode> (mode, &float_mode))
3545 temp = expand_absneg_bit (ABS, float_mode, op0, target);
3546 if (temp)
3547 return temp;
3550 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3551 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3552 && !HONOR_SIGNED_ZEROS (mode))
3554 rtx_insn *last = get_last_insn ();
3556 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3557 op0, NULL_RTX, 0);
3558 if (temp != 0)
3559 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3560 OPTAB_WIDEN);
3562 if (temp != 0)
3563 return temp;
3565 delete_insns_since (last);
3568 /* If this machine has expensive jumps, we can do integer absolute
3569 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3570 where W is the width of MODE. */
3572 scalar_int_mode int_mode;
3573 if (is_int_mode (mode, &int_mode)
3574 && BRANCH_COST (optimize_insn_for_speed_p (),
3575 false) >= 2)
3577 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3578 GET_MODE_PRECISION (int_mode) - 1,
3579 NULL_RTX, 0);
3581 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3582 OPTAB_LIB_WIDEN);
3583 if (temp != 0)
3584 temp = expand_binop (int_mode,
3585 result_unsignedp ? sub_optab : subv_optab,
3586 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3588 if (temp != 0)
3589 return temp;
3592 return NULL_RTX;
3596 expand_abs (machine_mode mode, rtx op0, rtx target,
3597 int result_unsignedp, int safe)
3599 rtx temp;
3600 rtx_code_label *op1;
3602 if (GET_MODE_CLASS (mode) != MODE_INT
3603 || ! flag_trapv)
3604 result_unsignedp = 1;
3606 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3607 if (temp != 0)
3608 return temp;
3610 /* If that does not win, use conditional jump and negate. */
3612 /* It is safe to use the target if it is the same
3613 as the source if this is also a pseudo register */
3614 if (op0 == target && REG_P (op0)
3615 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3616 safe = 1;
3618 op1 = gen_label_rtx ();
3619 if (target == 0 || ! safe
3620 || GET_MODE (target) != mode
3621 || (MEM_P (target) && MEM_VOLATILE_P (target))
3622 || (REG_P (target)
3623 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3624 target = gen_reg_rtx (mode);
3626 emit_move_insn (target, op0);
3627 NO_DEFER_POP;
3629 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3630 NULL_RTX, NULL, op1,
3631 profile_probability::uninitialized ());
3633 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3634 target, target, 0);
3635 if (op0 != target)
3636 emit_move_insn (target, op0);
3637 emit_label (op1);
3638 OK_DEFER_POP;
3639 return target;
3642 /* Emit code to compute the one's complement absolute value of OP0
3643 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3644 (TARGET may be NULL_RTX.) The return value says where the result
3645 actually is to be found.
3647 MODE is the mode of the operand; the mode of the result is
3648 different but can be deduced from MODE. */
3651 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3653 rtx temp;
3655 /* Not applicable for floating point modes. */
3656 if (FLOAT_MODE_P (mode))
3657 return NULL_RTX;
3659 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3660 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3662 rtx_insn *last = get_last_insn ();
3664 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3665 if (temp != 0)
3666 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3667 OPTAB_WIDEN);
3669 if (temp != 0)
3670 return temp;
3672 delete_insns_since (last);
3675 /* If this machine has expensive jumps, we can do one's complement
3676 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3678 scalar_int_mode int_mode;
3679 if (is_int_mode (mode, &int_mode)
3680 && BRANCH_COST (optimize_insn_for_speed_p (),
3681 false) >= 2)
3683 rtx extended = expand_shift (RSHIFT_EXPR, int_mode, op0,
3684 GET_MODE_PRECISION (int_mode) - 1,
3685 NULL_RTX, 0);
3687 temp = expand_binop (int_mode, xor_optab, extended, op0, target, 0,
3688 OPTAB_LIB_WIDEN);
3690 if (temp != 0)
3691 return temp;
3694 return NULL_RTX;
3697 /* A subroutine of expand_copysign, perform the copysign operation using the
3698 abs and neg primitives advertised to exist on the target. The assumption
3699 is that we have a split register file, and leaving op0 in fp registers,
3700 and not playing with subregs so much, will help the register allocator. */
3702 static rtx
3703 expand_copysign_absneg (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3704 int bitpos, bool op0_is_abs)
3706 scalar_int_mode imode;
3707 enum insn_code icode;
3708 rtx sign;
3709 rtx_code_label *label;
3711 if (target == op1)
3712 target = NULL_RTX;
3714 /* Check if the back end provides an insn that handles signbit for the
3715 argument's mode. */
3716 icode = optab_handler (signbit_optab, mode);
3717 if (icode != CODE_FOR_nothing)
3719 imode = as_a <scalar_int_mode> (insn_data[(int) icode].operand[0].mode);
3720 sign = gen_reg_rtx (imode);
3721 emit_unop_insn (icode, sign, op1, UNKNOWN);
3723 else
3725 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3727 if (!int_mode_for_mode (mode).exists (&imode))
3728 return NULL_RTX;
3729 op1 = gen_lowpart (imode, op1);
3731 else
3733 int word;
3735 imode = word_mode;
3736 if (FLOAT_WORDS_BIG_ENDIAN)
3737 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3738 else
3739 word = bitpos / BITS_PER_WORD;
3740 bitpos = bitpos % BITS_PER_WORD;
3741 op1 = operand_subword_force (op1, word, mode);
3744 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3745 sign = expand_binop (imode, and_optab, op1,
3746 immed_wide_int_const (mask, imode),
3747 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3750 if (!op0_is_abs)
3752 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3753 if (op0 == NULL)
3754 return NULL_RTX;
3755 target = op0;
3757 else
3759 if (target == NULL_RTX)
3760 target = copy_to_reg (op0);
3761 else
3762 emit_move_insn (target, op0);
3765 label = gen_label_rtx ();
3766 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3768 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3769 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3770 else
3771 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3772 if (op0 != target)
3773 emit_move_insn (target, op0);
3775 emit_label (label);
3777 return target;
3781 /* A subroutine of expand_copysign, perform the entire copysign operation
3782 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3783 is true if op0 is known to have its sign bit clear. */
3785 static rtx
3786 expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
3787 int bitpos, bool op0_is_abs)
3789 scalar_int_mode imode;
3790 int word, nwords, i;
3791 rtx temp;
3792 rtx_insn *insns;
3794 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3796 if (!int_mode_for_mode (mode).exists (&imode))
3797 return NULL_RTX;
3798 word = 0;
3799 nwords = 1;
3801 else
3803 imode = word_mode;
3805 if (FLOAT_WORDS_BIG_ENDIAN)
3806 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3807 else
3808 word = bitpos / BITS_PER_WORD;
3809 bitpos = bitpos % BITS_PER_WORD;
3810 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3813 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3815 if (target == 0
3816 || target == op0
3817 || target == op1
3818 || reg_overlap_mentioned_p (target, op0)
3819 || reg_overlap_mentioned_p (target, op1)
3820 || (nwords > 1 && !valid_multiword_target_p (target)))
3821 target = gen_reg_rtx (mode);
3823 if (nwords > 1)
3825 start_sequence ();
3827 for (i = 0; i < nwords; ++i)
3829 rtx targ_piece = operand_subword (target, i, 1, mode);
3830 rtx op0_piece = operand_subword_force (op0, i, mode);
3832 if (i == word)
3834 if (!op0_is_abs)
3835 op0_piece
3836 = expand_binop (imode, and_optab, op0_piece,
3837 immed_wide_int_const (~mask, imode),
3838 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3839 op1 = expand_binop (imode, and_optab,
3840 operand_subword_force (op1, i, mode),
3841 immed_wide_int_const (mask, imode),
3842 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3844 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3845 targ_piece, 1, OPTAB_LIB_WIDEN);
3846 if (temp != targ_piece)
3847 emit_move_insn (targ_piece, temp);
3849 else
3850 emit_move_insn (targ_piece, op0_piece);
3853 insns = get_insns ();
3854 end_sequence ();
3856 emit_insn (insns);
3858 else
3860 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3861 immed_wide_int_const (mask, imode),
3862 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3864 op0 = gen_lowpart (imode, op0);
3865 if (!op0_is_abs)
3866 op0 = expand_binop (imode, and_optab, op0,
3867 immed_wide_int_const (~mask, imode),
3868 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3870 temp = expand_binop (imode, ior_optab, op0, op1,
3871 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3872 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3875 return target;
3878 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3879 scalar floating point mode. Return NULL if we do not know how to
3880 expand the operation inline. */
3883 expand_copysign (rtx op0, rtx op1, rtx target)
3885 scalar_float_mode mode;
3886 const struct real_format *fmt;
3887 bool op0_is_abs;
3888 rtx temp;
3890 mode = as_a <scalar_float_mode> (GET_MODE (op0));
3891 gcc_assert (GET_MODE (op1) == mode);
3893 /* First try to do it with a special instruction. */
3894 temp = expand_binop (mode, copysign_optab, op0, op1,
3895 target, 0, OPTAB_DIRECT);
3896 if (temp)
3897 return temp;
3899 fmt = REAL_MODE_FORMAT (mode);
3900 if (fmt == NULL || !fmt->has_signed_zero)
3901 return NULL_RTX;
3903 op0_is_abs = false;
3904 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3906 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3907 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3908 op0_is_abs = true;
3911 if (fmt->signbit_ro >= 0
3912 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3913 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3914 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3916 temp = expand_copysign_absneg (mode, op0, op1, target,
3917 fmt->signbit_ro, op0_is_abs);
3918 if (temp)
3919 return temp;
3922 if (fmt->signbit_rw < 0)
3923 return NULL_RTX;
3924 return expand_copysign_bit (mode, op0, op1, target,
3925 fmt->signbit_rw, op0_is_abs);
3928 /* Generate an instruction whose insn-code is INSN_CODE,
3929 with two operands: an output TARGET and an input OP0.
3930 TARGET *must* be nonzero, and the output is always stored there.
3931 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3932 the value that is stored into TARGET.
3934 Return false if expansion failed. */
3936 bool
3937 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3938 enum rtx_code code)
3940 class expand_operand ops[2];
3941 rtx_insn *pat;
3943 create_output_operand (&ops[0], target, GET_MODE (target));
3944 create_input_operand (&ops[1], op0, GET_MODE (op0));
3945 pat = maybe_gen_insn (icode, 2, ops);
3946 if (!pat)
3947 return false;
3949 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3950 && code != UNKNOWN)
3951 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX,
3952 GET_MODE (op0));
3954 emit_insn (pat);
3956 if (ops[0].value != target)
3957 emit_move_insn (target, ops[0].value);
3958 return true;
3960 /* Generate an instruction whose insn-code is INSN_CODE,
3961 with two operands: an output TARGET and an input OP0.
3962 TARGET *must* be nonzero, and the output is always stored there.
3963 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3964 the value that is stored into TARGET. */
3966 void
3967 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3969 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3970 gcc_assert (ok);
3973 struct no_conflict_data
3975 rtx target;
3976 rtx_insn *first, *insn;
3977 bool must_stay;
3980 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3981 the currently examined clobber / store has to stay in the list of
3982 insns that constitute the actual libcall block. */
3983 static void
3984 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3986 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3988 /* If this inns directly contributes to setting the target, it must stay. */
3989 if (reg_overlap_mentioned_p (p->target, dest))
3990 p->must_stay = true;
3991 /* If we haven't committed to keeping any other insns in the list yet,
3992 there is nothing more to check. */
3993 else if (p->insn == p->first)
3994 return;
3995 /* If this insn sets / clobbers a register that feeds one of the insns
3996 already in the list, this insn has to stay too. */
3997 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3998 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3999 || reg_used_between_p (dest, p->first, p->insn)
4000 /* Likewise if this insn depends on a register set by a previous
4001 insn in the list, or if it sets a result (presumably a hard
4002 register) that is set or clobbered by a previous insn.
4003 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
4004 SET_DEST perform the former check on the address, and the latter
4005 check on the MEM. */
4006 || (GET_CODE (set) == SET
4007 && (modified_in_p (SET_SRC (set), p->first)
4008 || modified_in_p (SET_DEST (set), p->first)
4009 || modified_between_p (SET_SRC (set), p->first, p->insn)
4010 || modified_between_p (SET_DEST (set), p->first, p->insn))))
4011 p->must_stay = true;
4015 /* Emit code to make a call to a constant function or a library call.
4017 INSNS is a list containing all insns emitted in the call.
4018 These insns leave the result in RESULT. Our block is to copy RESULT
4019 to TARGET, which is logically equivalent to EQUIV.
4021 We first emit any insns that set a pseudo on the assumption that these are
4022 loading constants into registers; doing so allows them to be safely cse'ed
4023 between blocks. Then we emit all the other insns in the block, followed by
4024 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
4025 note with an operand of EQUIV. */
4027 static void
4028 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
4029 bool equiv_may_trap)
4031 rtx final_dest = target;
4032 rtx_insn *next, *last, *insn;
4034 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
4035 into a MEM later. Protect the libcall block from this change. */
4036 if (! REG_P (target) || REG_USERVAR_P (target))
4037 target = gen_reg_rtx (GET_MODE (target));
4039 /* If we're using non-call exceptions, a libcall corresponding to an
4040 operation that may trap may also trap. */
4041 /* ??? See the comment in front of make_reg_eh_region_note. */
4042 if (cfun->can_throw_non_call_exceptions
4043 && (equiv_may_trap || may_trap_p (equiv)))
4045 for (insn = insns; insn; insn = NEXT_INSN (insn))
4046 if (CALL_P (insn))
4048 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
4049 if (note)
4051 int lp_nr = INTVAL (XEXP (note, 0));
4052 if (lp_nr == 0 || lp_nr == INT_MIN)
4053 remove_note (insn, note);
4057 else
4059 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
4060 reg note to indicate that this call cannot throw or execute a nonlocal
4061 goto (unless there is already a REG_EH_REGION note, in which case
4062 we update it). */
4063 for (insn = insns; insn; insn = NEXT_INSN (insn))
4064 if (CALL_P (insn))
4065 make_reg_eh_region_note_nothrow_nononlocal (insn);
4068 /* First emit all insns that set pseudos. Remove them from the list as
4069 we go. Avoid insns that set pseudos which were referenced in previous
4070 insns. These can be generated by move_by_pieces, for example,
4071 to update an address. Similarly, avoid insns that reference things
4072 set in previous insns. */
4074 for (insn = insns; insn; insn = next)
4076 rtx set = single_set (insn);
4078 next = NEXT_INSN (insn);
4080 if (set != 0 && REG_P (SET_DEST (set))
4081 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
4083 struct no_conflict_data data;
4085 data.target = const0_rtx;
4086 data.first = insns;
4087 data.insn = insn;
4088 data.must_stay = 0;
4089 note_stores (insn, no_conflict_move_test, &data);
4090 if (! data.must_stay)
4092 if (PREV_INSN (insn))
4093 SET_NEXT_INSN (PREV_INSN (insn)) = next;
4094 else
4095 insns = next;
4097 if (next)
4098 SET_PREV_INSN (next) = PREV_INSN (insn);
4100 add_insn (insn);
4104 /* Some ports use a loop to copy large arguments onto the stack.
4105 Don't move anything outside such a loop. */
4106 if (LABEL_P (insn))
4107 break;
4110 /* Write the remaining insns followed by the final copy. */
4111 for (insn = insns; insn; insn = next)
4113 next = NEXT_INSN (insn);
4115 add_insn (insn);
4118 last = emit_move_insn (target, result);
4119 if (equiv)
4120 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
4122 if (final_dest != target)
4123 emit_move_insn (final_dest, target);
4126 void
4127 emit_libcall_block (rtx_insn *insns, rtx target, rtx result, rtx equiv)
4129 emit_libcall_block_1 (insns, target, result, equiv, false);
4132 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
4133 PURPOSE describes how this comparison will be used. CODE is the rtx
4134 comparison code we will be using.
4136 ??? Actually, CODE is slightly weaker than that. A target is still
4137 required to implement all of the normal bcc operations, but not
4138 required to implement all (or any) of the unordered bcc operations. */
4141 can_compare_p (enum rtx_code code, machine_mode mode,
4142 enum can_compare_purpose purpose)
4144 rtx test;
4145 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
4148 enum insn_code icode;
4150 if (purpose == ccp_jump
4151 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
4152 && insn_operand_matches (icode, 0, test))
4153 return 1;
4154 if (purpose == ccp_store_flag
4155 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
4156 && insn_operand_matches (icode, 1, test))
4157 return 1;
4158 if (purpose == ccp_cmov
4159 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
4160 return 1;
4162 mode = GET_MODE_WIDER_MODE (mode).else_void ();
4163 PUT_MODE (test, mode);
4165 while (mode != VOIDmode);
4167 return 0;
4170 /* Return whether RTL code CODE corresponds to an unsigned optab. */
4172 static bool
4173 unsigned_optab_p (enum rtx_code code)
4175 return code == LTU || code == LEU || code == GTU || code == GEU;
4178 /* Return whether the backend-emitted comparison for code CODE, comparing
4179 operands of mode VALUE_MODE and producing a result with MASK_MODE, matches
4180 operand OPNO of pattern ICODE. */
4182 static bool
4183 insn_predicate_matches_p (enum insn_code icode, unsigned int opno,
4184 enum rtx_code code, machine_mode mask_mode,
4185 machine_mode value_mode)
4187 rtx reg1 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 1);
4188 rtx reg2 = alloca_raw_REG (value_mode, LAST_VIRTUAL_REGISTER + 2);
4189 rtx test = alloca_rtx_fmt_ee (code, mask_mode, reg1, reg2);
4190 return insn_operand_matches (icode, opno, test);
4193 /* Return whether the backend can emit a vector comparison (vec_cmp/vec_cmpu)
4194 for code CODE, comparing operands of mode VALUE_MODE and producing a result
4195 with MASK_MODE. */
4197 bool
4198 can_vec_cmp_compare_p (enum rtx_code code, machine_mode value_mode,
4199 machine_mode mask_mode)
4201 enum insn_code icode
4202 = get_vec_cmp_icode (value_mode, mask_mode, unsigned_optab_p (code));
4203 if (icode == CODE_FOR_nothing)
4204 return false;
4206 return insn_predicate_matches_p (icode, 1, code, mask_mode, value_mode);
4209 /* Return whether the backend can emit a vector comparison (vcond/vcondu) for
4210 code CODE, comparing operands of mode CMP_OP_MODE and producing a result
4211 with VALUE_MODE. */
4213 bool
4214 can_vcond_compare_p (enum rtx_code code, machine_mode value_mode,
4215 machine_mode cmp_op_mode)
4217 enum insn_code icode
4218 = get_vcond_icode (value_mode, cmp_op_mode, unsigned_optab_p (code));
4219 if (icode == CODE_FOR_nothing)
4220 return false;
4222 return insn_predicate_matches_p (icode, 3, code, value_mode, cmp_op_mode);
4225 /* Return whether the backend can emit vector set instructions for inserting
4226 element into vector at variable index position. */
4228 bool
4229 can_vec_set_var_idx_p (machine_mode vec_mode)
4231 if (!VECTOR_MODE_P (vec_mode))
4232 return false;
4234 machine_mode inner_mode = GET_MODE_INNER (vec_mode);
4235 rtx reg1 = alloca_raw_REG (vec_mode, LAST_VIRTUAL_REGISTER + 1);
4236 rtx reg2 = alloca_raw_REG (inner_mode, LAST_VIRTUAL_REGISTER + 2);
4237 rtx reg3 = alloca_raw_REG (VOIDmode, LAST_VIRTUAL_REGISTER + 3);
4239 enum insn_code icode = optab_handler (vec_set_optab, vec_mode);
4241 return icode != CODE_FOR_nothing && insn_operand_matches (icode, 0, reg1)
4242 && insn_operand_matches (icode, 1, reg2)
4243 && insn_operand_matches (icode, 2, reg3);
4246 /* This function is called when we are going to emit a compare instruction that
4247 compares the values found in X and Y, using the rtl operator COMPARISON.
4249 If they have mode BLKmode, then SIZE specifies the size of both operands.
4251 UNSIGNEDP nonzero says that the operands are unsigned;
4252 this matters if they need to be widened (as given by METHODS).
4254 *PTEST is where the resulting comparison RTX is returned or NULL_RTX
4255 if we failed to produce one.
4257 *PMODE is the mode of the inputs (in case they are const_int).
4259 This function performs all the setup necessary so that the caller only has
4260 to emit a single comparison insn. This setup can involve doing a BLKmode
4261 comparison or emitting a library call to perform the comparison if no insn
4262 is available to handle it.
4263 The values which are passed in through pointers can be modified; the caller
4264 should perform the comparison on the modified values. Constant
4265 comparisons must have already been folded. */
4267 static void
4268 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4269 int unsignedp, enum optab_methods methods,
4270 rtx *ptest, machine_mode *pmode)
4272 machine_mode mode = *pmode;
4273 rtx libfunc, test;
4274 machine_mode cmp_mode;
4275 enum mode_class mclass;
4277 /* The other methods are not needed. */
4278 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
4279 || methods == OPTAB_LIB_WIDEN);
4281 if (CONST_SCALAR_INT_P (y))
4282 canonicalize_comparison (mode, &comparison, &y);
4284 /* If we are optimizing, force expensive constants into a register. */
4285 if (CONSTANT_P (x) && optimize
4286 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
4287 > COSTS_N_INSNS (1)))
4288 x = force_reg (mode, x);
4290 if (CONSTANT_P (y) && optimize
4291 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
4292 > COSTS_N_INSNS (1)))
4293 y = force_reg (mode, y);
4295 #if HAVE_cc0
4296 /* Make sure if we have a canonical comparison. The RTL
4297 documentation states that canonical comparisons are required only
4298 for targets which have cc0. */
4299 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
4300 #endif
4302 /* Don't let both operands fail to indicate the mode. */
4303 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4304 x = force_reg (mode, x);
4305 if (mode == VOIDmode)
4306 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
4308 /* Handle all BLKmode compares. */
4310 if (mode == BLKmode)
4312 machine_mode result_mode;
4313 enum insn_code cmp_code;
4314 rtx result;
4315 rtx opalign
4316 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4318 gcc_assert (size);
4320 /* Try to use a memory block compare insn - either cmpstr
4321 or cmpmem will do. */
4322 opt_scalar_int_mode cmp_mode_iter;
4323 FOR_EACH_MODE_IN_CLASS (cmp_mode_iter, MODE_INT)
4325 scalar_int_mode cmp_mode = cmp_mode_iter.require ();
4326 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
4327 if (cmp_code == CODE_FOR_nothing)
4328 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
4329 if (cmp_code == CODE_FOR_nothing)
4330 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
4331 if (cmp_code == CODE_FOR_nothing)
4332 continue;
4334 /* Must make sure the size fits the insn's mode. */
4335 if (CONST_INT_P (size)
4336 ? UINTVAL (size) > GET_MODE_MASK (cmp_mode)
4337 : (GET_MODE_BITSIZE (as_a <scalar_int_mode> (GET_MODE (size)))
4338 > GET_MODE_BITSIZE (cmp_mode)))
4339 continue;
4341 result_mode = insn_data[cmp_code].operand[0].mode;
4342 result = gen_reg_rtx (result_mode);
4343 size = convert_to_mode (cmp_mode, size, 1);
4344 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4346 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
4347 *pmode = result_mode;
4348 return;
4351 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
4352 goto fail;
4354 /* Otherwise call a library function. */
4355 result = emit_block_comp_via_libcall (x, y, size);
4357 x = result;
4358 y = const0_rtx;
4359 mode = TYPE_MODE (integer_type_node);
4360 methods = OPTAB_LIB_WIDEN;
4361 unsignedp = false;
4364 /* Don't allow operands to the compare to trap, as that can put the
4365 compare and branch in different basic blocks. */
4366 if (cfun->can_throw_non_call_exceptions)
4368 if (may_trap_p (x))
4369 x = copy_to_reg (x);
4370 if (may_trap_p (y))
4371 y = copy_to_reg (y);
4374 if (GET_MODE_CLASS (mode) == MODE_CC)
4376 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
4377 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4378 gcc_assert (icode != CODE_FOR_nothing
4379 && insn_operand_matches (icode, 0, test));
4380 *ptest = test;
4381 return;
4384 mclass = GET_MODE_CLASS (mode);
4385 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
4386 FOR_EACH_MODE_FROM (cmp_mode, mode)
4388 enum insn_code icode;
4389 icode = optab_handler (cbranch_optab, cmp_mode);
4390 if (icode != CODE_FOR_nothing
4391 && insn_operand_matches (icode, 0, test))
4393 rtx_insn *last = get_last_insn ();
4394 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
4395 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
4396 if (op0 && op1
4397 && insn_operand_matches (icode, 1, op0)
4398 && insn_operand_matches (icode, 2, op1))
4400 XEXP (test, 0) = op0;
4401 XEXP (test, 1) = op1;
4402 *ptest = test;
4403 *pmode = cmp_mode;
4404 return;
4406 delete_insns_since (last);
4409 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
4410 break;
4413 if (methods != OPTAB_LIB_WIDEN)
4414 goto fail;
4416 if (SCALAR_FLOAT_MODE_P (mode))
4418 /* Small trick if UNORDERED isn't implemented by the hardware. */
4419 if (comparison == UNORDERED && rtx_equal_p (x, y))
4421 prepare_cmp_insn (x, y, UNLT, NULL_RTX, unsignedp, OPTAB_WIDEN,
4422 ptest, pmode);
4423 if (*ptest)
4424 return;
4427 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
4429 else
4431 rtx result;
4432 machine_mode ret_mode;
4434 /* Handle a libcall just for the mode we are using. */
4435 libfunc = optab_libfunc (cmp_optab, mode);
4436 gcc_assert (libfunc);
4438 /* If we want unsigned, and this mode has a distinct unsigned
4439 comparison routine, use that. */
4440 if (unsignedp)
4442 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
4443 if (ulibfunc)
4444 libfunc = ulibfunc;
4447 ret_mode = targetm.libgcc_cmp_return_mode ();
4448 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4449 ret_mode, x, mode, y, mode);
4451 /* There are two kinds of comparison routines. Biased routines
4452 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4453 of gcc expect that the comparison operation is equivalent
4454 to the modified comparison. For signed comparisons compare the
4455 result against 1 in the biased case, and zero in the unbiased
4456 case. For unsigned comparisons always compare against 1 after
4457 biasing the unbiased result by adding 1. This gives us a way to
4458 represent LTU.
4459 The comparisons in the fixed-point helper library are always
4460 biased. */
4461 x = result;
4462 y = const1_rtx;
4464 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
4466 if (unsignedp)
4467 x = plus_constant (ret_mode, result, 1);
4468 else
4469 y = const0_rtx;
4472 *pmode = ret_mode;
4473 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
4474 ptest, pmode);
4477 return;
4479 fail:
4480 *ptest = NULL_RTX;
4483 /* Before emitting an insn with code ICODE, make sure that X, which is going
4484 to be used for operand OPNUM of the insn, is converted from mode MODE to
4485 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4486 that it is accepted by the operand predicate. Return the new value. */
4489 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
4490 machine_mode wider_mode, int unsignedp)
4492 if (mode != wider_mode)
4493 x = convert_modes (wider_mode, mode, x, unsignedp);
4495 if (!insn_operand_matches (icode, opnum, x))
4497 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
4498 if (reload_completed)
4499 return NULL_RTX;
4500 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
4501 return NULL_RTX;
4502 x = copy_to_mode_reg (op_mode, x);
4505 return x;
4508 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4509 we can do the branch. */
4511 static void
4512 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label,
4513 profile_probability prob)
4515 machine_mode optab_mode;
4516 enum mode_class mclass;
4517 enum insn_code icode;
4518 rtx_insn *insn;
4520 mclass = GET_MODE_CLASS (mode);
4521 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
4522 icode = optab_handler (cbranch_optab, optab_mode);
4524 gcc_assert (icode != CODE_FOR_nothing);
4525 gcc_assert (insn_operand_matches (icode, 0, test));
4526 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
4527 XEXP (test, 1), label));
4528 if (prob.initialized_p ()
4529 && profile_status_for_fn (cfun) != PROFILE_ABSENT
4530 && insn
4531 && JUMP_P (insn)
4532 && any_condjump_p (insn)
4533 && !find_reg_note (insn, REG_BR_PROB, 0))
4534 add_reg_br_prob_note (insn, prob);
4537 /* Generate code to compare X with Y so that the condition codes are
4538 set and to jump to LABEL if the condition is true. If X is a
4539 constant and Y is not a constant, then the comparison is swapped to
4540 ensure that the comparison RTL has the canonical form.
4542 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4543 need to be widened. UNSIGNEDP is also used to select the proper
4544 branch condition code.
4546 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4548 MODE is the mode of the inputs (in case they are const_int).
4550 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4551 It will be potentially converted into an unsigned variant based on
4552 UNSIGNEDP to select a proper jump instruction.
4554 PROB is the probability of jumping to LABEL. */
4556 void
4557 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4558 machine_mode mode, int unsignedp, rtx label,
4559 profile_probability prob)
4561 rtx op0 = x, op1 = y;
4562 rtx test;
4564 /* Swap operands and condition to ensure canonical RTL. */
4565 if (swap_commutative_operands_p (x, y)
4566 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4568 op0 = y, op1 = x;
4569 comparison = swap_condition (comparison);
4572 /* If OP0 is still a constant, then both X and Y must be constants
4573 or the opposite comparison is not supported. Force X into a register
4574 to create canonical RTL. */
4575 if (CONSTANT_P (op0))
4576 op0 = force_reg (mode, op0);
4578 if (unsignedp)
4579 comparison = unsigned_condition (comparison);
4581 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4582 &test, &mode);
4583 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4587 /* Emit a library call comparison between floating point X and Y.
4588 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4590 static void
4591 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4592 rtx *ptest, machine_mode *pmode)
4594 enum rtx_code swapped = swap_condition (comparison);
4595 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4596 machine_mode orig_mode = GET_MODE (x);
4597 machine_mode mode;
4598 rtx true_rtx, false_rtx;
4599 rtx value, target, equiv;
4600 rtx_insn *insns;
4601 rtx libfunc = 0;
4602 bool reversed_p = false;
4603 scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
4605 FOR_EACH_MODE_FROM (mode, orig_mode)
4607 if (code_to_optab (comparison)
4608 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4609 break;
4611 if (code_to_optab (swapped)
4612 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4614 std::swap (x, y);
4615 comparison = swapped;
4616 break;
4619 if (code_to_optab (reversed)
4620 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4622 comparison = reversed;
4623 reversed_p = true;
4624 break;
4628 gcc_assert (mode != VOIDmode);
4630 if (mode != orig_mode)
4632 x = convert_to_mode (mode, x, 0);
4633 y = convert_to_mode (mode, y, 0);
4636 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4637 the RTL. The allows the RTL optimizers to delete the libcall if the
4638 condition can be determined at compile-time. */
4639 if (comparison == UNORDERED
4640 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4642 true_rtx = const_true_rtx;
4643 false_rtx = const0_rtx;
4645 else
4647 switch (comparison)
4649 case EQ:
4650 true_rtx = const0_rtx;
4651 false_rtx = const_true_rtx;
4652 break;
4654 case NE:
4655 true_rtx = const_true_rtx;
4656 false_rtx = const0_rtx;
4657 break;
4659 case GT:
4660 true_rtx = const1_rtx;
4661 false_rtx = const0_rtx;
4662 break;
4664 case GE:
4665 true_rtx = const0_rtx;
4666 false_rtx = constm1_rtx;
4667 break;
4669 case LT:
4670 true_rtx = constm1_rtx;
4671 false_rtx = const0_rtx;
4672 break;
4674 case LE:
4675 true_rtx = const0_rtx;
4676 false_rtx = const1_rtx;
4677 break;
4679 default:
4680 gcc_unreachable ();
4684 if (comparison == UNORDERED)
4686 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4687 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4688 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4689 temp, const_true_rtx, equiv);
4691 else
4693 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4694 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4695 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4696 equiv, true_rtx, false_rtx);
4699 start_sequence ();
4700 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4701 cmp_mode, x, mode, y, mode);
4702 insns = get_insns ();
4703 end_sequence ();
4705 target = gen_reg_rtx (cmp_mode);
4706 emit_libcall_block (insns, target, value, equiv);
4708 if (comparison == UNORDERED
4709 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4710 || reversed_p)
4711 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4712 else
4713 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4715 *pmode = cmp_mode;
4718 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4720 void
4721 emit_indirect_jump (rtx loc)
4723 if (!targetm.have_indirect_jump ())
4724 sorry ("indirect jumps are not available on this target");
4725 else
4727 class expand_operand ops[1];
4728 create_address_operand (&ops[0], loc);
4729 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4730 emit_barrier ();
4735 /* Emit a conditional move instruction if the machine supports one for that
4736 condition and machine mode.
4738 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4739 the mode to use should they be constants. If it is VOIDmode, they cannot
4740 both be constants.
4742 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4743 should be stored there. MODE is the mode to use should they be constants.
4744 If it is VOIDmode, they cannot both be constants.
4746 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4747 is not supported. */
4750 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4751 machine_mode cmode, rtx op2, rtx op3,
4752 machine_mode mode, int unsignedp)
4754 rtx comparison;
4755 rtx_insn *last;
4756 enum insn_code icode;
4757 enum rtx_code reversed;
4759 /* If the two source operands are identical, that's just a move. */
4761 if (rtx_equal_p (op2, op3))
4763 if (!target)
4764 target = gen_reg_rtx (mode);
4766 emit_move_insn (target, op3);
4767 return target;
4770 /* If one operand is constant, make it the second one. Only do this
4771 if the other operand is not constant as well. */
4773 if (swap_commutative_operands_p (op0, op1))
4775 std::swap (op0, op1);
4776 code = swap_condition (code);
4779 /* get_condition will prefer to generate LT and GT even if the old
4780 comparison was against zero, so undo that canonicalization here since
4781 comparisons against zero are cheaper. */
4782 if (code == LT && op1 == const1_rtx)
4783 code = LE, op1 = const0_rtx;
4784 else if (code == GT && op1 == constm1_rtx)
4785 code = GE, op1 = const0_rtx;
4787 if (cmode == VOIDmode)
4788 cmode = GET_MODE (op0);
4790 enum rtx_code orig_code = code;
4791 bool swapped = false;
4792 if (swap_commutative_operands_p (op2, op3)
4793 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4794 != UNKNOWN))
4796 std::swap (op2, op3);
4797 code = reversed;
4798 swapped = true;
4801 if (mode == VOIDmode)
4802 mode = GET_MODE (op2);
4804 icode = direct_optab_handler (movcc_optab, mode);
4806 if (icode == CODE_FOR_nothing)
4807 return NULL_RTX;
4809 if (!target)
4810 target = gen_reg_rtx (mode);
4812 for (int pass = 0; ; pass++)
4814 code = unsignedp ? unsigned_condition (code) : code;
4815 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4817 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4818 punt and let the caller figure out how best to deal with this
4819 situation. */
4820 if (COMPARISON_P (comparison))
4822 saved_pending_stack_adjust save;
4823 save_pending_stack_adjust (&save);
4824 last = get_last_insn ();
4825 do_pending_stack_adjust ();
4826 machine_mode cmpmode = cmode;
4827 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4828 GET_CODE (comparison), NULL_RTX, unsignedp,
4829 OPTAB_WIDEN, &comparison, &cmpmode);
4830 if (comparison)
4832 class expand_operand ops[4];
4834 create_output_operand (&ops[0], target, mode);
4835 create_fixed_operand (&ops[1], comparison);
4836 create_input_operand (&ops[2], op2, mode);
4837 create_input_operand (&ops[3], op3, mode);
4838 if (maybe_expand_insn (icode, 4, ops))
4840 if (ops[0].value != target)
4841 convert_move (target, ops[0].value, false);
4842 return target;
4845 delete_insns_since (last);
4846 restore_pending_stack_adjust (&save);
4849 if (pass == 1)
4850 return NULL_RTX;
4852 /* If the preferred op2/op3 order is not usable, retry with other
4853 operand order, perhaps it will expand successfully. */
4854 if (swapped)
4855 code = orig_code;
4856 else if ((reversed = reversed_comparison_code_parts (orig_code, op0, op1,
4857 NULL))
4858 != UNKNOWN)
4859 code = reversed;
4860 else
4861 return NULL_RTX;
4862 std::swap (op2, op3);
4867 /* Emit a conditional negate or bitwise complement using the
4868 negcc or notcc optabs if available. Return NULL_RTX if such operations
4869 are not available. Otherwise return the RTX holding the result.
4870 TARGET is the desired destination of the result. COMP is the comparison
4871 on which to negate. If COND is true move into TARGET the negation
4872 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4873 CODE is either NEG or NOT. MODE is the machine mode in which the
4874 operation is performed. */
4877 emit_conditional_neg_or_complement (rtx target, rtx_code code,
4878 machine_mode mode, rtx cond, rtx op1,
4879 rtx op2)
4881 optab op = unknown_optab;
4882 if (code == NEG)
4883 op = negcc_optab;
4884 else if (code == NOT)
4885 op = notcc_optab;
4886 else
4887 gcc_unreachable ();
4889 insn_code icode = direct_optab_handler (op, mode);
4891 if (icode == CODE_FOR_nothing)
4892 return NULL_RTX;
4894 if (!target)
4895 target = gen_reg_rtx (mode);
4897 rtx_insn *last = get_last_insn ();
4898 class expand_operand ops[4];
4900 create_output_operand (&ops[0], target, mode);
4901 create_fixed_operand (&ops[1], cond);
4902 create_input_operand (&ops[2], op1, mode);
4903 create_input_operand (&ops[3], op2, mode);
4905 if (maybe_expand_insn (icode, 4, ops))
4907 if (ops[0].value != target)
4908 convert_move (target, ops[0].value, false);
4910 return target;
4912 delete_insns_since (last);
4913 return NULL_RTX;
4916 /* Emit a conditional addition instruction if the machine supports one for that
4917 condition and machine mode.
4919 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4920 the mode to use should they be constants. If it is VOIDmode, they cannot
4921 both be constants.
4923 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4924 should be stored there. MODE is the mode to use should they be constants.
4925 If it is VOIDmode, they cannot both be constants.
4927 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4928 is not supported. */
4931 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4932 machine_mode cmode, rtx op2, rtx op3,
4933 machine_mode mode, int unsignedp)
4935 rtx comparison;
4936 rtx_insn *last;
4937 enum insn_code icode;
4939 /* If one operand is constant, make it the second one. Only do this
4940 if the other operand is not constant as well. */
4942 if (swap_commutative_operands_p (op0, op1))
4944 std::swap (op0, op1);
4945 code = swap_condition (code);
4948 /* get_condition will prefer to generate LT and GT even if the old
4949 comparison was against zero, so undo that canonicalization here since
4950 comparisons against zero are cheaper. */
4951 if (code == LT && op1 == const1_rtx)
4952 code = LE, op1 = const0_rtx;
4953 else if (code == GT && op1 == constm1_rtx)
4954 code = GE, op1 = const0_rtx;
4956 if (cmode == VOIDmode)
4957 cmode = GET_MODE (op0);
4959 if (mode == VOIDmode)
4960 mode = GET_MODE (op2);
4962 icode = optab_handler (addcc_optab, mode);
4964 if (icode == CODE_FOR_nothing)
4965 return 0;
4967 if (!target)
4968 target = gen_reg_rtx (mode);
4970 code = unsignedp ? unsigned_condition (code) : code;
4971 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4973 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4974 return NULL and let the caller figure out how best to deal with this
4975 situation. */
4976 if (!COMPARISON_P (comparison))
4977 return NULL_RTX;
4979 do_pending_stack_adjust ();
4980 last = get_last_insn ();
4981 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4982 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4983 &comparison, &cmode);
4984 if (comparison)
4986 class expand_operand ops[4];
4988 create_output_operand (&ops[0], target, mode);
4989 create_fixed_operand (&ops[1], comparison);
4990 create_input_operand (&ops[2], op2, mode);
4991 create_input_operand (&ops[3], op3, mode);
4992 if (maybe_expand_insn (icode, 4, ops))
4994 if (ops[0].value != target)
4995 convert_move (target, ops[0].value, false);
4996 return target;
4999 delete_insns_since (last);
5000 return NULL_RTX;
5003 /* These functions attempt to generate an insn body, rather than
5004 emitting the insn, but if the gen function already emits them, we
5005 make no attempt to turn them back into naked patterns. */
5007 /* Generate and return an insn body to add Y to X. */
5009 rtx_insn *
5010 gen_add2_insn (rtx x, rtx y)
5012 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
5014 gcc_assert (insn_operand_matches (icode, 0, x));
5015 gcc_assert (insn_operand_matches (icode, 1, x));
5016 gcc_assert (insn_operand_matches (icode, 2, y));
5018 return GEN_FCN (icode) (x, x, y);
5021 /* Generate and return an insn body to add r1 and c,
5022 storing the result in r0. */
5024 rtx_insn *
5025 gen_add3_insn (rtx r0, rtx r1, rtx c)
5027 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
5029 if (icode == CODE_FOR_nothing
5030 || !insn_operand_matches (icode, 0, r0)
5031 || !insn_operand_matches (icode, 1, r1)
5032 || !insn_operand_matches (icode, 2, c))
5033 return NULL;
5035 return GEN_FCN (icode) (r0, r1, c);
5039 have_add2_insn (rtx x, rtx y)
5041 enum insn_code icode;
5043 gcc_assert (GET_MODE (x) != VOIDmode);
5045 icode = optab_handler (add_optab, GET_MODE (x));
5047 if (icode == CODE_FOR_nothing)
5048 return 0;
5050 if (!insn_operand_matches (icode, 0, x)
5051 || !insn_operand_matches (icode, 1, x)
5052 || !insn_operand_matches (icode, 2, y))
5053 return 0;
5055 return 1;
5058 /* Generate and return an insn body to add Y to X. */
5060 rtx_insn *
5061 gen_addptr3_insn (rtx x, rtx y, rtx z)
5063 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
5065 gcc_assert (insn_operand_matches (icode, 0, x));
5066 gcc_assert (insn_operand_matches (icode, 1, y));
5067 gcc_assert (insn_operand_matches (icode, 2, z));
5069 return GEN_FCN (icode) (x, y, z);
5072 /* Return true if the target implements an addptr pattern and X, Y,
5073 and Z are valid for the pattern predicates. */
5076 have_addptr3_insn (rtx x, rtx y, rtx z)
5078 enum insn_code icode;
5080 gcc_assert (GET_MODE (x) != VOIDmode);
5082 icode = optab_handler (addptr3_optab, GET_MODE (x));
5084 if (icode == CODE_FOR_nothing)
5085 return 0;
5087 if (!insn_operand_matches (icode, 0, x)
5088 || !insn_operand_matches (icode, 1, y)
5089 || !insn_operand_matches (icode, 2, z))
5090 return 0;
5092 return 1;
5095 /* Generate and return an insn body to subtract Y from X. */
5097 rtx_insn *
5098 gen_sub2_insn (rtx x, rtx y)
5100 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
5102 gcc_assert (insn_operand_matches (icode, 0, x));
5103 gcc_assert (insn_operand_matches (icode, 1, x));
5104 gcc_assert (insn_operand_matches (icode, 2, y));
5106 return GEN_FCN (icode) (x, x, y);
5109 /* Generate and return an insn body to subtract r1 and c,
5110 storing the result in r0. */
5112 rtx_insn *
5113 gen_sub3_insn (rtx r0, rtx r1, rtx c)
5115 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
5117 if (icode == CODE_FOR_nothing
5118 || !insn_operand_matches (icode, 0, r0)
5119 || !insn_operand_matches (icode, 1, r1)
5120 || !insn_operand_matches (icode, 2, c))
5121 return NULL;
5123 return GEN_FCN (icode) (r0, r1, c);
5127 have_sub2_insn (rtx x, rtx y)
5129 enum insn_code icode;
5131 gcc_assert (GET_MODE (x) != VOIDmode);
5133 icode = optab_handler (sub_optab, GET_MODE (x));
5135 if (icode == CODE_FOR_nothing)
5136 return 0;
5138 if (!insn_operand_matches (icode, 0, x)
5139 || !insn_operand_matches (icode, 1, x)
5140 || !insn_operand_matches (icode, 2, y))
5141 return 0;
5143 return 1;
5146 /* Generate the body of an insn to extend Y (with mode MFROM)
5147 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
5149 rtx_insn *
5150 gen_extend_insn (rtx x, rtx y, machine_mode mto,
5151 machine_mode mfrom, int unsignedp)
5153 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
5154 return GEN_FCN (icode) (x, y);
5157 /* Generate code to convert FROM to floating point
5158 and store in TO. FROM must be fixed point and not VOIDmode.
5159 UNSIGNEDP nonzero means regard FROM as unsigned.
5160 Normally this is done by correcting the final value
5161 if it is negative. */
5163 void
5164 expand_float (rtx to, rtx from, int unsignedp)
5166 enum insn_code icode;
5167 rtx target = to;
5168 scalar_mode from_mode, to_mode;
5169 machine_mode fmode, imode;
5170 bool can_do_signed = false;
5172 /* Crash now, because we won't be able to decide which mode to use. */
5173 gcc_assert (GET_MODE (from) != VOIDmode);
5175 /* Look for an insn to do the conversion. Do it in the specified
5176 modes if possible; otherwise convert either input, output or both to
5177 wider mode. If the integer mode is wider than the mode of FROM,
5178 we can do the conversion signed even if the input is unsigned. */
5180 FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
5181 FOR_EACH_MODE_FROM (imode, GET_MODE (from))
5183 int doing_unsigned = unsignedp;
5185 if (fmode != GET_MODE (to)
5186 && (significand_size (fmode)
5187 < GET_MODE_UNIT_PRECISION (GET_MODE (from))))
5188 continue;
5190 icode = can_float_p (fmode, imode, unsignedp);
5191 if (icode == CODE_FOR_nothing && unsignedp)
5193 enum insn_code scode = can_float_p (fmode, imode, 0);
5194 if (scode != CODE_FOR_nothing)
5195 can_do_signed = true;
5196 if (imode != GET_MODE (from))
5197 icode = scode, doing_unsigned = 0;
5200 if (icode != CODE_FOR_nothing)
5202 if (imode != GET_MODE (from))
5203 from = convert_to_mode (imode, from, unsignedp);
5205 if (fmode != GET_MODE (to))
5206 target = gen_reg_rtx (fmode);
5208 emit_unop_insn (icode, target, from,
5209 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5211 if (target != to)
5212 convert_move (to, target, 0);
5213 return;
5217 /* Unsigned integer, and no way to convert directly. Convert as signed,
5218 then unconditionally adjust the result. */
5219 if (unsignedp
5220 && can_do_signed
5221 && is_a <scalar_mode> (GET_MODE (to), &to_mode)
5222 && is_a <scalar_mode> (GET_MODE (from), &from_mode))
5224 opt_scalar_mode fmode_iter;
5225 rtx_code_label *label = gen_label_rtx ();
5226 rtx temp;
5227 REAL_VALUE_TYPE offset;
5229 /* Look for a usable floating mode FMODE wider than the source and at
5230 least as wide as the target. Using FMODE will avoid rounding woes
5231 with unsigned values greater than the signed maximum value. */
5233 FOR_EACH_MODE_FROM (fmode_iter, to_mode)
5235 scalar_mode fmode = fmode_iter.require ();
5236 if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode)
5237 && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing)
5238 break;
5241 if (!fmode_iter.exists (&fmode))
5243 /* There is no such mode. Pretend the target is wide enough. */
5244 fmode = to_mode;
5246 /* Avoid double-rounding when TO is narrower than FROM. */
5247 if ((significand_size (fmode) + 1)
5248 < GET_MODE_PRECISION (from_mode))
5250 rtx temp1;
5251 rtx_code_label *neglabel = gen_label_rtx ();
5253 /* Don't use TARGET if it isn't a register, is a hard register,
5254 or is the wrong mode. */
5255 if (!REG_P (target)
5256 || REGNO (target) < FIRST_PSEUDO_REGISTER
5257 || GET_MODE (target) != fmode)
5258 target = gen_reg_rtx (fmode);
5260 imode = from_mode;
5261 do_pending_stack_adjust ();
5263 /* Test whether the sign bit is set. */
5264 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5265 0, neglabel);
5267 /* The sign bit is not set. Convert as signed. */
5268 expand_float (target, from, 0);
5269 emit_jump_insn (targetm.gen_jump (label));
5270 emit_barrier ();
5272 /* The sign bit is set.
5273 Convert to a usable (positive signed) value by shifting right
5274 one bit, while remembering if a nonzero bit was shifted
5275 out; i.e., compute (from & 1) | (from >> 1). */
5277 emit_label (neglabel);
5278 temp = expand_binop (imode, and_optab, from, const1_rtx,
5279 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5280 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
5281 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5282 OPTAB_LIB_WIDEN);
5283 expand_float (target, temp, 0);
5285 /* Multiply by 2 to undo the shift above. */
5286 temp = expand_binop (fmode, add_optab, target, target,
5287 target, 0, OPTAB_LIB_WIDEN);
5288 if (temp != target)
5289 emit_move_insn (target, temp);
5291 do_pending_stack_adjust ();
5292 emit_label (label);
5293 goto done;
5297 /* If we are about to do some arithmetic to correct for an
5298 unsigned operand, do it in a pseudo-register. */
5300 if (to_mode != fmode
5301 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5302 target = gen_reg_rtx (fmode);
5304 /* Convert as signed integer to floating. */
5305 expand_float (target, from, 0);
5307 /* If FROM is negative (and therefore TO is negative),
5308 correct its value by 2**bitwidth. */
5310 do_pending_stack_adjust ();
5311 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, from_mode,
5312 0, label);
5315 real_2expN (&offset, GET_MODE_PRECISION (from_mode), fmode);
5316 temp = expand_binop (fmode, add_optab, target,
5317 const_double_from_real_value (offset, fmode),
5318 target, 0, OPTAB_LIB_WIDEN);
5319 if (temp != target)
5320 emit_move_insn (target, temp);
5322 do_pending_stack_adjust ();
5323 emit_label (label);
5324 goto done;
5327 /* No hardware instruction available; call a library routine. */
5329 rtx libfunc;
5330 rtx_insn *insns;
5331 rtx value;
5332 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5334 if (is_narrower_int_mode (GET_MODE (from), SImode))
5335 from = convert_to_mode (SImode, from, unsignedp);
5337 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5338 gcc_assert (libfunc);
5340 start_sequence ();
5342 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5343 GET_MODE (to), from, GET_MODE (from));
5344 insns = get_insns ();
5345 end_sequence ();
5347 emit_libcall_block (insns, target, value,
5348 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
5349 GET_MODE (to), from));
5352 done:
5354 /* Copy result to requested destination
5355 if we have been computing in a temp location. */
5357 if (target != to)
5359 if (GET_MODE (target) == GET_MODE (to))
5360 emit_move_insn (to, target);
5361 else
5362 convert_move (to, target, 0);
5366 /* Generate code to convert FROM to fixed point and store in TO. FROM
5367 must be floating point. */
5369 void
5370 expand_fix (rtx to, rtx from, int unsignedp)
5372 enum insn_code icode;
5373 rtx target = to;
5374 machine_mode fmode, imode;
5375 opt_scalar_mode fmode_iter;
5376 bool must_trunc = false;
5378 /* We first try to find a pair of modes, one real and one integer, at
5379 least as wide as FROM and TO, respectively, in which we can open-code
5380 this conversion. If the integer mode is wider than the mode of TO,
5381 we can do the conversion either signed or unsigned. */
5383 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5384 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5386 int doing_unsigned = unsignedp;
5388 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5389 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5390 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5392 if (icode != CODE_FOR_nothing)
5394 rtx_insn *last = get_last_insn ();
5395 if (fmode != GET_MODE (from))
5396 from = convert_to_mode (fmode, from, 0);
5398 if (must_trunc)
5400 rtx temp = gen_reg_rtx (GET_MODE (from));
5401 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5402 temp, 0);
5405 if (imode != GET_MODE (to))
5406 target = gen_reg_rtx (imode);
5408 if (maybe_emit_unop_insn (icode, target, from,
5409 doing_unsigned ? UNSIGNED_FIX : FIX))
5411 if (target != to)
5412 convert_move (to, target, unsignedp);
5413 return;
5415 delete_insns_since (last);
5419 /* For an unsigned conversion, there is one more way to do it.
5420 If we have a signed conversion, we generate code that compares
5421 the real value to the largest representable positive number. If if
5422 is smaller, the conversion is done normally. Otherwise, subtract
5423 one plus the highest signed number, convert, and add it back.
5425 We only need to check all real modes, since we know we didn't find
5426 anything with a wider integer mode.
5428 This code used to extend FP value into mode wider than the destination.
5429 This is needed for decimal float modes which cannot accurately
5430 represent one plus the highest signed number of the same size, but
5431 not for binary modes. Consider, for instance conversion from SFmode
5432 into DImode.
5434 The hot path through the code is dealing with inputs smaller than 2^63
5435 and doing just the conversion, so there is no bits to lose.
5437 In the other path we know the value is positive in the range 2^63..2^64-1
5438 inclusive. (as for other input overflow happens and result is undefined)
5439 So we know that the most important bit set in mantissa corresponds to
5440 2^63. The subtraction of 2^63 should not generate any rounding as it
5441 simply clears out that bit. The rest is trivial. */
5443 scalar_int_mode to_mode;
5444 if (unsignedp
5445 && is_a <scalar_int_mode> (GET_MODE (to), &to_mode)
5446 && HWI_COMPUTABLE_MODE_P (to_mode))
5447 FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from)))
5449 scalar_mode fmode = fmode_iter.require ();
5450 if (CODE_FOR_nothing != can_fix_p (to_mode, fmode,
5451 0, &must_trunc)
5452 && (!DECIMAL_FLOAT_MODE_P (fmode)
5453 || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))))
5455 int bitsize;
5456 REAL_VALUE_TYPE offset;
5457 rtx limit;
5458 rtx_code_label *lab1, *lab2;
5459 rtx_insn *insn;
5461 bitsize = GET_MODE_PRECISION (to_mode);
5462 real_2expN (&offset, bitsize - 1, fmode);
5463 limit = const_double_from_real_value (offset, fmode);
5464 lab1 = gen_label_rtx ();
5465 lab2 = gen_label_rtx ();
5467 if (fmode != GET_MODE (from))
5468 from = convert_to_mode (fmode, from, 0);
5470 /* See if we need to do the subtraction. */
5471 do_pending_stack_adjust ();
5472 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX,
5473 GET_MODE (from), 0, lab1);
5475 /* If not, do the signed "fix" and branch around fixup code. */
5476 expand_fix (to, from, 0);
5477 emit_jump_insn (targetm.gen_jump (lab2));
5478 emit_barrier ();
5480 /* Otherwise, subtract 2**(N-1), convert to signed number,
5481 then add 2**(N-1). Do the addition using XOR since this
5482 will often generate better code. */
5483 emit_label (lab1);
5484 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5485 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5486 expand_fix (to, target, 0);
5487 target = expand_binop (to_mode, xor_optab, to,
5488 gen_int_mode
5489 (HOST_WIDE_INT_1 << (bitsize - 1),
5490 to_mode),
5491 to, 1, OPTAB_LIB_WIDEN);
5493 if (target != to)
5494 emit_move_insn (to, target);
5496 emit_label (lab2);
5498 if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing)
5500 /* Make a place for a REG_NOTE and add it. */
5501 insn = emit_move_insn (to, to);
5502 set_dst_reg_note (insn, REG_EQUAL,
5503 gen_rtx_fmt_e (UNSIGNED_FIX, to_mode,
5504 copy_rtx (from)),
5505 to);
5508 return;
5512 /* We can't do it with an insn, so use a library call. But first ensure
5513 that the mode of TO is at least as wide as SImode, since those are the
5514 only library calls we know about. */
5516 if (is_narrower_int_mode (GET_MODE (to), SImode))
5518 target = gen_reg_rtx (SImode);
5520 expand_fix (target, from, unsignedp);
5522 else
5524 rtx_insn *insns;
5525 rtx value;
5526 rtx libfunc;
5528 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5529 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
5530 gcc_assert (libfunc);
5532 start_sequence ();
5534 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5535 GET_MODE (to), from, GET_MODE (from));
5536 insns = get_insns ();
5537 end_sequence ();
5539 emit_libcall_block (insns, target, value,
5540 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5541 GET_MODE (to), from));
5544 if (target != to)
5546 if (GET_MODE (to) == GET_MODE (target))
5547 emit_move_insn (to, target);
5548 else
5549 convert_move (to, target, 0);
5554 /* Promote integer arguments for a libcall if necessary.
5555 emit_library_call_value cannot do the promotion because it does not
5556 know if it should do a signed or unsigned promotion. This is because
5557 there are no tree types defined for libcalls. */
5559 static rtx
5560 prepare_libcall_arg (rtx arg, int uintp)
5562 scalar_int_mode mode;
5563 machine_mode arg_mode;
5564 if (is_a <scalar_int_mode> (GET_MODE (arg), &mode))
5566 /* If we need to promote the integer function argument we need to do
5567 it here instead of inside emit_library_call_value because in
5568 emit_library_call_value we don't know if we should do a signed or
5569 unsigned promotion. */
5571 int unsigned_p = 0;
5572 arg_mode = promote_function_mode (NULL_TREE, mode,
5573 &unsigned_p, NULL_TREE, 0);
5574 if (arg_mode != mode)
5575 return convert_to_mode (arg_mode, arg, uintp);
5577 return arg;
5580 /* Generate code to convert FROM or TO a fixed-point.
5581 If UINTP is true, either TO or FROM is an unsigned integer.
5582 If SATP is true, we need to saturate the result. */
5584 void
5585 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
5587 machine_mode to_mode = GET_MODE (to);
5588 machine_mode from_mode = GET_MODE (from);
5589 convert_optab tab;
5590 enum rtx_code this_code;
5591 enum insn_code code;
5592 rtx_insn *insns;
5593 rtx value;
5594 rtx libfunc;
5596 if (to_mode == from_mode)
5598 emit_move_insn (to, from);
5599 return;
5602 if (uintp)
5604 tab = satp ? satfractuns_optab : fractuns_optab;
5605 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5607 else
5609 tab = satp ? satfract_optab : fract_optab;
5610 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5612 code = convert_optab_handler (tab, to_mode, from_mode);
5613 if (code != CODE_FOR_nothing)
5615 emit_unop_insn (code, to, from, this_code);
5616 return;
5619 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5620 gcc_assert (libfunc);
5622 from = prepare_libcall_arg (from, uintp);
5623 from_mode = GET_MODE (from);
5625 start_sequence ();
5626 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5627 from, from_mode);
5628 insns = get_insns ();
5629 end_sequence ();
5631 emit_libcall_block (insns, to, value,
5632 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5635 /* Generate code to convert FROM to fixed point and store in TO. FROM
5636 must be floating point, TO must be signed. Use the conversion optab
5637 TAB to do the conversion. */
5639 bool
5640 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5642 enum insn_code icode;
5643 rtx target = to;
5644 machine_mode fmode, imode;
5646 /* We first try to find a pair of modes, one real and one integer, at
5647 least as wide as FROM and TO, respectively, in which we can open-code
5648 this conversion. If the integer mode is wider than the mode of TO,
5649 we can do the conversion either signed or unsigned. */
5651 FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
5652 FOR_EACH_MODE_FROM (imode, GET_MODE (to))
5654 icode = convert_optab_handler (tab, imode, fmode);
5655 if (icode != CODE_FOR_nothing)
5657 rtx_insn *last = get_last_insn ();
5658 if (fmode != GET_MODE (from))
5659 from = convert_to_mode (fmode, from, 0);
5661 if (imode != GET_MODE (to))
5662 target = gen_reg_rtx (imode);
5664 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5666 delete_insns_since (last);
5667 continue;
5669 if (target != to)
5670 convert_move (to, target, 0);
5671 return true;
5675 return false;
5678 /* Report whether we have an instruction to perform the operation
5679 specified by CODE on operands of mode MODE. */
5681 have_insn_for (enum rtx_code code, machine_mode mode)
5683 return (code_to_optab (code)
5684 && (optab_handler (code_to_optab (code), mode)
5685 != CODE_FOR_nothing));
5688 /* Print information about the current contents of the optabs on
5689 STDERR. */
5691 DEBUG_FUNCTION void
5692 debug_optab_libfuncs (void)
5694 int i, j, k;
5696 /* Dump the arithmetic optabs. */
5697 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5698 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5700 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5701 if (l)
5703 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5704 fprintf (stderr, "%s\t%s:\t%s\n",
5705 GET_RTX_NAME (optab_to_code ((optab) i)),
5706 GET_MODE_NAME (j),
5707 XSTR (l, 0));
5711 /* Dump the conversion optabs. */
5712 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5713 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5714 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5716 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5717 (machine_mode) k);
5718 if (l)
5720 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5721 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5722 GET_RTX_NAME (optab_to_code ((optab) i)),
5723 GET_MODE_NAME (j),
5724 GET_MODE_NAME (k),
5725 XSTR (l, 0));
5730 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5731 CODE. Return 0 on failure. */
5733 rtx_insn *
5734 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5736 machine_mode mode = GET_MODE (op1);
5737 enum insn_code icode;
5738 rtx_insn *insn;
5739 rtx trap_rtx;
5741 if (mode == VOIDmode)
5742 return 0;
5744 icode = optab_handler (ctrap_optab, mode);
5745 if (icode == CODE_FOR_nothing)
5746 return 0;
5748 /* Some targets only accept a zero trap code. */
5749 if (!insn_operand_matches (icode, 3, tcode))
5750 return 0;
5752 do_pending_stack_adjust ();
5753 start_sequence ();
5754 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5755 &trap_rtx, &mode);
5756 if (!trap_rtx)
5757 insn = NULL;
5758 else
5759 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5760 tcode);
5762 /* If that failed, then give up. */
5763 if (insn == 0)
5765 end_sequence ();
5766 return 0;
5769 emit_insn (insn);
5770 insn = get_insns ();
5771 end_sequence ();
5772 return insn;
5775 /* Return rtx code for TCODE or UNKNOWN. Use UNSIGNEDP to select signed
5776 or unsigned operation code. */
5778 enum rtx_code
5779 get_rtx_code_1 (enum tree_code tcode, bool unsignedp)
5781 enum rtx_code code;
5782 switch (tcode)
5784 case EQ_EXPR:
5785 code = EQ;
5786 break;
5787 case NE_EXPR:
5788 code = NE;
5789 break;
5790 case LT_EXPR:
5791 code = unsignedp ? LTU : LT;
5792 break;
5793 case LE_EXPR:
5794 code = unsignedp ? LEU : LE;
5795 break;
5796 case GT_EXPR:
5797 code = unsignedp ? GTU : GT;
5798 break;
5799 case GE_EXPR:
5800 code = unsignedp ? GEU : GE;
5801 break;
5803 case UNORDERED_EXPR:
5804 code = UNORDERED;
5805 break;
5806 case ORDERED_EXPR:
5807 code = ORDERED;
5808 break;
5809 case UNLT_EXPR:
5810 code = UNLT;
5811 break;
5812 case UNLE_EXPR:
5813 code = UNLE;
5814 break;
5815 case UNGT_EXPR:
5816 code = UNGT;
5817 break;
5818 case UNGE_EXPR:
5819 code = UNGE;
5820 break;
5821 case UNEQ_EXPR:
5822 code = UNEQ;
5823 break;
5824 case LTGT_EXPR:
5825 code = LTGT;
5826 break;
5828 case BIT_AND_EXPR:
5829 code = AND;
5830 break;
5832 case BIT_IOR_EXPR:
5833 code = IOR;
5834 break;
5836 default:
5837 code = UNKNOWN;
5838 break;
5840 return code;
5843 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5844 or unsigned operation code. */
5846 enum rtx_code
5847 get_rtx_code (enum tree_code tcode, bool unsignedp)
5849 enum rtx_code code = get_rtx_code_1 (tcode, unsignedp);
5850 gcc_assert (code != UNKNOWN);
5851 return code;
5854 /* Return a comparison rtx of mode CMP_MODE for COND. Use UNSIGNEDP to
5855 select signed or unsigned operators. OPNO holds the index of the
5856 first comparison operand for insn ICODE. Do not generate the
5857 compare instruction itself. */
5860 vector_compare_rtx (machine_mode cmp_mode, enum tree_code tcode,
5861 tree t_op0, tree t_op1, bool unsignedp,
5862 enum insn_code icode, unsigned int opno)
5864 class expand_operand ops[2];
5865 rtx rtx_op0, rtx_op1;
5866 machine_mode m0, m1;
5867 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5869 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5871 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5872 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5873 cases, use the original mode. */
5874 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5875 EXPAND_STACK_PARM);
5876 m0 = GET_MODE (rtx_op0);
5877 if (m0 == VOIDmode)
5878 m0 = TYPE_MODE (TREE_TYPE (t_op0));
5880 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5881 EXPAND_STACK_PARM);
5882 m1 = GET_MODE (rtx_op1);
5883 if (m1 == VOIDmode)
5884 m1 = TYPE_MODE (TREE_TYPE (t_op1));
5886 create_input_operand (&ops[0], rtx_op0, m0);
5887 create_input_operand (&ops[1], rtx_op1, m1);
5888 if (!maybe_legitimize_operands (icode, opno, 2, ops))
5889 gcc_unreachable ();
5890 return gen_rtx_fmt_ee (rcode, cmp_mode, ops[0].value, ops[1].value);
5893 /* Check if vec_perm mask SEL is a constant equivalent to a shift of
5894 the first vec_perm operand, assuming the second operand (for left shift
5895 first operand) is a constant vector of zeros. Return the shift distance
5896 in bits if so, or NULL_RTX if the vec_perm is not a shift. MODE is the
5897 mode of the value being shifted. SHIFT_OPTAB is vec_shr_optab for right
5898 shift or vec_shl_optab for left shift. */
5899 static rtx
5900 shift_amt_for_vec_perm_mask (machine_mode mode, const vec_perm_indices &sel,
5901 optab shift_optab)
5903 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (mode);
5904 poly_int64 first = sel[0];
5905 if (maybe_ge (sel[0], GET_MODE_NUNITS (mode)))
5906 return NULL_RTX;
5908 if (shift_optab == vec_shl_optab)
5910 unsigned int nelt;
5911 if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
5912 return NULL_RTX;
5913 unsigned firstidx = 0;
5914 for (unsigned int i = 0; i < nelt; i++)
5916 if (known_eq (sel[i], nelt))
5918 if (i == 0 || firstidx)
5919 return NULL_RTX;
5920 firstidx = i;
5922 else if (firstidx
5923 ? maybe_ne (sel[i], nelt + i - firstidx)
5924 : maybe_ge (sel[i], nelt))
5925 return NULL_RTX;
5928 if (firstidx == 0)
5929 return NULL_RTX;
5930 first = firstidx;
5932 else if (!sel.series_p (0, 1, first, 1))
5934 unsigned int nelt;
5935 if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
5936 return NULL_RTX;
5937 for (unsigned int i = 1; i < nelt; i++)
5939 poly_int64 expected = i + first;
5940 /* Indices into the second vector are all equivalent. */
5941 if (maybe_lt (sel[i], nelt)
5942 ? maybe_ne (sel[i], expected)
5943 : maybe_lt (expected, nelt))
5944 return NULL_RTX;
5948 return gen_int_shift_amount (mode, first * bitsize);
5951 /* A subroutine of expand_vec_perm_var for expanding one vec_perm insn. */
5953 static rtx
5954 expand_vec_perm_1 (enum insn_code icode, rtx target,
5955 rtx v0, rtx v1, rtx sel)
5957 machine_mode tmode = GET_MODE (target);
5958 machine_mode smode = GET_MODE (sel);
5959 class expand_operand ops[4];
5961 gcc_assert (GET_MODE_CLASS (smode) == MODE_VECTOR_INT
5962 || related_int_vector_mode (tmode).require () == smode);
5963 create_output_operand (&ops[0], target, tmode);
5964 create_input_operand (&ops[3], sel, smode);
5966 /* Make an effort to preserve v0 == v1. The target expander is able to
5967 rely on this to determine if we're permuting a single input operand. */
5968 if (rtx_equal_p (v0, v1))
5970 if (!insn_operand_matches (icode, 1, v0))
5971 v0 = force_reg (tmode, v0);
5972 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5973 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5975 create_fixed_operand (&ops[1], v0);
5976 create_fixed_operand (&ops[2], v0);
5978 else
5980 create_input_operand (&ops[1], v0, tmode);
5981 create_input_operand (&ops[2], v1, tmode);
5984 if (maybe_expand_insn (icode, 4, ops))
5985 return ops[0].value;
5986 return NULL_RTX;
5989 /* Implement a permutation of vectors v0 and v1 using the permutation
5990 vector in SEL and return the result. Use TARGET to hold the result
5991 if nonnull and convenient.
5993 MODE is the mode of the vectors being permuted (V0 and V1). SEL_MODE
5994 is the TYPE_MODE associated with SEL, or BLKmode if SEL isn't known
5995 to have a particular mode. */
5998 expand_vec_perm_const (machine_mode mode, rtx v0, rtx v1,
5999 const vec_perm_builder &sel, machine_mode sel_mode,
6000 rtx target)
6002 if (!target || !register_operand (target, mode))
6003 target = gen_reg_rtx (mode);
6005 /* Set QIMODE to a different vector mode with byte elements.
6006 If no such mode, or if MODE already has byte elements, use VOIDmode. */
6007 machine_mode qimode;
6008 if (!qimode_for_vec_perm (mode).exists (&qimode))
6009 qimode = VOIDmode;
6011 rtx_insn *last = get_last_insn ();
6013 bool single_arg_p = rtx_equal_p (v0, v1);
6014 /* Always specify two input vectors here and leave the target to handle
6015 cases in which the inputs are equal. Not all backends can cope with
6016 the single-input representation when testing for a double-input
6017 target instruction. */
6018 vec_perm_indices indices (sel, 2, GET_MODE_NUNITS (mode));
6020 /* See if this can be handled with a vec_shr or vec_shl. We only do this
6021 if the second (for vec_shr) or first (for vec_shl) vector is all
6022 zeroes. */
6023 insn_code shift_code = CODE_FOR_nothing;
6024 insn_code shift_code_qi = CODE_FOR_nothing;
6025 optab shift_optab = unknown_optab;
6026 rtx v2 = v0;
6027 if (v1 == CONST0_RTX (GET_MODE (v1)))
6028 shift_optab = vec_shr_optab;
6029 else if (v0 == CONST0_RTX (GET_MODE (v0)))
6031 shift_optab = vec_shl_optab;
6032 v2 = v1;
6034 if (shift_optab != unknown_optab)
6036 shift_code = optab_handler (shift_optab, mode);
6037 shift_code_qi = ((qimode != VOIDmode && qimode != mode)
6038 ? optab_handler (shift_optab, qimode)
6039 : CODE_FOR_nothing);
6041 if (shift_code != CODE_FOR_nothing || shift_code_qi != CODE_FOR_nothing)
6043 rtx shift_amt = shift_amt_for_vec_perm_mask (mode, indices, shift_optab);
6044 if (shift_amt)
6046 class expand_operand ops[3];
6047 if (shift_amt == const0_rtx)
6048 return v2;
6049 if (shift_code != CODE_FOR_nothing)
6051 create_output_operand (&ops[0], target, mode);
6052 create_input_operand (&ops[1], v2, mode);
6053 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
6054 if (maybe_expand_insn (shift_code, 3, ops))
6055 return ops[0].value;
6057 if (shift_code_qi != CODE_FOR_nothing)
6059 rtx tmp = gen_reg_rtx (qimode);
6060 create_output_operand (&ops[0], tmp, qimode);
6061 create_input_operand (&ops[1], gen_lowpart (qimode, v2), qimode);
6062 create_convert_operand_from_type (&ops[2], shift_amt, sizetype);
6063 if (maybe_expand_insn (shift_code_qi, 3, ops))
6064 return gen_lowpart (mode, ops[0].value);
6069 if (targetm.vectorize.vec_perm_const != NULL)
6071 v0 = force_reg (mode, v0);
6072 if (single_arg_p)
6073 v1 = v0;
6074 else
6075 v1 = force_reg (mode, v1);
6077 if (targetm.vectorize.vec_perm_const (mode, target, v0, v1, indices))
6078 return target;
6081 /* Fall back to a constant byte-based permutation. */
6082 vec_perm_indices qimode_indices;
6083 rtx target_qi = NULL_RTX, v0_qi = NULL_RTX, v1_qi = NULL_RTX;
6084 if (qimode != VOIDmode)
6086 qimode_indices.new_expanded_vector (indices, GET_MODE_UNIT_SIZE (mode));
6087 target_qi = gen_reg_rtx (qimode);
6088 v0_qi = gen_lowpart (qimode, v0);
6089 v1_qi = gen_lowpart (qimode, v1);
6090 if (targetm.vectorize.vec_perm_const != NULL
6091 && targetm.vectorize.vec_perm_const (qimode, target_qi, v0_qi,
6092 v1_qi, qimode_indices))
6093 return gen_lowpart (mode, target_qi);
6096 /* Otherwise expand as a fully variable permuation. */
6098 /* The optabs are only defined for selectors with the same width
6099 as the values being permuted. */
6100 machine_mode required_sel_mode;
6101 if (!related_int_vector_mode (mode).exists (&required_sel_mode))
6103 delete_insns_since (last);
6104 return NULL_RTX;
6107 /* We know that it is semantically valid to treat SEL as having SEL_MODE.
6108 If that isn't the mode we want then we need to prove that using
6109 REQUIRED_SEL_MODE is OK. */
6110 if (sel_mode != required_sel_mode)
6112 if (!selector_fits_mode_p (required_sel_mode, indices))
6114 delete_insns_since (last);
6115 return NULL_RTX;
6117 sel_mode = required_sel_mode;
6120 insn_code icode = direct_optab_handler (vec_perm_optab, mode);
6121 if (icode != CODE_FOR_nothing)
6123 rtx sel_rtx = vec_perm_indices_to_rtx (sel_mode, indices);
6124 rtx tmp = expand_vec_perm_1 (icode, target, v0, v1, sel_rtx);
6125 if (tmp)
6126 return tmp;
6129 if (qimode != VOIDmode
6130 && selector_fits_mode_p (qimode, qimode_indices))
6132 icode = direct_optab_handler (vec_perm_optab, qimode);
6133 if (icode != CODE_FOR_nothing)
6135 rtx sel_qi = vec_perm_indices_to_rtx (qimode, qimode_indices);
6136 rtx tmp = expand_vec_perm_1 (icode, target_qi, v0_qi, v1_qi, sel_qi);
6137 if (tmp)
6138 return gen_lowpart (mode, tmp);
6142 delete_insns_since (last);
6143 return NULL_RTX;
6146 /* Implement a permutation of vectors v0 and v1 using the permutation
6147 vector in SEL and return the result. Use TARGET to hold the result
6148 if nonnull and convenient.
6150 MODE is the mode of the vectors being permuted (V0 and V1).
6151 SEL must have the integer equivalent of MODE and is known to be
6152 unsuitable for permutes with a constant permutation vector. */
6155 expand_vec_perm_var (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
6157 enum insn_code icode;
6158 unsigned int i, u;
6159 rtx tmp, sel_qi;
6161 u = GET_MODE_UNIT_SIZE (mode);
6163 if (!target || GET_MODE (target) != mode)
6164 target = gen_reg_rtx (mode);
6166 icode = direct_optab_handler (vec_perm_optab, mode);
6167 if (icode != CODE_FOR_nothing)
6169 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
6170 if (tmp)
6171 return tmp;
6174 /* As a special case to aid several targets, lower the element-based
6175 permutation to a byte-based permutation and try again. */
6176 machine_mode qimode;
6177 if (!qimode_for_vec_perm (mode).exists (&qimode)
6178 || maybe_gt (GET_MODE_NUNITS (qimode), GET_MODE_MASK (QImode) + 1))
6179 return NULL_RTX;
6180 icode = direct_optab_handler (vec_perm_optab, qimode);
6181 if (icode == CODE_FOR_nothing)
6182 return NULL_RTX;
6184 /* Multiply each element by its byte size. */
6185 machine_mode selmode = GET_MODE (sel);
6186 if (u == 2)
6187 sel = expand_simple_binop (selmode, PLUS, sel, sel,
6188 NULL, 0, OPTAB_DIRECT);
6189 else
6190 sel = expand_simple_binop (selmode, ASHIFT, sel,
6191 gen_int_shift_amount (selmode, exact_log2 (u)),
6192 NULL, 0, OPTAB_DIRECT);
6193 gcc_assert (sel != NULL);
6195 /* Broadcast the low byte each element into each of its bytes.
6196 The encoding has U interleaved stepped patterns, one for each
6197 byte of an element. */
6198 vec_perm_builder const_sel (GET_MODE_SIZE (mode), u, 3);
6199 unsigned int low_byte_in_u = BYTES_BIG_ENDIAN ? u - 1 : 0;
6200 for (i = 0; i < 3; ++i)
6201 for (unsigned int j = 0; j < u; ++j)
6202 const_sel.quick_push (i * u + low_byte_in_u);
6203 sel = gen_lowpart (qimode, sel);
6204 sel = expand_vec_perm_const (qimode, sel, sel, const_sel, qimode, NULL);
6205 gcc_assert (sel != NULL);
6207 /* Add the byte offset to each byte element. */
6208 /* Note that the definition of the indicies here is memory ordering,
6209 so there should be no difference between big and little endian. */
6210 rtx_vector_builder byte_indices (qimode, u, 1);
6211 for (i = 0; i < u; ++i)
6212 byte_indices.quick_push (GEN_INT (i));
6213 tmp = byte_indices.build ();
6214 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
6215 sel, 0, OPTAB_DIRECT);
6216 gcc_assert (sel_qi != NULL);
6218 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
6219 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
6220 gen_lowpart (qimode, v1), sel_qi);
6221 if (tmp)
6222 tmp = gen_lowpart (mode, tmp);
6223 return tmp;
6226 /* Generate VEC_SERIES_EXPR <OP0, OP1>, returning a value of mode VMODE.
6227 Use TARGET for the result if nonnull and convenient. */
6230 expand_vec_series_expr (machine_mode vmode, rtx op0, rtx op1, rtx target)
6232 class expand_operand ops[3];
6233 enum insn_code icode;
6234 machine_mode emode = GET_MODE_INNER (vmode);
6236 icode = direct_optab_handler (vec_series_optab, vmode);
6237 gcc_assert (icode != CODE_FOR_nothing);
6239 create_output_operand (&ops[0], target, vmode);
6240 create_input_operand (&ops[1], op0, emode);
6241 create_input_operand (&ops[2], op1, emode);
6243 expand_insn (icode, 3, ops);
6244 return ops[0].value;
6247 /* Generate insns for a vector comparison into a mask. */
6250 expand_vec_cmp_expr (tree type, tree exp, rtx target)
6252 class expand_operand ops[4];
6253 enum insn_code icode;
6254 rtx comparison;
6255 machine_mode mask_mode = TYPE_MODE (type);
6256 machine_mode vmode;
6257 bool unsignedp;
6258 tree op0a, op0b;
6259 enum tree_code tcode;
6261 op0a = TREE_OPERAND (exp, 0);
6262 op0b = TREE_OPERAND (exp, 1);
6263 tcode = TREE_CODE (exp);
6265 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
6266 vmode = TYPE_MODE (TREE_TYPE (op0a));
6268 icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
6269 if (icode == CODE_FOR_nothing)
6271 if (tcode == EQ_EXPR || tcode == NE_EXPR)
6272 icode = get_vec_cmp_eq_icode (vmode, mask_mode);
6273 if (icode == CODE_FOR_nothing)
6274 return 0;
6277 comparison = vector_compare_rtx (mask_mode, tcode, op0a, op0b,
6278 unsignedp, icode, 2);
6279 create_output_operand (&ops[0], target, mask_mode);
6280 create_fixed_operand (&ops[1], comparison);
6281 create_fixed_operand (&ops[2], XEXP (comparison, 0));
6282 create_fixed_operand (&ops[3], XEXP (comparison, 1));
6283 expand_insn (icode, 4, ops);
6284 return ops[0].value;
6287 /* Expand a highpart multiply. */
6290 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
6291 rtx target, bool uns_p)
6293 class expand_operand eops[3];
6294 enum insn_code icode;
6295 int method, i;
6296 machine_mode wmode;
6297 rtx m1, m2;
6298 optab tab1, tab2;
6300 method = can_mult_highpart_p (mode, uns_p);
6301 switch (method)
6303 case 0:
6304 return NULL_RTX;
6305 case 1:
6306 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
6307 return expand_binop (mode, tab1, op0, op1, target, uns_p,
6308 OPTAB_LIB_WIDEN);
6309 case 2:
6310 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
6311 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
6312 break;
6313 case 3:
6314 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
6315 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
6316 if (BYTES_BIG_ENDIAN)
6317 std::swap (tab1, tab2);
6318 break;
6319 default:
6320 gcc_unreachable ();
6323 icode = optab_handler (tab1, mode);
6324 wmode = insn_data[icode].operand[0].mode;
6325 gcc_checking_assert (known_eq (2 * GET_MODE_NUNITS (wmode),
6326 GET_MODE_NUNITS (mode)));
6327 gcc_checking_assert (known_eq (GET_MODE_SIZE (wmode), GET_MODE_SIZE (mode)));
6329 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6330 create_input_operand (&eops[1], op0, mode);
6331 create_input_operand (&eops[2], op1, mode);
6332 expand_insn (icode, 3, eops);
6333 m1 = gen_lowpart (mode, eops[0].value);
6335 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
6336 create_input_operand (&eops[1], op0, mode);
6337 create_input_operand (&eops[2], op1, mode);
6338 expand_insn (optab_handler (tab2, mode), 3, eops);
6339 m2 = gen_lowpart (mode, eops[0].value);
6341 vec_perm_builder sel;
6342 if (method == 2)
6344 /* The encoding has 2 interleaved stepped patterns. */
6345 sel.new_vector (GET_MODE_NUNITS (mode), 2, 3);
6346 for (i = 0; i < 6; ++i)
6347 sel.quick_push (!BYTES_BIG_ENDIAN + (i & ~1)
6348 + ((i & 1) ? GET_MODE_NUNITS (mode) : 0));
6350 else
6352 /* The encoding has a single interleaved stepped pattern. */
6353 sel.new_vector (GET_MODE_NUNITS (mode), 1, 3);
6354 for (i = 0; i < 3; ++i)
6355 sel.quick_push (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
6358 return expand_vec_perm_const (mode, m1, m2, sel, BLKmode, target);
6361 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
6362 pattern. */
6364 static void
6365 find_cc_set (rtx x, const_rtx pat, void *data)
6367 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
6368 && GET_CODE (pat) == SET)
6370 rtx *p_cc_reg = (rtx *) data;
6371 gcc_assert (!*p_cc_reg);
6372 *p_cc_reg = x;
6376 /* This is a helper function for the other atomic operations. This function
6377 emits a loop that contains SEQ that iterates until a compare-and-swap
6378 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6379 a set of instructions that takes a value from OLD_REG as an input and
6380 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6381 set to the current contents of MEM. After SEQ, a compare-and-swap will
6382 attempt to update MEM with NEW_REG. The function returns true when the
6383 loop was generated successfully. */
6385 static bool
6386 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6388 machine_mode mode = GET_MODE (mem);
6389 rtx_code_label *label;
6390 rtx cmp_reg, success, oldval;
6392 /* The loop we want to generate looks like
6394 cmp_reg = mem;
6395 label:
6396 old_reg = cmp_reg;
6397 seq;
6398 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
6399 if (success)
6400 goto label;
6402 Note that we only do the plain load from memory once. Subsequent
6403 iterations use the value loaded by the compare-and-swap pattern. */
6405 label = gen_label_rtx ();
6406 cmp_reg = gen_reg_rtx (mode);
6408 emit_move_insn (cmp_reg, mem);
6409 emit_label (label);
6410 emit_move_insn (old_reg, cmp_reg);
6411 if (seq)
6412 emit_insn (seq);
6414 success = NULL_RTX;
6415 oldval = cmp_reg;
6416 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
6417 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
6418 MEMMODEL_RELAXED))
6419 return false;
6421 if (oldval != cmp_reg)
6422 emit_move_insn (cmp_reg, oldval);
6424 /* Mark this jump predicted not taken. */
6425 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
6426 GET_MODE (success), 1, label,
6427 profile_probability::guessed_never ());
6428 return true;
6432 /* This function tries to emit an atomic_exchange intruction. VAL is written
6433 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
6434 using TARGET if possible. */
6436 static rtx
6437 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6439 machine_mode mode = GET_MODE (mem);
6440 enum insn_code icode;
6442 /* If the target supports the exchange directly, great. */
6443 icode = direct_optab_handler (atomic_exchange_optab, mode);
6444 if (icode != CODE_FOR_nothing)
6446 class expand_operand ops[4];
6448 create_output_operand (&ops[0], target, mode);
6449 create_fixed_operand (&ops[1], mem);
6450 create_input_operand (&ops[2], val, mode);
6451 create_integer_operand (&ops[3], model);
6452 if (maybe_expand_insn (icode, 4, ops))
6453 return ops[0].value;
6456 return NULL_RTX;
6459 /* This function tries to implement an atomic exchange operation using
6460 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
6461 The previous contents of *MEM are returned, using TARGET if possible.
6462 Since this instructionn is an acquire barrier only, stronger memory
6463 models may require additional barriers to be emitted. */
6465 static rtx
6466 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
6467 enum memmodel model)
6469 machine_mode mode = GET_MODE (mem);
6470 enum insn_code icode;
6471 rtx_insn *last_insn = get_last_insn ();
6473 icode = optab_handler (sync_lock_test_and_set_optab, mode);
6475 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
6476 exists, and the memory model is stronger than acquire, add a release
6477 barrier before the instruction. */
6479 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
6480 expand_mem_thread_fence (model);
6482 if (icode != CODE_FOR_nothing)
6484 class expand_operand ops[3];
6485 create_output_operand (&ops[0], target, mode);
6486 create_fixed_operand (&ops[1], mem);
6487 create_input_operand (&ops[2], val, mode);
6488 if (maybe_expand_insn (icode, 3, ops))
6489 return ops[0].value;
6492 /* If an external test-and-set libcall is provided, use that instead of
6493 any external compare-and-swap that we might get from the compare-and-
6494 swap-loop expansion later. */
6495 if (!can_compare_and_swap_p (mode, false))
6497 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
6498 if (libfunc != NULL)
6500 rtx addr;
6502 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6503 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6504 mode, addr, ptr_mode,
6505 val, mode);
6509 /* If the test_and_set can't be emitted, eliminate any barrier that might
6510 have been emitted. */
6511 delete_insns_since (last_insn);
6512 return NULL_RTX;
6515 /* This function tries to implement an atomic exchange operation using a
6516 compare_and_swap loop. VAL is written to *MEM. The previous contents of
6517 *MEM are returned, using TARGET if possible. No memory model is required
6518 since a compare_and_swap loop is seq-cst. */
6520 static rtx
6521 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
6523 machine_mode mode = GET_MODE (mem);
6525 if (can_compare_and_swap_p (mode, true))
6527 if (!target || !register_operand (target, mode))
6528 target = gen_reg_rtx (mode);
6529 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6530 return target;
6533 return NULL_RTX;
6536 /* This function tries to implement an atomic test-and-set operation
6537 using the atomic_test_and_set instruction pattern. A boolean value
6538 is returned from the operation, using TARGET if possible. */
6540 static rtx
6541 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6543 machine_mode pat_bool_mode;
6544 class expand_operand ops[3];
6546 if (!targetm.have_atomic_test_and_set ())
6547 return NULL_RTX;
6549 /* While we always get QImode from __atomic_test_and_set, we get
6550 other memory modes from __sync_lock_test_and_set. Note that we
6551 use no endian adjustment here. This matches the 4.6 behavior
6552 in the Sparc backend. */
6553 enum insn_code icode = targetm.code_for_atomic_test_and_set;
6554 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
6555 if (GET_MODE (mem) != QImode)
6556 mem = adjust_address_nv (mem, QImode, 0);
6558 pat_bool_mode = insn_data[icode].operand[0].mode;
6559 create_output_operand (&ops[0], target, pat_bool_mode);
6560 create_fixed_operand (&ops[1], mem);
6561 create_integer_operand (&ops[2], model);
6563 if (maybe_expand_insn (icode, 3, ops))
6564 return ops[0].value;
6565 return NULL_RTX;
6568 /* This function expands the legacy _sync_lock test_and_set operation which is
6569 generally an atomic exchange. Some limited targets only allow the
6570 constant 1 to be stored. This is an ACQUIRE operation.
6572 TARGET is an optional place to stick the return value.
6573 MEM is where VAL is stored. */
6576 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
6578 rtx ret;
6580 /* Try an atomic_exchange first. */
6581 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
6582 if (ret)
6583 return ret;
6585 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
6586 MEMMODEL_SYNC_ACQUIRE);
6587 if (ret)
6588 return ret;
6590 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6591 if (ret)
6592 return ret;
6594 /* If there are no other options, try atomic_test_and_set if the value
6595 being stored is 1. */
6596 if (val == const1_rtx)
6597 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
6599 return ret;
6602 /* This function expands the atomic test_and_set operation:
6603 atomically store a boolean TRUE into MEM and return the previous value.
6605 MEMMODEL is the memory model variant to use.
6606 TARGET is an optional place to stick the return value. */
6609 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
6611 machine_mode mode = GET_MODE (mem);
6612 rtx ret, trueval, subtarget;
6614 ret = maybe_emit_atomic_test_and_set (target, mem, model);
6615 if (ret)
6616 return ret;
6618 /* Be binary compatible with non-default settings of trueval, and different
6619 cpu revisions. E.g. one revision may have atomic-test-and-set, but
6620 another only has atomic-exchange. */
6621 if (targetm.atomic_test_and_set_trueval == 1)
6623 trueval = const1_rtx;
6624 subtarget = target ? target : gen_reg_rtx (mode);
6626 else
6628 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
6629 subtarget = gen_reg_rtx (mode);
6632 /* Try the atomic-exchange optab... */
6633 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
6635 /* ... then an atomic-compare-and-swap loop ... */
6636 if (!ret)
6637 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
6639 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6640 if (!ret)
6641 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
6643 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6644 things with the value 1. Thus we try again without trueval. */
6645 if (!ret && targetm.atomic_test_and_set_trueval != 1)
6646 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
6648 /* Failing all else, assume a single threaded environment and simply
6649 perform the operation. */
6650 if (!ret)
6652 /* If the result is ignored skip the move to target. */
6653 if (subtarget != const0_rtx)
6654 emit_move_insn (subtarget, mem);
6656 emit_move_insn (mem, trueval);
6657 ret = subtarget;
6660 /* Recall that have to return a boolean value; rectify if trueval
6661 is not exactly one. */
6662 if (targetm.atomic_test_and_set_trueval != 1)
6663 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
6665 return ret;
6668 /* This function expands the atomic exchange operation:
6669 atomically store VAL in MEM and return the previous value in MEM.
6671 MEMMODEL is the memory model variant to use.
6672 TARGET is an optional place to stick the return value. */
6675 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6677 machine_mode mode = GET_MODE (mem);
6678 rtx ret;
6680 /* If loads are not atomic for the required size and we are not called to
6681 provide a __sync builtin, do not do anything so that we stay consistent
6682 with atomic loads of the same size. */
6683 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
6684 return NULL_RTX;
6686 ret = maybe_emit_atomic_exchange (target, mem, val, model);
6688 /* Next try a compare-and-swap loop for the exchange. */
6689 if (!ret)
6690 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6692 return ret;
6695 /* This function expands the atomic compare exchange operation:
6697 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6698 *PTARGET_OVAL is an optional place to store the old value from memory.
6699 Both target parameters may be NULL or const0_rtx to indicate that we do
6700 not care about that return value. Both target parameters are updated on
6701 success to the actual location of the corresponding result.
6703 MEMMODEL is the memory model variant to use.
6705 The return value of the function is true for success. */
6707 bool
6708 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
6709 rtx mem, rtx expected, rtx desired,
6710 bool is_weak, enum memmodel succ_model,
6711 enum memmodel fail_model)
6713 machine_mode mode = GET_MODE (mem);
6714 class expand_operand ops[8];
6715 enum insn_code icode;
6716 rtx target_oval, target_bool = NULL_RTX;
6717 rtx libfunc;
6719 /* If loads are not atomic for the required size and we are not called to
6720 provide a __sync builtin, do not do anything so that we stay consistent
6721 with atomic loads of the same size. */
6722 if (!can_atomic_load_p (mode) && !is_mm_sync (succ_model))
6723 return false;
6725 /* Load expected into a register for the compare and swap. */
6726 if (MEM_P (expected))
6727 expected = copy_to_reg (expected);
6729 /* Make sure we always have some place to put the return oldval.
6730 Further, make sure that place is distinct from the input expected,
6731 just in case we need that path down below. */
6732 if (ptarget_oval && *ptarget_oval == const0_rtx)
6733 ptarget_oval = NULL;
6735 if (ptarget_oval == NULL
6736 || (target_oval = *ptarget_oval) == NULL
6737 || reg_overlap_mentioned_p (expected, target_oval))
6738 target_oval = gen_reg_rtx (mode);
6740 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6741 if (icode != CODE_FOR_nothing)
6743 machine_mode bool_mode = insn_data[icode].operand[0].mode;
6745 if (ptarget_bool && *ptarget_bool == const0_rtx)
6746 ptarget_bool = NULL;
6748 /* Make sure we always have a place for the bool operand. */
6749 if (ptarget_bool == NULL
6750 || (target_bool = *ptarget_bool) == NULL
6751 || GET_MODE (target_bool) != bool_mode)
6752 target_bool = gen_reg_rtx (bool_mode);
6754 /* Emit the compare_and_swap. */
6755 create_output_operand (&ops[0], target_bool, bool_mode);
6756 create_output_operand (&ops[1], target_oval, mode);
6757 create_fixed_operand (&ops[2], mem);
6758 create_input_operand (&ops[3], expected, mode);
6759 create_input_operand (&ops[4], desired, mode);
6760 create_integer_operand (&ops[5], is_weak);
6761 create_integer_operand (&ops[6], succ_model);
6762 create_integer_operand (&ops[7], fail_model);
6763 if (maybe_expand_insn (icode, 8, ops))
6765 /* Return success/failure. */
6766 target_bool = ops[0].value;
6767 target_oval = ops[1].value;
6768 goto success;
6772 /* Otherwise fall back to the original __sync_val_compare_and_swap
6773 which is always seq-cst. */
6774 icode = optab_handler (sync_compare_and_swap_optab, mode);
6775 if (icode != CODE_FOR_nothing)
6777 rtx cc_reg;
6779 create_output_operand (&ops[0], target_oval, mode);
6780 create_fixed_operand (&ops[1], mem);
6781 create_input_operand (&ops[2], expected, mode);
6782 create_input_operand (&ops[3], desired, mode);
6783 if (!maybe_expand_insn (icode, 4, ops))
6784 return false;
6786 target_oval = ops[0].value;
6788 /* If the caller isn't interested in the boolean return value,
6789 skip the computation of it. */
6790 if (ptarget_bool == NULL)
6791 goto success;
6793 /* Otherwise, work out if the compare-and-swap succeeded. */
6794 cc_reg = NULL_RTX;
6795 if (have_insn_for (COMPARE, CCmode))
6796 note_stores (get_last_insn (), find_cc_set, &cc_reg);
6797 if (cc_reg)
6799 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6800 const0_rtx, VOIDmode, 0, 1);
6801 goto success;
6803 goto success_bool_from_val;
6806 /* Also check for library support for __sync_val_compare_and_swap. */
6807 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6808 if (libfunc != NULL)
6810 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6811 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6812 mode, addr, ptr_mode,
6813 expected, mode, desired, mode);
6814 emit_move_insn (target_oval, target);
6816 /* Compute the boolean return value only if requested. */
6817 if (ptarget_bool)
6818 goto success_bool_from_val;
6819 else
6820 goto success;
6823 /* Failure. */
6824 return false;
6826 success_bool_from_val:
6827 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
6828 expected, VOIDmode, 1, 1);
6829 success:
6830 /* Make sure that the oval output winds up where the caller asked. */
6831 if (ptarget_oval)
6832 *ptarget_oval = target_oval;
6833 if (ptarget_bool)
6834 *ptarget_bool = target_bool;
6835 return true;
6838 /* Generate asm volatile("" : : : "memory") as the memory blockage. */
6840 static void
6841 expand_asm_memory_blockage (void)
6843 rtx asm_op, clob;
6845 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
6846 rtvec_alloc (0), rtvec_alloc (0),
6847 rtvec_alloc (0), UNKNOWN_LOCATION);
6848 MEM_VOLATILE_P (asm_op) = 1;
6850 clob = gen_rtx_SCRATCH (VOIDmode);
6851 clob = gen_rtx_MEM (BLKmode, clob);
6852 clob = gen_rtx_CLOBBER (VOIDmode, clob);
6854 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
6857 /* Do not propagate memory accesses across this point. */
6859 static void
6860 expand_memory_blockage (void)
6862 if (targetm.have_memory_blockage ())
6863 emit_insn (targetm.gen_memory_blockage ());
6864 else
6865 expand_asm_memory_blockage ();
6868 /* Generate asm volatile("" : : : "memory") as a memory blockage, at the
6869 same time clobbering the register set specified by REGS. */
6871 void
6872 expand_asm_reg_clobber_mem_blockage (HARD_REG_SET regs)
6874 rtx asm_op, clob_mem;
6876 unsigned int num_of_regs = 0;
6877 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6878 if (TEST_HARD_REG_BIT (regs, i))
6879 num_of_regs++;
6881 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, "", "", 0,
6882 rtvec_alloc (0), rtvec_alloc (0),
6883 rtvec_alloc (0), UNKNOWN_LOCATION);
6884 MEM_VOLATILE_P (asm_op) = 1;
6886 rtvec v = rtvec_alloc (num_of_regs + 2);
6888 clob_mem = gen_rtx_SCRATCH (VOIDmode);
6889 clob_mem = gen_rtx_MEM (BLKmode, clob_mem);
6890 clob_mem = gen_rtx_CLOBBER (VOIDmode, clob_mem);
6892 RTVEC_ELT (v, 0) = asm_op;
6893 RTVEC_ELT (v, 1) = clob_mem;
6895 if (num_of_regs > 0)
6897 unsigned int j = 2;
6898 for (unsigned int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
6899 if (TEST_HARD_REG_BIT (regs, i))
6901 RTVEC_ELT (v, j) = gen_rtx_CLOBBER (VOIDmode, regno_reg_rtx[i]);
6902 j++;
6904 gcc_assert (j == (num_of_regs + 2));
6907 emit_insn (gen_rtx_PARALLEL (VOIDmode, v));
6910 /* This routine will either emit the mem_thread_fence pattern or issue a
6911 sync_synchronize to generate a fence for memory model MEMMODEL. */
6913 void
6914 expand_mem_thread_fence (enum memmodel model)
6916 if (is_mm_relaxed (model))
6917 return;
6918 if (targetm.have_mem_thread_fence ())
6920 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
6921 expand_memory_blockage ();
6923 else if (targetm.have_memory_barrier ())
6924 emit_insn (targetm.gen_memory_barrier ());
6925 else if (synchronize_libfunc != NULL_RTX)
6926 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode);
6927 else
6928 expand_memory_blockage ();
6931 /* Emit a signal fence with given memory model. */
6933 void
6934 expand_mem_signal_fence (enum memmodel model)
6936 /* No machine barrier is required to implement a signal fence, but
6937 a compiler memory barrier must be issued, except for relaxed MM. */
6938 if (!is_mm_relaxed (model))
6939 expand_memory_blockage ();
6942 /* This function expands the atomic load operation:
6943 return the atomically loaded value in MEM.
6945 MEMMODEL is the memory model variant to use.
6946 TARGET is an option place to stick the return value. */
6949 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6951 machine_mode mode = GET_MODE (mem);
6952 enum insn_code icode;
6954 /* If the target supports the load directly, great. */
6955 icode = direct_optab_handler (atomic_load_optab, mode);
6956 if (icode != CODE_FOR_nothing)
6958 class expand_operand ops[3];
6959 rtx_insn *last = get_last_insn ();
6960 if (is_mm_seq_cst (model))
6961 expand_memory_blockage ();
6963 create_output_operand (&ops[0], target, mode);
6964 create_fixed_operand (&ops[1], mem);
6965 create_integer_operand (&ops[2], model);
6966 if (maybe_expand_insn (icode, 3, ops))
6968 if (!is_mm_relaxed (model))
6969 expand_memory_blockage ();
6970 return ops[0].value;
6972 delete_insns_since (last);
6975 /* If the size of the object is greater than word size on this target,
6976 then we assume that a load will not be atomic. We could try to
6977 emulate a load with a compare-and-swap operation, but the store that
6978 doing this could result in would be incorrect if this is a volatile
6979 atomic load or targetting read-only-mapped memory. */
6980 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
6981 /* If there is no atomic load, leave the library call. */
6982 return NULL_RTX;
6984 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6985 if (!target || target == const0_rtx)
6986 target = gen_reg_rtx (mode);
6988 /* For SEQ_CST, emit a barrier before the load. */
6989 if (is_mm_seq_cst (model))
6990 expand_mem_thread_fence (model);
6992 emit_move_insn (target, mem);
6994 /* Emit the appropriate barrier after the load. */
6995 expand_mem_thread_fence (model);
6997 return target;
7000 /* This function expands the atomic store operation:
7001 Atomically store VAL in MEM.
7002 MEMMODEL is the memory model variant to use.
7003 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
7004 function returns const0_rtx if a pattern was emitted. */
7007 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
7009 machine_mode mode = GET_MODE (mem);
7010 enum insn_code icode;
7011 class expand_operand ops[3];
7013 /* If the target supports the store directly, great. */
7014 icode = direct_optab_handler (atomic_store_optab, mode);
7015 if (icode != CODE_FOR_nothing)
7017 rtx_insn *last = get_last_insn ();
7018 if (!is_mm_relaxed (model))
7019 expand_memory_blockage ();
7020 create_fixed_operand (&ops[0], mem);
7021 create_input_operand (&ops[1], val, mode);
7022 create_integer_operand (&ops[2], model);
7023 if (maybe_expand_insn (icode, 3, ops))
7025 if (is_mm_seq_cst (model))
7026 expand_memory_blockage ();
7027 return const0_rtx;
7029 delete_insns_since (last);
7032 /* If using __sync_lock_release is a viable alternative, try it.
7033 Note that this will not be set to true if we are expanding a generic
7034 __atomic_store_n. */
7035 if (use_release)
7037 icode = direct_optab_handler (sync_lock_release_optab, mode);
7038 if (icode != CODE_FOR_nothing)
7040 create_fixed_operand (&ops[0], mem);
7041 create_input_operand (&ops[1], const0_rtx, mode);
7042 if (maybe_expand_insn (icode, 2, ops))
7044 /* lock_release is only a release barrier. */
7045 if (is_mm_seq_cst (model))
7046 expand_mem_thread_fence (model);
7047 return const0_rtx;
7052 /* If the size of the object is greater than word size on this target,
7053 a default store will not be atomic. */
7054 if (maybe_gt (GET_MODE_PRECISION (mode), BITS_PER_WORD))
7056 /* If loads are atomic or we are called to provide a __sync builtin,
7057 we can try a atomic_exchange and throw away the result. Otherwise,
7058 don't do anything so that we do not create an inconsistency between
7059 loads and stores. */
7060 if (can_atomic_load_p (mode) || is_mm_sync (model))
7062 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
7063 if (!target)
7064 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem,
7065 val);
7066 if (target)
7067 return const0_rtx;
7069 return NULL_RTX;
7072 /* Otherwise assume stores are atomic, and emit the proper barriers. */
7073 expand_mem_thread_fence (model);
7075 emit_move_insn (mem, val);
7077 /* For SEQ_CST, also emit a barrier after the store. */
7078 if (is_mm_seq_cst (model))
7079 expand_mem_thread_fence (model);
7081 return const0_rtx;
7085 /* Structure containing the pointers and values required to process the
7086 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
7088 struct atomic_op_functions
7090 direct_optab mem_fetch_before;
7091 direct_optab mem_fetch_after;
7092 direct_optab mem_no_result;
7093 optab fetch_before;
7094 optab fetch_after;
7095 direct_optab no_result;
7096 enum rtx_code reverse_code;
7100 /* Fill in structure pointed to by OP with the various optab entries for an
7101 operation of type CODE. */
7103 static void
7104 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
7106 gcc_assert (op!= NULL);
7108 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
7109 in the source code during compilation, and the optab entries are not
7110 computable until runtime. Fill in the values at runtime. */
7111 switch (code)
7113 case PLUS:
7114 op->mem_fetch_before = atomic_fetch_add_optab;
7115 op->mem_fetch_after = atomic_add_fetch_optab;
7116 op->mem_no_result = atomic_add_optab;
7117 op->fetch_before = sync_old_add_optab;
7118 op->fetch_after = sync_new_add_optab;
7119 op->no_result = sync_add_optab;
7120 op->reverse_code = MINUS;
7121 break;
7122 case MINUS:
7123 op->mem_fetch_before = atomic_fetch_sub_optab;
7124 op->mem_fetch_after = atomic_sub_fetch_optab;
7125 op->mem_no_result = atomic_sub_optab;
7126 op->fetch_before = sync_old_sub_optab;
7127 op->fetch_after = sync_new_sub_optab;
7128 op->no_result = sync_sub_optab;
7129 op->reverse_code = PLUS;
7130 break;
7131 case XOR:
7132 op->mem_fetch_before = atomic_fetch_xor_optab;
7133 op->mem_fetch_after = atomic_xor_fetch_optab;
7134 op->mem_no_result = atomic_xor_optab;
7135 op->fetch_before = sync_old_xor_optab;
7136 op->fetch_after = sync_new_xor_optab;
7137 op->no_result = sync_xor_optab;
7138 op->reverse_code = XOR;
7139 break;
7140 case AND:
7141 op->mem_fetch_before = atomic_fetch_and_optab;
7142 op->mem_fetch_after = atomic_and_fetch_optab;
7143 op->mem_no_result = atomic_and_optab;
7144 op->fetch_before = sync_old_and_optab;
7145 op->fetch_after = sync_new_and_optab;
7146 op->no_result = sync_and_optab;
7147 op->reverse_code = UNKNOWN;
7148 break;
7149 case IOR:
7150 op->mem_fetch_before = atomic_fetch_or_optab;
7151 op->mem_fetch_after = atomic_or_fetch_optab;
7152 op->mem_no_result = atomic_or_optab;
7153 op->fetch_before = sync_old_ior_optab;
7154 op->fetch_after = sync_new_ior_optab;
7155 op->no_result = sync_ior_optab;
7156 op->reverse_code = UNKNOWN;
7157 break;
7158 case NOT:
7159 op->mem_fetch_before = atomic_fetch_nand_optab;
7160 op->mem_fetch_after = atomic_nand_fetch_optab;
7161 op->mem_no_result = atomic_nand_optab;
7162 op->fetch_before = sync_old_nand_optab;
7163 op->fetch_after = sync_new_nand_optab;
7164 op->no_result = sync_nand_optab;
7165 op->reverse_code = UNKNOWN;
7166 break;
7167 default:
7168 gcc_unreachable ();
7172 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
7173 using memory order MODEL. If AFTER is true the operation needs to return
7174 the value of *MEM after the operation, otherwise the previous value.
7175 TARGET is an optional place to place the result. The result is unused if
7176 it is const0_rtx.
7177 Return the result if there is a better sequence, otherwise NULL_RTX. */
7179 static rtx
7180 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7181 enum memmodel model, bool after)
7183 /* If the value is prefetched, or not used, it may be possible to replace
7184 the sequence with a native exchange operation. */
7185 if (!after || target == const0_rtx)
7187 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
7188 if (code == AND && val == const0_rtx)
7190 if (target == const0_rtx)
7191 target = gen_reg_rtx (GET_MODE (mem));
7192 return maybe_emit_atomic_exchange (target, mem, val, model);
7195 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
7196 if (code == IOR && val == constm1_rtx)
7198 if (target == const0_rtx)
7199 target = gen_reg_rtx (GET_MODE (mem));
7200 return maybe_emit_atomic_exchange (target, mem, val, model);
7204 return NULL_RTX;
7207 /* Try to emit an instruction for a specific operation varaition.
7208 OPTAB contains the OP functions.
7209 TARGET is an optional place to return the result. const0_rtx means unused.
7210 MEM is the memory location to operate on.
7211 VAL is the value to use in the operation.
7212 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
7213 MODEL is the memory model, if used.
7214 AFTER is true if the returned result is the value after the operation. */
7216 static rtx
7217 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
7218 rtx val, bool use_memmodel, enum memmodel model, bool after)
7220 machine_mode mode = GET_MODE (mem);
7221 class expand_operand ops[4];
7222 enum insn_code icode;
7223 int op_counter = 0;
7224 int num_ops;
7226 /* Check to see if there is a result returned. */
7227 if (target == const0_rtx)
7229 if (use_memmodel)
7231 icode = direct_optab_handler (optab->mem_no_result, mode);
7232 create_integer_operand (&ops[2], model);
7233 num_ops = 3;
7235 else
7237 icode = direct_optab_handler (optab->no_result, mode);
7238 num_ops = 2;
7241 /* Otherwise, we need to generate a result. */
7242 else
7244 if (use_memmodel)
7246 icode = direct_optab_handler (after ? optab->mem_fetch_after
7247 : optab->mem_fetch_before, mode);
7248 create_integer_operand (&ops[3], model);
7249 num_ops = 4;
7251 else
7253 icode = optab_handler (after ? optab->fetch_after
7254 : optab->fetch_before, mode);
7255 num_ops = 3;
7257 create_output_operand (&ops[op_counter++], target, mode);
7259 if (icode == CODE_FOR_nothing)
7260 return NULL_RTX;
7262 create_fixed_operand (&ops[op_counter++], mem);
7263 /* VAL may have been promoted to a wider mode. Shrink it if so. */
7264 create_convert_operand_to (&ops[op_counter++], val, mode, true);
7266 if (maybe_expand_insn (icode, num_ops, ops))
7267 return (target == const0_rtx ? const0_rtx : ops[0].value);
7269 return NULL_RTX;
7273 /* This function expands an atomic fetch_OP or OP_fetch operation:
7274 TARGET is an option place to stick the return value. const0_rtx indicates
7275 the result is unused.
7276 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7277 CODE is the operation being performed (OP)
7278 MEMMODEL is the memory model variant to use.
7279 AFTER is true to return the result of the operation (OP_fetch).
7280 AFTER is false to return the value before the operation (fetch_OP).
7282 This function will *only* generate instructions if there is a direct
7283 optab. No compare and swap loops or libcalls will be generated. */
7285 static rtx
7286 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
7287 enum rtx_code code, enum memmodel model,
7288 bool after)
7290 machine_mode mode = GET_MODE (mem);
7291 struct atomic_op_functions optab;
7292 rtx result;
7293 bool unused_result = (target == const0_rtx);
7295 get_atomic_op_for_code (&optab, code);
7297 /* Check to see if there are any better instructions. */
7298 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
7299 if (result)
7300 return result;
7302 /* Check for the case where the result isn't used and try those patterns. */
7303 if (unused_result)
7305 /* Try the memory model variant first. */
7306 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
7307 if (result)
7308 return result;
7310 /* Next try the old style withuot a memory model. */
7311 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
7312 if (result)
7313 return result;
7315 /* There is no no-result pattern, so try patterns with a result. */
7316 target = NULL_RTX;
7319 /* Try the __atomic version. */
7320 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
7321 if (result)
7322 return result;
7324 /* Try the older __sync version. */
7325 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
7326 if (result)
7327 return result;
7329 /* If the fetch value can be calculated from the other variation of fetch,
7330 try that operation. */
7331 if (after || unused_result || optab.reverse_code != UNKNOWN)
7333 /* Try the __atomic version, then the older __sync version. */
7334 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
7335 if (!result)
7336 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
7338 if (result)
7340 /* If the result isn't used, no need to do compensation code. */
7341 if (unused_result)
7342 return result;
7344 /* Issue compensation code. Fetch_after == fetch_before OP val.
7345 Fetch_before == after REVERSE_OP val. */
7346 if (!after)
7347 code = optab.reverse_code;
7348 if (code == NOT)
7350 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
7351 true, OPTAB_LIB_WIDEN);
7352 result = expand_simple_unop (mode, NOT, result, target, true);
7354 else
7355 result = expand_simple_binop (mode, code, result, val, target,
7356 true, OPTAB_LIB_WIDEN);
7357 return result;
7361 /* No direct opcode can be generated. */
7362 return NULL_RTX;
7367 /* This function expands an atomic fetch_OP or OP_fetch operation:
7368 TARGET is an option place to stick the return value. const0_rtx indicates
7369 the result is unused.
7370 atomically fetch MEM, perform the operation with VAL and return it to MEM.
7371 CODE is the operation being performed (OP)
7372 MEMMODEL is the memory model variant to use.
7373 AFTER is true to return the result of the operation (OP_fetch).
7374 AFTER is false to return the value before the operation (fetch_OP). */
7376 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
7377 enum memmodel model, bool after)
7379 machine_mode mode = GET_MODE (mem);
7380 rtx result;
7381 bool unused_result = (target == const0_rtx);
7383 /* If loads are not atomic for the required size and we are not called to
7384 provide a __sync builtin, do not do anything so that we stay consistent
7385 with atomic loads of the same size. */
7386 if (!can_atomic_load_p (mode) && !is_mm_sync (model))
7387 return NULL_RTX;
7389 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
7390 after);
7392 if (result)
7393 return result;
7395 /* Add/sub can be implemented by doing the reverse operation with -(val). */
7396 if (code == PLUS || code == MINUS)
7398 rtx tmp;
7399 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
7401 start_sequence ();
7402 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
7403 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
7404 model, after);
7405 if (result)
7407 /* PLUS worked so emit the insns and return. */
7408 tmp = get_insns ();
7409 end_sequence ();
7410 emit_insn (tmp);
7411 return result;
7414 /* PLUS did not work, so throw away the negation code and continue. */
7415 end_sequence ();
7418 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
7419 if (!can_compare_and_swap_p (mode, false))
7421 rtx libfunc;
7422 bool fixup = false;
7423 enum rtx_code orig_code = code;
7424 struct atomic_op_functions optab;
7426 get_atomic_op_for_code (&optab, code);
7427 libfunc = optab_libfunc (after ? optab.fetch_after
7428 : optab.fetch_before, mode);
7429 if (libfunc == NULL
7430 && (after || unused_result || optab.reverse_code != UNKNOWN))
7432 fixup = true;
7433 if (!after)
7434 code = optab.reverse_code;
7435 libfunc = optab_libfunc (after ? optab.fetch_before
7436 : optab.fetch_after, mode);
7438 if (libfunc != NULL)
7440 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
7441 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
7442 addr, ptr_mode, val, mode);
7444 if (!unused_result && fixup)
7445 result = expand_simple_binop (mode, code, result, val, target,
7446 true, OPTAB_LIB_WIDEN);
7447 return result;
7450 /* We need the original code for any further attempts. */
7451 code = orig_code;
7454 /* If nothing else has succeeded, default to a compare and swap loop. */
7455 if (can_compare_and_swap_p (mode, true))
7457 rtx_insn *insn;
7458 rtx t0 = gen_reg_rtx (mode), t1;
7460 start_sequence ();
7462 /* If the result is used, get a register for it. */
7463 if (!unused_result)
7465 if (!target || !register_operand (target, mode))
7466 target = gen_reg_rtx (mode);
7467 /* If fetch_before, copy the value now. */
7468 if (!after)
7469 emit_move_insn (target, t0);
7471 else
7472 target = const0_rtx;
7474 t1 = t0;
7475 if (code == NOT)
7477 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
7478 true, OPTAB_LIB_WIDEN);
7479 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
7481 else
7482 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
7483 OPTAB_LIB_WIDEN);
7485 /* For after, copy the value now. */
7486 if (!unused_result && after)
7487 emit_move_insn (target, t1);
7488 insn = get_insns ();
7489 end_sequence ();
7491 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
7492 return target;
7495 return NULL_RTX;
7498 /* Return true if OPERAND is suitable for operand number OPNO of
7499 instruction ICODE. */
7501 bool
7502 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
7504 return (!insn_data[(int) icode].operand[opno].predicate
7505 || (insn_data[(int) icode].operand[opno].predicate
7506 (operand, insn_data[(int) icode].operand[opno].mode)));
7509 /* TARGET is a target of a multiword operation that we are going to
7510 implement as a series of word-mode operations. Return true if
7511 TARGET is suitable for this purpose. */
7513 bool
7514 valid_multiword_target_p (rtx target)
7516 machine_mode mode;
7517 int i, size;
7519 mode = GET_MODE (target);
7520 if (!GET_MODE_SIZE (mode).is_constant (&size))
7521 return false;
7522 for (i = 0; i < size; i += UNITS_PER_WORD)
7523 if (!validate_subreg (word_mode, mode, target, i))
7524 return false;
7525 return true;
7528 /* Make OP describe an input operand that has value INTVAL and that has
7529 no inherent mode. This function should only be used for operands that
7530 are always expand-time constants. The backend may request that INTVAL
7531 be copied into a different kind of rtx, but it must specify the mode
7532 of that rtx if so. */
7534 void
7535 create_integer_operand (class expand_operand *op, poly_int64 intval)
7537 create_expand_operand (op, EXPAND_INTEGER,
7538 gen_int_mode (intval, MAX_MODE_INT),
7539 VOIDmode, false, intval);
7542 /* Like maybe_legitimize_operand, but do not change the code of the
7543 current rtx value. */
7545 static bool
7546 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
7547 class expand_operand *op)
7549 /* See if the operand matches in its current form. */
7550 if (insn_operand_matches (icode, opno, op->value))
7551 return true;
7553 /* If the operand is a memory whose address has no side effects,
7554 try forcing the address into a non-virtual pseudo register.
7555 The check for side effects is important because copy_to_mode_reg
7556 cannot handle things like auto-modified addresses. */
7557 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
7559 rtx addr, mem;
7561 mem = op->value;
7562 addr = XEXP (mem, 0);
7563 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
7564 && !side_effects_p (addr))
7566 rtx_insn *last;
7567 machine_mode mode;
7569 last = get_last_insn ();
7570 mode = get_address_mode (mem);
7571 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
7572 if (insn_operand_matches (icode, opno, mem))
7574 op->value = mem;
7575 return true;
7577 delete_insns_since (last);
7581 return false;
7584 /* Try to make OP match operand OPNO of instruction ICODE. Return true
7585 on success, storing the new operand value back in OP. */
7587 static bool
7588 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
7589 class expand_operand *op)
7591 machine_mode mode, imode, tmode;
7593 mode = op->mode;
7594 switch (op->type)
7596 case EXPAND_FIXED:
7598 temporary_volatile_ok v (true);
7599 return maybe_legitimize_operand_same_code (icode, opno, op);
7602 case EXPAND_OUTPUT:
7603 gcc_assert (mode != VOIDmode);
7604 if (op->value
7605 && op->value != const0_rtx
7606 && GET_MODE (op->value) == mode
7607 && maybe_legitimize_operand_same_code (icode, opno, op))
7608 return true;
7610 op->value = gen_reg_rtx (mode);
7611 op->target = 0;
7612 break;
7614 case EXPAND_INPUT:
7615 input:
7616 gcc_assert (mode != VOIDmode);
7617 gcc_assert (GET_MODE (op->value) == VOIDmode
7618 || GET_MODE (op->value) == mode);
7619 if (maybe_legitimize_operand_same_code (icode, opno, op))
7620 return true;
7622 op->value = copy_to_mode_reg (mode, op->value);
7623 break;
7625 case EXPAND_CONVERT_TO:
7626 gcc_assert (mode != VOIDmode);
7627 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
7628 goto input;
7630 case EXPAND_CONVERT_FROM:
7631 if (GET_MODE (op->value) != VOIDmode)
7632 mode = GET_MODE (op->value);
7633 else
7634 /* The caller must tell us what mode this value has. */
7635 gcc_assert (mode != VOIDmode);
7637 imode = insn_data[(int) icode].operand[opno].mode;
7638 tmode = (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode)
7639 ? GET_MODE_INNER (imode) : imode);
7640 if (tmode != VOIDmode && tmode != mode)
7642 op->value = convert_modes (tmode, mode, op->value, op->unsigned_p);
7643 mode = tmode;
7645 if (imode != VOIDmode && imode != mode)
7647 gcc_assert (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode));
7648 op->value = expand_vector_broadcast (imode, op->value);
7649 mode = imode;
7651 goto input;
7653 case EXPAND_ADDRESS:
7654 op->value = convert_memory_address (as_a <scalar_int_mode> (mode),
7655 op->value);
7656 goto input;
7658 case EXPAND_INTEGER:
7659 mode = insn_data[(int) icode].operand[opno].mode;
7660 if (mode != VOIDmode
7661 && known_eq (trunc_int_for_mode (op->int_value, mode),
7662 op->int_value))
7664 op->value = gen_int_mode (op->int_value, mode);
7665 goto input;
7667 break;
7669 return insn_operand_matches (icode, opno, op->value);
7672 /* Make OP describe an input operand that should have the same value
7673 as VALUE, after any mode conversion that the target might request.
7674 TYPE is the type of VALUE. */
7676 void
7677 create_convert_operand_from_type (class expand_operand *op,
7678 rtx value, tree type)
7680 create_convert_operand_from (op, value, TYPE_MODE (type),
7681 TYPE_UNSIGNED (type));
7684 /* Return true if the requirements on operands OP1 and OP2 of instruction
7685 ICODE are similar enough for the result of legitimizing OP1 to be
7686 reusable for OP2. OPNO1 and OPNO2 are the operand numbers associated
7687 with OP1 and OP2 respectively. */
7689 static inline bool
7690 can_reuse_operands_p (enum insn_code icode,
7691 unsigned int opno1, unsigned int opno2,
7692 const class expand_operand *op1,
7693 const class expand_operand *op2)
7695 /* Check requirements that are common to all types. */
7696 if (op1->type != op2->type
7697 || op1->mode != op2->mode
7698 || (insn_data[(int) icode].operand[opno1].mode
7699 != insn_data[(int) icode].operand[opno2].mode))
7700 return false;
7702 /* Check the requirements for specific types. */
7703 switch (op1->type)
7705 case EXPAND_OUTPUT:
7706 /* Outputs must remain distinct. */
7707 return false;
7709 case EXPAND_FIXED:
7710 case EXPAND_INPUT:
7711 case EXPAND_ADDRESS:
7712 case EXPAND_INTEGER:
7713 return true;
7715 case EXPAND_CONVERT_TO:
7716 case EXPAND_CONVERT_FROM:
7717 return op1->unsigned_p == op2->unsigned_p;
7719 gcc_unreachable ();
7722 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
7723 of instruction ICODE. Return true on success, leaving the new operand
7724 values in the OPS themselves. Emit no code on failure. */
7726 bool
7727 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
7728 unsigned int nops, class expand_operand *ops)
7730 rtx_insn *last = get_last_insn ();
7731 rtx *orig_values = XALLOCAVEC (rtx, nops);
7732 for (unsigned int i = 0; i < nops; i++)
7734 orig_values[i] = ops[i].value;
7736 /* First try reusing the result of an earlier legitimization.
7737 This avoids duplicate rtl and ensures that tied operands
7738 remain tied.
7740 This search is linear, but NOPS is bounded at compile time
7741 to a small number (current a single digit). */
7742 unsigned int j = 0;
7743 for (; j < i; ++j)
7744 if (can_reuse_operands_p (icode, opno + j, opno + i, &ops[j], &ops[i])
7745 && rtx_equal_p (orig_values[j], orig_values[i])
7746 && ops[j].value
7747 && insn_operand_matches (icode, opno + i, ops[j].value))
7749 ops[i].value = copy_rtx (ops[j].value);
7750 break;
7753 /* Otherwise try legitimizing the operand on its own. */
7754 if (j == i && !maybe_legitimize_operand (icode, opno + i, &ops[i]))
7756 delete_insns_since (last);
7757 return false;
7760 return true;
7763 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
7764 as its operands. Return the instruction pattern on success,
7765 and emit any necessary set-up code. Return null and emit no
7766 code on failure. */
7768 rtx_insn *
7769 maybe_gen_insn (enum insn_code icode, unsigned int nops,
7770 class expand_operand *ops)
7772 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
7773 if (!maybe_legitimize_operands (icode, 0, nops, ops))
7774 return NULL;
7776 switch (nops)
7778 case 1:
7779 return GEN_FCN (icode) (ops[0].value);
7780 case 2:
7781 return GEN_FCN (icode) (ops[0].value, ops[1].value);
7782 case 3:
7783 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
7784 case 4:
7785 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7786 ops[3].value);
7787 case 5:
7788 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7789 ops[3].value, ops[4].value);
7790 case 6:
7791 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7792 ops[3].value, ops[4].value, ops[5].value);
7793 case 7:
7794 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7795 ops[3].value, ops[4].value, ops[5].value,
7796 ops[6].value);
7797 case 8:
7798 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7799 ops[3].value, ops[4].value, ops[5].value,
7800 ops[6].value, ops[7].value);
7801 case 9:
7802 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7803 ops[3].value, ops[4].value, ops[5].value,
7804 ops[6].value, ops[7].value, ops[8].value);
7806 gcc_unreachable ();
7809 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7810 as its operands. Return true on success and emit no code on failure. */
7812 bool
7813 maybe_expand_insn (enum insn_code icode, unsigned int nops,
7814 class expand_operand *ops)
7816 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7817 if (pat)
7819 emit_insn (pat);
7820 return true;
7822 return false;
7825 /* Like maybe_expand_insn, but for jumps. */
7827 bool
7828 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
7829 class expand_operand *ops)
7831 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7832 if (pat)
7834 emit_jump_insn (pat);
7835 return true;
7837 return false;
7840 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7841 as its operands. */
7843 void
7844 expand_insn (enum insn_code icode, unsigned int nops,
7845 class expand_operand *ops)
7847 if (!maybe_expand_insn (icode, nops, ops))
7848 gcc_unreachable ();
7851 /* Like expand_insn, but for jumps. */
7853 void
7854 expand_jump_insn (enum insn_code icode, unsigned int nops,
7855 class expand_operand *ops)
7857 if (!maybe_expand_jump_insn (icode, nops, ops))
7858 gcc_unreachable ();