[AArch64] PR target/68129: Define TARGET_SUPPORTS_WIDE_INT
[official-gcc.git] / gcc / optabs.c
blob44971ad827fe5851f63469fb6b4638139f0a65f0
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2015 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 "predict.h"
29 #include "tm_p.h"
30 #include "expmed.h"
31 #include "optabs.h"
32 #include "emit-rtl.h"
33 #include "recog.h"
34 #include "diagnostic-core.h"
36 /* Include insn-config.h before expr.h so that HAVE_conditional_move
37 is properly defined. */
38 #include "stor-layout.h"
39 #include "except.h"
40 #include "dojump.h"
41 #include "explow.h"
42 #include "expr.h"
43 #include "optabs-tree.h"
44 #include "libfuncs.h"
46 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
47 machine_mode *);
48 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
49 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
51 /* Debug facility for use in GDB. */
52 void debug_optab_libfuncs (void);
54 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
55 the result of operation CODE applied to OP0 (and OP1 if it is a binary
56 operation).
58 If the last insn does not set TARGET, don't do anything, but return 1.
60 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
61 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
62 try again, ensuring that TARGET is not one of the operands. */
64 static int
65 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
67 rtx_insn *last_insn;
68 rtx set;
69 rtx note;
71 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
73 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
74 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
75 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
76 && GET_RTX_CLASS (code) != RTX_COMPARE
77 && GET_RTX_CLASS (code) != RTX_UNARY)
78 return 1;
80 if (GET_CODE (target) == ZERO_EXTRACT)
81 return 1;
83 for (last_insn = insns;
84 NEXT_INSN (last_insn) != NULL_RTX;
85 last_insn = NEXT_INSN (last_insn))
88 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
89 a value changing in the insn, so the note would be invalid for CSE. */
90 if (reg_overlap_mentioned_p (target, op0)
91 || (op1 && reg_overlap_mentioned_p (target, op1)))
93 if (MEM_P (target)
94 && (rtx_equal_p (target, op0)
95 || (op1 && rtx_equal_p (target, op1))))
97 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
98 over expanding it as temp = MEM op X, MEM = temp. If the target
99 supports MEM = MEM op X instructions, it is sometimes too hard
100 to reconstruct that form later, especially if X is also a memory,
101 and due to multiple occurrences of addresses the address might
102 be forced into register unnecessarily.
103 Note that not emitting the REG_EQUIV note might inhibit
104 CSE in some cases. */
105 set = single_set (last_insn);
106 if (set
107 && GET_CODE (SET_SRC (set)) == code
108 && MEM_P (SET_DEST (set))
109 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
110 || (op1 && rtx_equal_p (SET_DEST (set),
111 XEXP (SET_SRC (set), 1)))))
112 return 1;
114 return 0;
117 set = set_for_reg_notes (last_insn);
118 if (set == NULL_RTX)
119 return 1;
121 if (! rtx_equal_p (SET_DEST (set), target)
122 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
123 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
124 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
125 return 1;
127 if (GET_RTX_CLASS (code) == RTX_UNARY)
128 switch (code)
130 case FFS:
131 case CLZ:
132 case CTZ:
133 case CLRSB:
134 case POPCOUNT:
135 case PARITY:
136 case BSWAP:
137 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
139 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
140 if (GET_MODE_SIZE (GET_MODE (op0))
141 > GET_MODE_SIZE (GET_MODE (target)))
142 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
143 note, GET_MODE (op0));
144 else
145 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
146 note, GET_MODE (op0));
147 break;
149 /* FALLTHRU */
150 default:
151 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
152 break;
154 else
155 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
157 set_unique_reg_note (last_insn, REG_EQUAL, note);
159 return 1;
162 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
163 for a widening operation would be. In most cases this would be OP0, but if
164 that's a constant it'll be VOIDmode, which isn't useful. */
166 static machine_mode
167 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
169 machine_mode m0 = GET_MODE (op0);
170 machine_mode m1 = GET_MODE (op1);
171 machine_mode result;
173 if (m0 == VOIDmode && m1 == VOIDmode)
174 return to_mode;
175 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
176 result = m1;
177 else
178 result = m0;
180 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
181 return to_mode;
183 return result;
186 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
187 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
188 not actually do a sign-extend or zero-extend, but can leave the
189 higher-order bits of the result rtx undefined, for example, in the case
190 of logical operations, but not right shifts. */
192 static rtx
193 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
194 int unsignedp, int no_extend)
196 rtx result;
198 /* If we don't have to extend and this is a constant, return it. */
199 if (no_extend && GET_MODE (op) == VOIDmode)
200 return op;
202 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
203 extend since it will be more efficient to do so unless the signedness of
204 a promoted object differs from our extension. */
205 if (! no_extend
206 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
207 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
208 return convert_modes (mode, oldmode, op, unsignedp);
210 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
211 SUBREG. */
212 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
213 return gen_lowpart (mode, force_reg (GET_MODE (op), op));
215 /* Otherwise, get an object of MODE, clobber it, and set the low-order
216 part to OP. */
218 result = gen_reg_rtx (mode);
219 emit_clobber (result);
220 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
221 return result;
224 /* Expand vector widening operations.
226 There are two different classes of operations handled here:
227 1) Operations whose result is wider than all the arguments to the operation.
228 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
229 In this case OP0 and optionally OP1 would be initialized,
230 but WIDE_OP wouldn't (not relevant for this case).
231 2) Operations whose result is of the same size as the last argument to the
232 operation, but wider than all the other arguments to the operation.
233 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
234 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
236 E.g, when called to expand the following operations, this is how
237 the arguments will be initialized:
238 nops OP0 OP1 WIDE_OP
239 widening-sum 2 oprnd0 - oprnd1
240 widening-dot-product 3 oprnd0 oprnd1 oprnd2
241 widening-mult 2 oprnd0 oprnd1 -
242 type-promotion (vec-unpack) 1 oprnd0 - - */
245 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
246 rtx target, int unsignedp)
248 struct expand_operand eops[4];
249 tree oprnd0, oprnd1, oprnd2;
250 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
251 optab widen_pattern_optab;
252 enum insn_code icode;
253 int nops = TREE_CODE_LENGTH (ops->code);
254 int op;
256 oprnd0 = ops->op0;
257 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
258 widen_pattern_optab =
259 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
260 if (ops->code == WIDEN_MULT_PLUS_EXPR
261 || ops->code == WIDEN_MULT_MINUS_EXPR)
262 icode = find_widening_optab_handler (widen_pattern_optab,
263 TYPE_MODE (TREE_TYPE (ops->op2)),
264 tmode0, 0);
265 else
266 icode = optab_handler (widen_pattern_optab, tmode0);
267 gcc_assert (icode != CODE_FOR_nothing);
269 if (nops >= 2)
271 oprnd1 = ops->op1;
272 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
275 /* The last operand is of a wider mode than the rest of the operands. */
276 if (nops == 2)
277 wmode = tmode1;
278 else if (nops == 3)
280 gcc_assert (tmode1 == tmode0);
281 gcc_assert (op1);
282 oprnd2 = ops->op2;
283 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
286 op = 0;
287 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
288 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
289 if (op1)
290 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
291 if (wide_op)
292 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
293 expand_insn (icode, op, eops);
294 return eops[0].value;
297 /* Generate code to perform an operation specified by TERNARY_OPTAB
298 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
300 UNSIGNEDP is for the case where we have to widen the operands
301 to perform the operation. It says to use zero-extension.
303 If TARGET is nonzero, the value
304 is generated there, if it is convenient to do so.
305 In all cases an rtx is returned for the locus of the value;
306 this may or may not be TARGET. */
309 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
310 rtx op1, rtx op2, rtx target, int unsignedp)
312 struct expand_operand ops[4];
313 enum insn_code icode = optab_handler (ternary_optab, mode);
315 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
317 create_output_operand (&ops[0], target, mode);
318 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
319 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
320 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
321 expand_insn (icode, 4, ops);
322 return ops[0].value;
326 /* Like expand_binop, but return a constant rtx if the result can be
327 calculated at compile time. The arguments and return value are
328 otherwise the same as for expand_binop. */
331 simplify_expand_binop (machine_mode mode, optab binoptab,
332 rtx op0, rtx op1, rtx target, int unsignedp,
333 enum optab_methods methods)
335 if (CONSTANT_P (op0) && CONSTANT_P (op1))
337 rtx x = simplify_binary_operation (optab_to_code (binoptab),
338 mode, op0, op1);
339 if (x)
340 return x;
343 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
346 /* Like simplify_expand_binop, but always put the result in TARGET.
347 Return true if the expansion succeeded. */
349 bool
350 force_expand_binop (machine_mode mode, optab binoptab,
351 rtx op0, rtx op1, rtx target, int unsignedp,
352 enum optab_methods methods)
354 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
355 target, unsignedp, methods);
356 if (x == 0)
357 return false;
358 if (x != target)
359 emit_move_insn (target, x);
360 return true;
363 /* Create a new vector value in VMODE with all elements set to OP. The
364 mode of OP must be the element mode of VMODE. If OP is a constant,
365 then the return value will be a constant. */
367 static rtx
368 expand_vector_broadcast (machine_mode vmode, rtx op)
370 enum insn_code icode;
371 rtvec vec;
372 rtx ret;
373 int i, n;
375 gcc_checking_assert (VECTOR_MODE_P (vmode));
377 n = GET_MODE_NUNITS (vmode);
378 vec = rtvec_alloc (n);
379 for (i = 0; i < n; ++i)
380 RTVEC_ELT (vec, i) = op;
382 if (CONSTANT_P (op))
383 return gen_rtx_CONST_VECTOR (vmode, vec);
385 /* ??? If the target doesn't have a vec_init, then we have no easy way
386 of performing this operation. Most of this sort of generic support
387 is hidden away in the vector lowering support in gimple. */
388 icode = optab_handler (vec_init_optab, vmode);
389 if (icode == CODE_FOR_nothing)
390 return NULL;
392 ret = gen_reg_rtx (vmode);
393 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
395 return ret;
398 /* This subroutine of expand_doubleword_shift handles the cases in which
399 the effective shift value is >= BITS_PER_WORD. The arguments and return
400 value are the same as for the parent routine, except that SUPERWORD_OP1
401 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
402 INTO_TARGET may be null if the caller has decided to calculate it. */
404 static bool
405 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
406 rtx outof_target, rtx into_target,
407 int unsignedp, enum optab_methods methods)
409 if (into_target != 0)
410 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
411 into_target, unsignedp, methods))
412 return false;
414 if (outof_target != 0)
416 /* For a signed right shift, we must fill OUTOF_TARGET with copies
417 of the sign bit, otherwise we must fill it with zeros. */
418 if (binoptab != ashr_optab)
419 emit_move_insn (outof_target, CONST0_RTX (word_mode));
420 else
421 if (!force_expand_binop (word_mode, binoptab,
422 outof_input, GEN_INT (BITS_PER_WORD - 1),
423 outof_target, unsignedp, methods))
424 return false;
426 return true;
429 /* This subroutine of expand_doubleword_shift handles the cases in which
430 the effective shift value is < BITS_PER_WORD. The arguments and return
431 value are the same as for the parent routine. */
433 static bool
434 expand_subword_shift (machine_mode op1_mode, optab binoptab,
435 rtx outof_input, rtx into_input, rtx op1,
436 rtx outof_target, rtx into_target,
437 int unsignedp, enum optab_methods methods,
438 unsigned HOST_WIDE_INT shift_mask)
440 optab reverse_unsigned_shift, unsigned_shift;
441 rtx tmp, carries;
443 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
444 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
446 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
447 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
448 the opposite direction to BINOPTAB. */
449 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
451 carries = outof_input;
452 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
453 op1_mode), op1_mode);
454 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
455 0, true, methods);
457 else
459 /* We must avoid shifting by BITS_PER_WORD bits since that is either
460 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
461 has unknown behavior. Do a single shift first, then shift by the
462 remainder. It's OK to use ~OP1 as the remainder if shift counts
463 are truncated to the mode size. */
464 carries = expand_binop (word_mode, reverse_unsigned_shift,
465 outof_input, const1_rtx, 0, unsignedp, methods);
466 if (shift_mask == BITS_PER_WORD - 1)
468 tmp = immed_wide_int_const
469 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
470 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
471 0, true, methods);
473 else
475 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
476 op1_mode), op1_mode);
477 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
478 0, true, methods);
481 if (tmp == 0 || carries == 0)
482 return false;
483 carries = expand_binop (word_mode, reverse_unsigned_shift,
484 carries, tmp, 0, unsignedp, methods);
485 if (carries == 0)
486 return false;
488 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
489 so the result can go directly into INTO_TARGET if convenient. */
490 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
491 into_target, unsignedp, methods);
492 if (tmp == 0)
493 return false;
495 /* Now OR in the bits carried over from OUTOF_INPUT. */
496 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
497 into_target, unsignedp, methods))
498 return false;
500 /* Use a standard word_mode shift for the out-of half. */
501 if (outof_target != 0)
502 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
503 outof_target, unsignedp, methods))
504 return false;
506 return true;
510 /* Try implementing expand_doubleword_shift using conditional moves.
511 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
512 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
513 are the shift counts to use in the former and latter case. All other
514 arguments are the same as the parent routine. */
516 static bool
517 expand_doubleword_shift_condmove (machine_mode op1_mode, optab binoptab,
518 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
519 rtx outof_input, rtx into_input,
520 rtx subword_op1, rtx superword_op1,
521 rtx outof_target, rtx into_target,
522 int unsignedp, enum optab_methods methods,
523 unsigned HOST_WIDE_INT shift_mask)
525 rtx outof_superword, into_superword;
527 /* Put the superword version of the output into OUTOF_SUPERWORD and
528 INTO_SUPERWORD. */
529 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
530 if (outof_target != 0 && subword_op1 == superword_op1)
532 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
533 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
534 into_superword = outof_target;
535 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
536 outof_superword, 0, unsignedp, methods))
537 return false;
539 else
541 into_superword = gen_reg_rtx (word_mode);
542 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
543 outof_superword, into_superword,
544 unsignedp, methods))
545 return false;
548 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
549 if (!expand_subword_shift (op1_mode, binoptab,
550 outof_input, into_input, subword_op1,
551 outof_target, into_target,
552 unsignedp, methods, shift_mask))
553 return false;
555 /* Select between them. Do the INTO half first because INTO_SUPERWORD
556 might be the current value of OUTOF_TARGET. */
557 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
558 into_target, into_superword, word_mode, false))
559 return false;
561 if (outof_target != 0)
562 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
563 outof_target, outof_superword,
564 word_mode, false))
565 return false;
567 return true;
570 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
571 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
572 input operand; the shift moves bits in the direction OUTOF_INPUT->
573 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
574 of the target. OP1 is the shift count and OP1_MODE is its mode.
575 If OP1 is constant, it will have been truncated as appropriate
576 and is known to be nonzero.
578 If SHIFT_MASK is zero, the result of word shifts is undefined when the
579 shift count is outside the range [0, BITS_PER_WORD). This routine must
580 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
582 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
583 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
584 fill with zeros or sign bits as appropriate.
586 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
587 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
588 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
589 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
590 are undefined.
592 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
593 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
594 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
595 function wants to calculate it itself.
597 Return true if the shift could be successfully synthesized. */
599 static bool
600 expand_doubleword_shift (machine_mode op1_mode, optab binoptab,
601 rtx outof_input, rtx into_input, rtx op1,
602 rtx outof_target, rtx into_target,
603 int unsignedp, enum optab_methods methods,
604 unsigned HOST_WIDE_INT shift_mask)
606 rtx superword_op1, tmp, cmp1, cmp2;
607 enum rtx_code cmp_code;
609 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
610 fill the result with sign or zero bits as appropriate. If so, the value
611 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
612 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
613 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
615 This isn't worthwhile for constant shifts since the optimizers will
616 cope better with in-range shift counts. */
617 if (shift_mask >= BITS_PER_WORD
618 && outof_target != 0
619 && !CONSTANT_P (op1))
621 if (!expand_doubleword_shift (op1_mode, binoptab,
622 outof_input, into_input, op1,
623 0, into_target,
624 unsignedp, methods, shift_mask))
625 return false;
626 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
627 outof_target, unsignedp, methods))
628 return false;
629 return true;
632 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
633 is true when the effective shift value is less than BITS_PER_WORD.
634 Set SUPERWORD_OP1 to the shift count that should be used to shift
635 OUTOF_INPUT into INTO_TARGET when the condition is false. */
636 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
637 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
639 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
640 is a subword shift count. */
641 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
642 0, true, methods);
643 cmp2 = CONST0_RTX (op1_mode);
644 cmp_code = EQ;
645 superword_op1 = op1;
647 else
649 /* Set CMP1 to OP1 - BITS_PER_WORD. */
650 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
651 0, true, methods);
652 cmp2 = CONST0_RTX (op1_mode);
653 cmp_code = LT;
654 superword_op1 = cmp1;
656 if (cmp1 == 0)
657 return false;
659 /* If we can compute the condition at compile time, pick the
660 appropriate subroutine. */
661 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
662 if (tmp != 0 && CONST_INT_P (tmp))
664 if (tmp == const0_rtx)
665 return expand_superword_shift (binoptab, outof_input, superword_op1,
666 outof_target, into_target,
667 unsignedp, methods);
668 else
669 return expand_subword_shift (op1_mode, binoptab,
670 outof_input, into_input, op1,
671 outof_target, into_target,
672 unsignedp, methods, shift_mask);
675 /* Try using conditional moves to generate straight-line code. */
676 if (HAVE_conditional_move)
678 rtx_insn *start = get_last_insn ();
679 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
680 cmp_code, cmp1, cmp2,
681 outof_input, into_input,
682 op1, superword_op1,
683 outof_target, into_target,
684 unsignedp, methods, shift_mask))
685 return true;
686 delete_insns_since (start);
689 /* As a last resort, use branches to select the correct alternative. */
690 rtx_code_label *subword_label = gen_label_rtx ();
691 rtx_code_label *done_label = gen_label_rtx ();
693 NO_DEFER_POP;
694 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
695 0, 0, subword_label, -1);
696 OK_DEFER_POP;
698 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
699 outof_target, into_target,
700 unsignedp, methods))
701 return false;
703 emit_jump_insn (targetm.gen_jump (done_label));
704 emit_barrier ();
705 emit_label (subword_label);
707 if (!expand_subword_shift (op1_mode, binoptab,
708 outof_input, into_input, op1,
709 outof_target, into_target,
710 unsignedp, methods, shift_mask))
711 return false;
713 emit_label (done_label);
714 return true;
717 /* Subroutine of expand_binop. Perform a double word multiplication of
718 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
719 as the target's word_mode. This function return NULL_RTX if anything
720 goes wrong, in which case it may have already emitted instructions
721 which need to be deleted.
723 If we want to multiply two two-word values and have normal and widening
724 multiplies of single-word values, we can do this with three smaller
725 multiplications.
727 The multiplication proceeds as follows:
728 _______________________
729 [__op0_high_|__op0_low__]
730 _______________________
731 * [__op1_high_|__op1_low__]
732 _______________________________________________
733 _______________________
734 (1) [__op0_low__*__op1_low__]
735 _______________________
736 (2a) [__op0_low__*__op1_high_]
737 _______________________
738 (2b) [__op0_high_*__op1_low__]
739 _______________________
740 (3) [__op0_high_*__op1_high_]
743 This gives a 4-word result. Since we are only interested in the
744 lower 2 words, partial result (3) and the upper words of (2a) and
745 (2b) don't need to be calculated. Hence (2a) and (2b) can be
746 calculated using non-widening multiplication.
748 (1), however, needs to be calculated with an unsigned widening
749 multiplication. If this operation is not directly supported we
750 try using a signed widening multiplication and adjust the result.
751 This adjustment works as follows:
753 If both operands are positive then no adjustment is needed.
755 If the operands have different signs, for example op0_low < 0 and
756 op1_low >= 0, the instruction treats the most significant bit of
757 op0_low as a sign bit instead of a bit with significance
758 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
759 with 2**BITS_PER_WORD - op0_low, and two's complements the
760 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
761 the result.
763 Similarly, if both operands are negative, we need to add
764 (op0_low + op1_low) * 2**BITS_PER_WORD.
766 We use a trick to adjust quickly. We logically shift op0_low right
767 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
768 op0_high (op1_high) before it is used to calculate 2b (2a). If no
769 logical shift exists, we do an arithmetic right shift and subtract
770 the 0 or -1. */
772 static rtx
773 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
774 bool umulp, enum optab_methods methods)
776 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
777 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
778 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
779 rtx product, adjust, product_high, temp;
781 rtx op0_high = operand_subword_force (op0, high, mode);
782 rtx op0_low = operand_subword_force (op0, low, mode);
783 rtx op1_high = operand_subword_force (op1, high, mode);
784 rtx op1_low = operand_subword_force (op1, low, mode);
786 /* If we're using an unsigned multiply to directly compute the product
787 of the low-order words of the operands and perform any required
788 adjustments of the operands, we begin by trying two more multiplications
789 and then computing the appropriate sum.
791 We have checked above that the required addition is provided.
792 Full-word addition will normally always succeed, especially if
793 it is provided at all, so we don't worry about its failure. The
794 multiplication may well fail, however, so we do handle that. */
796 if (!umulp)
798 /* ??? This could be done with emit_store_flag where available. */
799 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
800 NULL_RTX, 1, methods);
801 if (temp)
802 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
803 NULL_RTX, 0, OPTAB_DIRECT);
804 else
806 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
807 NULL_RTX, 0, methods);
808 if (!temp)
809 return NULL_RTX;
810 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
811 NULL_RTX, 0, OPTAB_DIRECT);
814 if (!op0_high)
815 return NULL_RTX;
818 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
819 NULL_RTX, 0, OPTAB_DIRECT);
820 if (!adjust)
821 return NULL_RTX;
823 /* OP0_HIGH should now be dead. */
825 if (!umulp)
827 /* ??? This could be done with emit_store_flag where available. */
828 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
829 NULL_RTX, 1, methods);
830 if (temp)
831 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
832 NULL_RTX, 0, OPTAB_DIRECT);
833 else
835 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
836 NULL_RTX, 0, methods);
837 if (!temp)
838 return NULL_RTX;
839 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
840 NULL_RTX, 0, OPTAB_DIRECT);
843 if (!op1_high)
844 return NULL_RTX;
847 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
848 NULL_RTX, 0, OPTAB_DIRECT);
849 if (!temp)
850 return NULL_RTX;
852 /* OP1_HIGH should now be dead. */
854 adjust = expand_binop (word_mode, add_optab, adjust, temp,
855 NULL_RTX, 0, OPTAB_DIRECT);
857 if (target && !REG_P (target))
858 target = NULL_RTX;
860 if (umulp)
861 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
862 target, 1, OPTAB_DIRECT);
863 else
864 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
865 target, 1, OPTAB_DIRECT);
867 if (!product)
868 return NULL_RTX;
870 product_high = operand_subword (product, high, 1, mode);
871 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
872 NULL_RTX, 0, OPTAB_DIRECT);
873 emit_move_insn (product_high, adjust);
874 return product;
877 /* Wrapper around expand_binop which takes an rtx code to specify
878 the operation to perform, not an optab pointer. All other
879 arguments are the same. */
881 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
882 rtx op1, rtx target, int unsignedp,
883 enum optab_methods methods)
885 optab binop = code_to_optab (code);
886 gcc_assert (binop);
888 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
891 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
892 binop. Order them according to commutative_operand_precedence and, if
893 possible, try to put TARGET or a pseudo first. */
894 static bool
895 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
897 int op0_prec = commutative_operand_precedence (op0);
898 int op1_prec = commutative_operand_precedence (op1);
900 if (op0_prec < op1_prec)
901 return true;
903 if (op0_prec > op1_prec)
904 return false;
906 /* With equal precedence, both orders are ok, but it is better if the
907 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
908 if (target == 0 || REG_P (target))
909 return (REG_P (op1) && !REG_P (op0)) || target == op1;
910 else
911 return rtx_equal_p (op1, target);
914 /* Return true if BINOPTAB implements a shift operation. */
916 static bool
917 shift_optab_p (optab binoptab)
919 switch (optab_to_code (binoptab))
921 case ASHIFT:
922 case SS_ASHIFT:
923 case US_ASHIFT:
924 case ASHIFTRT:
925 case LSHIFTRT:
926 case ROTATE:
927 case ROTATERT:
928 return true;
930 default:
931 return false;
935 /* Return true if BINOPTAB implements a commutative binary operation. */
937 static bool
938 commutative_optab_p (optab binoptab)
940 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
941 || binoptab == smul_widen_optab
942 || binoptab == umul_widen_optab
943 || binoptab == smul_highpart_optab
944 || binoptab == umul_highpart_optab);
947 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
948 optimizing, and if the operand is a constant that costs more than
949 1 instruction, force the constant into a register and return that
950 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
952 static rtx
953 avoid_expensive_constant (machine_mode mode, optab binoptab,
954 int opn, rtx x, bool unsignedp)
956 bool speed = optimize_insn_for_speed_p ();
958 if (mode != VOIDmode
959 && optimize
960 && CONSTANT_P (x)
961 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
962 > set_src_cost (x, mode, speed)))
964 if (CONST_INT_P (x))
966 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
967 if (intval != INTVAL (x))
968 x = GEN_INT (intval);
970 else
971 x = convert_modes (mode, VOIDmode, x, unsignedp);
972 x = force_reg (mode, x);
974 return x;
977 /* Helper function for expand_binop: handle the case where there
978 is an insn that directly implements the indicated operation.
979 Returns null if this is not possible. */
980 static rtx
981 expand_binop_directly (machine_mode mode, optab binoptab,
982 rtx op0, rtx op1,
983 rtx target, int unsignedp, enum optab_methods methods,
984 rtx_insn *last)
986 machine_mode from_mode = widened_mode (mode, op0, op1);
987 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
988 from_mode, 1);
989 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
990 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
991 machine_mode mode0, mode1, tmp_mode;
992 struct expand_operand ops[3];
993 bool commutative_p;
994 rtx_insn *pat;
995 rtx xop0 = op0, xop1 = op1;
997 /* If it is a commutative operator and the modes would match
998 if we would swap the operands, we can save the conversions. */
999 commutative_p = commutative_optab_p (binoptab);
1000 if (commutative_p
1001 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1002 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1003 std::swap (xop0, xop1);
1005 /* If we are optimizing, force expensive constants into a register. */
1006 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1007 if (!shift_optab_p (binoptab))
1008 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1010 /* In case the insn wants input operands in modes different from
1011 those of the actual operands, convert the operands. It would
1012 seem that we don't need to convert CONST_INTs, but we do, so
1013 that they're properly zero-extended, sign-extended or truncated
1014 for their mode. */
1016 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1017 if (xmode0 != VOIDmode && xmode0 != mode0)
1019 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1020 mode0 = xmode0;
1023 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1024 if (xmode1 != VOIDmode && xmode1 != mode1)
1026 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1027 mode1 = xmode1;
1030 /* If operation is commutative,
1031 try to make the first operand a register.
1032 Even better, try to make it the same as the target.
1033 Also try to make the last operand a constant. */
1034 if (commutative_p
1035 && swap_commutative_operands_with_target (target, xop0, xop1))
1036 std::swap (xop0, xop1);
1038 /* Now, if insn's predicates don't allow our operands, put them into
1039 pseudo regs. */
1041 if (binoptab == vec_pack_trunc_optab
1042 || binoptab == vec_pack_usat_optab
1043 || binoptab == vec_pack_ssat_optab
1044 || binoptab == vec_pack_ufix_trunc_optab
1045 || binoptab == vec_pack_sfix_trunc_optab)
1047 /* The mode of the result is different then the mode of the
1048 arguments. */
1049 tmp_mode = insn_data[(int) icode].operand[0].mode;
1050 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1052 delete_insns_since (last);
1053 return NULL_RTX;
1056 else
1057 tmp_mode = mode;
1059 create_output_operand (&ops[0], target, tmp_mode);
1060 create_input_operand (&ops[1], xop0, mode0);
1061 create_input_operand (&ops[2], xop1, mode1);
1062 pat = maybe_gen_insn (icode, 3, ops);
1063 if (pat)
1065 /* If PAT is composed of more than one insn, try to add an appropriate
1066 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1067 operand, call expand_binop again, this time without a target. */
1068 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1069 && ! add_equal_note (pat, ops[0].value,
1070 optab_to_code (binoptab),
1071 ops[1].value, ops[2].value))
1073 delete_insns_since (last);
1074 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1075 unsignedp, methods);
1078 emit_insn (pat);
1079 return ops[0].value;
1081 delete_insns_since (last);
1082 return NULL_RTX;
1085 /* Generate code to perform an operation specified by BINOPTAB
1086 on operands OP0 and OP1, with result having machine-mode MODE.
1088 UNSIGNEDP is for the case where we have to widen the operands
1089 to perform the operation. It says to use zero-extension.
1091 If TARGET is nonzero, the value
1092 is generated there, if it is convenient to do so.
1093 In all cases an rtx is returned for the locus of the value;
1094 this may or may not be TARGET. */
1097 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1098 rtx target, int unsignedp, enum optab_methods methods)
1100 enum optab_methods next_methods
1101 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1102 ? OPTAB_WIDEN : methods);
1103 enum mode_class mclass;
1104 machine_mode wider_mode;
1105 rtx libfunc;
1106 rtx temp;
1107 rtx_insn *entry_last = get_last_insn ();
1108 rtx_insn *last;
1110 mclass = GET_MODE_CLASS (mode);
1112 /* If subtracting an integer constant, convert this into an addition of
1113 the negated constant. */
1115 if (binoptab == sub_optab && CONST_INT_P (op1))
1117 op1 = negate_rtx (mode, op1);
1118 binoptab = add_optab;
1121 /* Record where to delete back to if we backtrack. */
1122 last = get_last_insn ();
1124 /* If we can do it with a three-operand insn, do so. */
1126 if (methods != OPTAB_MUST_WIDEN
1127 && find_widening_optab_handler (binoptab, mode,
1128 widened_mode (mode, op0, op1), 1)
1129 != CODE_FOR_nothing)
1131 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1132 unsignedp, methods, last);
1133 if (temp)
1134 return temp;
1137 /* If we were trying to rotate, and that didn't work, try rotating
1138 the other direction before falling back to shifts and bitwise-or. */
1139 if (((binoptab == rotl_optab
1140 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1141 || (binoptab == rotr_optab
1142 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1143 && mclass == MODE_INT)
1145 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1146 rtx newop1;
1147 unsigned int bits = GET_MODE_PRECISION (mode);
1149 if (CONST_INT_P (op1))
1150 newop1 = GEN_INT (bits - INTVAL (op1));
1151 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1152 newop1 = negate_rtx (GET_MODE (op1), op1);
1153 else
1154 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1155 gen_int_mode (bits, GET_MODE (op1)), op1,
1156 NULL_RTX, unsignedp, OPTAB_DIRECT);
1158 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1159 target, unsignedp, methods, last);
1160 if (temp)
1161 return temp;
1164 /* If this is a multiply, see if we can do a widening operation that
1165 takes operands of this mode and makes a wider mode. */
1167 if (binoptab == smul_optab
1168 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1169 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1170 : smul_widen_optab),
1171 GET_MODE_2XWIDER_MODE (mode), mode)
1172 != CODE_FOR_nothing))
1174 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1175 unsignedp ? umul_widen_optab : smul_widen_optab,
1176 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1178 if (temp != 0)
1180 if (GET_MODE_CLASS (mode) == MODE_INT
1181 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1182 return gen_lowpart (mode, temp);
1183 else
1184 return convert_to_mode (mode, temp, unsignedp);
1188 /* If this is a vector shift by a scalar, see if we can do a vector
1189 shift by a vector. If so, broadcast the scalar into a vector. */
1190 if (mclass == MODE_VECTOR_INT)
1192 optab otheroptab = unknown_optab;
1194 if (binoptab == ashl_optab)
1195 otheroptab = vashl_optab;
1196 else if (binoptab == ashr_optab)
1197 otheroptab = vashr_optab;
1198 else if (binoptab == lshr_optab)
1199 otheroptab = vlshr_optab;
1200 else if (binoptab == rotl_optab)
1201 otheroptab = vrotl_optab;
1202 else if (binoptab == rotr_optab)
1203 otheroptab = vrotr_optab;
1205 if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing)
1207 /* The scalar may have been extended to be too wide. Truncate
1208 it back to the proper size to fit in the broadcast vector. */
1209 machine_mode inner_mode = GET_MODE_INNER (mode);
1210 if (!CONST_INT_P (op1)
1211 && (GET_MODE_BITSIZE (inner_mode)
1212 < GET_MODE_BITSIZE (GET_MODE (op1))))
1213 op1 = force_reg (inner_mode,
1214 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1215 GET_MODE (op1)));
1216 rtx vop1 = expand_vector_broadcast (mode, op1);
1217 if (vop1)
1219 temp = expand_binop_directly (mode, otheroptab, op0, vop1,
1220 target, unsignedp, methods, last);
1221 if (temp)
1222 return temp;
1227 /* Look for a wider mode of the same class for which we think we
1228 can open-code the operation. Check for a widening multiply at the
1229 wider mode as well. */
1231 if (CLASS_HAS_WIDER_MODES_P (mclass)
1232 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1233 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1234 wider_mode != VOIDmode;
1235 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1237 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1238 || (binoptab == smul_optab
1239 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1240 && (find_widening_optab_handler ((unsignedp
1241 ? umul_widen_optab
1242 : smul_widen_optab),
1243 GET_MODE_WIDER_MODE (wider_mode),
1244 mode, 0)
1245 != CODE_FOR_nothing)))
1247 rtx xop0 = op0, xop1 = op1;
1248 int no_extend = 0;
1250 /* For certain integer operations, we need not actually extend
1251 the narrow operands, as long as we will truncate
1252 the results to the same narrowness. */
1254 if ((binoptab == ior_optab || binoptab == and_optab
1255 || binoptab == xor_optab
1256 || binoptab == add_optab || binoptab == sub_optab
1257 || binoptab == smul_optab || binoptab == ashl_optab)
1258 && mclass == MODE_INT)
1260 no_extend = 1;
1261 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1262 xop0, unsignedp);
1263 if (binoptab != ashl_optab)
1264 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1265 xop1, unsignedp);
1268 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1270 /* The second operand of a shift must always be extended. */
1271 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1272 no_extend && binoptab != ashl_optab);
1274 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1275 unsignedp, OPTAB_DIRECT);
1276 if (temp)
1278 if (mclass != MODE_INT
1279 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1281 if (target == 0)
1282 target = gen_reg_rtx (mode);
1283 convert_move (target, temp, 0);
1284 return target;
1286 else
1287 return gen_lowpart (mode, temp);
1289 else
1290 delete_insns_since (last);
1294 /* If operation is commutative,
1295 try to make the first operand a register.
1296 Even better, try to make it the same as the target.
1297 Also try to make the last operand a constant. */
1298 if (commutative_optab_p (binoptab)
1299 && swap_commutative_operands_with_target (target, op0, op1))
1300 std::swap (op0, op1);
1302 /* These can be done a word at a time. */
1303 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1304 && mclass == MODE_INT
1305 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1306 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1308 int i;
1309 rtx_insn *insns;
1311 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1312 won't be accurate, so use a new target. */
1313 if (target == 0
1314 || target == op0
1315 || target == op1
1316 || !valid_multiword_target_p (target))
1317 target = gen_reg_rtx (mode);
1319 start_sequence ();
1321 /* Do the actual arithmetic. */
1322 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1324 rtx target_piece = operand_subword (target, i, 1, mode);
1325 rtx x = expand_binop (word_mode, binoptab,
1326 operand_subword_force (op0, i, mode),
1327 operand_subword_force (op1, i, mode),
1328 target_piece, unsignedp, next_methods);
1330 if (x == 0)
1331 break;
1333 if (target_piece != x)
1334 emit_move_insn (target_piece, x);
1337 insns = get_insns ();
1338 end_sequence ();
1340 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1342 emit_insn (insns);
1343 return target;
1347 /* Synthesize double word shifts from single word shifts. */
1348 if ((binoptab == lshr_optab || binoptab == ashl_optab
1349 || binoptab == ashr_optab)
1350 && mclass == MODE_INT
1351 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1352 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1353 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1354 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1355 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1356 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1358 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1359 machine_mode op1_mode;
1361 double_shift_mask = targetm.shift_truncation_mask (mode);
1362 shift_mask = targetm.shift_truncation_mask (word_mode);
1363 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1365 /* Apply the truncation to constant shifts. */
1366 if (double_shift_mask > 0 && CONST_INT_P (op1))
1367 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1369 if (op1 == CONST0_RTX (op1_mode))
1370 return op0;
1372 /* Make sure that this is a combination that expand_doubleword_shift
1373 can handle. See the comments there for details. */
1374 if (double_shift_mask == 0
1375 || (shift_mask == BITS_PER_WORD - 1
1376 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1378 rtx_insn *insns;
1379 rtx into_target, outof_target;
1380 rtx into_input, outof_input;
1381 int left_shift, outof_word;
1383 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1384 won't be accurate, so use a new target. */
1385 if (target == 0
1386 || target == op0
1387 || target == op1
1388 || !valid_multiword_target_p (target))
1389 target = gen_reg_rtx (mode);
1391 start_sequence ();
1393 /* OUTOF_* is the word we are shifting bits away from, and
1394 INTO_* is the word that we are shifting bits towards, thus
1395 they differ depending on the direction of the shift and
1396 WORDS_BIG_ENDIAN. */
1398 left_shift = binoptab == ashl_optab;
1399 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1401 outof_target = operand_subword (target, outof_word, 1, mode);
1402 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1404 outof_input = operand_subword_force (op0, outof_word, mode);
1405 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1407 if (expand_doubleword_shift (op1_mode, binoptab,
1408 outof_input, into_input, op1,
1409 outof_target, into_target,
1410 unsignedp, next_methods, shift_mask))
1412 insns = get_insns ();
1413 end_sequence ();
1415 emit_insn (insns);
1416 return target;
1418 end_sequence ();
1422 /* Synthesize double word rotates from single word shifts. */
1423 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1424 && mclass == MODE_INT
1425 && CONST_INT_P (op1)
1426 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1427 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1428 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1430 rtx_insn *insns;
1431 rtx into_target, outof_target;
1432 rtx into_input, outof_input;
1433 rtx inter;
1434 int shift_count, left_shift, outof_word;
1436 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1437 won't be accurate, so use a new target. Do this also if target is not
1438 a REG, first because having a register instead may open optimization
1439 opportunities, and second because if target and op0 happen to be MEMs
1440 designating the same location, we would risk clobbering it too early
1441 in the code sequence we generate below. */
1442 if (target == 0
1443 || target == op0
1444 || target == op1
1445 || !REG_P (target)
1446 || !valid_multiword_target_p (target))
1447 target = gen_reg_rtx (mode);
1449 start_sequence ();
1451 shift_count = INTVAL (op1);
1453 /* OUTOF_* is the word we are shifting bits away from, and
1454 INTO_* is the word that we are shifting bits towards, thus
1455 they differ depending on the direction of the shift and
1456 WORDS_BIG_ENDIAN. */
1458 left_shift = (binoptab == rotl_optab);
1459 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1461 outof_target = operand_subword (target, outof_word, 1, mode);
1462 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1464 outof_input = operand_subword_force (op0, outof_word, mode);
1465 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1467 if (shift_count == BITS_PER_WORD)
1469 /* This is just a word swap. */
1470 emit_move_insn (outof_target, into_input);
1471 emit_move_insn (into_target, outof_input);
1472 inter = const0_rtx;
1474 else
1476 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1477 rtx first_shift_count, second_shift_count;
1478 optab reverse_unsigned_shift, unsigned_shift;
1480 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1481 ? lshr_optab : ashl_optab);
1483 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1484 ? ashl_optab : lshr_optab);
1486 if (shift_count > BITS_PER_WORD)
1488 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1489 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1491 else
1493 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1494 second_shift_count = GEN_INT (shift_count);
1497 into_temp1 = expand_binop (word_mode, unsigned_shift,
1498 outof_input, first_shift_count,
1499 NULL_RTX, unsignedp, next_methods);
1500 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1501 into_input, second_shift_count,
1502 NULL_RTX, unsignedp, next_methods);
1504 if (into_temp1 != 0 && into_temp2 != 0)
1505 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1506 into_target, unsignedp, next_methods);
1507 else
1508 inter = 0;
1510 if (inter != 0 && inter != into_target)
1511 emit_move_insn (into_target, inter);
1513 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1514 into_input, first_shift_count,
1515 NULL_RTX, unsignedp, next_methods);
1516 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1517 outof_input, second_shift_count,
1518 NULL_RTX, unsignedp, next_methods);
1520 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1521 inter = expand_binop (word_mode, ior_optab,
1522 outof_temp1, outof_temp2,
1523 outof_target, unsignedp, next_methods);
1525 if (inter != 0 && inter != outof_target)
1526 emit_move_insn (outof_target, inter);
1529 insns = get_insns ();
1530 end_sequence ();
1532 if (inter != 0)
1534 emit_insn (insns);
1535 return target;
1539 /* These can be done a word at a time by propagating carries. */
1540 if ((binoptab == add_optab || binoptab == sub_optab)
1541 && mclass == MODE_INT
1542 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1543 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1545 unsigned int i;
1546 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1547 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1548 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1549 rtx xop0, xop1, xtarget;
1551 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1552 value is one of those, use it. Otherwise, use 1 since it is the
1553 one easiest to get. */
1554 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1555 int normalizep = STORE_FLAG_VALUE;
1556 #else
1557 int normalizep = 1;
1558 #endif
1560 /* Prepare the operands. */
1561 xop0 = force_reg (mode, op0);
1562 xop1 = force_reg (mode, op1);
1564 xtarget = gen_reg_rtx (mode);
1566 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1567 target = xtarget;
1569 /* Indicate for flow that the entire target reg is being set. */
1570 if (REG_P (target))
1571 emit_clobber (xtarget);
1573 /* Do the actual arithmetic. */
1574 for (i = 0; i < nwords; i++)
1576 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1577 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1578 rtx op0_piece = operand_subword_force (xop0, index, mode);
1579 rtx op1_piece = operand_subword_force (xop1, index, mode);
1580 rtx x;
1582 /* Main add/subtract of the input operands. */
1583 x = expand_binop (word_mode, binoptab,
1584 op0_piece, op1_piece,
1585 target_piece, unsignedp, next_methods);
1586 if (x == 0)
1587 break;
1589 if (i + 1 < nwords)
1591 /* Store carry from main add/subtract. */
1592 carry_out = gen_reg_rtx (word_mode);
1593 carry_out = emit_store_flag_force (carry_out,
1594 (binoptab == add_optab
1595 ? LT : GT),
1596 x, op0_piece,
1597 word_mode, 1, normalizep);
1600 if (i > 0)
1602 rtx newx;
1604 /* Add/subtract previous carry to main result. */
1605 newx = expand_binop (word_mode,
1606 normalizep == 1 ? binoptab : otheroptab,
1607 x, carry_in,
1608 NULL_RTX, 1, next_methods);
1610 if (i + 1 < nwords)
1612 /* Get out carry from adding/subtracting carry in. */
1613 rtx carry_tmp = gen_reg_rtx (word_mode);
1614 carry_tmp = emit_store_flag_force (carry_tmp,
1615 (binoptab == add_optab
1616 ? LT : GT),
1617 newx, x,
1618 word_mode, 1, normalizep);
1620 /* Logical-ior the two poss. carry together. */
1621 carry_out = expand_binop (word_mode, ior_optab,
1622 carry_out, carry_tmp,
1623 carry_out, 0, next_methods);
1624 if (carry_out == 0)
1625 break;
1627 emit_move_insn (target_piece, newx);
1629 else
1631 if (x != target_piece)
1632 emit_move_insn (target_piece, x);
1635 carry_in = carry_out;
1638 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1640 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
1641 || ! rtx_equal_p (target, xtarget))
1643 rtx_insn *temp = emit_move_insn (target, xtarget);
1645 set_dst_reg_note (temp, REG_EQUAL,
1646 gen_rtx_fmt_ee (optab_to_code (binoptab),
1647 mode, copy_rtx (xop0),
1648 copy_rtx (xop1)),
1649 target);
1651 else
1652 target = xtarget;
1654 return target;
1657 else
1658 delete_insns_since (last);
1661 /* Attempt to synthesize double word multiplies using a sequence of word
1662 mode multiplications. We first attempt to generate a sequence using a
1663 more efficient unsigned widening multiply, and if that fails we then
1664 try using a signed widening multiply. */
1666 if (binoptab == smul_optab
1667 && mclass == MODE_INT
1668 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1669 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1670 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1672 rtx product = NULL_RTX;
1673 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
1674 != CODE_FOR_nothing)
1676 product = expand_doubleword_mult (mode, op0, op1, target,
1677 true, methods);
1678 if (!product)
1679 delete_insns_since (last);
1682 if (product == NULL_RTX
1683 && widening_optab_handler (smul_widen_optab, mode, word_mode)
1684 != CODE_FOR_nothing)
1686 product = expand_doubleword_mult (mode, op0, op1, target,
1687 false, methods);
1688 if (!product)
1689 delete_insns_since (last);
1692 if (product != NULL_RTX)
1694 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
1696 temp = emit_move_insn (target ? target : product, product);
1697 set_dst_reg_note (temp,
1698 REG_EQUAL,
1699 gen_rtx_fmt_ee (MULT, mode,
1700 copy_rtx (op0),
1701 copy_rtx (op1)),
1702 target ? target : product);
1704 return product;
1708 /* It can't be open-coded in this mode.
1709 Use a library call if one is available and caller says that's ok. */
1711 libfunc = optab_libfunc (binoptab, mode);
1712 if (libfunc
1713 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1715 rtx_insn *insns;
1716 rtx op1x = op1;
1717 machine_mode op1_mode = mode;
1718 rtx value;
1720 start_sequence ();
1722 if (shift_optab_p (binoptab))
1724 op1_mode = targetm.libgcc_shift_count_mode ();
1725 /* Specify unsigned here,
1726 since negative shift counts are meaningless. */
1727 op1x = convert_to_mode (op1_mode, op1, 1);
1730 if (GET_MODE (op0) != VOIDmode
1731 && GET_MODE (op0) != mode)
1732 op0 = convert_to_mode (mode, op0, unsignedp);
1734 /* Pass 1 for NO_QUEUE so we don't lose any increments
1735 if the libcall is cse'd or moved. */
1736 value = emit_library_call_value (libfunc,
1737 NULL_RTX, LCT_CONST, mode, 2,
1738 op0, mode, op1x, op1_mode);
1740 insns = get_insns ();
1741 end_sequence ();
1743 bool trapv = trapv_binoptab_p (binoptab);
1744 target = gen_reg_rtx (mode);
1745 emit_libcall_block_1 (insns, target, value,
1746 trapv ? NULL_RTX
1747 : gen_rtx_fmt_ee (optab_to_code (binoptab),
1748 mode, op0, op1), trapv);
1750 return target;
1753 delete_insns_since (last);
1755 /* It can't be done in this mode. Can we do it in a wider mode? */
1757 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1758 || methods == OPTAB_MUST_WIDEN))
1760 /* Caller says, don't even try. */
1761 delete_insns_since (entry_last);
1762 return 0;
1765 /* Compute the value of METHODS to pass to recursive calls.
1766 Don't allow widening to be tried recursively. */
1768 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1770 /* Look for a wider mode of the same class for which it appears we can do
1771 the operation. */
1773 if (CLASS_HAS_WIDER_MODES_P (mclass))
1775 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1776 wider_mode != VOIDmode;
1777 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1779 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
1780 != CODE_FOR_nothing
1781 || (methods == OPTAB_LIB
1782 && optab_libfunc (binoptab, wider_mode)))
1784 rtx xop0 = op0, xop1 = op1;
1785 int no_extend = 0;
1787 /* For certain integer operations, we need not actually extend
1788 the narrow operands, as long as we will truncate
1789 the results to the same narrowness. */
1791 if ((binoptab == ior_optab || binoptab == and_optab
1792 || binoptab == xor_optab
1793 || binoptab == add_optab || binoptab == sub_optab
1794 || binoptab == smul_optab || binoptab == ashl_optab)
1795 && mclass == MODE_INT)
1796 no_extend = 1;
1798 xop0 = widen_operand (xop0, wider_mode, mode,
1799 unsignedp, no_extend);
1801 /* The second operand of a shift must always be extended. */
1802 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1803 no_extend && binoptab != ashl_optab);
1805 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1806 unsignedp, methods);
1807 if (temp)
1809 if (mclass != MODE_INT
1810 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1812 if (target == 0)
1813 target = gen_reg_rtx (mode);
1814 convert_move (target, temp, 0);
1815 return target;
1817 else
1818 return gen_lowpart (mode, temp);
1820 else
1821 delete_insns_since (last);
1826 delete_insns_since (entry_last);
1827 return 0;
1830 /* Expand a binary operator which has both signed and unsigned forms.
1831 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1832 signed operations.
1834 If we widen unsigned operands, we may use a signed wider operation instead
1835 of an unsigned wider operation, since the result would be the same. */
1838 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
1839 rtx op0, rtx op1, rtx target, int unsignedp,
1840 enum optab_methods methods)
1842 rtx temp;
1843 optab direct_optab = unsignedp ? uoptab : soptab;
1844 bool save_enable;
1846 /* Do it without widening, if possible. */
1847 temp = expand_binop (mode, direct_optab, op0, op1, target,
1848 unsignedp, OPTAB_DIRECT);
1849 if (temp || methods == OPTAB_DIRECT)
1850 return temp;
1852 /* Try widening to a signed int. Disable any direct use of any
1853 signed insn in the current mode. */
1854 save_enable = swap_optab_enable (soptab, mode, false);
1856 temp = expand_binop (mode, soptab, op0, op1, target,
1857 unsignedp, OPTAB_WIDEN);
1859 /* For unsigned operands, try widening to an unsigned int. */
1860 if (!temp && unsignedp)
1861 temp = expand_binop (mode, uoptab, op0, op1, target,
1862 unsignedp, OPTAB_WIDEN);
1863 if (temp || methods == OPTAB_WIDEN)
1864 goto egress;
1866 /* Use the right width libcall if that exists. */
1867 temp = expand_binop (mode, direct_optab, op0, op1, target,
1868 unsignedp, OPTAB_LIB);
1869 if (temp || methods == OPTAB_LIB)
1870 goto egress;
1872 /* Must widen and use a libcall, use either signed or unsigned. */
1873 temp = expand_binop (mode, soptab, op0, op1, target,
1874 unsignedp, methods);
1875 if (!temp && unsignedp)
1876 temp = expand_binop (mode, uoptab, op0, op1, target,
1877 unsignedp, methods);
1879 egress:
1880 /* Undo the fiddling above. */
1881 if (save_enable)
1882 swap_optab_enable (soptab, mode, true);
1883 return temp;
1886 /* Generate code to perform an operation specified by UNOPPTAB
1887 on operand OP0, with two results to TARG0 and TARG1.
1888 We assume that the order of the operands for the instruction
1889 is TARG0, TARG1, OP0.
1891 Either TARG0 or TARG1 may be zero, but what that means is that
1892 the result is not actually wanted. We will generate it into
1893 a dummy pseudo-reg and discard it. They may not both be zero.
1895 Returns 1 if this operation can be performed; 0 if not. */
1898 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1899 int unsignedp)
1901 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1902 enum mode_class mclass;
1903 machine_mode wider_mode;
1904 rtx_insn *entry_last = get_last_insn ();
1905 rtx_insn *last;
1907 mclass = GET_MODE_CLASS (mode);
1909 if (!targ0)
1910 targ0 = gen_reg_rtx (mode);
1911 if (!targ1)
1912 targ1 = gen_reg_rtx (mode);
1914 /* Record where to go back to if we fail. */
1915 last = get_last_insn ();
1917 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
1919 struct expand_operand ops[3];
1920 enum insn_code icode = optab_handler (unoptab, mode);
1922 create_fixed_operand (&ops[0], targ0);
1923 create_fixed_operand (&ops[1], targ1);
1924 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
1925 if (maybe_expand_insn (icode, 3, ops))
1926 return 1;
1929 /* It can't be done in this mode. Can we do it in a wider mode? */
1931 if (CLASS_HAS_WIDER_MODES_P (mclass))
1933 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1934 wider_mode != VOIDmode;
1935 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1937 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
1939 rtx t0 = gen_reg_rtx (wider_mode);
1940 rtx t1 = gen_reg_rtx (wider_mode);
1941 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1943 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
1945 convert_move (targ0, t0, unsignedp);
1946 convert_move (targ1, t1, unsignedp);
1947 return 1;
1949 else
1950 delete_insns_since (last);
1955 delete_insns_since (entry_last);
1956 return 0;
1959 /* Generate code to perform an operation specified by BINOPTAB
1960 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1961 We assume that the order of the operands for the instruction
1962 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1963 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1965 Either TARG0 or TARG1 may be zero, but what that means is that
1966 the result is not actually wanted. We will generate it into
1967 a dummy pseudo-reg and discard it. They may not both be zero.
1969 Returns 1 if this operation can be performed; 0 if not. */
1972 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
1973 int unsignedp)
1975 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1976 enum mode_class mclass;
1977 machine_mode wider_mode;
1978 rtx_insn *entry_last = get_last_insn ();
1979 rtx_insn *last;
1981 mclass = GET_MODE_CLASS (mode);
1983 if (!targ0)
1984 targ0 = gen_reg_rtx (mode);
1985 if (!targ1)
1986 targ1 = gen_reg_rtx (mode);
1988 /* Record where to go back to if we fail. */
1989 last = get_last_insn ();
1991 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
1993 struct expand_operand ops[4];
1994 enum insn_code icode = optab_handler (binoptab, mode);
1995 machine_mode mode0 = insn_data[icode].operand[1].mode;
1996 machine_mode mode1 = insn_data[icode].operand[2].mode;
1997 rtx xop0 = op0, xop1 = op1;
1999 /* If we are optimizing, force expensive constants into a register. */
2000 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2001 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2003 create_fixed_operand (&ops[0], targ0);
2004 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2005 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2006 create_fixed_operand (&ops[3], targ1);
2007 if (maybe_expand_insn (icode, 4, ops))
2008 return 1;
2009 delete_insns_since (last);
2012 /* It can't be done in this mode. Can we do it in a wider mode? */
2014 if (CLASS_HAS_WIDER_MODES_P (mclass))
2016 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2017 wider_mode != VOIDmode;
2018 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2020 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2022 rtx t0 = gen_reg_rtx (wider_mode);
2023 rtx t1 = gen_reg_rtx (wider_mode);
2024 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2025 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2027 if (expand_twoval_binop (binoptab, cop0, cop1,
2028 t0, t1, unsignedp))
2030 convert_move (targ0, t0, unsignedp);
2031 convert_move (targ1, t1, unsignedp);
2032 return 1;
2034 else
2035 delete_insns_since (last);
2040 delete_insns_since (entry_last);
2041 return 0;
2044 /* Expand the two-valued library call indicated by BINOPTAB, but
2045 preserve only one of the values. If TARG0 is non-NULL, the first
2046 value is placed into TARG0; otherwise the second value is placed
2047 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2048 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2049 This routine assumes that the value returned by the library call is
2050 as if the return value was of an integral mode twice as wide as the
2051 mode of OP0. Returns 1 if the call was successful. */
2053 bool
2054 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2055 rtx targ0, rtx targ1, enum rtx_code code)
2057 machine_mode mode;
2058 machine_mode libval_mode;
2059 rtx libval;
2060 rtx_insn *insns;
2061 rtx libfunc;
2063 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2064 gcc_assert (!targ0 != !targ1);
2066 mode = GET_MODE (op0);
2067 libfunc = optab_libfunc (binoptab, mode);
2068 if (!libfunc)
2069 return false;
2071 /* The value returned by the library function will have twice as
2072 many bits as the nominal MODE. */
2073 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2074 MODE_INT);
2075 start_sequence ();
2076 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2077 libval_mode, 2,
2078 op0, mode,
2079 op1, mode);
2080 /* Get the part of VAL containing the value that we want. */
2081 libval = simplify_gen_subreg (mode, libval, libval_mode,
2082 targ0 ? 0 : GET_MODE_SIZE (mode));
2083 insns = get_insns ();
2084 end_sequence ();
2085 /* Move the into the desired location. */
2086 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2087 gen_rtx_fmt_ee (code, mode, op0, op1));
2089 return true;
2093 /* Wrapper around expand_unop which takes an rtx code to specify
2094 the operation to perform, not an optab pointer. All other
2095 arguments are the same. */
2097 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2098 rtx target, int unsignedp)
2100 optab unop = code_to_optab (code);
2101 gcc_assert (unop);
2103 return expand_unop (mode, unop, op0, target, unsignedp);
2106 /* Try calculating
2107 (clz:narrow x)
2109 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2111 A similar operation can be used for clrsb. UNOPTAB says which operation
2112 we are trying to expand. */
2113 static rtx
2114 widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab)
2116 enum mode_class mclass = GET_MODE_CLASS (mode);
2117 if (CLASS_HAS_WIDER_MODES_P (mclass))
2119 machine_mode wider_mode;
2120 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2121 wider_mode != VOIDmode;
2122 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2124 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2126 rtx xop0, temp;
2127 rtx_insn *last;
2129 last = get_last_insn ();
2131 if (target == 0)
2132 target = gen_reg_rtx (mode);
2133 xop0 = widen_operand (op0, wider_mode, mode,
2134 unoptab != clrsb_optab, false);
2135 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2136 unoptab != clrsb_optab);
2137 if (temp != 0)
2138 temp = expand_binop
2139 (wider_mode, sub_optab, temp,
2140 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2141 - GET_MODE_PRECISION (mode),
2142 wider_mode),
2143 target, true, OPTAB_DIRECT);
2144 if (temp == 0)
2145 delete_insns_since (last);
2147 return temp;
2151 return 0;
2154 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2155 quantities, choosing which based on whether the high word is nonzero. */
2156 static rtx
2157 expand_doubleword_clz (machine_mode mode, rtx op0, rtx target)
2159 rtx xop0 = force_reg (mode, op0);
2160 rtx subhi = gen_highpart (word_mode, xop0);
2161 rtx sublo = gen_lowpart (word_mode, xop0);
2162 rtx_code_label *hi0_label = gen_label_rtx ();
2163 rtx_code_label *after_label = gen_label_rtx ();
2164 rtx_insn *seq;
2165 rtx temp, result;
2167 /* If we were not given a target, use a word_mode register, not a
2168 'mode' register. The result will fit, and nobody is expecting
2169 anything bigger (the return type of __builtin_clz* is int). */
2170 if (!target)
2171 target = gen_reg_rtx (word_mode);
2173 /* In any case, write to a word_mode scratch in both branches of the
2174 conditional, so we can ensure there is a single move insn setting
2175 'target' to tag a REG_EQUAL note on. */
2176 result = gen_reg_rtx (word_mode);
2178 start_sequence ();
2180 /* If the high word is not equal to zero,
2181 then clz of the full value is clz of the high word. */
2182 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2183 word_mode, true, hi0_label);
2185 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2186 if (!temp)
2187 goto fail;
2189 if (temp != result)
2190 convert_move (result, temp, true);
2192 emit_jump_insn (targetm.gen_jump (after_label));
2193 emit_barrier ();
2195 /* Else clz of the full value is clz of the low word plus the number
2196 of bits in the high word. */
2197 emit_label (hi0_label);
2199 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2200 if (!temp)
2201 goto fail;
2202 temp = expand_binop (word_mode, add_optab, temp,
2203 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2204 result, true, OPTAB_DIRECT);
2205 if (!temp)
2206 goto fail;
2207 if (temp != result)
2208 convert_move (result, temp, true);
2210 emit_label (after_label);
2211 convert_move (target, result, true);
2213 seq = get_insns ();
2214 end_sequence ();
2216 add_equal_note (seq, target, CLZ, xop0, 0);
2217 emit_insn (seq);
2218 return target;
2220 fail:
2221 end_sequence ();
2222 return 0;
2225 /* Try calculating
2226 (bswap:narrow x)
2228 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2229 static rtx
2230 widen_bswap (machine_mode mode, rtx op0, rtx target)
2232 enum mode_class mclass = GET_MODE_CLASS (mode);
2233 machine_mode wider_mode;
2234 rtx x;
2235 rtx_insn *last;
2237 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2238 return NULL_RTX;
2240 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2241 wider_mode != VOIDmode;
2242 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2243 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2244 goto found;
2245 return NULL_RTX;
2247 found:
2248 last = get_last_insn ();
2250 x = widen_operand (op0, wider_mode, mode, true, true);
2251 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2253 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2254 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2255 if (x != 0)
2256 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2257 GET_MODE_BITSIZE (wider_mode)
2258 - GET_MODE_BITSIZE (mode),
2259 NULL_RTX, true);
2261 if (x != 0)
2263 if (target == 0)
2264 target = gen_reg_rtx (mode);
2265 emit_move_insn (target, gen_lowpart (mode, x));
2267 else
2268 delete_insns_since (last);
2270 return target;
2273 /* Try calculating bswap as two bswaps of two word-sized operands. */
2275 static rtx
2276 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2278 rtx t0, t1;
2280 t1 = expand_unop (word_mode, bswap_optab,
2281 operand_subword_force (op, 0, mode), NULL_RTX, true);
2282 t0 = expand_unop (word_mode, bswap_optab,
2283 operand_subword_force (op, 1, mode), NULL_RTX, true);
2285 if (target == 0 || !valid_multiword_target_p (target))
2286 target = gen_reg_rtx (mode);
2287 if (REG_P (target))
2288 emit_clobber (target);
2289 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2290 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2292 return target;
2295 /* Try calculating (parity x) as (and (popcount x) 1), where
2296 popcount can also be done in a wider mode. */
2297 static rtx
2298 expand_parity (machine_mode mode, rtx op0, rtx target)
2300 enum mode_class mclass = GET_MODE_CLASS (mode);
2301 if (CLASS_HAS_WIDER_MODES_P (mclass))
2303 machine_mode wider_mode;
2304 for (wider_mode = mode; wider_mode != VOIDmode;
2305 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2307 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2309 rtx xop0, temp;
2310 rtx_insn *last;
2312 last = get_last_insn ();
2314 if (target == 0)
2315 target = gen_reg_rtx (mode);
2316 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2317 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2318 true);
2319 if (temp != 0)
2320 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2321 target, true, OPTAB_DIRECT);
2322 if (temp == 0)
2323 delete_insns_since (last);
2325 return temp;
2329 return 0;
2332 /* Try calculating ctz(x) as K - clz(x & -x) ,
2333 where K is GET_MODE_PRECISION(mode) - 1.
2335 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2336 don't have to worry about what the hardware does in that case. (If
2337 the clz instruction produces the usual value at 0, which is K, the
2338 result of this code sequence will be -1; expand_ffs, below, relies
2339 on this. It might be nice to have it be K instead, for consistency
2340 with the (very few) processors that provide a ctz with a defined
2341 value, but that would take one more instruction, and it would be
2342 less convenient for expand_ffs anyway. */
2344 static rtx
2345 expand_ctz (machine_mode mode, rtx op0, rtx target)
2347 rtx_insn *seq;
2348 rtx temp;
2350 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2351 return 0;
2353 start_sequence ();
2355 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2356 if (temp)
2357 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2358 true, OPTAB_DIRECT);
2359 if (temp)
2360 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2361 if (temp)
2362 temp = expand_binop (mode, sub_optab,
2363 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2364 temp, target,
2365 true, OPTAB_DIRECT);
2366 if (temp == 0)
2368 end_sequence ();
2369 return 0;
2372 seq = get_insns ();
2373 end_sequence ();
2375 add_equal_note (seq, temp, CTZ, op0, 0);
2376 emit_insn (seq);
2377 return temp;
2381 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2382 else with the sequence used by expand_clz.
2384 The ffs builtin promises to return zero for a zero value and ctz/clz
2385 may have an undefined value in that case. If they do not give us a
2386 convenient value, we have to generate a test and branch. */
2387 static rtx
2388 expand_ffs (machine_mode mode, rtx op0, rtx target)
2390 HOST_WIDE_INT val = 0;
2391 bool defined_at_zero = false;
2392 rtx temp;
2393 rtx_insn *seq;
2395 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2397 start_sequence ();
2399 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2400 if (!temp)
2401 goto fail;
2403 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2405 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2407 start_sequence ();
2408 temp = expand_ctz (mode, op0, 0);
2409 if (!temp)
2410 goto fail;
2412 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2414 defined_at_zero = true;
2415 val = (GET_MODE_PRECISION (mode) - 1) - val;
2418 else
2419 return 0;
2421 if (defined_at_zero && val == -1)
2422 /* No correction needed at zero. */;
2423 else
2425 /* We don't try to do anything clever with the situation found
2426 on some processors (eg Alpha) where ctz(0:mode) ==
2427 bitsize(mode). If someone can think of a way to send N to -1
2428 and leave alone all values in the range 0..N-1 (where N is a
2429 power of two), cheaper than this test-and-branch, please add it.
2431 The test-and-branch is done after the operation itself, in case
2432 the operation sets condition codes that can be recycled for this.
2433 (This is true on i386, for instance.) */
2435 rtx_code_label *nonzero_label = gen_label_rtx ();
2436 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2437 mode, true, nonzero_label);
2439 convert_move (temp, GEN_INT (-1), false);
2440 emit_label (nonzero_label);
2443 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2444 to produce a value in the range 0..bitsize. */
2445 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2446 target, false, OPTAB_DIRECT);
2447 if (!temp)
2448 goto fail;
2450 seq = get_insns ();
2451 end_sequence ();
2453 add_equal_note (seq, temp, FFS, op0, 0);
2454 emit_insn (seq);
2455 return temp;
2457 fail:
2458 end_sequence ();
2459 return 0;
2462 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2463 conditions, VAL may already be a SUBREG against which we cannot generate
2464 a further SUBREG. In this case, we expect forcing the value into a
2465 register will work around the situation. */
2467 static rtx
2468 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2469 machine_mode imode)
2471 rtx ret;
2472 ret = lowpart_subreg (omode, val, imode);
2473 if (ret == NULL)
2475 val = force_reg (imode, val);
2476 ret = lowpart_subreg (omode, val, imode);
2477 gcc_assert (ret != NULL);
2479 return ret;
2482 /* Expand a floating point absolute value or negation operation via a
2483 logical operation on the sign bit. */
2485 static rtx
2486 expand_absneg_bit (enum rtx_code code, machine_mode mode,
2487 rtx op0, rtx target)
2489 const struct real_format *fmt;
2490 int bitpos, word, nwords, i;
2491 machine_mode imode;
2492 rtx temp;
2493 rtx_insn *insns;
2495 /* The format has to have a simple sign bit. */
2496 fmt = REAL_MODE_FORMAT (mode);
2497 if (fmt == NULL)
2498 return NULL_RTX;
2500 bitpos = fmt->signbit_rw;
2501 if (bitpos < 0)
2502 return NULL_RTX;
2504 /* Don't create negative zeros if the format doesn't support them. */
2505 if (code == NEG && !fmt->has_signed_zero)
2506 return NULL_RTX;
2508 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2510 imode = int_mode_for_mode (mode);
2511 if (imode == BLKmode)
2512 return NULL_RTX;
2513 word = 0;
2514 nwords = 1;
2516 else
2518 imode = word_mode;
2520 if (FLOAT_WORDS_BIG_ENDIAN)
2521 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2522 else
2523 word = bitpos / BITS_PER_WORD;
2524 bitpos = bitpos % BITS_PER_WORD;
2525 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2528 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2529 if (code == ABS)
2530 mask = ~mask;
2532 if (target == 0
2533 || target == op0
2534 || (nwords > 1 && !valid_multiword_target_p (target)))
2535 target = gen_reg_rtx (mode);
2537 if (nwords > 1)
2539 start_sequence ();
2541 for (i = 0; i < nwords; ++i)
2543 rtx targ_piece = operand_subword (target, i, 1, mode);
2544 rtx op0_piece = operand_subword_force (op0, i, mode);
2546 if (i == word)
2548 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2549 op0_piece,
2550 immed_wide_int_const (mask, imode),
2551 targ_piece, 1, OPTAB_LIB_WIDEN);
2552 if (temp != targ_piece)
2553 emit_move_insn (targ_piece, temp);
2555 else
2556 emit_move_insn (targ_piece, op0_piece);
2559 insns = get_insns ();
2560 end_sequence ();
2562 emit_insn (insns);
2564 else
2566 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2567 gen_lowpart (imode, op0),
2568 immed_wide_int_const (mask, imode),
2569 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2570 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2572 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2573 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2574 target);
2577 return target;
2580 /* As expand_unop, but will fail rather than attempt the operation in a
2581 different mode or with a libcall. */
2582 static rtx
2583 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2584 int unsignedp)
2586 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2588 struct expand_operand ops[2];
2589 enum insn_code icode = optab_handler (unoptab, mode);
2590 rtx_insn *last = get_last_insn ();
2591 rtx_insn *pat;
2593 create_output_operand (&ops[0], target, mode);
2594 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2595 pat = maybe_gen_insn (icode, 2, ops);
2596 if (pat)
2598 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2599 && ! add_equal_note (pat, ops[0].value,
2600 optab_to_code (unoptab),
2601 ops[1].value, NULL_RTX))
2603 delete_insns_since (last);
2604 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2607 emit_insn (pat);
2609 return ops[0].value;
2612 return 0;
2615 /* Generate code to perform an operation specified by UNOPTAB
2616 on operand OP0, with result having machine-mode MODE.
2618 UNSIGNEDP is for the case where we have to widen the operands
2619 to perform the operation. It says to use zero-extension.
2621 If TARGET is nonzero, the value
2622 is generated there, if it is convenient to do so.
2623 In all cases an rtx is returned for the locus of the value;
2624 this may or may not be TARGET. */
2627 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2628 int unsignedp)
2630 enum mode_class mclass = GET_MODE_CLASS (mode);
2631 machine_mode wider_mode;
2632 rtx temp;
2633 rtx libfunc;
2635 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2636 if (temp)
2637 return temp;
2639 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2641 /* Widening (or narrowing) clz needs special treatment. */
2642 if (unoptab == clz_optab)
2644 temp = widen_leading (mode, op0, target, unoptab);
2645 if (temp)
2646 return temp;
2648 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2649 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2651 temp = expand_doubleword_clz (mode, op0, target);
2652 if (temp)
2653 return temp;
2656 goto try_libcall;
2659 if (unoptab == clrsb_optab)
2661 temp = widen_leading (mode, op0, target, unoptab);
2662 if (temp)
2663 return temp;
2664 goto try_libcall;
2667 /* Widening (or narrowing) bswap needs special treatment. */
2668 if (unoptab == bswap_optab)
2670 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2671 or ROTATERT. First try these directly; if this fails, then try the
2672 obvious pair of shifts with allowed widening, as this will probably
2673 be always more efficient than the other fallback methods. */
2674 if (mode == HImode)
2676 rtx_insn *last;
2677 rtx temp1, temp2;
2679 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2681 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
2682 unsignedp, OPTAB_DIRECT);
2683 if (temp)
2684 return temp;
2687 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2689 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
2690 unsignedp, OPTAB_DIRECT);
2691 if (temp)
2692 return temp;
2695 last = get_last_insn ();
2697 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
2698 unsignedp, OPTAB_WIDEN);
2699 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
2700 unsignedp, OPTAB_WIDEN);
2701 if (temp1 && temp2)
2703 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2704 unsignedp, OPTAB_WIDEN);
2705 if (temp)
2706 return temp;
2709 delete_insns_since (last);
2712 temp = widen_bswap (mode, op0, target);
2713 if (temp)
2714 return temp;
2716 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2717 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2719 temp = expand_doubleword_bswap (mode, op0, target);
2720 if (temp)
2721 return temp;
2724 goto try_libcall;
2727 if (CLASS_HAS_WIDER_MODES_P (mclass))
2728 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2729 wider_mode != VOIDmode;
2730 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2732 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2734 rtx xop0 = op0;
2735 rtx_insn *last = get_last_insn ();
2737 /* For certain operations, we need not actually extend
2738 the narrow operand, as long as we will truncate the
2739 results to the same narrowness. */
2741 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2742 (unoptab == neg_optab
2743 || unoptab == one_cmpl_optab)
2744 && mclass == MODE_INT);
2746 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2747 unsignedp);
2749 if (temp)
2751 if (mclass != MODE_INT
2752 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2754 if (target == 0)
2755 target = gen_reg_rtx (mode);
2756 convert_move (target, temp, 0);
2757 return target;
2759 else
2760 return gen_lowpart (mode, temp);
2762 else
2763 delete_insns_since (last);
2767 /* These can be done a word at a time. */
2768 if (unoptab == one_cmpl_optab
2769 && mclass == MODE_INT
2770 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2771 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2773 int i;
2774 rtx_insn *insns;
2776 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2777 target = gen_reg_rtx (mode);
2779 start_sequence ();
2781 /* Do the actual arithmetic. */
2782 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2784 rtx target_piece = operand_subword (target, i, 1, mode);
2785 rtx x = expand_unop (word_mode, unoptab,
2786 operand_subword_force (op0, i, mode),
2787 target_piece, unsignedp);
2789 if (target_piece != x)
2790 emit_move_insn (target_piece, x);
2793 insns = get_insns ();
2794 end_sequence ();
2796 emit_insn (insns);
2797 return target;
2800 if (optab_to_code (unoptab) == NEG)
2802 /* Try negating floating point values by flipping the sign bit. */
2803 if (SCALAR_FLOAT_MODE_P (mode))
2805 temp = expand_absneg_bit (NEG, mode, op0, target);
2806 if (temp)
2807 return temp;
2810 /* If there is no negation pattern, and we have no negative zero,
2811 try subtracting from zero. */
2812 if (!HONOR_SIGNED_ZEROS (mode))
2814 temp = expand_binop (mode, (unoptab == negv_optab
2815 ? subv_optab : sub_optab),
2816 CONST0_RTX (mode), op0, target,
2817 unsignedp, OPTAB_DIRECT);
2818 if (temp)
2819 return temp;
2823 /* Try calculating parity (x) as popcount (x) % 2. */
2824 if (unoptab == parity_optab)
2826 temp = expand_parity (mode, op0, target);
2827 if (temp)
2828 return temp;
2831 /* Try implementing ffs (x) in terms of clz (x). */
2832 if (unoptab == ffs_optab)
2834 temp = expand_ffs (mode, op0, target);
2835 if (temp)
2836 return temp;
2839 /* Try implementing ctz (x) in terms of clz (x). */
2840 if (unoptab == ctz_optab)
2842 temp = expand_ctz (mode, op0, target);
2843 if (temp)
2844 return temp;
2847 try_libcall:
2848 /* Now try a library call in this mode. */
2849 libfunc = optab_libfunc (unoptab, mode);
2850 if (libfunc)
2852 rtx_insn *insns;
2853 rtx value;
2854 rtx eq_value;
2855 machine_mode outmode = mode;
2857 /* All of these functions return small values. Thus we choose to
2858 have them return something that isn't a double-word. */
2859 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2860 || unoptab == clrsb_optab || unoptab == popcount_optab
2861 || unoptab == parity_optab)
2862 outmode
2863 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
2864 optab_libfunc (unoptab, mode)));
2866 start_sequence ();
2868 /* Pass 1 for NO_QUEUE so we don't lose any increments
2869 if the libcall is cse'd or moved. */
2870 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
2871 1, op0, mode);
2872 insns = get_insns ();
2873 end_sequence ();
2875 target = gen_reg_rtx (outmode);
2876 bool trapv = trapv_unoptab_p (unoptab);
2877 if (trapv)
2878 eq_value = NULL_RTX;
2879 else
2881 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
2882 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
2883 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
2884 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
2885 eq_value = simplify_gen_unary (ZERO_EXTEND,
2886 outmode, eq_value, mode);
2888 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
2890 return target;
2893 /* It can't be done in this mode. Can we do it in a wider mode? */
2895 if (CLASS_HAS_WIDER_MODES_P (mclass))
2897 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2898 wider_mode != VOIDmode;
2899 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2901 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
2902 || optab_libfunc (unoptab, wider_mode))
2904 rtx xop0 = op0;
2905 rtx_insn *last = get_last_insn ();
2907 /* For certain operations, we need not actually extend
2908 the narrow operand, as long as we will truncate the
2909 results to the same narrowness. */
2910 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2911 (unoptab == neg_optab
2912 || unoptab == one_cmpl_optab
2913 || unoptab == bswap_optab)
2914 && mclass == MODE_INT);
2916 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2917 unsignedp);
2919 /* If we are generating clz using wider mode, adjust the
2920 result. Similarly for clrsb. */
2921 if ((unoptab == clz_optab || unoptab == clrsb_optab)
2922 && temp != 0)
2923 temp = expand_binop
2924 (wider_mode, sub_optab, temp,
2925 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2926 - GET_MODE_PRECISION (mode),
2927 wider_mode),
2928 target, true, OPTAB_DIRECT);
2930 /* Likewise for bswap. */
2931 if (unoptab == bswap_optab && temp != 0)
2933 gcc_assert (GET_MODE_PRECISION (wider_mode)
2934 == GET_MODE_BITSIZE (wider_mode)
2935 && GET_MODE_PRECISION (mode)
2936 == GET_MODE_BITSIZE (mode));
2938 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
2939 GET_MODE_BITSIZE (wider_mode)
2940 - GET_MODE_BITSIZE (mode),
2941 NULL_RTX, true);
2944 if (temp)
2946 if (mclass != MODE_INT)
2948 if (target == 0)
2949 target = gen_reg_rtx (mode);
2950 convert_move (target, temp, 0);
2951 return target;
2953 else
2954 return gen_lowpart (mode, temp);
2956 else
2957 delete_insns_since (last);
2962 /* One final attempt at implementing negation via subtraction,
2963 this time allowing widening of the operand. */
2964 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
2966 rtx temp;
2967 temp = expand_binop (mode,
2968 unoptab == negv_optab ? subv_optab : sub_optab,
2969 CONST0_RTX (mode), op0,
2970 target, unsignedp, OPTAB_LIB_WIDEN);
2971 if (temp)
2972 return temp;
2975 return 0;
2978 /* Emit code to compute the absolute value of OP0, with result to
2979 TARGET if convenient. (TARGET may be 0.) The return value says
2980 where the result actually is to be found.
2982 MODE is the mode of the operand; the mode of the result is
2983 different but can be deduced from MODE.
2988 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
2989 int result_unsignedp)
2991 rtx temp;
2993 if (GET_MODE_CLASS (mode) != MODE_INT
2994 || ! flag_trapv)
2995 result_unsignedp = 1;
2997 /* First try to do it with a special abs instruction. */
2998 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2999 op0, target, 0);
3000 if (temp != 0)
3001 return temp;
3003 /* For floating point modes, try clearing the sign bit. */
3004 if (SCALAR_FLOAT_MODE_P (mode))
3006 temp = expand_absneg_bit (ABS, mode, op0, target);
3007 if (temp)
3008 return temp;
3011 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3012 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3013 && !HONOR_SIGNED_ZEROS (mode))
3015 rtx_insn *last = get_last_insn ();
3017 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3018 op0, NULL_RTX, 0);
3019 if (temp != 0)
3020 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3021 OPTAB_WIDEN);
3023 if (temp != 0)
3024 return temp;
3026 delete_insns_since (last);
3029 /* If this machine has expensive jumps, we can do integer absolute
3030 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3031 where W is the width of MODE. */
3033 if (GET_MODE_CLASS (mode) == MODE_INT
3034 && BRANCH_COST (optimize_insn_for_speed_p (),
3035 false) >= 2)
3037 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3038 GET_MODE_PRECISION (mode) - 1,
3039 NULL_RTX, 0);
3041 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3042 OPTAB_LIB_WIDEN);
3043 if (temp != 0)
3044 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3045 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3047 if (temp != 0)
3048 return temp;
3051 return NULL_RTX;
3055 expand_abs (machine_mode mode, rtx op0, rtx target,
3056 int result_unsignedp, int safe)
3058 rtx temp;
3059 rtx_code_label *op1;
3061 if (GET_MODE_CLASS (mode) != MODE_INT
3062 || ! flag_trapv)
3063 result_unsignedp = 1;
3065 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3066 if (temp != 0)
3067 return temp;
3069 /* If that does not win, use conditional jump and negate. */
3071 /* It is safe to use the target if it is the same
3072 as the source if this is also a pseudo register */
3073 if (op0 == target && REG_P (op0)
3074 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3075 safe = 1;
3077 op1 = gen_label_rtx ();
3078 if (target == 0 || ! safe
3079 || GET_MODE (target) != mode
3080 || (MEM_P (target) && MEM_VOLATILE_P (target))
3081 || (REG_P (target)
3082 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3083 target = gen_reg_rtx (mode);
3085 emit_move_insn (target, op0);
3086 NO_DEFER_POP;
3088 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3089 NULL_RTX, NULL, op1, -1);
3091 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3092 target, target, 0);
3093 if (op0 != target)
3094 emit_move_insn (target, op0);
3095 emit_label (op1);
3096 OK_DEFER_POP;
3097 return target;
3100 /* Emit code to compute the one's complement absolute value of OP0
3101 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3102 (TARGET may be NULL_RTX.) The return value says where the result
3103 actually is to be found.
3105 MODE is the mode of the operand; the mode of the result is
3106 different but can be deduced from MODE. */
3109 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3111 rtx temp;
3113 /* Not applicable for floating point modes. */
3114 if (FLOAT_MODE_P (mode))
3115 return NULL_RTX;
3117 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3118 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3120 rtx_insn *last = get_last_insn ();
3122 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3123 if (temp != 0)
3124 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3125 OPTAB_WIDEN);
3127 if (temp != 0)
3128 return temp;
3130 delete_insns_since (last);
3133 /* If this machine has expensive jumps, we can do one's complement
3134 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3136 if (GET_MODE_CLASS (mode) == MODE_INT
3137 && BRANCH_COST (optimize_insn_for_speed_p (),
3138 false) >= 2)
3140 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3141 GET_MODE_PRECISION (mode) - 1,
3142 NULL_RTX, 0);
3144 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3145 OPTAB_LIB_WIDEN);
3147 if (temp != 0)
3148 return temp;
3151 return NULL_RTX;
3154 /* A subroutine of expand_copysign, perform the copysign operation using the
3155 abs and neg primitives advertised to exist on the target. The assumption
3156 is that we have a split register file, and leaving op0 in fp registers,
3157 and not playing with subregs so much, will help the register allocator. */
3159 static rtx
3160 expand_copysign_absneg (machine_mode mode, rtx op0, rtx op1, rtx target,
3161 int bitpos, bool op0_is_abs)
3163 machine_mode imode;
3164 enum insn_code icode;
3165 rtx sign;
3166 rtx_code_label *label;
3168 if (target == op1)
3169 target = NULL_RTX;
3171 /* Check if the back end provides an insn that handles signbit for the
3172 argument's mode. */
3173 icode = optab_handler (signbit_optab, mode);
3174 if (icode != CODE_FOR_nothing)
3176 imode = insn_data[(int) icode].operand[0].mode;
3177 sign = gen_reg_rtx (imode);
3178 emit_unop_insn (icode, sign, op1, UNKNOWN);
3180 else
3182 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3184 imode = int_mode_for_mode (mode);
3185 if (imode == BLKmode)
3186 return NULL_RTX;
3187 op1 = gen_lowpart (imode, op1);
3189 else
3191 int word;
3193 imode = word_mode;
3194 if (FLOAT_WORDS_BIG_ENDIAN)
3195 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3196 else
3197 word = bitpos / BITS_PER_WORD;
3198 bitpos = bitpos % BITS_PER_WORD;
3199 op1 = operand_subword_force (op1, word, mode);
3202 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3203 sign = expand_binop (imode, and_optab, op1,
3204 immed_wide_int_const (mask, imode),
3205 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3208 if (!op0_is_abs)
3210 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3211 if (op0 == NULL)
3212 return NULL_RTX;
3213 target = op0;
3215 else
3217 if (target == NULL_RTX)
3218 target = copy_to_reg (op0);
3219 else
3220 emit_move_insn (target, op0);
3223 label = gen_label_rtx ();
3224 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3226 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3227 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3228 else
3229 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3230 if (op0 != target)
3231 emit_move_insn (target, op0);
3233 emit_label (label);
3235 return target;
3239 /* A subroutine of expand_copysign, perform the entire copysign operation
3240 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3241 is true if op0 is known to have its sign bit clear. */
3243 static rtx
3244 expand_copysign_bit (machine_mode mode, rtx op0, rtx op1, rtx target,
3245 int bitpos, bool op0_is_abs)
3247 machine_mode imode;
3248 int word, nwords, i;
3249 rtx temp;
3250 rtx_insn *insns;
3252 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3254 imode = int_mode_for_mode (mode);
3255 if (imode == BLKmode)
3256 return NULL_RTX;
3257 word = 0;
3258 nwords = 1;
3260 else
3262 imode = word_mode;
3264 if (FLOAT_WORDS_BIG_ENDIAN)
3265 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3266 else
3267 word = bitpos / BITS_PER_WORD;
3268 bitpos = bitpos % BITS_PER_WORD;
3269 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3272 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3274 if (target == 0
3275 || target == op0
3276 || target == op1
3277 || (nwords > 1 && !valid_multiword_target_p (target)))
3278 target = gen_reg_rtx (mode);
3280 if (nwords > 1)
3282 start_sequence ();
3284 for (i = 0; i < nwords; ++i)
3286 rtx targ_piece = operand_subword (target, i, 1, mode);
3287 rtx op0_piece = operand_subword_force (op0, i, mode);
3289 if (i == word)
3291 if (!op0_is_abs)
3292 op0_piece
3293 = expand_binop (imode, and_optab, op0_piece,
3294 immed_wide_int_const (~mask, imode),
3295 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3296 op1 = expand_binop (imode, and_optab,
3297 operand_subword_force (op1, i, mode),
3298 immed_wide_int_const (mask, imode),
3299 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3301 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3302 targ_piece, 1, OPTAB_LIB_WIDEN);
3303 if (temp != targ_piece)
3304 emit_move_insn (targ_piece, temp);
3306 else
3307 emit_move_insn (targ_piece, op0_piece);
3310 insns = get_insns ();
3311 end_sequence ();
3313 emit_insn (insns);
3315 else
3317 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3318 immed_wide_int_const (mask, imode),
3319 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3321 op0 = gen_lowpart (imode, op0);
3322 if (!op0_is_abs)
3323 op0 = expand_binop (imode, and_optab, op0,
3324 immed_wide_int_const (~mask, imode),
3325 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3327 temp = expand_binop (imode, ior_optab, op0, op1,
3328 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3329 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3332 return target;
3335 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3336 scalar floating point mode. Return NULL if we do not know how to
3337 expand the operation inline. */
3340 expand_copysign (rtx op0, rtx op1, rtx target)
3342 machine_mode mode = GET_MODE (op0);
3343 const struct real_format *fmt;
3344 bool op0_is_abs;
3345 rtx temp;
3347 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3348 gcc_assert (GET_MODE (op1) == mode);
3350 /* First try to do it with a special instruction. */
3351 temp = expand_binop (mode, copysign_optab, op0, op1,
3352 target, 0, OPTAB_DIRECT);
3353 if (temp)
3354 return temp;
3356 fmt = REAL_MODE_FORMAT (mode);
3357 if (fmt == NULL || !fmt->has_signed_zero)
3358 return NULL_RTX;
3360 op0_is_abs = false;
3361 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3363 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3364 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3365 op0_is_abs = true;
3368 if (fmt->signbit_ro >= 0
3369 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3370 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3371 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3373 temp = expand_copysign_absneg (mode, op0, op1, target,
3374 fmt->signbit_ro, op0_is_abs);
3375 if (temp)
3376 return temp;
3379 if (fmt->signbit_rw < 0)
3380 return NULL_RTX;
3381 return expand_copysign_bit (mode, op0, op1, target,
3382 fmt->signbit_rw, op0_is_abs);
3385 /* Generate an instruction whose insn-code is INSN_CODE,
3386 with two operands: an output TARGET and an input OP0.
3387 TARGET *must* be nonzero, and the output is always stored there.
3388 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3389 the value that is stored into TARGET.
3391 Return false if expansion failed. */
3393 bool
3394 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3395 enum rtx_code code)
3397 struct expand_operand ops[2];
3398 rtx_insn *pat;
3400 create_output_operand (&ops[0], target, GET_MODE (target));
3401 create_input_operand (&ops[1], op0, GET_MODE (op0));
3402 pat = maybe_gen_insn (icode, 2, ops);
3403 if (!pat)
3404 return false;
3406 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3407 && code != UNKNOWN)
3408 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3410 emit_insn (pat);
3412 if (ops[0].value != target)
3413 emit_move_insn (target, ops[0].value);
3414 return true;
3416 /* Generate an instruction whose insn-code is INSN_CODE,
3417 with two operands: an output TARGET and an input OP0.
3418 TARGET *must* be nonzero, and the output is always stored there.
3419 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3420 the value that is stored into TARGET. */
3422 void
3423 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3425 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3426 gcc_assert (ok);
3429 struct no_conflict_data
3431 rtx target;
3432 rtx_insn *first, *insn;
3433 bool must_stay;
3436 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3437 the currently examined clobber / store has to stay in the list of
3438 insns that constitute the actual libcall block. */
3439 static void
3440 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3442 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3444 /* If this inns directly contributes to setting the target, it must stay. */
3445 if (reg_overlap_mentioned_p (p->target, dest))
3446 p->must_stay = true;
3447 /* If we haven't committed to keeping any other insns in the list yet,
3448 there is nothing more to check. */
3449 else if (p->insn == p->first)
3450 return;
3451 /* If this insn sets / clobbers a register that feeds one of the insns
3452 already in the list, this insn has to stay too. */
3453 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3454 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3455 || reg_used_between_p (dest, p->first, p->insn)
3456 /* Likewise if this insn depends on a register set by a previous
3457 insn in the list, or if it sets a result (presumably a hard
3458 register) that is set or clobbered by a previous insn.
3459 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3460 SET_DEST perform the former check on the address, and the latter
3461 check on the MEM. */
3462 || (GET_CODE (set) == SET
3463 && (modified_in_p (SET_SRC (set), p->first)
3464 || modified_in_p (SET_DEST (set), p->first)
3465 || modified_between_p (SET_SRC (set), p->first, p->insn)
3466 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3467 p->must_stay = true;
3471 /* Emit code to make a call to a constant function or a library call.
3473 INSNS is a list containing all insns emitted in the call.
3474 These insns leave the result in RESULT. Our block is to copy RESULT
3475 to TARGET, which is logically equivalent to EQUIV.
3477 We first emit any insns that set a pseudo on the assumption that these are
3478 loading constants into registers; doing so allows them to be safely cse'ed
3479 between blocks. Then we emit all the other insns in the block, followed by
3480 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3481 note with an operand of EQUIV. */
3483 static void
3484 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3485 bool equiv_may_trap)
3487 rtx final_dest = target;
3488 rtx_insn *next, *last, *insn;
3490 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3491 into a MEM later. Protect the libcall block from this change. */
3492 if (! REG_P (target) || REG_USERVAR_P (target))
3493 target = gen_reg_rtx (GET_MODE (target));
3495 /* If we're using non-call exceptions, a libcall corresponding to an
3496 operation that may trap may also trap. */
3497 /* ??? See the comment in front of make_reg_eh_region_note. */
3498 if (cfun->can_throw_non_call_exceptions
3499 && (equiv_may_trap || may_trap_p (equiv)))
3501 for (insn = insns; insn; insn = NEXT_INSN (insn))
3502 if (CALL_P (insn))
3504 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3505 if (note)
3507 int lp_nr = INTVAL (XEXP (note, 0));
3508 if (lp_nr == 0 || lp_nr == INT_MIN)
3509 remove_note (insn, note);
3513 else
3515 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3516 reg note to indicate that this call cannot throw or execute a nonlocal
3517 goto (unless there is already a REG_EH_REGION note, in which case
3518 we update it). */
3519 for (insn = insns; insn; insn = NEXT_INSN (insn))
3520 if (CALL_P (insn))
3521 make_reg_eh_region_note_nothrow_nononlocal (insn);
3524 /* First emit all insns that set pseudos. Remove them from the list as
3525 we go. Avoid insns that set pseudos which were referenced in previous
3526 insns. These can be generated by move_by_pieces, for example,
3527 to update an address. Similarly, avoid insns that reference things
3528 set in previous insns. */
3530 for (insn = insns; insn; insn = next)
3532 rtx set = single_set (insn);
3534 next = NEXT_INSN (insn);
3536 if (set != 0 && REG_P (SET_DEST (set))
3537 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3539 struct no_conflict_data data;
3541 data.target = const0_rtx;
3542 data.first = insns;
3543 data.insn = insn;
3544 data.must_stay = 0;
3545 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3546 if (! data.must_stay)
3548 if (PREV_INSN (insn))
3549 SET_NEXT_INSN (PREV_INSN (insn)) = next;
3550 else
3551 insns = next;
3553 if (next)
3554 SET_PREV_INSN (next) = PREV_INSN (insn);
3556 add_insn (insn);
3560 /* Some ports use a loop to copy large arguments onto the stack.
3561 Don't move anything outside such a loop. */
3562 if (LABEL_P (insn))
3563 break;
3566 /* Write the remaining insns followed by the final copy. */
3567 for (insn = insns; insn; insn = next)
3569 next = NEXT_INSN (insn);
3571 add_insn (insn);
3574 last = emit_move_insn (target, result);
3575 if (equiv)
3576 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3578 if (final_dest != target)
3579 emit_move_insn (final_dest, target);
3582 void
3583 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3585 emit_libcall_block_1 (safe_as_a <rtx_insn *> (insns),
3586 target, result, equiv, false);
3589 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3590 PURPOSE describes how this comparison will be used. CODE is the rtx
3591 comparison code we will be using.
3593 ??? Actually, CODE is slightly weaker than that. A target is still
3594 required to implement all of the normal bcc operations, but not
3595 required to implement all (or any) of the unordered bcc operations. */
3598 can_compare_p (enum rtx_code code, machine_mode mode,
3599 enum can_compare_purpose purpose)
3601 rtx test;
3602 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3605 enum insn_code icode;
3607 if (purpose == ccp_jump
3608 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3609 && insn_operand_matches (icode, 0, test))
3610 return 1;
3611 if (purpose == ccp_store_flag
3612 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3613 && insn_operand_matches (icode, 1, test))
3614 return 1;
3615 if (purpose == ccp_cmov
3616 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3617 return 1;
3619 mode = GET_MODE_WIDER_MODE (mode);
3620 PUT_MODE (test, mode);
3622 while (mode != VOIDmode);
3624 return 0;
3627 /* This function is called when we are going to emit a compare instruction that
3628 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3630 *PMODE is the mode of the inputs (in case they are const_int).
3631 *PUNSIGNEDP nonzero says that the operands are unsigned;
3632 this matters if they need to be widened (as given by METHODS).
3634 If they have mode BLKmode, then SIZE specifies the size of both operands.
3636 This function performs all the setup necessary so that the caller only has
3637 to emit a single comparison insn. This setup can involve doing a BLKmode
3638 comparison or emitting a library call to perform the comparison if no insn
3639 is available to handle it.
3640 The values which are passed in through pointers can be modified; the caller
3641 should perform the comparison on the modified values. Constant
3642 comparisons must have already been folded. */
3644 static void
3645 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3646 int unsignedp, enum optab_methods methods,
3647 rtx *ptest, machine_mode *pmode)
3649 machine_mode mode = *pmode;
3650 rtx libfunc, test;
3651 machine_mode cmp_mode;
3652 enum mode_class mclass;
3654 /* The other methods are not needed. */
3655 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3656 || methods == OPTAB_LIB_WIDEN);
3658 /* If we are optimizing, force expensive constants into a register. */
3659 if (CONSTANT_P (x) && optimize
3660 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
3661 > COSTS_N_INSNS (1)))
3662 x = force_reg (mode, x);
3664 if (CONSTANT_P (y) && optimize
3665 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
3666 > COSTS_N_INSNS (1)))
3667 y = force_reg (mode, y);
3669 #if HAVE_cc0
3670 /* Make sure if we have a canonical comparison. The RTL
3671 documentation states that canonical comparisons are required only
3672 for targets which have cc0. */
3673 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3674 #endif
3676 /* Don't let both operands fail to indicate the mode. */
3677 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3678 x = force_reg (mode, x);
3679 if (mode == VOIDmode)
3680 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3682 /* Handle all BLKmode compares. */
3684 if (mode == BLKmode)
3686 machine_mode result_mode;
3687 enum insn_code cmp_code;
3688 tree length_type;
3689 rtx libfunc;
3690 rtx result;
3691 rtx opalign
3692 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3694 gcc_assert (size);
3696 /* Try to use a memory block compare insn - either cmpstr
3697 or cmpmem will do. */
3698 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3699 cmp_mode != VOIDmode;
3700 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3702 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3703 if (cmp_code == CODE_FOR_nothing)
3704 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3705 if (cmp_code == CODE_FOR_nothing)
3706 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3707 if (cmp_code == CODE_FOR_nothing)
3708 continue;
3710 /* Must make sure the size fits the insn's mode. */
3711 if ((CONST_INT_P (size)
3712 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3713 || (GET_MODE_BITSIZE (GET_MODE (size))
3714 > GET_MODE_BITSIZE (cmp_mode)))
3715 continue;
3717 result_mode = insn_data[cmp_code].operand[0].mode;
3718 result = gen_reg_rtx (result_mode);
3719 size = convert_to_mode (cmp_mode, size, 1);
3720 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3722 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3723 *pmode = result_mode;
3724 return;
3727 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3728 goto fail;
3730 /* Otherwise call a library function, memcmp. */
3731 libfunc = memcmp_libfunc;
3732 length_type = sizetype;
3733 result_mode = TYPE_MODE (integer_type_node);
3734 cmp_mode = TYPE_MODE (length_type);
3735 size = convert_to_mode (TYPE_MODE (length_type), size,
3736 TYPE_UNSIGNED (length_type));
3738 result = emit_library_call_value (libfunc, 0, LCT_PURE,
3739 result_mode, 3,
3740 XEXP (x, 0), Pmode,
3741 XEXP (y, 0), Pmode,
3742 size, cmp_mode);
3743 x = result;
3744 y = const0_rtx;
3745 mode = result_mode;
3746 methods = OPTAB_LIB_WIDEN;
3747 unsignedp = false;
3750 /* Don't allow operands to the compare to trap, as that can put the
3751 compare and branch in different basic blocks. */
3752 if (cfun->can_throw_non_call_exceptions)
3754 if (may_trap_p (x))
3755 x = force_reg (mode, x);
3756 if (may_trap_p (y))
3757 y = force_reg (mode, y);
3760 if (GET_MODE_CLASS (mode) == MODE_CC)
3762 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
3763 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3764 gcc_assert (icode != CODE_FOR_nothing
3765 && insn_operand_matches (icode, 0, test));
3766 *ptest = test;
3767 return;
3770 mclass = GET_MODE_CLASS (mode);
3771 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3772 cmp_mode = mode;
3775 enum insn_code icode;
3776 icode = optab_handler (cbranch_optab, cmp_mode);
3777 if (icode != CODE_FOR_nothing
3778 && insn_operand_matches (icode, 0, test))
3780 rtx_insn *last = get_last_insn ();
3781 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3782 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3783 if (op0 && op1
3784 && insn_operand_matches (icode, 1, op0)
3785 && insn_operand_matches (icode, 2, op1))
3787 XEXP (test, 0) = op0;
3788 XEXP (test, 1) = op1;
3789 *ptest = test;
3790 *pmode = cmp_mode;
3791 return;
3793 delete_insns_since (last);
3796 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3797 break;
3798 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
3800 while (cmp_mode != VOIDmode);
3802 if (methods != OPTAB_LIB_WIDEN)
3803 goto fail;
3805 if (!SCALAR_FLOAT_MODE_P (mode))
3807 rtx result;
3808 machine_mode ret_mode;
3810 /* Handle a libcall just for the mode we are using. */
3811 libfunc = optab_libfunc (cmp_optab, mode);
3812 gcc_assert (libfunc);
3814 /* If we want unsigned, and this mode has a distinct unsigned
3815 comparison routine, use that. */
3816 if (unsignedp)
3818 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
3819 if (ulibfunc)
3820 libfunc = ulibfunc;
3823 ret_mode = targetm.libgcc_cmp_return_mode ();
3824 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3825 ret_mode, 2, x, mode, y, mode);
3827 /* There are two kinds of comparison routines. Biased routines
3828 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3829 of gcc expect that the comparison operation is equivalent
3830 to the modified comparison. For signed comparisons compare the
3831 result against 1 in the biased case, and zero in the unbiased
3832 case. For unsigned comparisons always compare against 1 after
3833 biasing the unbiased result by adding 1. This gives us a way to
3834 represent LTU.
3835 The comparisons in the fixed-point helper library are always
3836 biased. */
3837 x = result;
3838 y = const1_rtx;
3840 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
3842 if (unsignedp)
3843 x = plus_constant (ret_mode, result, 1);
3844 else
3845 y = const0_rtx;
3848 *pmode = ret_mode;
3849 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
3850 ptest, pmode);
3852 else
3853 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
3855 return;
3857 fail:
3858 *ptest = NULL_RTX;
3861 /* Before emitting an insn with code ICODE, make sure that X, which is going
3862 to be used for operand OPNUM of the insn, is converted from mode MODE to
3863 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3864 that it is accepted by the operand predicate. Return the new value. */
3867 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
3868 machine_mode wider_mode, int unsignedp)
3870 if (mode != wider_mode)
3871 x = convert_modes (wider_mode, mode, x, unsignedp);
3873 if (!insn_operand_matches (icode, opnum, x))
3875 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
3876 if (reload_completed)
3877 return NULL_RTX;
3878 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
3879 return NULL_RTX;
3880 x = copy_to_mode_reg (op_mode, x);
3883 return x;
3886 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3887 we can do the branch. */
3889 static void
3890 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, int prob)
3892 machine_mode optab_mode;
3893 enum mode_class mclass;
3894 enum insn_code icode;
3895 rtx_insn *insn;
3897 mclass = GET_MODE_CLASS (mode);
3898 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
3899 icode = optab_handler (cbranch_optab, optab_mode);
3901 gcc_assert (icode != CODE_FOR_nothing);
3902 gcc_assert (insn_operand_matches (icode, 0, test));
3903 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
3904 XEXP (test, 1), label));
3905 if (prob != -1
3906 && profile_status_for_fn (cfun) != PROFILE_ABSENT
3907 && insn
3908 && JUMP_P (insn)
3909 && any_condjump_p (insn)
3910 && !find_reg_note (insn, REG_BR_PROB, 0))
3911 add_int_reg_note (insn, REG_BR_PROB, prob);
3914 /* Generate code to compare X with Y so that the condition codes are
3915 set and to jump to LABEL if the condition is true. If X is a
3916 constant and Y is not a constant, then the comparison is swapped to
3917 ensure that the comparison RTL has the canonical form.
3919 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3920 need to be widened. UNSIGNEDP is also used to select the proper
3921 branch condition code.
3923 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3925 MODE is the mode of the inputs (in case they are const_int).
3927 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
3928 It will be potentially converted into an unsigned variant based on
3929 UNSIGNEDP to select a proper jump instruction.
3931 PROB is the probability of jumping to LABEL. */
3933 void
3934 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3935 machine_mode mode, int unsignedp, rtx label,
3936 int prob)
3938 rtx op0 = x, op1 = y;
3939 rtx test;
3941 /* Swap operands and condition to ensure canonical RTL. */
3942 if (swap_commutative_operands_p (x, y)
3943 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
3945 op0 = y, op1 = x;
3946 comparison = swap_condition (comparison);
3949 /* If OP0 is still a constant, then both X and Y must be constants
3950 or the opposite comparison is not supported. Force X into a register
3951 to create canonical RTL. */
3952 if (CONSTANT_P (op0))
3953 op0 = force_reg (mode, op0);
3955 if (unsignedp)
3956 comparison = unsigned_condition (comparison);
3958 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
3959 &test, &mode);
3960 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
3964 /* Emit a library call comparison between floating point X and Y.
3965 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3967 static void
3968 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
3969 rtx *ptest, machine_mode *pmode)
3971 enum rtx_code swapped = swap_condition (comparison);
3972 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3973 machine_mode orig_mode = GET_MODE (x);
3974 machine_mode mode, cmp_mode;
3975 rtx true_rtx, false_rtx;
3976 rtx value, target, equiv;
3977 rtx_insn *insns;
3978 rtx libfunc = 0;
3979 bool reversed_p = false;
3980 cmp_mode = targetm.libgcc_cmp_return_mode ();
3982 for (mode = orig_mode;
3983 mode != VOIDmode;
3984 mode = GET_MODE_WIDER_MODE (mode))
3986 if (code_to_optab (comparison)
3987 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
3988 break;
3990 if (code_to_optab (swapped)
3991 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
3993 std::swap (x, y);
3994 comparison = swapped;
3995 break;
3998 if (code_to_optab (reversed)
3999 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4001 comparison = reversed;
4002 reversed_p = true;
4003 break;
4007 gcc_assert (mode != VOIDmode);
4009 if (mode != orig_mode)
4011 x = convert_to_mode (mode, x, 0);
4012 y = convert_to_mode (mode, y, 0);
4015 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4016 the RTL. The allows the RTL optimizers to delete the libcall if the
4017 condition can be determined at compile-time. */
4018 if (comparison == UNORDERED
4019 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4021 true_rtx = const_true_rtx;
4022 false_rtx = const0_rtx;
4024 else
4026 switch (comparison)
4028 case EQ:
4029 true_rtx = const0_rtx;
4030 false_rtx = const_true_rtx;
4031 break;
4033 case NE:
4034 true_rtx = const_true_rtx;
4035 false_rtx = const0_rtx;
4036 break;
4038 case GT:
4039 true_rtx = const1_rtx;
4040 false_rtx = const0_rtx;
4041 break;
4043 case GE:
4044 true_rtx = const0_rtx;
4045 false_rtx = constm1_rtx;
4046 break;
4048 case LT:
4049 true_rtx = constm1_rtx;
4050 false_rtx = const0_rtx;
4051 break;
4053 case LE:
4054 true_rtx = const0_rtx;
4055 false_rtx = const1_rtx;
4056 break;
4058 default:
4059 gcc_unreachable ();
4063 if (comparison == UNORDERED)
4065 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4066 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4067 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4068 temp, const_true_rtx, equiv);
4070 else
4072 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4073 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4074 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4075 equiv, true_rtx, false_rtx);
4078 start_sequence ();
4079 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4080 cmp_mode, 2, x, mode, y, mode);
4081 insns = get_insns ();
4082 end_sequence ();
4084 target = gen_reg_rtx (cmp_mode);
4085 emit_libcall_block (insns, target, value, equiv);
4087 if (comparison == UNORDERED
4088 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4089 || reversed_p)
4090 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4091 else
4092 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4094 *pmode = cmp_mode;
4097 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4099 void
4100 emit_indirect_jump (rtx loc)
4102 if (!targetm.have_indirect_jump ())
4103 sorry ("indirect jumps are not available on this target");
4104 else
4106 struct expand_operand ops[1];
4107 create_address_operand (&ops[0], loc);
4108 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4109 emit_barrier ();
4114 /* Emit a conditional move instruction if the machine supports one for that
4115 condition and machine mode.
4117 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4118 the mode to use should they be constants. If it is VOIDmode, they cannot
4119 both be constants.
4121 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4122 should be stored there. MODE is the mode to use should they be constants.
4123 If it is VOIDmode, they cannot both be constants.
4125 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4126 is not supported. */
4129 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4130 machine_mode cmode, rtx op2, rtx op3,
4131 machine_mode mode, int unsignedp)
4133 rtx comparison;
4134 rtx_insn *last;
4135 enum insn_code icode;
4136 enum rtx_code reversed;
4138 /* If one operand is constant, make it the second one. Only do this
4139 if the other operand is not constant as well. */
4141 if (swap_commutative_operands_p (op0, op1))
4143 std::swap (op0, op1);
4144 code = swap_condition (code);
4147 /* get_condition will prefer to generate LT and GT even if the old
4148 comparison was against zero, so undo that canonicalization here since
4149 comparisons against zero are cheaper. */
4150 if (code == LT && op1 == const1_rtx)
4151 code = LE, op1 = const0_rtx;
4152 else if (code == GT && op1 == constm1_rtx)
4153 code = GE, op1 = const0_rtx;
4155 if (cmode == VOIDmode)
4156 cmode = GET_MODE (op0);
4158 if (swap_commutative_operands_p (op2, op3)
4159 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4160 != UNKNOWN))
4162 std::swap (op2, op3);
4163 code = reversed;
4166 if (mode == VOIDmode)
4167 mode = GET_MODE (op2);
4169 icode = direct_optab_handler (movcc_optab, mode);
4171 if (icode == CODE_FOR_nothing)
4172 return 0;
4174 if (!target)
4175 target = gen_reg_rtx (mode);
4177 code = unsignedp ? unsigned_condition (code) : code;
4178 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4180 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4181 return NULL and let the caller figure out how best to deal with this
4182 situation. */
4183 if (!COMPARISON_P (comparison))
4184 return NULL_RTX;
4186 saved_pending_stack_adjust save;
4187 save_pending_stack_adjust (&save);
4188 last = get_last_insn ();
4189 do_pending_stack_adjust ();
4190 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4191 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4192 &comparison, &cmode);
4193 if (comparison)
4195 struct expand_operand ops[4];
4197 create_output_operand (&ops[0], target, mode);
4198 create_fixed_operand (&ops[1], comparison);
4199 create_input_operand (&ops[2], op2, mode);
4200 create_input_operand (&ops[3], op3, mode);
4201 if (maybe_expand_insn (icode, 4, ops))
4203 if (ops[0].value != target)
4204 convert_move (target, ops[0].value, false);
4205 return target;
4208 delete_insns_since (last);
4209 restore_pending_stack_adjust (&save);
4210 return NULL_RTX;
4213 /* Emit a conditional addition instruction if the machine supports one for that
4214 condition and machine mode.
4216 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4217 the mode to use should they be constants. If it is VOIDmode, they cannot
4218 both be constants.
4220 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4221 should be stored there. MODE is the mode to use should they be constants.
4222 If it is VOIDmode, they cannot both be constants.
4224 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4225 is not supported. */
4228 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4229 machine_mode cmode, rtx op2, rtx op3,
4230 machine_mode mode, int unsignedp)
4232 rtx comparison;
4233 rtx_insn *last;
4234 enum insn_code icode;
4236 /* If one operand is constant, make it the second one. Only do this
4237 if the other operand is not constant as well. */
4239 if (swap_commutative_operands_p (op0, op1))
4241 std::swap (op0, op1);
4242 code = swap_condition (code);
4245 /* get_condition will prefer to generate LT and GT even if the old
4246 comparison was against zero, so undo that canonicalization here since
4247 comparisons against zero are cheaper. */
4248 if (code == LT && op1 == const1_rtx)
4249 code = LE, op1 = const0_rtx;
4250 else if (code == GT && op1 == constm1_rtx)
4251 code = GE, op1 = const0_rtx;
4253 if (cmode == VOIDmode)
4254 cmode = GET_MODE (op0);
4256 if (mode == VOIDmode)
4257 mode = GET_MODE (op2);
4259 icode = optab_handler (addcc_optab, mode);
4261 if (icode == CODE_FOR_nothing)
4262 return 0;
4264 if (!target)
4265 target = gen_reg_rtx (mode);
4267 code = unsignedp ? unsigned_condition (code) : code;
4268 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4270 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4271 return NULL and let the caller figure out how best to deal with this
4272 situation. */
4273 if (!COMPARISON_P (comparison))
4274 return NULL_RTX;
4276 do_pending_stack_adjust ();
4277 last = get_last_insn ();
4278 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4279 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4280 &comparison, &cmode);
4281 if (comparison)
4283 struct expand_operand ops[4];
4285 create_output_operand (&ops[0], target, mode);
4286 create_fixed_operand (&ops[1], comparison);
4287 create_input_operand (&ops[2], op2, mode);
4288 create_input_operand (&ops[3], op3, mode);
4289 if (maybe_expand_insn (icode, 4, ops))
4291 if (ops[0].value != target)
4292 convert_move (target, ops[0].value, false);
4293 return target;
4296 delete_insns_since (last);
4297 return NULL_RTX;
4300 /* These functions attempt to generate an insn body, rather than
4301 emitting the insn, but if the gen function already emits them, we
4302 make no attempt to turn them back into naked patterns. */
4304 /* Generate and return an insn body to add Y to X. */
4306 rtx_insn *
4307 gen_add2_insn (rtx x, rtx y)
4309 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4311 gcc_assert (insn_operand_matches (icode, 0, x));
4312 gcc_assert (insn_operand_matches (icode, 1, x));
4313 gcc_assert (insn_operand_matches (icode, 2, y));
4315 return GEN_FCN (icode) (x, x, y);
4318 /* Generate and return an insn body to add r1 and c,
4319 storing the result in r0. */
4321 rtx_insn *
4322 gen_add3_insn (rtx r0, rtx r1, rtx c)
4324 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4326 if (icode == CODE_FOR_nothing
4327 || !insn_operand_matches (icode, 0, r0)
4328 || !insn_operand_matches (icode, 1, r1)
4329 || !insn_operand_matches (icode, 2, c))
4330 return NULL;
4332 return GEN_FCN (icode) (r0, r1, c);
4336 have_add2_insn (rtx x, rtx y)
4338 enum insn_code icode;
4340 gcc_assert (GET_MODE (x) != VOIDmode);
4342 icode = optab_handler (add_optab, GET_MODE (x));
4344 if (icode == CODE_FOR_nothing)
4345 return 0;
4347 if (!insn_operand_matches (icode, 0, x)
4348 || !insn_operand_matches (icode, 1, x)
4349 || !insn_operand_matches (icode, 2, y))
4350 return 0;
4352 return 1;
4355 /* Generate and return an insn body to add Y to X. */
4357 rtx_insn *
4358 gen_addptr3_insn (rtx x, rtx y, rtx z)
4360 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4362 gcc_assert (insn_operand_matches (icode, 0, x));
4363 gcc_assert (insn_operand_matches (icode, 1, y));
4364 gcc_assert (insn_operand_matches (icode, 2, z));
4366 return GEN_FCN (icode) (x, y, z);
4369 /* Return true if the target implements an addptr pattern and X, Y,
4370 and Z are valid for the pattern predicates. */
4373 have_addptr3_insn (rtx x, rtx y, rtx z)
4375 enum insn_code icode;
4377 gcc_assert (GET_MODE (x) != VOIDmode);
4379 icode = optab_handler (addptr3_optab, GET_MODE (x));
4381 if (icode == CODE_FOR_nothing)
4382 return 0;
4384 if (!insn_operand_matches (icode, 0, x)
4385 || !insn_operand_matches (icode, 1, y)
4386 || !insn_operand_matches (icode, 2, z))
4387 return 0;
4389 return 1;
4392 /* Generate and return an insn body to subtract Y from X. */
4394 rtx_insn *
4395 gen_sub2_insn (rtx x, rtx y)
4397 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4399 gcc_assert (insn_operand_matches (icode, 0, x));
4400 gcc_assert (insn_operand_matches (icode, 1, x));
4401 gcc_assert (insn_operand_matches (icode, 2, y));
4403 return GEN_FCN (icode) (x, x, y);
4406 /* Generate and return an insn body to subtract r1 and c,
4407 storing the result in r0. */
4409 rtx_insn *
4410 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4412 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4414 if (icode == CODE_FOR_nothing
4415 || !insn_operand_matches (icode, 0, r0)
4416 || !insn_operand_matches (icode, 1, r1)
4417 || !insn_operand_matches (icode, 2, c))
4418 return NULL;
4420 return GEN_FCN (icode) (r0, r1, c);
4424 have_sub2_insn (rtx x, rtx y)
4426 enum insn_code icode;
4428 gcc_assert (GET_MODE (x) != VOIDmode);
4430 icode = optab_handler (sub_optab, GET_MODE (x));
4432 if (icode == CODE_FOR_nothing)
4433 return 0;
4435 if (!insn_operand_matches (icode, 0, x)
4436 || !insn_operand_matches (icode, 1, x)
4437 || !insn_operand_matches (icode, 2, y))
4438 return 0;
4440 return 1;
4443 /* Generate the body of an insn to extend Y (with mode MFROM)
4444 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4446 rtx_insn *
4447 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4448 machine_mode mfrom, int unsignedp)
4450 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4451 return GEN_FCN (icode) (x, y);
4454 /* Generate code to convert FROM to floating point
4455 and store in TO. FROM must be fixed point and not VOIDmode.
4456 UNSIGNEDP nonzero means regard FROM as unsigned.
4457 Normally this is done by correcting the final value
4458 if it is negative. */
4460 void
4461 expand_float (rtx to, rtx from, int unsignedp)
4463 enum insn_code icode;
4464 rtx target = to;
4465 machine_mode fmode, imode;
4466 bool can_do_signed = false;
4468 /* Crash now, because we won't be able to decide which mode to use. */
4469 gcc_assert (GET_MODE (from) != VOIDmode);
4471 /* Look for an insn to do the conversion. Do it in the specified
4472 modes if possible; otherwise convert either input, output or both to
4473 wider mode. If the integer mode is wider than the mode of FROM,
4474 we can do the conversion signed even if the input is unsigned. */
4476 for (fmode = GET_MODE (to); fmode != VOIDmode;
4477 fmode = GET_MODE_WIDER_MODE (fmode))
4478 for (imode = GET_MODE (from); imode != VOIDmode;
4479 imode = GET_MODE_WIDER_MODE (imode))
4481 int doing_unsigned = unsignedp;
4483 if (fmode != GET_MODE (to)
4484 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
4485 continue;
4487 icode = can_float_p (fmode, imode, unsignedp);
4488 if (icode == CODE_FOR_nothing && unsignedp)
4490 enum insn_code scode = can_float_p (fmode, imode, 0);
4491 if (scode != CODE_FOR_nothing)
4492 can_do_signed = true;
4493 if (imode != GET_MODE (from))
4494 icode = scode, doing_unsigned = 0;
4497 if (icode != CODE_FOR_nothing)
4499 if (imode != GET_MODE (from))
4500 from = convert_to_mode (imode, from, unsignedp);
4502 if (fmode != GET_MODE (to))
4503 target = gen_reg_rtx (fmode);
4505 emit_unop_insn (icode, target, from,
4506 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4508 if (target != to)
4509 convert_move (to, target, 0);
4510 return;
4514 /* Unsigned integer, and no way to convert directly. Convert as signed,
4515 then unconditionally adjust the result. */
4516 if (unsignedp && can_do_signed)
4518 rtx_code_label *label = gen_label_rtx ();
4519 rtx temp;
4520 REAL_VALUE_TYPE offset;
4522 /* Look for a usable floating mode FMODE wider than the source and at
4523 least as wide as the target. Using FMODE will avoid rounding woes
4524 with unsigned values greater than the signed maximum value. */
4526 for (fmode = GET_MODE (to); fmode != VOIDmode;
4527 fmode = GET_MODE_WIDER_MODE (fmode))
4528 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4529 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4530 break;
4532 if (fmode == VOIDmode)
4534 /* There is no such mode. Pretend the target is wide enough. */
4535 fmode = GET_MODE (to);
4537 /* Avoid double-rounding when TO is narrower than FROM. */
4538 if ((significand_size (fmode) + 1)
4539 < GET_MODE_PRECISION (GET_MODE (from)))
4541 rtx temp1;
4542 rtx_code_label *neglabel = gen_label_rtx ();
4544 /* Don't use TARGET if it isn't a register, is a hard register,
4545 or is the wrong mode. */
4546 if (!REG_P (target)
4547 || REGNO (target) < FIRST_PSEUDO_REGISTER
4548 || GET_MODE (target) != fmode)
4549 target = gen_reg_rtx (fmode);
4551 imode = GET_MODE (from);
4552 do_pending_stack_adjust ();
4554 /* Test whether the sign bit is set. */
4555 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4556 0, neglabel);
4558 /* The sign bit is not set. Convert as signed. */
4559 expand_float (target, from, 0);
4560 emit_jump_insn (targetm.gen_jump (label));
4561 emit_barrier ();
4563 /* The sign bit is set.
4564 Convert to a usable (positive signed) value by shifting right
4565 one bit, while remembering if a nonzero bit was shifted
4566 out; i.e., compute (from & 1) | (from >> 1). */
4568 emit_label (neglabel);
4569 temp = expand_binop (imode, and_optab, from, const1_rtx,
4570 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4571 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4572 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4573 OPTAB_LIB_WIDEN);
4574 expand_float (target, temp, 0);
4576 /* Multiply by 2 to undo the shift above. */
4577 temp = expand_binop (fmode, add_optab, target, target,
4578 target, 0, OPTAB_LIB_WIDEN);
4579 if (temp != target)
4580 emit_move_insn (target, temp);
4582 do_pending_stack_adjust ();
4583 emit_label (label);
4584 goto done;
4588 /* If we are about to do some arithmetic to correct for an
4589 unsigned operand, do it in a pseudo-register. */
4591 if (GET_MODE (to) != fmode
4592 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4593 target = gen_reg_rtx (fmode);
4595 /* Convert as signed integer to floating. */
4596 expand_float (target, from, 0);
4598 /* If FROM is negative (and therefore TO is negative),
4599 correct its value by 2**bitwidth. */
4601 do_pending_stack_adjust ();
4602 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4603 0, label);
4606 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
4607 temp = expand_binop (fmode, add_optab, target,
4608 const_double_from_real_value (offset, fmode),
4609 target, 0, OPTAB_LIB_WIDEN);
4610 if (temp != target)
4611 emit_move_insn (target, temp);
4613 do_pending_stack_adjust ();
4614 emit_label (label);
4615 goto done;
4618 /* No hardware instruction available; call a library routine. */
4620 rtx libfunc;
4621 rtx_insn *insns;
4622 rtx value;
4623 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4625 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_PRECISION (SImode))
4626 from = convert_to_mode (SImode, from, unsignedp);
4628 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4629 gcc_assert (libfunc);
4631 start_sequence ();
4633 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4634 GET_MODE (to), 1, from,
4635 GET_MODE (from));
4636 insns = get_insns ();
4637 end_sequence ();
4639 emit_libcall_block (insns, target, value,
4640 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4641 GET_MODE (to), from));
4644 done:
4646 /* Copy result to requested destination
4647 if we have been computing in a temp location. */
4649 if (target != to)
4651 if (GET_MODE (target) == GET_MODE (to))
4652 emit_move_insn (to, target);
4653 else
4654 convert_move (to, target, 0);
4658 /* Generate code to convert FROM to fixed point and store in TO. FROM
4659 must be floating point. */
4661 void
4662 expand_fix (rtx to, rtx from, int unsignedp)
4664 enum insn_code icode;
4665 rtx target = to;
4666 machine_mode fmode, imode;
4667 bool must_trunc = false;
4669 /* We first try to find a pair of modes, one real and one integer, at
4670 least as wide as FROM and TO, respectively, in which we can open-code
4671 this conversion. If the integer mode is wider than the mode of TO,
4672 we can do the conversion either signed or unsigned. */
4674 for (fmode = GET_MODE (from); fmode != VOIDmode;
4675 fmode = GET_MODE_WIDER_MODE (fmode))
4676 for (imode = GET_MODE (to); imode != VOIDmode;
4677 imode = GET_MODE_WIDER_MODE (imode))
4679 int doing_unsigned = unsignedp;
4681 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4682 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4683 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4685 if (icode != CODE_FOR_nothing)
4687 rtx_insn *last = get_last_insn ();
4688 if (fmode != GET_MODE (from))
4689 from = convert_to_mode (fmode, from, 0);
4691 if (must_trunc)
4693 rtx temp = gen_reg_rtx (GET_MODE (from));
4694 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4695 temp, 0);
4698 if (imode != GET_MODE (to))
4699 target = gen_reg_rtx (imode);
4701 if (maybe_emit_unop_insn (icode, target, from,
4702 doing_unsigned ? UNSIGNED_FIX : FIX))
4704 if (target != to)
4705 convert_move (to, target, unsignedp);
4706 return;
4708 delete_insns_since (last);
4712 /* For an unsigned conversion, there is one more way to do it.
4713 If we have a signed conversion, we generate code that compares
4714 the real value to the largest representable positive number. If if
4715 is smaller, the conversion is done normally. Otherwise, subtract
4716 one plus the highest signed number, convert, and add it back.
4718 We only need to check all real modes, since we know we didn't find
4719 anything with a wider integer mode.
4721 This code used to extend FP value into mode wider than the destination.
4722 This is needed for decimal float modes which cannot accurately
4723 represent one plus the highest signed number of the same size, but
4724 not for binary modes. Consider, for instance conversion from SFmode
4725 into DImode.
4727 The hot path through the code is dealing with inputs smaller than 2^63
4728 and doing just the conversion, so there is no bits to lose.
4730 In the other path we know the value is positive in the range 2^63..2^64-1
4731 inclusive. (as for other input overflow happens and result is undefined)
4732 So we know that the most important bit set in mantissa corresponds to
4733 2^63. The subtraction of 2^63 should not generate any rounding as it
4734 simply clears out that bit. The rest is trivial. */
4736 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4737 for (fmode = GET_MODE (from); fmode != VOIDmode;
4738 fmode = GET_MODE_WIDER_MODE (fmode))
4739 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
4740 && (!DECIMAL_FLOAT_MODE_P (fmode)
4741 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
4743 int bitsize;
4744 REAL_VALUE_TYPE offset;
4745 rtx limit;
4746 rtx_code_label *lab1, *lab2;
4747 rtx_insn *insn;
4749 bitsize = GET_MODE_PRECISION (GET_MODE (to));
4750 real_2expN (&offset, bitsize - 1, fmode);
4751 limit = const_double_from_real_value (offset, fmode);
4752 lab1 = gen_label_rtx ();
4753 lab2 = gen_label_rtx ();
4755 if (fmode != GET_MODE (from))
4756 from = convert_to_mode (fmode, from, 0);
4758 /* See if we need to do the subtraction. */
4759 do_pending_stack_adjust ();
4760 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4761 0, lab1);
4763 /* If not, do the signed "fix" and branch around fixup code. */
4764 expand_fix (to, from, 0);
4765 emit_jump_insn (targetm.gen_jump (lab2));
4766 emit_barrier ();
4768 /* Otherwise, subtract 2**(N-1), convert to signed number,
4769 then add 2**(N-1). Do the addition using XOR since this
4770 will often generate better code. */
4771 emit_label (lab1);
4772 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4773 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4774 expand_fix (to, target, 0);
4775 target = expand_binop (GET_MODE (to), xor_optab, to,
4776 gen_int_mode
4777 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4778 GET_MODE (to)),
4779 to, 1, OPTAB_LIB_WIDEN);
4781 if (target != to)
4782 emit_move_insn (to, target);
4784 emit_label (lab2);
4786 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
4788 /* Make a place for a REG_NOTE and add it. */
4789 insn = emit_move_insn (to, to);
4790 set_dst_reg_note (insn, REG_EQUAL,
4791 gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
4792 copy_rtx (from)),
4793 to);
4796 return;
4799 /* We can't do it with an insn, so use a library call. But first ensure
4800 that the mode of TO is at least as wide as SImode, since those are the
4801 only library calls we know about. */
4803 if (GET_MODE_PRECISION (GET_MODE (to)) < GET_MODE_PRECISION (SImode))
4805 target = gen_reg_rtx (SImode);
4807 expand_fix (target, from, unsignedp);
4809 else
4811 rtx_insn *insns;
4812 rtx value;
4813 rtx libfunc;
4815 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4816 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4817 gcc_assert (libfunc);
4819 start_sequence ();
4821 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4822 GET_MODE (to), 1, from,
4823 GET_MODE (from));
4824 insns = get_insns ();
4825 end_sequence ();
4827 emit_libcall_block (insns, target, value,
4828 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4829 GET_MODE (to), from));
4832 if (target != to)
4834 if (GET_MODE (to) == GET_MODE (target))
4835 emit_move_insn (to, target);
4836 else
4837 convert_move (to, target, 0);
4841 /* Generate code to convert FROM or TO a fixed-point.
4842 If UINTP is true, either TO or FROM is an unsigned integer.
4843 If SATP is true, we need to saturate the result. */
4845 void
4846 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
4848 machine_mode to_mode = GET_MODE (to);
4849 machine_mode from_mode = GET_MODE (from);
4850 convert_optab tab;
4851 enum rtx_code this_code;
4852 enum insn_code code;
4853 rtx_insn *insns;
4854 rtx value;
4855 rtx libfunc;
4857 if (to_mode == from_mode)
4859 emit_move_insn (to, from);
4860 return;
4863 if (uintp)
4865 tab = satp ? satfractuns_optab : fractuns_optab;
4866 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
4868 else
4870 tab = satp ? satfract_optab : fract_optab;
4871 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
4873 code = convert_optab_handler (tab, to_mode, from_mode);
4874 if (code != CODE_FOR_nothing)
4876 emit_unop_insn (code, to, from, this_code);
4877 return;
4880 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
4881 gcc_assert (libfunc);
4883 start_sequence ();
4884 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
4885 1, from, from_mode);
4886 insns = get_insns ();
4887 end_sequence ();
4889 emit_libcall_block (insns, to, value,
4890 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
4893 /* Generate code to convert FROM to fixed point and store in TO. FROM
4894 must be floating point, TO must be signed. Use the conversion optab
4895 TAB to do the conversion. */
4897 bool
4898 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
4900 enum insn_code icode;
4901 rtx target = to;
4902 machine_mode fmode, imode;
4904 /* We first try to find a pair of modes, one real and one integer, at
4905 least as wide as FROM and TO, respectively, in which we can open-code
4906 this conversion. If the integer mode is wider than the mode of TO,
4907 we can do the conversion either signed or unsigned. */
4909 for (fmode = GET_MODE (from); fmode != VOIDmode;
4910 fmode = GET_MODE_WIDER_MODE (fmode))
4911 for (imode = GET_MODE (to); imode != VOIDmode;
4912 imode = GET_MODE_WIDER_MODE (imode))
4914 icode = convert_optab_handler (tab, imode, fmode);
4915 if (icode != CODE_FOR_nothing)
4917 rtx_insn *last = get_last_insn ();
4918 if (fmode != GET_MODE (from))
4919 from = convert_to_mode (fmode, from, 0);
4921 if (imode != GET_MODE (to))
4922 target = gen_reg_rtx (imode);
4924 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
4926 delete_insns_since (last);
4927 continue;
4929 if (target != to)
4930 convert_move (to, target, 0);
4931 return true;
4935 return false;
4938 /* Report whether we have an instruction to perform the operation
4939 specified by CODE on operands of mode MODE. */
4941 have_insn_for (enum rtx_code code, machine_mode mode)
4943 return (code_to_optab (code)
4944 && (optab_handler (code_to_optab (code), mode)
4945 != CODE_FOR_nothing));
4948 /* Print information about the current contents of the optabs on
4949 STDERR. */
4951 DEBUG_FUNCTION void
4952 debug_optab_libfuncs (void)
4954 int i, j, k;
4956 /* Dump the arithmetic optabs. */
4957 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
4958 for (j = 0; j < NUM_MACHINE_MODES; ++j)
4960 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
4961 if (l)
4963 gcc_assert (GET_CODE (l) == SYMBOL_REF);
4964 fprintf (stderr, "%s\t%s:\t%s\n",
4965 GET_RTX_NAME (optab_to_code ((optab) i)),
4966 GET_MODE_NAME (j),
4967 XSTR (l, 0));
4971 /* Dump the conversion optabs. */
4972 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
4973 for (j = 0; j < NUM_MACHINE_MODES; ++j)
4974 for (k = 0; k < NUM_MACHINE_MODES; ++k)
4976 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
4977 (machine_mode) k);
4978 if (l)
4980 gcc_assert (GET_CODE (l) == SYMBOL_REF);
4981 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
4982 GET_RTX_NAME (optab_to_code ((optab) i)),
4983 GET_MODE_NAME (j),
4984 GET_MODE_NAME (k),
4985 XSTR (l, 0));
4990 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4991 CODE. Return 0 on failure. */
4993 rtx_insn *
4994 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
4996 machine_mode mode = GET_MODE (op1);
4997 enum insn_code icode;
4998 rtx_insn *insn;
4999 rtx trap_rtx;
5001 if (mode == VOIDmode)
5002 return 0;
5004 icode = optab_handler (ctrap_optab, mode);
5005 if (icode == CODE_FOR_nothing)
5006 return 0;
5008 /* Some targets only accept a zero trap code. */
5009 if (!insn_operand_matches (icode, 3, tcode))
5010 return 0;
5012 do_pending_stack_adjust ();
5013 start_sequence ();
5014 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5015 &trap_rtx, &mode);
5016 if (!trap_rtx)
5017 insn = NULL;
5018 else
5019 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5020 tcode);
5022 /* If that failed, then give up. */
5023 if (insn == 0)
5025 end_sequence ();
5026 return 0;
5029 emit_insn (insn);
5030 insn = get_insns ();
5031 end_sequence ();
5032 return insn;
5035 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5036 or unsigned operation code. */
5038 enum rtx_code
5039 get_rtx_code (enum tree_code tcode, bool unsignedp)
5041 enum rtx_code code;
5042 switch (tcode)
5044 case EQ_EXPR:
5045 code = EQ;
5046 break;
5047 case NE_EXPR:
5048 code = NE;
5049 break;
5050 case LT_EXPR:
5051 code = unsignedp ? LTU : LT;
5052 break;
5053 case LE_EXPR:
5054 code = unsignedp ? LEU : LE;
5055 break;
5056 case GT_EXPR:
5057 code = unsignedp ? GTU : GT;
5058 break;
5059 case GE_EXPR:
5060 code = unsignedp ? GEU : GE;
5061 break;
5063 case UNORDERED_EXPR:
5064 code = UNORDERED;
5065 break;
5066 case ORDERED_EXPR:
5067 code = ORDERED;
5068 break;
5069 case UNLT_EXPR:
5070 code = UNLT;
5071 break;
5072 case UNLE_EXPR:
5073 code = UNLE;
5074 break;
5075 case UNGT_EXPR:
5076 code = UNGT;
5077 break;
5078 case UNGE_EXPR:
5079 code = UNGE;
5080 break;
5081 case UNEQ_EXPR:
5082 code = UNEQ;
5083 break;
5084 case LTGT_EXPR:
5085 code = LTGT;
5086 break;
5088 case BIT_AND_EXPR:
5089 code = AND;
5090 break;
5092 case BIT_IOR_EXPR:
5093 code = IOR;
5094 break;
5096 default:
5097 gcc_unreachable ();
5099 return code;
5102 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5103 unsigned operators. Do not generate compare instruction. */
5105 static rtx
5106 vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
5107 bool unsignedp, enum insn_code icode)
5109 struct expand_operand ops[2];
5110 rtx rtx_op0, rtx_op1;
5111 machine_mode m0, m1;
5112 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5114 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5116 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5117 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5118 cases, use the original mode. */
5119 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5120 EXPAND_STACK_PARM);
5121 m0 = GET_MODE (rtx_op0);
5122 if (m0 == VOIDmode)
5123 m0 = TYPE_MODE (TREE_TYPE (t_op0));
5125 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5126 EXPAND_STACK_PARM);
5127 m1 = GET_MODE (rtx_op1);
5128 if (m1 == VOIDmode)
5129 m1 = TYPE_MODE (TREE_TYPE (t_op1));
5131 create_input_operand (&ops[0], rtx_op0, m0);
5132 create_input_operand (&ops[1], rtx_op1, m1);
5133 if (!maybe_legitimize_operands (icode, 4, 2, ops))
5134 gcc_unreachable ();
5135 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
5138 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
5139 vec_perm operand, assuming the second operand is a constant vector of zeroes.
5140 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
5141 shift. */
5142 static rtx
5143 shift_amt_for_vec_perm_mask (rtx sel)
5145 unsigned int i, first, nelt = GET_MODE_NUNITS (GET_MODE (sel));
5146 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (GET_MODE (sel));
5148 if (GET_CODE (sel) != CONST_VECTOR)
5149 return NULL_RTX;
5151 first = INTVAL (CONST_VECTOR_ELT (sel, 0));
5152 if (first >= 2*nelt)
5153 return NULL_RTX;
5154 for (i = 1; i < nelt; i++)
5156 int idx = INTVAL (CONST_VECTOR_ELT (sel, i));
5157 unsigned int expected = (i + first) & (2 * nelt - 1);
5158 /* Indices into the second vector are all equivalent. */
5159 if (idx < 0 || (MIN (nelt, (unsigned) idx) != MIN (nelt, expected)))
5160 return NULL_RTX;
5163 return GEN_INT (first * bitsize);
5166 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
5168 static rtx
5169 expand_vec_perm_1 (enum insn_code icode, rtx target,
5170 rtx v0, rtx v1, rtx sel)
5172 machine_mode tmode = GET_MODE (target);
5173 machine_mode smode = GET_MODE (sel);
5174 struct expand_operand ops[4];
5176 create_output_operand (&ops[0], target, tmode);
5177 create_input_operand (&ops[3], sel, smode);
5179 /* Make an effort to preserve v0 == v1. The target expander is able to
5180 rely on this to determine if we're permuting a single input operand. */
5181 if (rtx_equal_p (v0, v1))
5183 if (!insn_operand_matches (icode, 1, v0))
5184 v0 = force_reg (tmode, v0);
5185 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5186 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5188 create_fixed_operand (&ops[1], v0);
5189 create_fixed_operand (&ops[2], v0);
5191 else
5193 create_input_operand (&ops[1], v0, tmode);
5194 /* See if this can be handled with a vec_shr. We only do this if the
5195 second vector is all zeroes. */
5196 enum insn_code shift_code = optab_handler (vec_shr_optab, GET_MODE (v0));
5197 if (v1 == CONST0_RTX (GET_MODE (v1)) && shift_code)
5198 if (rtx shift_amt = shift_amt_for_vec_perm_mask (sel))
5200 create_convert_operand_from_type (&ops[2], shift_amt,
5201 sizetype_tab[(int) stk_sizetype]);
5202 if (maybe_expand_insn (shift_code, 3, ops))
5203 return ops[0].value;
5205 create_input_operand (&ops[2], v1, tmode);
5208 if (maybe_expand_insn (icode, 4, ops))
5209 return ops[0].value;
5210 return NULL_RTX;
5213 /* Generate instructions for vec_perm optab given its mode
5214 and three operands. */
5217 expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
5219 enum insn_code icode;
5220 machine_mode qimode;
5221 unsigned int i, w, e, u;
5222 rtx tmp, sel_qi = NULL;
5223 rtvec vec;
5225 if (!target || GET_MODE (target) != mode)
5226 target = gen_reg_rtx (mode);
5228 w = GET_MODE_SIZE (mode);
5229 e = GET_MODE_NUNITS (mode);
5230 u = GET_MODE_UNIT_SIZE (mode);
5232 /* Set QIMODE to a different vector mode with byte elements.
5233 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5234 qimode = VOIDmode;
5235 if (GET_MODE_INNER (mode) != QImode)
5237 qimode = mode_for_vector (QImode, w);
5238 if (!VECTOR_MODE_P (qimode))
5239 qimode = VOIDmode;
5242 /* If the input is a constant, expand it specially. */
5243 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
5244 if (GET_CODE (sel) == CONST_VECTOR)
5246 icode = direct_optab_handler (vec_perm_const_optab, mode);
5247 if (icode != CODE_FOR_nothing)
5249 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5250 if (tmp)
5251 return tmp;
5254 /* Fall back to a constant byte-based permutation. */
5255 if (qimode != VOIDmode)
5257 vec = rtvec_alloc (w);
5258 for (i = 0; i < e; ++i)
5260 unsigned int j, this_e;
5262 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
5263 this_e &= 2 * e - 1;
5264 this_e *= u;
5266 for (j = 0; j < u; ++j)
5267 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
5269 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
5271 icode = direct_optab_handler (vec_perm_const_optab, qimode);
5272 if (icode != CODE_FOR_nothing)
5274 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5275 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5276 gen_lowpart (qimode, v1), sel_qi);
5277 if (tmp)
5278 return gen_lowpart (mode, tmp);
5283 /* Otherwise expand as a fully variable permuation. */
5284 icode = direct_optab_handler (vec_perm_optab, mode);
5285 if (icode != CODE_FOR_nothing)
5287 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5288 if (tmp)
5289 return tmp;
5292 /* As a special case to aid several targets, lower the element-based
5293 permutation to a byte-based permutation and try again. */
5294 if (qimode == VOIDmode)
5295 return NULL_RTX;
5296 icode = direct_optab_handler (vec_perm_optab, qimode);
5297 if (icode == CODE_FOR_nothing)
5298 return NULL_RTX;
5300 if (sel_qi == NULL)
5302 /* Multiply each element by its byte size. */
5303 machine_mode selmode = GET_MODE (sel);
5304 if (u == 2)
5305 sel = expand_simple_binop (selmode, PLUS, sel, sel,
5306 NULL, 0, OPTAB_DIRECT);
5307 else
5308 sel = expand_simple_binop (selmode, ASHIFT, sel,
5309 GEN_INT (exact_log2 (u)),
5310 NULL, 0, OPTAB_DIRECT);
5311 gcc_assert (sel != NULL);
5313 /* Broadcast the low byte each element into each of its bytes. */
5314 vec = rtvec_alloc (w);
5315 for (i = 0; i < w; ++i)
5317 int this_e = i / u * u;
5318 if (BYTES_BIG_ENDIAN)
5319 this_e += u - 1;
5320 RTVEC_ELT (vec, i) = GEN_INT (this_e);
5322 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5323 sel = gen_lowpart (qimode, sel);
5324 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
5325 gcc_assert (sel != NULL);
5327 /* Add the byte offset to each byte element. */
5328 /* Note that the definition of the indicies here is memory ordering,
5329 so there should be no difference between big and little endian. */
5330 vec = rtvec_alloc (w);
5331 for (i = 0; i < w; ++i)
5332 RTVEC_ELT (vec, i) = GEN_INT (i % u);
5333 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5334 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
5335 sel, 0, OPTAB_DIRECT);
5336 gcc_assert (sel_qi != NULL);
5339 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5340 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5341 gen_lowpart (qimode, v1), sel_qi);
5342 if (tmp)
5343 tmp = gen_lowpart (mode, tmp);
5344 return tmp;
5347 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5348 three operands. */
5351 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5352 rtx target)
5354 struct expand_operand ops[6];
5355 enum insn_code icode;
5356 rtx comparison, rtx_op1, rtx_op2;
5357 machine_mode mode = TYPE_MODE (vec_cond_type);
5358 machine_mode cmp_op_mode;
5359 bool unsignedp;
5360 tree op0a, op0b;
5361 enum tree_code tcode;
5363 if (COMPARISON_CLASS_P (op0))
5365 op0a = TREE_OPERAND (op0, 0);
5366 op0b = TREE_OPERAND (op0, 1);
5367 tcode = TREE_CODE (op0);
5369 else
5371 /* Fake op0 < 0. */
5372 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
5373 op0a = op0;
5374 op0b = build_zero_cst (TREE_TYPE (op0));
5375 tcode = LT_EXPR;
5377 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
5378 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5381 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
5382 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
5384 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
5385 if (icode == CODE_FOR_nothing)
5386 return 0;
5388 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
5389 rtx_op1 = expand_normal (op1);
5390 rtx_op2 = expand_normal (op2);
5392 create_output_operand (&ops[0], target, mode);
5393 create_input_operand (&ops[1], rtx_op1, mode);
5394 create_input_operand (&ops[2], rtx_op2, mode);
5395 create_fixed_operand (&ops[3], comparison);
5396 create_fixed_operand (&ops[4], XEXP (comparison, 0));
5397 create_fixed_operand (&ops[5], XEXP (comparison, 1));
5398 expand_insn (icode, 6, ops);
5399 return ops[0].value;
5402 /* Expand a highpart multiply. */
5405 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
5406 rtx target, bool uns_p)
5408 struct expand_operand eops[3];
5409 enum insn_code icode;
5410 int method, i, nunits;
5411 machine_mode wmode;
5412 rtx m1, m2, perm;
5413 optab tab1, tab2;
5414 rtvec v;
5416 method = can_mult_highpart_p (mode, uns_p);
5417 switch (method)
5419 case 0:
5420 return NULL_RTX;
5421 case 1:
5422 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
5423 return expand_binop (mode, tab1, op0, op1, target, uns_p,
5424 OPTAB_LIB_WIDEN);
5425 case 2:
5426 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
5427 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
5428 break;
5429 case 3:
5430 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
5431 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
5432 if (BYTES_BIG_ENDIAN)
5433 std::swap (tab1, tab2);
5434 break;
5435 default:
5436 gcc_unreachable ();
5439 icode = optab_handler (tab1, mode);
5440 nunits = GET_MODE_NUNITS (mode);
5441 wmode = insn_data[icode].operand[0].mode;
5442 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
5443 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
5445 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5446 create_input_operand (&eops[1], op0, mode);
5447 create_input_operand (&eops[2], op1, mode);
5448 expand_insn (icode, 3, eops);
5449 m1 = gen_lowpart (mode, eops[0].value);
5451 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5452 create_input_operand (&eops[1], op0, mode);
5453 create_input_operand (&eops[2], op1, mode);
5454 expand_insn (optab_handler (tab2, mode), 3, eops);
5455 m2 = gen_lowpart (mode, eops[0].value);
5457 v = rtvec_alloc (nunits);
5458 if (method == 2)
5460 for (i = 0; i < nunits; ++i)
5461 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
5462 + ((i & 1) ? nunits : 0));
5464 else
5466 for (i = 0; i < nunits; ++i)
5467 RTVEC_ELT (v, i) = GEN_INT (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
5469 perm = gen_rtx_CONST_VECTOR (mode, v);
5471 return expand_vec_perm (mode, m1, m2, perm, target);
5474 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5475 pattern. */
5477 static void
5478 find_cc_set (rtx x, const_rtx pat, void *data)
5480 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
5481 && GET_CODE (pat) == SET)
5483 rtx *p_cc_reg = (rtx *) data;
5484 gcc_assert (!*p_cc_reg);
5485 *p_cc_reg = x;
5489 /* This is a helper function for the other atomic operations. This function
5490 emits a loop that contains SEQ that iterates until a compare-and-swap
5491 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5492 a set of instructions that takes a value from OLD_REG as an input and
5493 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5494 set to the current contents of MEM. After SEQ, a compare-and-swap will
5495 attempt to update MEM with NEW_REG. The function returns true when the
5496 loop was generated successfully. */
5498 static bool
5499 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5501 machine_mode mode = GET_MODE (mem);
5502 rtx_code_label *label;
5503 rtx cmp_reg, success, oldval;
5505 /* The loop we want to generate looks like
5507 cmp_reg = mem;
5508 label:
5509 old_reg = cmp_reg;
5510 seq;
5511 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5512 if (success)
5513 goto label;
5515 Note that we only do the plain load from memory once. Subsequent
5516 iterations use the value loaded by the compare-and-swap pattern. */
5518 label = gen_label_rtx ();
5519 cmp_reg = gen_reg_rtx (mode);
5521 emit_move_insn (cmp_reg, mem);
5522 emit_label (label);
5523 emit_move_insn (old_reg, cmp_reg);
5524 if (seq)
5525 emit_insn (seq);
5527 success = NULL_RTX;
5528 oldval = cmp_reg;
5529 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
5530 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
5531 MEMMODEL_RELAXED))
5532 return false;
5534 if (oldval != cmp_reg)
5535 emit_move_insn (cmp_reg, oldval);
5537 /* Mark this jump predicted not taken. */
5538 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
5539 GET_MODE (success), 1, label, 0);
5540 return true;
5544 /* This function tries to emit an atomic_exchange intruction. VAL is written
5545 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
5546 using TARGET if possible. */
5548 static rtx
5549 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5551 machine_mode mode = GET_MODE (mem);
5552 enum insn_code icode;
5554 /* If the target supports the exchange directly, great. */
5555 icode = direct_optab_handler (atomic_exchange_optab, mode);
5556 if (icode != CODE_FOR_nothing)
5558 struct expand_operand ops[4];
5560 create_output_operand (&ops[0], target, mode);
5561 create_fixed_operand (&ops[1], mem);
5562 create_input_operand (&ops[2], val, mode);
5563 create_integer_operand (&ops[3], model);
5564 if (maybe_expand_insn (icode, 4, ops))
5565 return ops[0].value;
5568 return NULL_RTX;
5571 /* This function tries to implement an atomic exchange operation using
5572 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
5573 The previous contents of *MEM are returned, using TARGET if possible.
5574 Since this instructionn is an acquire barrier only, stronger memory
5575 models may require additional barriers to be emitted. */
5577 static rtx
5578 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
5579 enum memmodel model)
5581 machine_mode mode = GET_MODE (mem);
5582 enum insn_code icode;
5583 rtx_insn *last_insn = get_last_insn ();
5585 icode = optab_handler (sync_lock_test_and_set_optab, mode);
5587 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
5588 exists, and the memory model is stronger than acquire, add a release
5589 barrier before the instruction. */
5591 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
5592 expand_mem_thread_fence (model);
5594 if (icode != CODE_FOR_nothing)
5596 struct expand_operand ops[3];
5597 create_output_operand (&ops[0], target, mode);
5598 create_fixed_operand (&ops[1], mem);
5599 create_input_operand (&ops[2], val, mode);
5600 if (maybe_expand_insn (icode, 3, ops))
5601 return ops[0].value;
5604 /* If an external test-and-set libcall is provided, use that instead of
5605 any external compare-and-swap that we might get from the compare-and-
5606 swap-loop expansion later. */
5607 if (!can_compare_and_swap_p (mode, false))
5609 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
5610 if (libfunc != NULL)
5612 rtx addr;
5614 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5615 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5616 mode, 2, addr, ptr_mode,
5617 val, mode);
5621 /* If the test_and_set can't be emitted, eliminate any barrier that might
5622 have been emitted. */
5623 delete_insns_since (last_insn);
5624 return NULL_RTX;
5627 /* This function tries to implement an atomic exchange operation using a
5628 compare_and_swap loop. VAL is written to *MEM. The previous contents of
5629 *MEM are returned, using TARGET if possible. No memory model is required
5630 since a compare_and_swap loop is seq-cst. */
5632 static rtx
5633 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
5635 machine_mode mode = GET_MODE (mem);
5637 if (can_compare_and_swap_p (mode, true))
5639 if (!target || !register_operand (target, mode))
5640 target = gen_reg_rtx (mode);
5641 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
5642 return target;
5645 return NULL_RTX;
5648 /* This function tries to implement an atomic test-and-set operation
5649 using the atomic_test_and_set instruction pattern. A boolean value
5650 is returned from the operation, using TARGET if possible. */
5652 static rtx
5653 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5655 machine_mode pat_bool_mode;
5656 struct expand_operand ops[3];
5658 if (!targetm.have_atomic_test_and_set ())
5659 return NULL_RTX;
5661 /* While we always get QImode from __atomic_test_and_set, we get
5662 other memory modes from __sync_lock_test_and_set. Note that we
5663 use no endian adjustment here. This matches the 4.6 behavior
5664 in the Sparc backend. */
5665 enum insn_code icode = targetm.code_for_atomic_test_and_set;
5666 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
5667 if (GET_MODE (mem) != QImode)
5668 mem = adjust_address_nv (mem, QImode, 0);
5670 pat_bool_mode = insn_data[icode].operand[0].mode;
5671 create_output_operand (&ops[0], target, pat_bool_mode);
5672 create_fixed_operand (&ops[1], mem);
5673 create_integer_operand (&ops[2], model);
5675 if (maybe_expand_insn (icode, 3, ops))
5676 return ops[0].value;
5677 return NULL_RTX;
5680 /* This function expands the legacy _sync_lock test_and_set operation which is
5681 generally an atomic exchange. Some limited targets only allow the
5682 constant 1 to be stored. This is an ACQUIRE operation.
5684 TARGET is an optional place to stick the return value.
5685 MEM is where VAL is stored. */
5688 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
5690 rtx ret;
5692 /* Try an atomic_exchange first. */
5693 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
5694 if (ret)
5695 return ret;
5697 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
5698 MEMMODEL_SYNC_ACQUIRE);
5699 if (ret)
5700 return ret;
5702 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
5703 if (ret)
5704 return ret;
5706 /* If there are no other options, try atomic_test_and_set if the value
5707 being stored is 1. */
5708 if (val == const1_rtx)
5709 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
5711 return ret;
5714 /* This function expands the atomic test_and_set operation:
5715 atomically store a boolean TRUE into MEM and return the previous value.
5717 MEMMODEL is the memory model variant to use.
5718 TARGET is an optional place to stick the return value. */
5721 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5723 machine_mode mode = GET_MODE (mem);
5724 rtx ret, trueval, subtarget;
5726 ret = maybe_emit_atomic_test_and_set (target, mem, model);
5727 if (ret)
5728 return ret;
5730 /* Be binary compatible with non-default settings of trueval, and different
5731 cpu revisions. E.g. one revision may have atomic-test-and-set, but
5732 another only has atomic-exchange. */
5733 if (targetm.atomic_test_and_set_trueval == 1)
5735 trueval = const1_rtx;
5736 subtarget = target ? target : gen_reg_rtx (mode);
5738 else
5740 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
5741 subtarget = gen_reg_rtx (mode);
5744 /* Try the atomic-exchange optab... */
5745 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
5747 /* ... then an atomic-compare-and-swap loop ... */
5748 if (!ret)
5749 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
5751 /* ... before trying the vaguely defined legacy lock_test_and_set. */
5752 if (!ret)
5753 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
5755 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
5756 things with the value 1. Thus we try again without trueval. */
5757 if (!ret && targetm.atomic_test_and_set_trueval != 1)
5758 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
5760 /* Failing all else, assume a single threaded environment and simply
5761 perform the operation. */
5762 if (!ret)
5764 /* If the result is ignored skip the move to target. */
5765 if (subtarget != const0_rtx)
5766 emit_move_insn (subtarget, mem);
5768 emit_move_insn (mem, trueval);
5769 ret = subtarget;
5772 /* Recall that have to return a boolean value; rectify if trueval
5773 is not exactly one. */
5774 if (targetm.atomic_test_and_set_trueval != 1)
5775 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
5777 return ret;
5780 /* This function expands the atomic exchange operation:
5781 atomically store VAL in MEM and return the previous value in MEM.
5783 MEMMODEL is the memory model variant to use.
5784 TARGET is an optional place to stick the return value. */
5787 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5789 rtx ret;
5791 ret = maybe_emit_atomic_exchange (target, mem, val, model);
5793 /* Next try a compare-and-swap loop for the exchange. */
5794 if (!ret)
5795 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
5797 return ret;
5800 /* This function expands the atomic compare exchange operation:
5802 *PTARGET_BOOL is an optional place to store the boolean success/failure.
5803 *PTARGET_OVAL is an optional place to store the old value from memory.
5804 Both target parameters may be NULL or const0_rtx to indicate that we do
5805 not care about that return value. Both target parameters are updated on
5806 success to the actual location of the corresponding result.
5808 MEMMODEL is the memory model variant to use.
5810 The return value of the function is true for success. */
5812 bool
5813 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
5814 rtx mem, rtx expected, rtx desired,
5815 bool is_weak, enum memmodel succ_model,
5816 enum memmodel fail_model)
5818 machine_mode mode = GET_MODE (mem);
5819 struct expand_operand ops[8];
5820 enum insn_code icode;
5821 rtx target_oval, target_bool = NULL_RTX;
5822 rtx libfunc;
5824 /* Load expected into a register for the compare and swap. */
5825 if (MEM_P (expected))
5826 expected = copy_to_reg (expected);
5828 /* Make sure we always have some place to put the return oldval.
5829 Further, make sure that place is distinct from the input expected,
5830 just in case we need that path down below. */
5831 if (ptarget_oval && *ptarget_oval == const0_rtx)
5832 ptarget_oval = NULL;
5834 if (ptarget_oval == NULL
5835 || (target_oval = *ptarget_oval) == NULL
5836 || reg_overlap_mentioned_p (expected, target_oval))
5837 target_oval = gen_reg_rtx (mode);
5839 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
5840 if (icode != CODE_FOR_nothing)
5842 machine_mode bool_mode = insn_data[icode].operand[0].mode;
5844 if (ptarget_bool && *ptarget_bool == const0_rtx)
5845 ptarget_bool = NULL;
5847 /* Make sure we always have a place for the bool operand. */
5848 if (ptarget_bool == NULL
5849 || (target_bool = *ptarget_bool) == NULL
5850 || GET_MODE (target_bool) != bool_mode)
5851 target_bool = gen_reg_rtx (bool_mode);
5853 /* Emit the compare_and_swap. */
5854 create_output_operand (&ops[0], target_bool, bool_mode);
5855 create_output_operand (&ops[1], target_oval, mode);
5856 create_fixed_operand (&ops[2], mem);
5857 create_input_operand (&ops[3], expected, mode);
5858 create_input_operand (&ops[4], desired, mode);
5859 create_integer_operand (&ops[5], is_weak);
5860 create_integer_operand (&ops[6], succ_model);
5861 create_integer_operand (&ops[7], fail_model);
5862 if (maybe_expand_insn (icode, 8, ops))
5864 /* Return success/failure. */
5865 target_bool = ops[0].value;
5866 target_oval = ops[1].value;
5867 goto success;
5871 /* Otherwise fall back to the original __sync_val_compare_and_swap
5872 which is always seq-cst. */
5873 icode = optab_handler (sync_compare_and_swap_optab, mode);
5874 if (icode != CODE_FOR_nothing)
5876 rtx cc_reg;
5878 create_output_operand (&ops[0], target_oval, mode);
5879 create_fixed_operand (&ops[1], mem);
5880 create_input_operand (&ops[2], expected, mode);
5881 create_input_operand (&ops[3], desired, mode);
5882 if (!maybe_expand_insn (icode, 4, ops))
5883 return false;
5885 target_oval = ops[0].value;
5887 /* If the caller isn't interested in the boolean return value,
5888 skip the computation of it. */
5889 if (ptarget_bool == NULL)
5890 goto success;
5892 /* Otherwise, work out if the compare-and-swap succeeded. */
5893 cc_reg = NULL_RTX;
5894 if (have_insn_for (COMPARE, CCmode))
5895 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
5896 if (cc_reg)
5898 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
5899 const0_rtx, VOIDmode, 0, 1);
5900 goto success;
5902 goto success_bool_from_val;
5905 /* Also check for library support for __sync_val_compare_and_swap. */
5906 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
5907 if (libfunc != NULL)
5909 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5910 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5911 mode, 3, addr, ptr_mode,
5912 expected, mode, desired, mode);
5913 emit_move_insn (target_oval, target);
5915 /* Compute the boolean return value only if requested. */
5916 if (ptarget_bool)
5917 goto success_bool_from_val;
5918 else
5919 goto success;
5922 /* Failure. */
5923 return false;
5925 success_bool_from_val:
5926 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
5927 expected, VOIDmode, 1, 1);
5928 success:
5929 /* Make sure that the oval output winds up where the caller asked. */
5930 if (ptarget_oval)
5931 *ptarget_oval = target_oval;
5932 if (ptarget_bool)
5933 *ptarget_bool = target_bool;
5934 return true;
5937 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
5939 static void
5940 expand_asm_memory_barrier (void)
5942 rtx asm_op, clob;
5944 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
5945 rtvec_alloc (0), rtvec_alloc (0),
5946 rtvec_alloc (0), UNKNOWN_LOCATION);
5947 MEM_VOLATILE_P (asm_op) = 1;
5949 clob = gen_rtx_SCRATCH (VOIDmode);
5950 clob = gen_rtx_MEM (BLKmode, clob);
5951 clob = gen_rtx_CLOBBER (VOIDmode, clob);
5953 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
5956 /* This routine will either emit the mem_thread_fence pattern or issue a
5957 sync_synchronize to generate a fence for memory model MEMMODEL. */
5959 void
5960 expand_mem_thread_fence (enum memmodel model)
5962 if (targetm.have_mem_thread_fence ())
5963 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
5964 else if (!is_mm_relaxed (model))
5966 if (targetm.have_memory_barrier ())
5967 emit_insn (targetm.gen_memory_barrier ());
5968 else if (synchronize_libfunc != NULL_RTX)
5969 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
5970 else
5971 expand_asm_memory_barrier ();
5975 /* This routine will either emit the mem_signal_fence pattern or issue a
5976 sync_synchronize to generate a fence for memory model MEMMODEL. */
5978 void
5979 expand_mem_signal_fence (enum memmodel model)
5981 if (targetm.have_mem_signal_fence ())
5982 emit_insn (targetm.gen_mem_signal_fence (GEN_INT (model)));
5983 else if (!is_mm_relaxed (model))
5985 /* By default targets are coherent between a thread and the signal
5986 handler running on the same thread. Thus this really becomes a
5987 compiler barrier, in that stores must not be sunk past
5988 (or raised above) a given point. */
5989 expand_asm_memory_barrier ();
5993 /* This function expands the atomic load operation:
5994 return the atomically loaded value in MEM.
5996 MEMMODEL is the memory model variant to use.
5997 TARGET is an option place to stick the return value. */
6000 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6002 machine_mode mode = GET_MODE (mem);
6003 enum insn_code icode;
6005 /* If the target supports the load directly, great. */
6006 icode = direct_optab_handler (atomic_load_optab, mode);
6007 if (icode != CODE_FOR_nothing)
6009 struct expand_operand ops[3];
6011 create_output_operand (&ops[0], target, mode);
6012 create_fixed_operand (&ops[1], mem);
6013 create_integer_operand (&ops[2], model);
6014 if (maybe_expand_insn (icode, 3, ops))
6015 return ops[0].value;
6018 /* If the size of the object is greater than word size on this target,
6019 then we assume that a load will not be atomic. */
6020 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6022 /* Issue val = compare_and_swap (mem, 0, 0).
6023 This may cause the occasional harmless store of 0 when the value is
6024 already 0, but it seems to be OK according to the standards guys. */
6025 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
6026 const0_rtx, false, model, model))
6027 return target;
6028 else
6029 /* Otherwise there is no atomic load, leave the library call. */
6030 return NULL_RTX;
6033 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6034 if (!target || target == const0_rtx)
6035 target = gen_reg_rtx (mode);
6037 /* For SEQ_CST, emit a barrier before the load. */
6038 if (is_mm_seq_cst (model))
6039 expand_mem_thread_fence (model);
6041 emit_move_insn (target, mem);
6043 /* Emit the appropriate barrier after the load. */
6044 expand_mem_thread_fence (model);
6046 return target;
6049 /* This function expands the atomic store operation:
6050 Atomically store VAL in MEM.
6051 MEMMODEL is the memory model variant to use.
6052 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6053 function returns const0_rtx if a pattern was emitted. */
6056 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6058 machine_mode mode = GET_MODE (mem);
6059 enum insn_code icode;
6060 struct expand_operand ops[3];
6062 /* If the target supports the store directly, great. */
6063 icode = direct_optab_handler (atomic_store_optab, mode);
6064 if (icode != CODE_FOR_nothing)
6066 create_fixed_operand (&ops[0], mem);
6067 create_input_operand (&ops[1], val, mode);
6068 create_integer_operand (&ops[2], model);
6069 if (maybe_expand_insn (icode, 3, ops))
6070 return const0_rtx;
6073 /* If using __sync_lock_release is a viable alternative, try it. */
6074 if (use_release)
6076 icode = direct_optab_handler (sync_lock_release_optab, mode);
6077 if (icode != CODE_FOR_nothing)
6079 create_fixed_operand (&ops[0], mem);
6080 create_input_operand (&ops[1], const0_rtx, mode);
6081 if (maybe_expand_insn (icode, 2, ops))
6083 /* lock_release is only a release barrier. */
6084 if (is_mm_seq_cst (model))
6085 expand_mem_thread_fence (model);
6086 return const0_rtx;
6091 /* If the size of the object is greater than word size on this target,
6092 a default store will not be atomic, Try a mem_exchange and throw away
6093 the result. If that doesn't work, don't do anything. */
6094 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6096 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6097 if (!target)
6098 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
6099 if (target)
6100 return const0_rtx;
6101 else
6102 return NULL_RTX;
6105 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6106 expand_mem_thread_fence (model);
6108 emit_move_insn (mem, val);
6110 /* For SEQ_CST, also emit a barrier after the store. */
6111 if (is_mm_seq_cst (model))
6112 expand_mem_thread_fence (model);
6114 return const0_rtx;
6118 /* Structure containing the pointers and values required to process the
6119 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6121 struct atomic_op_functions
6123 direct_optab mem_fetch_before;
6124 direct_optab mem_fetch_after;
6125 direct_optab mem_no_result;
6126 optab fetch_before;
6127 optab fetch_after;
6128 direct_optab no_result;
6129 enum rtx_code reverse_code;
6133 /* Fill in structure pointed to by OP with the various optab entries for an
6134 operation of type CODE. */
6136 static void
6137 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6139 gcc_assert (op!= NULL);
6141 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6142 in the source code during compilation, and the optab entries are not
6143 computable until runtime. Fill in the values at runtime. */
6144 switch (code)
6146 case PLUS:
6147 op->mem_fetch_before = atomic_fetch_add_optab;
6148 op->mem_fetch_after = atomic_add_fetch_optab;
6149 op->mem_no_result = atomic_add_optab;
6150 op->fetch_before = sync_old_add_optab;
6151 op->fetch_after = sync_new_add_optab;
6152 op->no_result = sync_add_optab;
6153 op->reverse_code = MINUS;
6154 break;
6155 case MINUS:
6156 op->mem_fetch_before = atomic_fetch_sub_optab;
6157 op->mem_fetch_after = atomic_sub_fetch_optab;
6158 op->mem_no_result = atomic_sub_optab;
6159 op->fetch_before = sync_old_sub_optab;
6160 op->fetch_after = sync_new_sub_optab;
6161 op->no_result = sync_sub_optab;
6162 op->reverse_code = PLUS;
6163 break;
6164 case XOR:
6165 op->mem_fetch_before = atomic_fetch_xor_optab;
6166 op->mem_fetch_after = atomic_xor_fetch_optab;
6167 op->mem_no_result = atomic_xor_optab;
6168 op->fetch_before = sync_old_xor_optab;
6169 op->fetch_after = sync_new_xor_optab;
6170 op->no_result = sync_xor_optab;
6171 op->reverse_code = XOR;
6172 break;
6173 case AND:
6174 op->mem_fetch_before = atomic_fetch_and_optab;
6175 op->mem_fetch_after = atomic_and_fetch_optab;
6176 op->mem_no_result = atomic_and_optab;
6177 op->fetch_before = sync_old_and_optab;
6178 op->fetch_after = sync_new_and_optab;
6179 op->no_result = sync_and_optab;
6180 op->reverse_code = UNKNOWN;
6181 break;
6182 case IOR:
6183 op->mem_fetch_before = atomic_fetch_or_optab;
6184 op->mem_fetch_after = atomic_or_fetch_optab;
6185 op->mem_no_result = atomic_or_optab;
6186 op->fetch_before = sync_old_ior_optab;
6187 op->fetch_after = sync_new_ior_optab;
6188 op->no_result = sync_ior_optab;
6189 op->reverse_code = UNKNOWN;
6190 break;
6191 case NOT:
6192 op->mem_fetch_before = atomic_fetch_nand_optab;
6193 op->mem_fetch_after = atomic_nand_fetch_optab;
6194 op->mem_no_result = atomic_nand_optab;
6195 op->fetch_before = sync_old_nand_optab;
6196 op->fetch_after = sync_new_nand_optab;
6197 op->no_result = sync_nand_optab;
6198 op->reverse_code = UNKNOWN;
6199 break;
6200 default:
6201 gcc_unreachable ();
6205 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6206 using memory order MODEL. If AFTER is true the operation needs to return
6207 the value of *MEM after the operation, otherwise the previous value.
6208 TARGET is an optional place to place the result. The result is unused if
6209 it is const0_rtx.
6210 Return the result if there is a better sequence, otherwise NULL_RTX. */
6212 static rtx
6213 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6214 enum memmodel model, bool after)
6216 /* If the value is prefetched, or not used, it may be possible to replace
6217 the sequence with a native exchange operation. */
6218 if (!after || target == const0_rtx)
6220 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6221 if (code == AND && val == const0_rtx)
6223 if (target == const0_rtx)
6224 target = gen_reg_rtx (GET_MODE (mem));
6225 return maybe_emit_atomic_exchange (target, mem, val, model);
6228 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6229 if (code == IOR && val == constm1_rtx)
6231 if (target == const0_rtx)
6232 target = gen_reg_rtx (GET_MODE (mem));
6233 return maybe_emit_atomic_exchange (target, mem, val, model);
6237 return NULL_RTX;
6240 /* Try to emit an instruction for a specific operation varaition.
6241 OPTAB contains the OP functions.
6242 TARGET is an optional place to return the result. const0_rtx means unused.
6243 MEM is the memory location to operate on.
6244 VAL is the value to use in the operation.
6245 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6246 MODEL is the memory model, if used.
6247 AFTER is true if the returned result is the value after the operation. */
6249 static rtx
6250 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6251 rtx val, bool use_memmodel, enum memmodel model, bool after)
6253 machine_mode mode = GET_MODE (mem);
6254 struct expand_operand ops[4];
6255 enum insn_code icode;
6256 int op_counter = 0;
6257 int num_ops;
6259 /* Check to see if there is a result returned. */
6260 if (target == const0_rtx)
6262 if (use_memmodel)
6264 icode = direct_optab_handler (optab->mem_no_result, mode);
6265 create_integer_operand (&ops[2], model);
6266 num_ops = 3;
6268 else
6270 icode = direct_optab_handler (optab->no_result, mode);
6271 num_ops = 2;
6274 /* Otherwise, we need to generate a result. */
6275 else
6277 if (use_memmodel)
6279 icode = direct_optab_handler (after ? optab->mem_fetch_after
6280 : optab->mem_fetch_before, mode);
6281 create_integer_operand (&ops[3], model);
6282 num_ops = 4;
6284 else
6286 icode = optab_handler (after ? optab->fetch_after
6287 : optab->fetch_before, mode);
6288 num_ops = 3;
6290 create_output_operand (&ops[op_counter++], target, mode);
6292 if (icode == CODE_FOR_nothing)
6293 return NULL_RTX;
6295 create_fixed_operand (&ops[op_counter++], mem);
6296 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6297 create_convert_operand_to (&ops[op_counter++], val, mode, true);
6299 if (maybe_expand_insn (icode, num_ops, ops))
6300 return (target == const0_rtx ? const0_rtx : ops[0].value);
6302 return NULL_RTX;
6306 /* This function expands an atomic fetch_OP or OP_fetch operation:
6307 TARGET is an option place to stick the return value. const0_rtx indicates
6308 the result is unused.
6309 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6310 CODE is the operation being performed (OP)
6311 MEMMODEL is the memory model variant to use.
6312 AFTER is true to return the result of the operation (OP_fetch).
6313 AFTER is false to return the value before the operation (fetch_OP).
6315 This function will *only* generate instructions if there is a direct
6316 optab. No compare and swap loops or libcalls will be generated. */
6318 static rtx
6319 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6320 enum rtx_code code, enum memmodel model,
6321 bool after)
6323 machine_mode mode = GET_MODE (mem);
6324 struct atomic_op_functions optab;
6325 rtx result;
6326 bool unused_result = (target == const0_rtx);
6328 get_atomic_op_for_code (&optab, code);
6330 /* Check to see if there are any better instructions. */
6331 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6332 if (result)
6333 return result;
6335 /* Check for the case where the result isn't used and try those patterns. */
6336 if (unused_result)
6338 /* Try the memory model variant first. */
6339 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6340 if (result)
6341 return result;
6343 /* Next try the old style withuot a memory model. */
6344 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6345 if (result)
6346 return result;
6348 /* There is no no-result pattern, so try patterns with a result. */
6349 target = NULL_RTX;
6352 /* Try the __atomic version. */
6353 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6354 if (result)
6355 return result;
6357 /* Try the older __sync version. */
6358 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6359 if (result)
6360 return result;
6362 /* If the fetch value can be calculated from the other variation of fetch,
6363 try that operation. */
6364 if (after || unused_result || optab.reverse_code != UNKNOWN)
6366 /* Try the __atomic version, then the older __sync version. */
6367 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6368 if (!result)
6369 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6371 if (result)
6373 /* If the result isn't used, no need to do compensation code. */
6374 if (unused_result)
6375 return result;
6377 /* Issue compensation code. Fetch_after == fetch_before OP val.
6378 Fetch_before == after REVERSE_OP val. */
6379 if (!after)
6380 code = optab.reverse_code;
6381 if (code == NOT)
6383 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6384 true, OPTAB_LIB_WIDEN);
6385 result = expand_simple_unop (mode, NOT, result, target, true);
6387 else
6388 result = expand_simple_binop (mode, code, result, val, target,
6389 true, OPTAB_LIB_WIDEN);
6390 return result;
6394 /* No direct opcode can be generated. */
6395 return NULL_RTX;
6400 /* This function expands an atomic fetch_OP or OP_fetch operation:
6401 TARGET is an option place to stick the return value. const0_rtx indicates
6402 the result is unused.
6403 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6404 CODE is the operation being performed (OP)
6405 MEMMODEL is the memory model variant to use.
6406 AFTER is true to return the result of the operation (OP_fetch).
6407 AFTER is false to return the value before the operation (fetch_OP). */
6409 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6410 enum memmodel model, bool after)
6412 machine_mode mode = GET_MODE (mem);
6413 rtx result;
6414 bool unused_result = (target == const0_rtx);
6416 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6417 after);
6419 if (result)
6420 return result;
6422 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6423 if (code == PLUS || code == MINUS)
6425 rtx tmp;
6426 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6428 start_sequence ();
6429 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6430 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6431 model, after);
6432 if (result)
6434 /* PLUS worked so emit the insns and return. */
6435 tmp = get_insns ();
6436 end_sequence ();
6437 emit_insn (tmp);
6438 return result;
6441 /* PLUS did not work, so throw away the negation code and continue. */
6442 end_sequence ();
6445 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6446 if (!can_compare_and_swap_p (mode, false))
6448 rtx libfunc;
6449 bool fixup = false;
6450 enum rtx_code orig_code = code;
6451 struct atomic_op_functions optab;
6453 get_atomic_op_for_code (&optab, code);
6454 libfunc = optab_libfunc (after ? optab.fetch_after
6455 : optab.fetch_before, mode);
6456 if (libfunc == NULL
6457 && (after || unused_result || optab.reverse_code != UNKNOWN))
6459 fixup = true;
6460 if (!after)
6461 code = optab.reverse_code;
6462 libfunc = optab_libfunc (after ? optab.fetch_before
6463 : optab.fetch_after, mode);
6465 if (libfunc != NULL)
6467 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6468 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
6469 2, addr, ptr_mode, val, mode);
6471 if (!unused_result && fixup)
6472 result = expand_simple_binop (mode, code, result, val, target,
6473 true, OPTAB_LIB_WIDEN);
6474 return result;
6477 /* We need the original code for any further attempts. */
6478 code = orig_code;
6481 /* If nothing else has succeeded, default to a compare and swap loop. */
6482 if (can_compare_and_swap_p (mode, true))
6484 rtx_insn *insn;
6485 rtx t0 = gen_reg_rtx (mode), t1;
6487 start_sequence ();
6489 /* If the result is used, get a register for it. */
6490 if (!unused_result)
6492 if (!target || !register_operand (target, mode))
6493 target = gen_reg_rtx (mode);
6494 /* If fetch_before, copy the value now. */
6495 if (!after)
6496 emit_move_insn (target, t0);
6498 else
6499 target = const0_rtx;
6501 t1 = t0;
6502 if (code == NOT)
6504 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
6505 true, OPTAB_LIB_WIDEN);
6506 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
6508 else
6509 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
6510 OPTAB_LIB_WIDEN);
6512 /* For after, copy the value now. */
6513 if (!unused_result && after)
6514 emit_move_insn (target, t1);
6515 insn = get_insns ();
6516 end_sequence ();
6518 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6519 return target;
6522 return NULL_RTX;
6525 /* Return true if OPERAND is suitable for operand number OPNO of
6526 instruction ICODE. */
6528 bool
6529 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
6531 return (!insn_data[(int) icode].operand[opno].predicate
6532 || (insn_data[(int) icode].operand[opno].predicate
6533 (operand, insn_data[(int) icode].operand[opno].mode)));
6536 /* TARGET is a target of a multiword operation that we are going to
6537 implement as a series of word-mode operations. Return true if
6538 TARGET is suitable for this purpose. */
6540 bool
6541 valid_multiword_target_p (rtx target)
6543 machine_mode mode;
6544 int i;
6546 mode = GET_MODE (target);
6547 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
6548 if (!validate_subreg (word_mode, mode, target, i))
6549 return false;
6550 return true;
6553 /* Like maybe_legitimize_operand, but do not change the code of the
6554 current rtx value. */
6556 static bool
6557 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
6558 struct expand_operand *op)
6560 /* See if the operand matches in its current form. */
6561 if (insn_operand_matches (icode, opno, op->value))
6562 return true;
6564 /* If the operand is a memory whose address has no side effects,
6565 try forcing the address into a non-virtual pseudo register.
6566 The check for side effects is important because copy_to_mode_reg
6567 cannot handle things like auto-modified addresses. */
6568 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
6570 rtx addr, mem;
6572 mem = op->value;
6573 addr = XEXP (mem, 0);
6574 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
6575 && !side_effects_p (addr))
6577 rtx_insn *last;
6578 machine_mode mode;
6580 last = get_last_insn ();
6581 mode = get_address_mode (mem);
6582 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
6583 if (insn_operand_matches (icode, opno, mem))
6585 op->value = mem;
6586 return true;
6588 delete_insns_since (last);
6592 return false;
6595 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6596 on success, storing the new operand value back in OP. */
6598 static bool
6599 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
6600 struct expand_operand *op)
6602 machine_mode mode, imode;
6603 bool old_volatile_ok, result;
6605 mode = op->mode;
6606 switch (op->type)
6608 case EXPAND_FIXED:
6609 old_volatile_ok = volatile_ok;
6610 volatile_ok = true;
6611 result = maybe_legitimize_operand_same_code (icode, opno, op);
6612 volatile_ok = old_volatile_ok;
6613 return result;
6615 case EXPAND_OUTPUT:
6616 gcc_assert (mode != VOIDmode);
6617 if (op->value
6618 && op->value != const0_rtx
6619 && GET_MODE (op->value) == mode
6620 && maybe_legitimize_operand_same_code (icode, opno, op))
6621 return true;
6623 op->value = gen_reg_rtx (mode);
6624 break;
6626 case EXPAND_INPUT:
6627 input:
6628 gcc_assert (mode != VOIDmode);
6629 gcc_assert (GET_MODE (op->value) == VOIDmode
6630 || GET_MODE (op->value) == mode);
6631 if (maybe_legitimize_operand_same_code (icode, opno, op))
6632 return true;
6634 op->value = copy_to_mode_reg (mode, op->value);
6635 break;
6637 case EXPAND_CONVERT_TO:
6638 gcc_assert (mode != VOIDmode);
6639 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
6640 goto input;
6642 case EXPAND_CONVERT_FROM:
6643 if (GET_MODE (op->value) != VOIDmode)
6644 mode = GET_MODE (op->value);
6645 else
6646 /* The caller must tell us what mode this value has. */
6647 gcc_assert (mode != VOIDmode);
6649 imode = insn_data[(int) icode].operand[opno].mode;
6650 if (imode != VOIDmode && imode != mode)
6652 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
6653 mode = imode;
6655 goto input;
6657 case EXPAND_ADDRESS:
6658 gcc_assert (mode != VOIDmode);
6659 op->value = convert_memory_address (mode, op->value);
6660 goto input;
6662 case EXPAND_INTEGER:
6663 mode = insn_data[(int) icode].operand[opno].mode;
6664 if (mode != VOIDmode && const_int_operand (op->value, mode))
6665 goto input;
6666 break;
6668 return insn_operand_matches (icode, opno, op->value);
6671 /* Make OP describe an input operand that should have the same value
6672 as VALUE, after any mode conversion that the target might request.
6673 TYPE is the type of VALUE. */
6675 void
6676 create_convert_operand_from_type (struct expand_operand *op,
6677 rtx value, tree type)
6679 create_convert_operand_from (op, value, TYPE_MODE (type),
6680 TYPE_UNSIGNED (type));
6683 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
6684 of instruction ICODE. Return true on success, leaving the new operand
6685 values in the OPS themselves. Emit no code on failure. */
6687 bool
6688 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
6689 unsigned int nops, struct expand_operand *ops)
6691 rtx_insn *last;
6692 unsigned int i;
6694 last = get_last_insn ();
6695 for (i = 0; i < nops; i++)
6696 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
6698 delete_insns_since (last);
6699 return false;
6701 return true;
6704 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
6705 as its operands. Return the instruction pattern on success,
6706 and emit any necessary set-up code. Return null and emit no
6707 code on failure. */
6709 rtx_insn *
6710 maybe_gen_insn (enum insn_code icode, unsigned int nops,
6711 struct expand_operand *ops)
6713 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
6714 if (!maybe_legitimize_operands (icode, 0, nops, ops))
6715 return NULL;
6717 switch (nops)
6719 case 1:
6720 return GEN_FCN (icode) (ops[0].value);
6721 case 2:
6722 return GEN_FCN (icode) (ops[0].value, ops[1].value);
6723 case 3:
6724 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
6725 case 4:
6726 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6727 ops[3].value);
6728 case 5:
6729 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6730 ops[3].value, ops[4].value);
6731 case 6:
6732 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6733 ops[3].value, ops[4].value, ops[5].value);
6734 case 7:
6735 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6736 ops[3].value, ops[4].value, ops[5].value,
6737 ops[6].value);
6738 case 8:
6739 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6740 ops[3].value, ops[4].value, ops[5].value,
6741 ops[6].value, ops[7].value);
6742 case 9:
6743 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6744 ops[3].value, ops[4].value, ops[5].value,
6745 ops[6].value, ops[7].value, ops[8].value);
6747 gcc_unreachable ();
6750 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
6751 as its operands. Return true on success and emit no code on failure. */
6753 bool
6754 maybe_expand_insn (enum insn_code icode, unsigned int nops,
6755 struct expand_operand *ops)
6757 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6758 if (pat)
6760 emit_insn (pat);
6761 return true;
6763 return false;
6766 /* Like maybe_expand_insn, but for jumps. */
6768 bool
6769 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
6770 struct expand_operand *ops)
6772 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6773 if (pat)
6775 emit_jump_insn (pat);
6776 return true;
6778 return false;
6781 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
6782 as its operands. */
6784 void
6785 expand_insn (enum insn_code icode, unsigned int nops,
6786 struct expand_operand *ops)
6788 if (!maybe_expand_insn (icode, nops, ops))
6789 gcc_unreachable ();
6792 /* Like expand_insn, but for jumps. */
6794 void
6795 expand_jump_insn (enum insn_code icode, unsigned int nops,
6796 struct expand_operand *ops)
6798 if (!maybe_expand_jump_insn (icode, nops, ops))
6799 gcc_unreachable ();