2015-09-25 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / optabs.c
blobc49d66b5a0e92a75a4c8048527dd6ae1bf8d9d98
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 "predict.h"
26 #include "diagnostic-core.h"
28 /* Include insn-config.h before expr.h so that HAVE_conditional_move
29 is properly defined. */
30 #include "insn-config.h"
31 #include "rtl.h"
32 #include "alias.h"
33 #include "tree.h"
34 #include "tree-hasher.h"
35 #include "stor-layout.h"
36 #include "tm_p.h"
37 #include "flags.h"
38 #include "except.h"
39 #include "expmed.h"
40 #include "dojump.h"
41 #include "explow.h"
42 #include "calls.h"
43 #include "emit-rtl.h"
44 #include "stmt.h"
45 #include "expr.h"
46 #include "insn-codes.h"
47 #include "optabs.h"
48 #include "optabs-tree.h"
49 #include "libfuncs.h"
50 #include "recog.h"
51 #include "reload.h"
52 #include "target.h"
54 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
55 machine_mode *);
56 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
57 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
59 /* Debug facility for use in GDB. */
60 void debug_optab_libfuncs (void);
62 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
63 the result of operation CODE applied to OP0 (and OP1 if it is a binary
64 operation).
66 If the last insn does not set TARGET, don't do anything, but return 1.
68 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
69 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
70 try again, ensuring that TARGET is not one of the operands. */
72 static int
73 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
75 rtx_insn *last_insn;
76 rtx set;
77 rtx note;
79 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
81 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
82 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
83 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
84 && GET_RTX_CLASS (code) != RTX_COMPARE
85 && GET_RTX_CLASS (code) != RTX_UNARY)
86 return 1;
88 if (GET_CODE (target) == ZERO_EXTRACT)
89 return 1;
91 for (last_insn = insns;
92 NEXT_INSN (last_insn) != NULL_RTX;
93 last_insn = NEXT_INSN (last_insn))
96 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
97 a value changing in the insn, so the note would be invalid for CSE. */
98 if (reg_overlap_mentioned_p (target, op0)
99 || (op1 && reg_overlap_mentioned_p (target, op1)))
101 if (MEM_P (target)
102 && (rtx_equal_p (target, op0)
103 || (op1 && rtx_equal_p (target, op1))))
105 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
106 over expanding it as temp = MEM op X, MEM = temp. If the target
107 supports MEM = MEM op X instructions, it is sometimes too hard
108 to reconstruct that form later, especially if X is also a memory,
109 and due to multiple occurrences of addresses the address might
110 be forced into register unnecessarily.
111 Note that not emitting the REG_EQUIV note might inhibit
112 CSE in some cases. */
113 set = single_set (last_insn);
114 if (set
115 && GET_CODE (SET_SRC (set)) == code
116 && MEM_P (SET_DEST (set))
117 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
118 || (op1 && rtx_equal_p (SET_DEST (set),
119 XEXP (SET_SRC (set), 1)))))
120 return 1;
122 return 0;
125 set = set_for_reg_notes (last_insn);
126 if (set == NULL_RTX)
127 return 1;
129 if (! rtx_equal_p (SET_DEST (set), target)
130 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
131 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
132 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
133 return 1;
135 if (GET_RTX_CLASS (code) == RTX_UNARY)
136 switch (code)
138 case FFS:
139 case CLZ:
140 case CTZ:
141 case CLRSB:
142 case POPCOUNT:
143 case PARITY:
144 case BSWAP:
145 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
147 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
148 if (GET_MODE_SIZE (GET_MODE (op0))
149 > GET_MODE_SIZE (GET_MODE (target)))
150 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
151 note, GET_MODE (op0));
152 else
153 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
154 note, GET_MODE (op0));
155 break;
157 /* FALLTHRU */
158 default:
159 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
160 break;
162 else
163 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
165 set_unique_reg_note (last_insn, REG_EQUAL, note);
167 return 1;
170 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
171 for a widening operation would be. In most cases this would be OP0, but if
172 that's a constant it'll be VOIDmode, which isn't useful. */
174 static machine_mode
175 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
177 machine_mode m0 = GET_MODE (op0);
178 machine_mode m1 = GET_MODE (op1);
179 machine_mode result;
181 if (m0 == VOIDmode && m1 == VOIDmode)
182 return to_mode;
183 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
184 result = m1;
185 else
186 result = m0;
188 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
189 return to_mode;
191 return result;
194 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
195 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
196 not actually do a sign-extend or zero-extend, but can leave the
197 higher-order bits of the result rtx undefined, for example, in the case
198 of logical operations, but not right shifts. */
200 static rtx
201 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
202 int unsignedp, int no_extend)
204 rtx result;
206 /* If we don't have to extend and this is a constant, return it. */
207 if (no_extend && GET_MODE (op) == VOIDmode)
208 return op;
210 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
211 extend since it will be more efficient to do so unless the signedness of
212 a promoted object differs from our extension. */
213 if (! no_extend
214 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
215 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
216 return convert_modes (mode, oldmode, op, unsignedp);
218 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
219 SUBREG. */
220 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
221 return gen_lowpart (mode, force_reg (GET_MODE (op), op));
223 /* Otherwise, get an object of MODE, clobber it, and set the low-order
224 part to OP. */
226 result = gen_reg_rtx (mode);
227 emit_clobber (result);
228 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
229 return result;
232 /* Expand vector widening operations.
234 There are two different classes of operations handled here:
235 1) Operations whose result is wider than all the arguments to the operation.
236 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
237 In this case OP0 and optionally OP1 would be initialized,
238 but WIDE_OP wouldn't (not relevant for this case).
239 2) Operations whose result is of the same size as the last argument to the
240 operation, but wider than all the other arguments to the operation.
241 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
242 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
244 E.g, when called to expand the following operations, this is how
245 the arguments will be initialized:
246 nops OP0 OP1 WIDE_OP
247 widening-sum 2 oprnd0 - oprnd1
248 widening-dot-product 3 oprnd0 oprnd1 oprnd2
249 widening-mult 2 oprnd0 oprnd1 -
250 type-promotion (vec-unpack) 1 oprnd0 - - */
253 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
254 rtx target, int unsignedp)
256 struct expand_operand eops[4];
257 tree oprnd0, oprnd1, oprnd2;
258 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
259 optab widen_pattern_optab;
260 enum insn_code icode;
261 int nops = TREE_CODE_LENGTH (ops->code);
262 int op;
264 oprnd0 = ops->op0;
265 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
266 widen_pattern_optab =
267 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
268 if (ops->code == WIDEN_MULT_PLUS_EXPR
269 || ops->code == WIDEN_MULT_MINUS_EXPR)
270 icode = find_widening_optab_handler (widen_pattern_optab,
271 TYPE_MODE (TREE_TYPE (ops->op2)),
272 tmode0, 0);
273 else
274 icode = optab_handler (widen_pattern_optab, tmode0);
275 gcc_assert (icode != CODE_FOR_nothing);
277 if (nops >= 2)
279 oprnd1 = ops->op1;
280 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
283 /* The last operand is of a wider mode than the rest of the operands. */
284 if (nops == 2)
285 wmode = tmode1;
286 else if (nops == 3)
288 gcc_assert (tmode1 == tmode0);
289 gcc_assert (op1);
290 oprnd2 = ops->op2;
291 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
294 op = 0;
295 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
296 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
297 if (op1)
298 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
299 if (wide_op)
300 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
301 expand_insn (icode, op, eops);
302 return eops[0].value;
305 /* Generate code to perform an operation specified by TERNARY_OPTAB
306 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
308 UNSIGNEDP is for the case where we have to widen the operands
309 to perform the operation. It says to use zero-extension.
311 If TARGET is nonzero, the value
312 is generated there, if it is convenient to do so.
313 In all cases an rtx is returned for the locus of the value;
314 this may or may not be TARGET. */
317 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
318 rtx op1, rtx op2, rtx target, int unsignedp)
320 struct expand_operand ops[4];
321 enum insn_code icode = optab_handler (ternary_optab, mode);
323 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
325 create_output_operand (&ops[0], target, mode);
326 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
327 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
328 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
329 expand_insn (icode, 4, ops);
330 return ops[0].value;
334 /* Like expand_binop, but return a constant rtx if the result can be
335 calculated at compile time. The arguments and return value are
336 otherwise the same as for expand_binop. */
339 simplify_expand_binop (machine_mode mode, optab binoptab,
340 rtx op0, rtx op1, rtx target, int unsignedp,
341 enum optab_methods methods)
343 if (CONSTANT_P (op0) && CONSTANT_P (op1))
345 rtx x = simplify_binary_operation (optab_to_code (binoptab),
346 mode, op0, op1);
347 if (x)
348 return x;
351 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
354 /* Like simplify_expand_binop, but always put the result in TARGET.
355 Return true if the expansion succeeded. */
357 bool
358 force_expand_binop (machine_mode mode, optab binoptab,
359 rtx op0, rtx op1, rtx target, int unsignedp,
360 enum optab_methods methods)
362 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
363 target, unsignedp, methods);
364 if (x == 0)
365 return false;
366 if (x != target)
367 emit_move_insn (target, x);
368 return true;
371 /* Create a new vector value in VMODE with all elements set to OP. The
372 mode of OP must be the element mode of VMODE. If OP is a constant,
373 then the return value will be a constant. */
375 static rtx
376 expand_vector_broadcast (machine_mode vmode, rtx op)
378 enum insn_code icode;
379 rtvec vec;
380 rtx ret;
381 int i, n;
383 gcc_checking_assert (VECTOR_MODE_P (vmode));
385 n = GET_MODE_NUNITS (vmode);
386 vec = rtvec_alloc (n);
387 for (i = 0; i < n; ++i)
388 RTVEC_ELT (vec, i) = op;
390 if (CONSTANT_P (op))
391 return gen_rtx_CONST_VECTOR (vmode, vec);
393 /* ??? If the target doesn't have a vec_init, then we have no easy way
394 of performing this operation. Most of this sort of generic support
395 is hidden away in the vector lowering support in gimple. */
396 icode = optab_handler (vec_init_optab, vmode);
397 if (icode == CODE_FOR_nothing)
398 return NULL;
400 ret = gen_reg_rtx (vmode);
401 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
403 return ret;
406 /* This subroutine of expand_doubleword_shift handles the cases in which
407 the effective shift value is >= BITS_PER_WORD. The arguments and return
408 value are the same as for the parent routine, except that SUPERWORD_OP1
409 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
410 INTO_TARGET may be null if the caller has decided to calculate it. */
412 static bool
413 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
414 rtx outof_target, rtx into_target,
415 int unsignedp, enum optab_methods methods)
417 if (into_target != 0)
418 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
419 into_target, unsignedp, methods))
420 return false;
422 if (outof_target != 0)
424 /* For a signed right shift, we must fill OUTOF_TARGET with copies
425 of the sign bit, otherwise we must fill it with zeros. */
426 if (binoptab != ashr_optab)
427 emit_move_insn (outof_target, CONST0_RTX (word_mode));
428 else
429 if (!force_expand_binop (word_mode, binoptab,
430 outof_input, GEN_INT (BITS_PER_WORD - 1),
431 outof_target, unsignedp, methods))
432 return false;
434 return true;
437 /* This subroutine of expand_doubleword_shift handles the cases in which
438 the effective shift value is < BITS_PER_WORD. The arguments and return
439 value are the same as for the parent routine. */
441 static bool
442 expand_subword_shift (machine_mode op1_mode, optab binoptab,
443 rtx outof_input, rtx into_input, rtx op1,
444 rtx outof_target, rtx into_target,
445 int unsignedp, enum optab_methods methods,
446 unsigned HOST_WIDE_INT shift_mask)
448 optab reverse_unsigned_shift, unsigned_shift;
449 rtx tmp, carries;
451 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
452 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
454 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
455 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
456 the opposite direction to BINOPTAB. */
457 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
459 carries = outof_input;
460 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
461 op1_mode), op1_mode);
462 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
463 0, true, methods);
465 else
467 /* We must avoid shifting by BITS_PER_WORD bits since that is either
468 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
469 has unknown behavior. Do a single shift first, then shift by the
470 remainder. It's OK to use ~OP1 as the remainder if shift counts
471 are truncated to the mode size. */
472 carries = expand_binop (word_mode, reverse_unsigned_shift,
473 outof_input, const1_rtx, 0, unsignedp, methods);
474 if (shift_mask == BITS_PER_WORD - 1)
476 tmp = immed_wide_int_const
477 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
478 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
479 0, true, methods);
481 else
483 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
484 op1_mode), op1_mode);
485 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
486 0, true, methods);
489 if (tmp == 0 || carries == 0)
490 return false;
491 carries = expand_binop (word_mode, reverse_unsigned_shift,
492 carries, tmp, 0, unsignedp, methods);
493 if (carries == 0)
494 return false;
496 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
497 so the result can go directly into INTO_TARGET if convenient. */
498 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
499 into_target, unsignedp, methods);
500 if (tmp == 0)
501 return false;
503 /* Now OR in the bits carried over from OUTOF_INPUT. */
504 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
505 into_target, unsignedp, methods))
506 return false;
508 /* Use a standard word_mode shift for the out-of half. */
509 if (outof_target != 0)
510 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
511 outof_target, unsignedp, methods))
512 return false;
514 return true;
518 /* Try implementing expand_doubleword_shift using conditional moves.
519 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
520 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
521 are the shift counts to use in the former and latter case. All other
522 arguments are the same as the parent routine. */
524 static bool
525 expand_doubleword_shift_condmove (machine_mode op1_mode, optab binoptab,
526 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
527 rtx outof_input, rtx into_input,
528 rtx subword_op1, rtx superword_op1,
529 rtx outof_target, rtx into_target,
530 int unsignedp, enum optab_methods methods,
531 unsigned HOST_WIDE_INT shift_mask)
533 rtx outof_superword, into_superword;
535 /* Put the superword version of the output into OUTOF_SUPERWORD and
536 INTO_SUPERWORD. */
537 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
538 if (outof_target != 0 && subword_op1 == superword_op1)
540 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
541 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
542 into_superword = outof_target;
543 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
544 outof_superword, 0, unsignedp, methods))
545 return false;
547 else
549 into_superword = gen_reg_rtx (word_mode);
550 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
551 outof_superword, into_superword,
552 unsignedp, methods))
553 return false;
556 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
557 if (!expand_subword_shift (op1_mode, binoptab,
558 outof_input, into_input, subword_op1,
559 outof_target, into_target,
560 unsignedp, methods, shift_mask))
561 return false;
563 /* Select between them. Do the INTO half first because INTO_SUPERWORD
564 might be the current value of OUTOF_TARGET. */
565 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
566 into_target, into_superword, word_mode, false))
567 return false;
569 if (outof_target != 0)
570 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
571 outof_target, outof_superword,
572 word_mode, false))
573 return false;
575 return true;
578 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
579 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
580 input operand; the shift moves bits in the direction OUTOF_INPUT->
581 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
582 of the target. OP1 is the shift count and OP1_MODE is its mode.
583 If OP1 is constant, it will have been truncated as appropriate
584 and is known to be nonzero.
586 If SHIFT_MASK is zero, the result of word shifts is undefined when the
587 shift count is outside the range [0, BITS_PER_WORD). This routine must
588 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
590 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
591 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
592 fill with zeros or sign bits as appropriate.
594 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
595 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
596 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
597 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
598 are undefined.
600 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
601 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
602 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
603 function wants to calculate it itself.
605 Return true if the shift could be successfully synthesized. */
607 static bool
608 expand_doubleword_shift (machine_mode op1_mode, optab binoptab,
609 rtx outof_input, rtx into_input, rtx op1,
610 rtx outof_target, rtx into_target,
611 int unsignedp, enum optab_methods methods,
612 unsigned HOST_WIDE_INT shift_mask)
614 rtx superword_op1, tmp, cmp1, cmp2;
615 enum rtx_code cmp_code;
617 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
618 fill the result with sign or zero bits as appropriate. If so, the value
619 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
620 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
621 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
623 This isn't worthwhile for constant shifts since the optimizers will
624 cope better with in-range shift counts. */
625 if (shift_mask >= BITS_PER_WORD
626 && outof_target != 0
627 && !CONSTANT_P (op1))
629 if (!expand_doubleword_shift (op1_mode, binoptab,
630 outof_input, into_input, op1,
631 0, into_target,
632 unsignedp, methods, shift_mask))
633 return false;
634 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
635 outof_target, unsignedp, methods))
636 return false;
637 return true;
640 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
641 is true when the effective shift value is less than BITS_PER_WORD.
642 Set SUPERWORD_OP1 to the shift count that should be used to shift
643 OUTOF_INPUT into INTO_TARGET when the condition is false. */
644 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
645 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
647 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
648 is a subword shift count. */
649 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
650 0, true, methods);
651 cmp2 = CONST0_RTX (op1_mode);
652 cmp_code = EQ;
653 superword_op1 = op1;
655 else
657 /* Set CMP1 to OP1 - BITS_PER_WORD. */
658 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
659 0, true, methods);
660 cmp2 = CONST0_RTX (op1_mode);
661 cmp_code = LT;
662 superword_op1 = cmp1;
664 if (cmp1 == 0)
665 return false;
667 /* If we can compute the condition at compile time, pick the
668 appropriate subroutine. */
669 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
670 if (tmp != 0 && CONST_INT_P (tmp))
672 if (tmp == const0_rtx)
673 return expand_superword_shift (binoptab, outof_input, superword_op1,
674 outof_target, into_target,
675 unsignedp, methods);
676 else
677 return expand_subword_shift (op1_mode, binoptab,
678 outof_input, into_input, op1,
679 outof_target, into_target,
680 unsignedp, methods, shift_mask);
683 /* Try using conditional moves to generate straight-line code. */
684 if (HAVE_conditional_move)
686 rtx_insn *start = get_last_insn ();
687 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
688 cmp_code, cmp1, cmp2,
689 outof_input, into_input,
690 op1, superword_op1,
691 outof_target, into_target,
692 unsignedp, methods, shift_mask))
693 return true;
694 delete_insns_since (start);
697 /* As a last resort, use branches to select the correct alternative. */
698 rtx_code_label *subword_label = gen_label_rtx ();
699 rtx_code_label *done_label = gen_label_rtx ();
701 NO_DEFER_POP;
702 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
703 0, 0, subword_label, -1);
704 OK_DEFER_POP;
706 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
707 outof_target, into_target,
708 unsignedp, methods))
709 return false;
711 emit_jump_insn (targetm.gen_jump (done_label));
712 emit_barrier ();
713 emit_label (subword_label);
715 if (!expand_subword_shift (op1_mode, binoptab,
716 outof_input, into_input, op1,
717 outof_target, into_target,
718 unsignedp, methods, shift_mask))
719 return false;
721 emit_label (done_label);
722 return true;
725 /* Subroutine of expand_binop. Perform a double word multiplication of
726 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
727 as the target's word_mode. This function return NULL_RTX if anything
728 goes wrong, in which case it may have already emitted instructions
729 which need to be deleted.
731 If we want to multiply two two-word values and have normal and widening
732 multiplies of single-word values, we can do this with three smaller
733 multiplications.
735 The multiplication proceeds as follows:
736 _______________________
737 [__op0_high_|__op0_low__]
738 _______________________
739 * [__op1_high_|__op1_low__]
740 _______________________________________________
741 _______________________
742 (1) [__op0_low__*__op1_low__]
743 _______________________
744 (2a) [__op0_low__*__op1_high_]
745 _______________________
746 (2b) [__op0_high_*__op1_low__]
747 _______________________
748 (3) [__op0_high_*__op1_high_]
751 This gives a 4-word result. Since we are only interested in the
752 lower 2 words, partial result (3) and the upper words of (2a) and
753 (2b) don't need to be calculated. Hence (2a) and (2b) can be
754 calculated using non-widening multiplication.
756 (1), however, needs to be calculated with an unsigned widening
757 multiplication. If this operation is not directly supported we
758 try using a signed widening multiplication and adjust the result.
759 This adjustment works as follows:
761 If both operands are positive then no adjustment is needed.
763 If the operands have different signs, for example op0_low < 0 and
764 op1_low >= 0, the instruction treats the most significant bit of
765 op0_low as a sign bit instead of a bit with significance
766 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
767 with 2**BITS_PER_WORD - op0_low, and two's complements the
768 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
769 the result.
771 Similarly, if both operands are negative, we need to add
772 (op0_low + op1_low) * 2**BITS_PER_WORD.
774 We use a trick to adjust quickly. We logically shift op0_low right
775 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
776 op0_high (op1_high) before it is used to calculate 2b (2a). If no
777 logical shift exists, we do an arithmetic right shift and subtract
778 the 0 or -1. */
780 static rtx
781 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
782 bool umulp, enum optab_methods methods)
784 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
785 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
786 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
787 rtx product, adjust, product_high, temp;
789 rtx op0_high = operand_subword_force (op0, high, mode);
790 rtx op0_low = operand_subword_force (op0, low, mode);
791 rtx op1_high = operand_subword_force (op1, high, mode);
792 rtx op1_low = operand_subword_force (op1, low, mode);
794 /* If we're using an unsigned multiply to directly compute the product
795 of the low-order words of the operands and perform any required
796 adjustments of the operands, we begin by trying two more multiplications
797 and then computing the appropriate sum.
799 We have checked above that the required addition is provided.
800 Full-word addition will normally always succeed, especially if
801 it is provided at all, so we don't worry about its failure. The
802 multiplication may well fail, however, so we do handle that. */
804 if (!umulp)
806 /* ??? This could be done with emit_store_flag where available. */
807 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
808 NULL_RTX, 1, methods);
809 if (temp)
810 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
811 NULL_RTX, 0, OPTAB_DIRECT);
812 else
814 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
815 NULL_RTX, 0, methods);
816 if (!temp)
817 return NULL_RTX;
818 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
819 NULL_RTX, 0, OPTAB_DIRECT);
822 if (!op0_high)
823 return NULL_RTX;
826 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
827 NULL_RTX, 0, OPTAB_DIRECT);
828 if (!adjust)
829 return NULL_RTX;
831 /* OP0_HIGH should now be dead. */
833 if (!umulp)
835 /* ??? This could be done with emit_store_flag where available. */
836 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
837 NULL_RTX, 1, methods);
838 if (temp)
839 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
840 NULL_RTX, 0, OPTAB_DIRECT);
841 else
843 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
844 NULL_RTX, 0, methods);
845 if (!temp)
846 return NULL_RTX;
847 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
848 NULL_RTX, 0, OPTAB_DIRECT);
851 if (!op1_high)
852 return NULL_RTX;
855 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
856 NULL_RTX, 0, OPTAB_DIRECT);
857 if (!temp)
858 return NULL_RTX;
860 /* OP1_HIGH should now be dead. */
862 adjust = expand_binop (word_mode, add_optab, adjust, temp,
863 NULL_RTX, 0, OPTAB_DIRECT);
865 if (target && !REG_P (target))
866 target = NULL_RTX;
868 if (umulp)
869 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
870 target, 1, OPTAB_DIRECT);
871 else
872 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
873 target, 1, OPTAB_DIRECT);
875 if (!product)
876 return NULL_RTX;
878 product_high = operand_subword (product, high, 1, mode);
879 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
880 NULL_RTX, 0, OPTAB_DIRECT);
881 emit_move_insn (product_high, adjust);
882 return product;
885 /* Wrapper around expand_binop which takes an rtx code to specify
886 the operation to perform, not an optab pointer. All other
887 arguments are the same. */
889 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
890 rtx op1, rtx target, int unsignedp,
891 enum optab_methods methods)
893 optab binop = code_to_optab (code);
894 gcc_assert (binop);
896 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
899 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
900 binop. Order them according to commutative_operand_precedence and, if
901 possible, try to put TARGET or a pseudo first. */
902 static bool
903 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
905 int op0_prec = commutative_operand_precedence (op0);
906 int op1_prec = commutative_operand_precedence (op1);
908 if (op0_prec < op1_prec)
909 return true;
911 if (op0_prec > op1_prec)
912 return false;
914 /* With equal precedence, both orders are ok, but it is better if the
915 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
916 if (target == 0 || REG_P (target))
917 return (REG_P (op1) && !REG_P (op0)) || target == op1;
918 else
919 return rtx_equal_p (op1, target);
922 /* Return true if BINOPTAB implements a shift operation. */
924 static bool
925 shift_optab_p (optab binoptab)
927 switch (optab_to_code (binoptab))
929 case ASHIFT:
930 case SS_ASHIFT:
931 case US_ASHIFT:
932 case ASHIFTRT:
933 case LSHIFTRT:
934 case ROTATE:
935 case ROTATERT:
936 return true;
938 default:
939 return false;
943 /* Return true if BINOPTAB implements a commutative binary operation. */
945 static bool
946 commutative_optab_p (optab binoptab)
948 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
949 || binoptab == smul_widen_optab
950 || binoptab == umul_widen_optab
951 || binoptab == smul_highpart_optab
952 || binoptab == umul_highpart_optab);
955 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
956 optimizing, and if the operand is a constant that costs more than
957 1 instruction, force the constant into a register and return that
958 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
960 static rtx
961 avoid_expensive_constant (machine_mode mode, optab binoptab,
962 int opn, rtx x, bool unsignedp)
964 bool speed = optimize_insn_for_speed_p ();
966 if (mode != VOIDmode
967 && optimize
968 && CONSTANT_P (x)
969 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
970 > set_src_cost (x, mode, speed)))
972 if (CONST_INT_P (x))
974 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
975 if (intval != INTVAL (x))
976 x = GEN_INT (intval);
978 else
979 x = convert_modes (mode, VOIDmode, x, unsignedp);
980 x = force_reg (mode, x);
982 return x;
985 /* Helper function for expand_binop: handle the case where there
986 is an insn that directly implements the indicated operation.
987 Returns null if this is not possible. */
988 static rtx
989 expand_binop_directly (machine_mode mode, optab binoptab,
990 rtx op0, rtx op1,
991 rtx target, int unsignedp, enum optab_methods methods,
992 rtx_insn *last)
994 machine_mode from_mode = widened_mode (mode, op0, op1);
995 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
996 from_mode, 1);
997 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
998 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
999 machine_mode mode0, mode1, tmp_mode;
1000 struct expand_operand ops[3];
1001 bool commutative_p;
1002 rtx_insn *pat;
1003 rtx xop0 = op0, xop1 = op1;
1005 /* If it is a commutative operator and the modes would match
1006 if we would swap the operands, we can save the conversions. */
1007 commutative_p = commutative_optab_p (binoptab);
1008 if (commutative_p
1009 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1010 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1011 std::swap (xop0, xop1);
1013 /* If we are optimizing, force expensive constants into a register. */
1014 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1015 if (!shift_optab_p (binoptab))
1016 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1018 /* In case the insn wants input operands in modes different from
1019 those of the actual operands, convert the operands. It would
1020 seem that we don't need to convert CONST_INTs, but we do, so
1021 that they're properly zero-extended, sign-extended or truncated
1022 for their mode. */
1024 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1025 if (xmode0 != VOIDmode && xmode0 != mode0)
1027 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1028 mode0 = xmode0;
1031 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1032 if (xmode1 != VOIDmode && xmode1 != mode1)
1034 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1035 mode1 = xmode1;
1038 /* If operation is commutative,
1039 try to make the first operand a register.
1040 Even better, try to make it the same as the target.
1041 Also try to make the last operand a constant. */
1042 if (commutative_p
1043 && swap_commutative_operands_with_target (target, xop0, xop1))
1044 std::swap (xop0, xop1);
1046 /* Now, if insn's predicates don't allow our operands, put them into
1047 pseudo regs. */
1049 if (binoptab == vec_pack_trunc_optab
1050 || binoptab == vec_pack_usat_optab
1051 || binoptab == vec_pack_ssat_optab
1052 || binoptab == vec_pack_ufix_trunc_optab
1053 || binoptab == vec_pack_sfix_trunc_optab)
1055 /* The mode of the result is different then the mode of the
1056 arguments. */
1057 tmp_mode = insn_data[(int) icode].operand[0].mode;
1058 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1060 delete_insns_since (last);
1061 return NULL_RTX;
1064 else
1065 tmp_mode = mode;
1067 create_output_operand (&ops[0], target, tmp_mode);
1068 create_input_operand (&ops[1], xop0, mode0);
1069 create_input_operand (&ops[2], xop1, mode1);
1070 pat = maybe_gen_insn (icode, 3, ops);
1071 if (pat)
1073 /* If PAT is composed of more than one insn, try to add an appropriate
1074 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1075 operand, call expand_binop again, this time without a target. */
1076 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1077 && ! add_equal_note (pat, ops[0].value,
1078 optab_to_code (binoptab),
1079 ops[1].value, ops[2].value))
1081 delete_insns_since (last);
1082 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1083 unsignedp, methods);
1086 emit_insn (pat);
1087 return ops[0].value;
1089 delete_insns_since (last);
1090 return NULL_RTX;
1093 /* Generate code to perform an operation specified by BINOPTAB
1094 on operands OP0 and OP1, with result having machine-mode MODE.
1096 UNSIGNEDP is for the case where we have to widen the operands
1097 to perform the operation. It says to use zero-extension.
1099 If TARGET is nonzero, the value
1100 is generated there, if it is convenient to do so.
1101 In all cases an rtx is returned for the locus of the value;
1102 this may or may not be TARGET. */
1105 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1106 rtx target, int unsignedp, enum optab_methods methods)
1108 enum optab_methods next_methods
1109 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1110 ? OPTAB_WIDEN : methods);
1111 enum mode_class mclass;
1112 machine_mode wider_mode;
1113 rtx libfunc;
1114 rtx temp;
1115 rtx_insn *entry_last = get_last_insn ();
1116 rtx_insn *last;
1118 mclass = GET_MODE_CLASS (mode);
1120 /* If subtracting an integer constant, convert this into an addition of
1121 the negated constant. */
1123 if (binoptab == sub_optab && CONST_INT_P (op1))
1125 op1 = negate_rtx (mode, op1);
1126 binoptab = add_optab;
1129 /* Record where to delete back to if we backtrack. */
1130 last = get_last_insn ();
1132 /* If we can do it with a three-operand insn, do so. */
1134 if (methods != OPTAB_MUST_WIDEN
1135 && find_widening_optab_handler (binoptab, mode,
1136 widened_mode (mode, op0, op1), 1)
1137 != CODE_FOR_nothing)
1139 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1140 unsignedp, methods, last);
1141 if (temp)
1142 return temp;
1145 /* If we were trying to rotate, and that didn't work, try rotating
1146 the other direction before falling back to shifts and bitwise-or. */
1147 if (((binoptab == rotl_optab
1148 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1149 || (binoptab == rotr_optab
1150 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1151 && mclass == MODE_INT)
1153 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1154 rtx newop1;
1155 unsigned int bits = GET_MODE_PRECISION (mode);
1157 if (CONST_INT_P (op1))
1158 newop1 = GEN_INT (bits - INTVAL (op1));
1159 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1160 newop1 = negate_rtx (GET_MODE (op1), op1);
1161 else
1162 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1163 gen_int_mode (bits, GET_MODE (op1)), op1,
1164 NULL_RTX, unsignedp, OPTAB_DIRECT);
1166 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1167 target, unsignedp, methods, last);
1168 if (temp)
1169 return temp;
1172 /* If this is a multiply, see if we can do a widening operation that
1173 takes operands of this mode and makes a wider mode. */
1175 if (binoptab == smul_optab
1176 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1177 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1178 : smul_widen_optab),
1179 GET_MODE_2XWIDER_MODE (mode), mode)
1180 != CODE_FOR_nothing))
1182 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1183 unsignedp ? umul_widen_optab : smul_widen_optab,
1184 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1186 if (temp != 0)
1188 if (GET_MODE_CLASS (mode) == MODE_INT
1189 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1190 return gen_lowpart (mode, temp);
1191 else
1192 return convert_to_mode (mode, temp, unsignedp);
1196 /* If this is a vector shift by a scalar, see if we can do a vector
1197 shift by a vector. If so, broadcast the scalar into a vector. */
1198 if (mclass == MODE_VECTOR_INT)
1200 optab otheroptab = unknown_optab;
1202 if (binoptab == ashl_optab)
1203 otheroptab = vashl_optab;
1204 else if (binoptab == ashr_optab)
1205 otheroptab = vashr_optab;
1206 else if (binoptab == lshr_optab)
1207 otheroptab = vlshr_optab;
1208 else if (binoptab == rotl_optab)
1209 otheroptab = vrotl_optab;
1210 else if (binoptab == rotr_optab)
1211 otheroptab = vrotr_optab;
1213 if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing)
1215 /* The scalar may have been extended to be too wide. Truncate
1216 it back to the proper size to fit in the broadcast vector. */
1217 machine_mode inner_mode = GET_MODE_INNER (mode);
1218 if (!CONST_INT_P (op1)
1219 && (GET_MODE_BITSIZE (inner_mode)
1220 < GET_MODE_BITSIZE (GET_MODE (op1))))
1221 op1 = force_reg (inner_mode,
1222 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1223 GET_MODE (op1)));
1224 rtx vop1 = expand_vector_broadcast (mode, op1);
1225 if (vop1)
1227 temp = expand_binop_directly (mode, otheroptab, op0, vop1,
1228 target, unsignedp, methods, last);
1229 if (temp)
1230 return temp;
1235 /* Look for a wider mode of the same class for which we think we
1236 can open-code the operation. Check for a widening multiply at the
1237 wider mode as well. */
1239 if (CLASS_HAS_WIDER_MODES_P (mclass)
1240 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1241 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1242 wider_mode != VOIDmode;
1243 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1245 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1246 || (binoptab == smul_optab
1247 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1248 && (find_widening_optab_handler ((unsignedp
1249 ? umul_widen_optab
1250 : smul_widen_optab),
1251 GET_MODE_WIDER_MODE (wider_mode),
1252 mode, 0)
1253 != CODE_FOR_nothing)))
1255 rtx xop0 = op0, xop1 = op1;
1256 int no_extend = 0;
1258 /* For certain integer operations, we need not actually extend
1259 the narrow operands, as long as we will truncate
1260 the results to the same narrowness. */
1262 if ((binoptab == ior_optab || binoptab == and_optab
1263 || binoptab == xor_optab
1264 || binoptab == add_optab || binoptab == sub_optab
1265 || binoptab == smul_optab || binoptab == ashl_optab)
1266 && mclass == MODE_INT)
1268 no_extend = 1;
1269 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1270 xop0, unsignedp);
1271 if (binoptab != ashl_optab)
1272 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1273 xop1, unsignedp);
1276 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1278 /* The second operand of a shift must always be extended. */
1279 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1280 no_extend && binoptab != ashl_optab);
1282 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1283 unsignedp, OPTAB_DIRECT);
1284 if (temp)
1286 if (mclass != MODE_INT
1287 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1289 if (target == 0)
1290 target = gen_reg_rtx (mode);
1291 convert_move (target, temp, 0);
1292 return target;
1294 else
1295 return gen_lowpart (mode, temp);
1297 else
1298 delete_insns_since (last);
1302 /* If operation is commutative,
1303 try to make the first operand a register.
1304 Even better, try to make it the same as the target.
1305 Also try to make the last operand a constant. */
1306 if (commutative_optab_p (binoptab)
1307 && swap_commutative_operands_with_target (target, op0, op1))
1308 std::swap (op0, op1);
1310 /* These can be done a word at a time. */
1311 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1312 && mclass == MODE_INT
1313 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1314 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1316 int i;
1317 rtx_insn *insns;
1319 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1320 won't be accurate, so use a new target. */
1321 if (target == 0
1322 || target == op0
1323 || target == op1
1324 || !valid_multiword_target_p (target))
1325 target = gen_reg_rtx (mode);
1327 start_sequence ();
1329 /* Do the actual arithmetic. */
1330 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1332 rtx target_piece = operand_subword (target, i, 1, mode);
1333 rtx x = expand_binop (word_mode, binoptab,
1334 operand_subword_force (op0, i, mode),
1335 operand_subword_force (op1, i, mode),
1336 target_piece, unsignedp, next_methods);
1338 if (x == 0)
1339 break;
1341 if (target_piece != x)
1342 emit_move_insn (target_piece, x);
1345 insns = get_insns ();
1346 end_sequence ();
1348 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1350 emit_insn (insns);
1351 return target;
1355 /* Synthesize double word shifts from single word shifts. */
1356 if ((binoptab == lshr_optab || binoptab == ashl_optab
1357 || binoptab == ashr_optab)
1358 && mclass == MODE_INT
1359 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1360 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1361 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1362 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1363 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1364 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1366 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1367 machine_mode op1_mode;
1369 double_shift_mask = targetm.shift_truncation_mask (mode);
1370 shift_mask = targetm.shift_truncation_mask (word_mode);
1371 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1373 /* Apply the truncation to constant shifts. */
1374 if (double_shift_mask > 0 && CONST_INT_P (op1))
1375 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1377 if (op1 == CONST0_RTX (op1_mode))
1378 return op0;
1380 /* Make sure that this is a combination that expand_doubleword_shift
1381 can handle. See the comments there for details. */
1382 if (double_shift_mask == 0
1383 || (shift_mask == BITS_PER_WORD - 1
1384 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1386 rtx_insn *insns;
1387 rtx into_target, outof_target;
1388 rtx into_input, outof_input;
1389 int left_shift, outof_word;
1391 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1392 won't be accurate, so use a new target. */
1393 if (target == 0
1394 || target == op0
1395 || target == op1
1396 || !valid_multiword_target_p (target))
1397 target = gen_reg_rtx (mode);
1399 start_sequence ();
1401 /* OUTOF_* is the word we are shifting bits away from, and
1402 INTO_* is the word that we are shifting bits towards, thus
1403 they differ depending on the direction of the shift and
1404 WORDS_BIG_ENDIAN. */
1406 left_shift = binoptab == ashl_optab;
1407 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1409 outof_target = operand_subword (target, outof_word, 1, mode);
1410 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1412 outof_input = operand_subword_force (op0, outof_word, mode);
1413 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1415 if (expand_doubleword_shift (op1_mode, binoptab,
1416 outof_input, into_input, op1,
1417 outof_target, into_target,
1418 unsignedp, next_methods, shift_mask))
1420 insns = get_insns ();
1421 end_sequence ();
1423 emit_insn (insns);
1424 return target;
1426 end_sequence ();
1430 /* Synthesize double word rotates from single word shifts. */
1431 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1432 && mclass == MODE_INT
1433 && CONST_INT_P (op1)
1434 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1435 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1436 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1438 rtx_insn *insns;
1439 rtx into_target, outof_target;
1440 rtx into_input, outof_input;
1441 rtx inter;
1442 int shift_count, left_shift, outof_word;
1444 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1445 won't be accurate, so use a new target. Do this also if target is not
1446 a REG, first because having a register instead may open optimization
1447 opportunities, and second because if target and op0 happen to be MEMs
1448 designating the same location, we would risk clobbering it too early
1449 in the code sequence we generate below. */
1450 if (target == 0
1451 || target == op0
1452 || target == op1
1453 || !REG_P (target)
1454 || !valid_multiword_target_p (target))
1455 target = gen_reg_rtx (mode);
1457 start_sequence ();
1459 shift_count = INTVAL (op1);
1461 /* OUTOF_* is the word we are shifting bits away from, and
1462 INTO_* is the word that we are shifting bits towards, thus
1463 they differ depending on the direction of the shift and
1464 WORDS_BIG_ENDIAN. */
1466 left_shift = (binoptab == rotl_optab);
1467 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1469 outof_target = operand_subword (target, outof_word, 1, mode);
1470 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1472 outof_input = operand_subword_force (op0, outof_word, mode);
1473 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1475 if (shift_count == BITS_PER_WORD)
1477 /* This is just a word swap. */
1478 emit_move_insn (outof_target, into_input);
1479 emit_move_insn (into_target, outof_input);
1480 inter = const0_rtx;
1482 else
1484 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1485 rtx first_shift_count, second_shift_count;
1486 optab reverse_unsigned_shift, unsigned_shift;
1488 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1489 ? lshr_optab : ashl_optab);
1491 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1492 ? ashl_optab : lshr_optab);
1494 if (shift_count > BITS_PER_WORD)
1496 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1497 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1499 else
1501 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1502 second_shift_count = GEN_INT (shift_count);
1505 into_temp1 = expand_binop (word_mode, unsigned_shift,
1506 outof_input, first_shift_count,
1507 NULL_RTX, unsignedp, next_methods);
1508 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1509 into_input, second_shift_count,
1510 NULL_RTX, unsignedp, next_methods);
1512 if (into_temp1 != 0 && into_temp2 != 0)
1513 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1514 into_target, unsignedp, next_methods);
1515 else
1516 inter = 0;
1518 if (inter != 0 && inter != into_target)
1519 emit_move_insn (into_target, inter);
1521 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1522 into_input, first_shift_count,
1523 NULL_RTX, unsignedp, next_methods);
1524 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1525 outof_input, second_shift_count,
1526 NULL_RTX, unsignedp, next_methods);
1528 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1529 inter = expand_binop (word_mode, ior_optab,
1530 outof_temp1, outof_temp2,
1531 outof_target, unsignedp, next_methods);
1533 if (inter != 0 && inter != outof_target)
1534 emit_move_insn (outof_target, inter);
1537 insns = get_insns ();
1538 end_sequence ();
1540 if (inter != 0)
1542 emit_insn (insns);
1543 return target;
1547 /* These can be done a word at a time by propagating carries. */
1548 if ((binoptab == add_optab || binoptab == sub_optab)
1549 && mclass == MODE_INT
1550 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1551 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1553 unsigned int i;
1554 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1555 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1556 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1557 rtx xop0, xop1, xtarget;
1559 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1560 value is one of those, use it. Otherwise, use 1 since it is the
1561 one easiest to get. */
1562 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1563 int normalizep = STORE_FLAG_VALUE;
1564 #else
1565 int normalizep = 1;
1566 #endif
1568 /* Prepare the operands. */
1569 xop0 = force_reg (mode, op0);
1570 xop1 = force_reg (mode, op1);
1572 xtarget = gen_reg_rtx (mode);
1574 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1575 target = xtarget;
1577 /* Indicate for flow that the entire target reg is being set. */
1578 if (REG_P (target))
1579 emit_clobber (xtarget);
1581 /* Do the actual arithmetic. */
1582 for (i = 0; i < nwords; i++)
1584 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1585 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1586 rtx op0_piece = operand_subword_force (xop0, index, mode);
1587 rtx op1_piece = operand_subword_force (xop1, index, mode);
1588 rtx x;
1590 /* Main add/subtract of the input operands. */
1591 x = expand_binop (word_mode, binoptab,
1592 op0_piece, op1_piece,
1593 target_piece, unsignedp, next_methods);
1594 if (x == 0)
1595 break;
1597 if (i + 1 < nwords)
1599 /* Store carry from main add/subtract. */
1600 carry_out = gen_reg_rtx (word_mode);
1601 carry_out = emit_store_flag_force (carry_out,
1602 (binoptab == add_optab
1603 ? LT : GT),
1604 x, op0_piece,
1605 word_mode, 1, normalizep);
1608 if (i > 0)
1610 rtx newx;
1612 /* Add/subtract previous carry to main result. */
1613 newx = expand_binop (word_mode,
1614 normalizep == 1 ? binoptab : otheroptab,
1615 x, carry_in,
1616 NULL_RTX, 1, next_methods);
1618 if (i + 1 < nwords)
1620 /* Get out carry from adding/subtracting carry in. */
1621 rtx carry_tmp = gen_reg_rtx (word_mode);
1622 carry_tmp = emit_store_flag_force (carry_tmp,
1623 (binoptab == add_optab
1624 ? LT : GT),
1625 newx, x,
1626 word_mode, 1, normalizep);
1628 /* Logical-ior the two poss. carry together. */
1629 carry_out = expand_binop (word_mode, ior_optab,
1630 carry_out, carry_tmp,
1631 carry_out, 0, next_methods);
1632 if (carry_out == 0)
1633 break;
1635 emit_move_insn (target_piece, newx);
1637 else
1639 if (x != target_piece)
1640 emit_move_insn (target_piece, x);
1643 carry_in = carry_out;
1646 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1648 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
1649 || ! rtx_equal_p (target, xtarget))
1651 rtx_insn *temp = emit_move_insn (target, xtarget);
1653 set_dst_reg_note (temp, REG_EQUAL,
1654 gen_rtx_fmt_ee (optab_to_code (binoptab),
1655 mode, copy_rtx (xop0),
1656 copy_rtx (xop1)),
1657 target);
1659 else
1660 target = xtarget;
1662 return target;
1665 else
1666 delete_insns_since (last);
1669 /* Attempt to synthesize double word multiplies using a sequence of word
1670 mode multiplications. We first attempt to generate a sequence using a
1671 more efficient unsigned widening multiply, and if that fails we then
1672 try using a signed widening multiply. */
1674 if (binoptab == smul_optab
1675 && mclass == MODE_INT
1676 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1677 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1678 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1680 rtx product = NULL_RTX;
1681 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
1682 != CODE_FOR_nothing)
1684 product = expand_doubleword_mult (mode, op0, op1, target,
1685 true, methods);
1686 if (!product)
1687 delete_insns_since (last);
1690 if (product == NULL_RTX
1691 && widening_optab_handler (smul_widen_optab, mode, word_mode)
1692 != CODE_FOR_nothing)
1694 product = expand_doubleword_mult (mode, op0, op1, target,
1695 false, methods);
1696 if (!product)
1697 delete_insns_since (last);
1700 if (product != NULL_RTX)
1702 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
1704 temp = emit_move_insn (target ? target : product, product);
1705 set_dst_reg_note (temp,
1706 REG_EQUAL,
1707 gen_rtx_fmt_ee (MULT, mode,
1708 copy_rtx (op0),
1709 copy_rtx (op1)),
1710 target ? target : product);
1712 return product;
1716 /* It can't be open-coded in this mode.
1717 Use a library call if one is available and caller says that's ok. */
1719 libfunc = optab_libfunc (binoptab, mode);
1720 if (libfunc
1721 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1723 rtx_insn *insns;
1724 rtx op1x = op1;
1725 machine_mode op1_mode = mode;
1726 rtx value;
1728 start_sequence ();
1730 if (shift_optab_p (binoptab))
1732 op1_mode = targetm.libgcc_shift_count_mode ();
1733 /* Specify unsigned here,
1734 since negative shift counts are meaningless. */
1735 op1x = convert_to_mode (op1_mode, op1, 1);
1738 if (GET_MODE (op0) != VOIDmode
1739 && GET_MODE (op0) != mode)
1740 op0 = convert_to_mode (mode, op0, unsignedp);
1742 /* Pass 1 for NO_QUEUE so we don't lose any increments
1743 if the libcall is cse'd or moved. */
1744 value = emit_library_call_value (libfunc,
1745 NULL_RTX, LCT_CONST, mode, 2,
1746 op0, mode, op1x, op1_mode);
1748 insns = get_insns ();
1749 end_sequence ();
1751 target = gen_reg_rtx (mode);
1752 emit_libcall_block_1 (insns, target, value,
1753 gen_rtx_fmt_ee (optab_to_code (binoptab),
1754 mode, op0, op1),
1755 trapv_binoptab_p (binoptab));
1757 return target;
1760 delete_insns_since (last);
1762 /* It can't be done in this mode. Can we do it in a wider mode? */
1764 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1765 || methods == OPTAB_MUST_WIDEN))
1767 /* Caller says, don't even try. */
1768 delete_insns_since (entry_last);
1769 return 0;
1772 /* Compute the value of METHODS to pass to recursive calls.
1773 Don't allow widening to be tried recursively. */
1775 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1777 /* Look for a wider mode of the same class for which it appears we can do
1778 the operation. */
1780 if (CLASS_HAS_WIDER_MODES_P (mclass))
1782 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1783 wider_mode != VOIDmode;
1784 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1786 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
1787 != CODE_FOR_nothing
1788 || (methods == OPTAB_LIB
1789 && optab_libfunc (binoptab, wider_mode)))
1791 rtx xop0 = op0, xop1 = op1;
1792 int no_extend = 0;
1794 /* For certain integer operations, we need not actually extend
1795 the narrow operands, as long as we will truncate
1796 the results to the same narrowness. */
1798 if ((binoptab == ior_optab || binoptab == and_optab
1799 || binoptab == xor_optab
1800 || binoptab == add_optab || binoptab == sub_optab
1801 || binoptab == smul_optab || binoptab == ashl_optab)
1802 && mclass == MODE_INT)
1803 no_extend = 1;
1805 xop0 = widen_operand (xop0, wider_mode, mode,
1806 unsignedp, no_extend);
1808 /* The second operand of a shift must always be extended. */
1809 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1810 no_extend && binoptab != ashl_optab);
1812 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1813 unsignedp, methods);
1814 if (temp)
1816 if (mclass != MODE_INT
1817 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1819 if (target == 0)
1820 target = gen_reg_rtx (mode);
1821 convert_move (target, temp, 0);
1822 return target;
1824 else
1825 return gen_lowpart (mode, temp);
1827 else
1828 delete_insns_since (last);
1833 delete_insns_since (entry_last);
1834 return 0;
1837 /* Expand a binary operator which has both signed and unsigned forms.
1838 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1839 signed operations.
1841 If we widen unsigned operands, we may use a signed wider operation instead
1842 of an unsigned wider operation, since the result would be the same. */
1845 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
1846 rtx op0, rtx op1, rtx target, int unsignedp,
1847 enum optab_methods methods)
1849 rtx temp;
1850 optab direct_optab = unsignedp ? uoptab : soptab;
1851 bool save_enable;
1853 /* Do it without widening, if possible. */
1854 temp = expand_binop (mode, direct_optab, op0, op1, target,
1855 unsignedp, OPTAB_DIRECT);
1856 if (temp || methods == OPTAB_DIRECT)
1857 return temp;
1859 /* Try widening to a signed int. Disable any direct use of any
1860 signed insn in the current mode. */
1861 save_enable = swap_optab_enable (soptab, mode, false);
1863 temp = expand_binop (mode, soptab, op0, op1, target,
1864 unsignedp, OPTAB_WIDEN);
1866 /* For unsigned operands, try widening to an unsigned int. */
1867 if (!temp && unsignedp)
1868 temp = expand_binop (mode, uoptab, op0, op1, target,
1869 unsignedp, OPTAB_WIDEN);
1870 if (temp || methods == OPTAB_WIDEN)
1871 goto egress;
1873 /* Use the right width libcall if that exists. */
1874 temp = expand_binop (mode, direct_optab, op0, op1, target,
1875 unsignedp, OPTAB_LIB);
1876 if (temp || methods == OPTAB_LIB)
1877 goto egress;
1879 /* Must widen and use a libcall, use either signed or unsigned. */
1880 temp = expand_binop (mode, soptab, op0, op1, target,
1881 unsignedp, methods);
1882 if (!temp && unsignedp)
1883 temp = expand_binop (mode, uoptab, op0, op1, target,
1884 unsignedp, methods);
1886 egress:
1887 /* Undo the fiddling above. */
1888 if (save_enable)
1889 swap_optab_enable (soptab, mode, true);
1890 return temp;
1893 /* Generate code to perform an operation specified by UNOPPTAB
1894 on operand OP0, with two results to TARG0 and TARG1.
1895 We assume that the order of the operands for the instruction
1896 is TARG0, TARG1, OP0.
1898 Either TARG0 or TARG1 may be zero, but what that means is that
1899 the result is not actually wanted. We will generate it into
1900 a dummy pseudo-reg and discard it. They may not both be zero.
1902 Returns 1 if this operation can be performed; 0 if not. */
1905 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1906 int unsignedp)
1908 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1909 enum mode_class mclass;
1910 machine_mode wider_mode;
1911 rtx_insn *entry_last = get_last_insn ();
1912 rtx_insn *last;
1914 mclass = GET_MODE_CLASS (mode);
1916 if (!targ0)
1917 targ0 = gen_reg_rtx (mode);
1918 if (!targ1)
1919 targ1 = gen_reg_rtx (mode);
1921 /* Record where to go back to if we fail. */
1922 last = get_last_insn ();
1924 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
1926 struct expand_operand ops[3];
1927 enum insn_code icode = optab_handler (unoptab, mode);
1929 create_fixed_operand (&ops[0], targ0);
1930 create_fixed_operand (&ops[1], targ1);
1931 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
1932 if (maybe_expand_insn (icode, 3, ops))
1933 return 1;
1936 /* It can't be done in this mode. Can we do it in a wider mode? */
1938 if (CLASS_HAS_WIDER_MODES_P (mclass))
1940 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1941 wider_mode != VOIDmode;
1942 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1944 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
1946 rtx t0 = gen_reg_rtx (wider_mode);
1947 rtx t1 = gen_reg_rtx (wider_mode);
1948 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1950 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
1952 convert_move (targ0, t0, unsignedp);
1953 convert_move (targ1, t1, unsignedp);
1954 return 1;
1956 else
1957 delete_insns_since (last);
1962 delete_insns_since (entry_last);
1963 return 0;
1966 /* Generate code to perform an operation specified by BINOPTAB
1967 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1968 We assume that the order of the operands for the instruction
1969 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1970 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1972 Either TARG0 or TARG1 may be zero, but what that means is that
1973 the result is not actually wanted. We will generate it into
1974 a dummy pseudo-reg and discard it. They may not both be zero.
1976 Returns 1 if this operation can be performed; 0 if not. */
1979 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
1980 int unsignedp)
1982 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1983 enum mode_class mclass;
1984 machine_mode wider_mode;
1985 rtx_insn *entry_last = get_last_insn ();
1986 rtx_insn *last;
1988 mclass = GET_MODE_CLASS (mode);
1990 if (!targ0)
1991 targ0 = gen_reg_rtx (mode);
1992 if (!targ1)
1993 targ1 = gen_reg_rtx (mode);
1995 /* Record where to go back to if we fail. */
1996 last = get_last_insn ();
1998 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2000 struct expand_operand ops[4];
2001 enum insn_code icode = optab_handler (binoptab, mode);
2002 machine_mode mode0 = insn_data[icode].operand[1].mode;
2003 machine_mode mode1 = insn_data[icode].operand[2].mode;
2004 rtx xop0 = op0, xop1 = op1;
2006 /* If we are optimizing, force expensive constants into a register. */
2007 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2008 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2010 create_fixed_operand (&ops[0], targ0);
2011 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2012 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2013 create_fixed_operand (&ops[3], targ1);
2014 if (maybe_expand_insn (icode, 4, ops))
2015 return 1;
2016 delete_insns_since (last);
2019 /* It can't be done in this mode. Can we do it in a wider mode? */
2021 if (CLASS_HAS_WIDER_MODES_P (mclass))
2023 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2024 wider_mode != VOIDmode;
2025 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2027 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2029 rtx t0 = gen_reg_rtx (wider_mode);
2030 rtx t1 = gen_reg_rtx (wider_mode);
2031 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2032 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2034 if (expand_twoval_binop (binoptab, cop0, cop1,
2035 t0, t1, unsignedp))
2037 convert_move (targ0, t0, unsignedp);
2038 convert_move (targ1, t1, unsignedp);
2039 return 1;
2041 else
2042 delete_insns_since (last);
2047 delete_insns_since (entry_last);
2048 return 0;
2051 /* Expand the two-valued library call indicated by BINOPTAB, but
2052 preserve only one of the values. If TARG0 is non-NULL, the first
2053 value is placed into TARG0; otherwise the second value is placed
2054 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2055 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2056 This routine assumes that the value returned by the library call is
2057 as if the return value was of an integral mode twice as wide as the
2058 mode of OP0. Returns 1 if the call was successful. */
2060 bool
2061 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2062 rtx targ0, rtx targ1, enum rtx_code code)
2064 machine_mode mode;
2065 machine_mode libval_mode;
2066 rtx libval;
2067 rtx_insn *insns;
2068 rtx libfunc;
2070 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2071 gcc_assert (!targ0 != !targ1);
2073 mode = GET_MODE (op0);
2074 libfunc = optab_libfunc (binoptab, mode);
2075 if (!libfunc)
2076 return false;
2078 /* The value returned by the library function will have twice as
2079 many bits as the nominal MODE. */
2080 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2081 MODE_INT);
2082 start_sequence ();
2083 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2084 libval_mode, 2,
2085 op0, mode,
2086 op1, mode);
2087 /* Get the part of VAL containing the value that we want. */
2088 libval = simplify_gen_subreg (mode, libval, libval_mode,
2089 targ0 ? 0 : GET_MODE_SIZE (mode));
2090 insns = get_insns ();
2091 end_sequence ();
2092 /* Move the into the desired location. */
2093 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2094 gen_rtx_fmt_ee (code, mode, op0, op1));
2096 return true;
2100 /* Wrapper around expand_unop which takes an rtx code to specify
2101 the operation to perform, not an optab pointer. All other
2102 arguments are the same. */
2104 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2105 rtx target, int unsignedp)
2107 optab unop = code_to_optab (code);
2108 gcc_assert (unop);
2110 return expand_unop (mode, unop, op0, target, unsignedp);
2113 /* Try calculating
2114 (clz:narrow x)
2116 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2118 A similar operation can be used for clrsb. UNOPTAB says which operation
2119 we are trying to expand. */
2120 static rtx
2121 widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab)
2123 enum mode_class mclass = GET_MODE_CLASS (mode);
2124 if (CLASS_HAS_WIDER_MODES_P (mclass))
2126 machine_mode wider_mode;
2127 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2128 wider_mode != VOIDmode;
2129 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2131 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2133 rtx xop0, temp;
2134 rtx_insn *last;
2136 last = get_last_insn ();
2138 if (target == 0)
2139 target = gen_reg_rtx (mode);
2140 xop0 = widen_operand (op0, wider_mode, mode,
2141 unoptab != clrsb_optab, false);
2142 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2143 unoptab != clrsb_optab);
2144 if (temp != 0)
2145 temp = expand_binop
2146 (wider_mode, sub_optab, temp,
2147 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2148 - GET_MODE_PRECISION (mode),
2149 wider_mode),
2150 target, true, OPTAB_DIRECT);
2151 if (temp == 0)
2152 delete_insns_since (last);
2154 return temp;
2158 return 0;
2161 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2162 quantities, choosing which based on whether the high word is nonzero. */
2163 static rtx
2164 expand_doubleword_clz (machine_mode mode, rtx op0, rtx target)
2166 rtx xop0 = force_reg (mode, op0);
2167 rtx subhi = gen_highpart (word_mode, xop0);
2168 rtx sublo = gen_lowpart (word_mode, xop0);
2169 rtx_code_label *hi0_label = gen_label_rtx ();
2170 rtx_code_label *after_label = gen_label_rtx ();
2171 rtx_insn *seq;
2172 rtx temp, result;
2174 /* If we were not given a target, use a word_mode register, not a
2175 'mode' register. The result will fit, and nobody is expecting
2176 anything bigger (the return type of __builtin_clz* is int). */
2177 if (!target)
2178 target = gen_reg_rtx (word_mode);
2180 /* In any case, write to a word_mode scratch in both branches of the
2181 conditional, so we can ensure there is a single move insn setting
2182 'target' to tag a REG_EQUAL note on. */
2183 result = gen_reg_rtx (word_mode);
2185 start_sequence ();
2187 /* If the high word is not equal to zero,
2188 then clz of the full value is clz of the high word. */
2189 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2190 word_mode, true, hi0_label);
2192 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2193 if (!temp)
2194 goto fail;
2196 if (temp != result)
2197 convert_move (result, temp, true);
2199 emit_jump_insn (targetm.gen_jump (after_label));
2200 emit_barrier ();
2202 /* Else clz of the full value is clz of the low word plus the number
2203 of bits in the high word. */
2204 emit_label (hi0_label);
2206 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2207 if (!temp)
2208 goto fail;
2209 temp = expand_binop (word_mode, add_optab, temp,
2210 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2211 result, true, OPTAB_DIRECT);
2212 if (!temp)
2213 goto fail;
2214 if (temp != result)
2215 convert_move (result, temp, true);
2217 emit_label (after_label);
2218 convert_move (target, result, true);
2220 seq = get_insns ();
2221 end_sequence ();
2223 add_equal_note (seq, target, CLZ, xop0, 0);
2224 emit_insn (seq);
2225 return target;
2227 fail:
2228 end_sequence ();
2229 return 0;
2232 /* Try calculating
2233 (bswap:narrow x)
2235 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2236 static rtx
2237 widen_bswap (machine_mode mode, rtx op0, rtx target)
2239 enum mode_class mclass = GET_MODE_CLASS (mode);
2240 machine_mode wider_mode;
2241 rtx x;
2242 rtx_insn *last;
2244 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2245 return NULL_RTX;
2247 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2248 wider_mode != VOIDmode;
2249 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2250 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2251 goto found;
2252 return NULL_RTX;
2254 found:
2255 last = get_last_insn ();
2257 x = widen_operand (op0, wider_mode, mode, true, true);
2258 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2260 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2261 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2262 if (x != 0)
2263 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2264 GET_MODE_BITSIZE (wider_mode)
2265 - GET_MODE_BITSIZE (mode),
2266 NULL_RTX, true);
2268 if (x != 0)
2270 if (target == 0)
2271 target = gen_reg_rtx (mode);
2272 emit_move_insn (target, gen_lowpart (mode, x));
2274 else
2275 delete_insns_since (last);
2277 return target;
2280 /* Try calculating bswap as two bswaps of two word-sized operands. */
2282 static rtx
2283 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2285 rtx t0, t1;
2287 t1 = expand_unop (word_mode, bswap_optab,
2288 operand_subword_force (op, 0, mode), NULL_RTX, true);
2289 t0 = expand_unop (word_mode, bswap_optab,
2290 operand_subword_force (op, 1, mode), NULL_RTX, true);
2292 if (target == 0 || !valid_multiword_target_p (target))
2293 target = gen_reg_rtx (mode);
2294 if (REG_P (target))
2295 emit_clobber (target);
2296 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2297 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2299 return target;
2302 /* Try calculating (parity x) as (and (popcount x) 1), where
2303 popcount can also be done in a wider mode. */
2304 static rtx
2305 expand_parity (machine_mode mode, rtx op0, rtx target)
2307 enum mode_class mclass = GET_MODE_CLASS (mode);
2308 if (CLASS_HAS_WIDER_MODES_P (mclass))
2310 machine_mode wider_mode;
2311 for (wider_mode = mode; wider_mode != VOIDmode;
2312 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2314 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2316 rtx xop0, temp;
2317 rtx_insn *last;
2319 last = get_last_insn ();
2321 if (target == 0)
2322 target = gen_reg_rtx (mode);
2323 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2324 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2325 true);
2326 if (temp != 0)
2327 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2328 target, true, OPTAB_DIRECT);
2329 if (temp == 0)
2330 delete_insns_since (last);
2332 return temp;
2336 return 0;
2339 /* Try calculating ctz(x) as K - clz(x & -x) ,
2340 where K is GET_MODE_PRECISION(mode) - 1.
2342 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2343 don't have to worry about what the hardware does in that case. (If
2344 the clz instruction produces the usual value at 0, which is K, the
2345 result of this code sequence will be -1; expand_ffs, below, relies
2346 on this. It might be nice to have it be K instead, for consistency
2347 with the (very few) processors that provide a ctz with a defined
2348 value, but that would take one more instruction, and it would be
2349 less convenient for expand_ffs anyway. */
2351 static rtx
2352 expand_ctz (machine_mode mode, rtx op0, rtx target)
2354 rtx_insn *seq;
2355 rtx temp;
2357 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2358 return 0;
2360 start_sequence ();
2362 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2363 if (temp)
2364 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2365 true, OPTAB_DIRECT);
2366 if (temp)
2367 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2368 if (temp)
2369 temp = expand_binop (mode, sub_optab,
2370 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2371 temp, target,
2372 true, OPTAB_DIRECT);
2373 if (temp == 0)
2375 end_sequence ();
2376 return 0;
2379 seq = get_insns ();
2380 end_sequence ();
2382 add_equal_note (seq, temp, CTZ, op0, 0);
2383 emit_insn (seq);
2384 return temp;
2388 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2389 else with the sequence used by expand_clz.
2391 The ffs builtin promises to return zero for a zero value and ctz/clz
2392 may have an undefined value in that case. If they do not give us a
2393 convenient value, we have to generate a test and branch. */
2394 static rtx
2395 expand_ffs (machine_mode mode, rtx op0, rtx target)
2397 HOST_WIDE_INT val = 0;
2398 bool defined_at_zero = false;
2399 rtx temp;
2400 rtx_insn *seq;
2402 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2404 start_sequence ();
2406 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2407 if (!temp)
2408 goto fail;
2410 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2412 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2414 start_sequence ();
2415 temp = expand_ctz (mode, op0, 0);
2416 if (!temp)
2417 goto fail;
2419 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2421 defined_at_zero = true;
2422 val = (GET_MODE_PRECISION (mode) - 1) - val;
2425 else
2426 return 0;
2428 if (defined_at_zero && val == -1)
2429 /* No correction needed at zero. */;
2430 else
2432 /* We don't try to do anything clever with the situation found
2433 on some processors (eg Alpha) where ctz(0:mode) ==
2434 bitsize(mode). If someone can think of a way to send N to -1
2435 and leave alone all values in the range 0..N-1 (where N is a
2436 power of two), cheaper than this test-and-branch, please add it.
2438 The test-and-branch is done after the operation itself, in case
2439 the operation sets condition codes that can be recycled for this.
2440 (This is true on i386, for instance.) */
2442 rtx_code_label *nonzero_label = gen_label_rtx ();
2443 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2444 mode, true, nonzero_label);
2446 convert_move (temp, GEN_INT (-1), false);
2447 emit_label (nonzero_label);
2450 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2451 to produce a value in the range 0..bitsize. */
2452 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2453 target, false, OPTAB_DIRECT);
2454 if (!temp)
2455 goto fail;
2457 seq = get_insns ();
2458 end_sequence ();
2460 add_equal_note (seq, temp, FFS, op0, 0);
2461 emit_insn (seq);
2462 return temp;
2464 fail:
2465 end_sequence ();
2466 return 0;
2469 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2470 conditions, VAL may already be a SUBREG against which we cannot generate
2471 a further SUBREG. In this case, we expect forcing the value into a
2472 register will work around the situation. */
2474 static rtx
2475 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2476 machine_mode imode)
2478 rtx ret;
2479 ret = lowpart_subreg (omode, val, imode);
2480 if (ret == NULL)
2482 val = force_reg (imode, val);
2483 ret = lowpart_subreg (omode, val, imode);
2484 gcc_assert (ret != NULL);
2486 return ret;
2489 /* Expand a floating point absolute value or negation operation via a
2490 logical operation on the sign bit. */
2492 static rtx
2493 expand_absneg_bit (enum rtx_code code, machine_mode mode,
2494 rtx op0, rtx target)
2496 const struct real_format *fmt;
2497 int bitpos, word, nwords, i;
2498 machine_mode imode;
2499 rtx temp;
2500 rtx_insn *insns;
2502 /* The format has to have a simple sign bit. */
2503 fmt = REAL_MODE_FORMAT (mode);
2504 if (fmt == NULL)
2505 return NULL_RTX;
2507 bitpos = fmt->signbit_rw;
2508 if (bitpos < 0)
2509 return NULL_RTX;
2511 /* Don't create negative zeros if the format doesn't support them. */
2512 if (code == NEG && !fmt->has_signed_zero)
2513 return NULL_RTX;
2515 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2517 imode = int_mode_for_mode (mode);
2518 if (imode == BLKmode)
2519 return NULL_RTX;
2520 word = 0;
2521 nwords = 1;
2523 else
2525 imode = word_mode;
2527 if (FLOAT_WORDS_BIG_ENDIAN)
2528 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2529 else
2530 word = bitpos / BITS_PER_WORD;
2531 bitpos = bitpos % BITS_PER_WORD;
2532 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2535 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2536 if (code == ABS)
2537 mask = ~mask;
2539 if (target == 0
2540 || target == op0
2541 || (nwords > 1 && !valid_multiword_target_p (target)))
2542 target = gen_reg_rtx (mode);
2544 if (nwords > 1)
2546 start_sequence ();
2548 for (i = 0; i < nwords; ++i)
2550 rtx targ_piece = operand_subword (target, i, 1, mode);
2551 rtx op0_piece = operand_subword_force (op0, i, mode);
2553 if (i == word)
2555 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2556 op0_piece,
2557 immed_wide_int_const (mask, imode),
2558 targ_piece, 1, OPTAB_LIB_WIDEN);
2559 if (temp != targ_piece)
2560 emit_move_insn (targ_piece, temp);
2562 else
2563 emit_move_insn (targ_piece, op0_piece);
2566 insns = get_insns ();
2567 end_sequence ();
2569 emit_insn (insns);
2571 else
2573 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2574 gen_lowpart (imode, op0),
2575 immed_wide_int_const (mask, imode),
2576 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2577 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2579 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2580 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2581 target);
2584 return target;
2587 /* As expand_unop, but will fail rather than attempt the operation in a
2588 different mode or with a libcall. */
2589 static rtx
2590 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2591 int unsignedp)
2593 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2595 struct expand_operand ops[2];
2596 enum insn_code icode = optab_handler (unoptab, mode);
2597 rtx_insn *last = get_last_insn ();
2598 rtx_insn *pat;
2600 create_output_operand (&ops[0], target, mode);
2601 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2602 pat = maybe_gen_insn (icode, 2, ops);
2603 if (pat)
2605 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2606 && ! add_equal_note (pat, ops[0].value,
2607 optab_to_code (unoptab),
2608 ops[1].value, NULL_RTX))
2610 delete_insns_since (last);
2611 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2614 emit_insn (pat);
2616 return ops[0].value;
2619 return 0;
2622 /* Generate code to perform an operation specified by UNOPTAB
2623 on operand OP0, with result having machine-mode MODE.
2625 UNSIGNEDP is for the case where we have to widen the operands
2626 to perform the operation. It says to use zero-extension.
2628 If TARGET is nonzero, the value
2629 is generated there, if it is convenient to do so.
2630 In all cases an rtx is returned for the locus of the value;
2631 this may or may not be TARGET. */
2634 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2635 int unsignedp)
2637 enum mode_class mclass = GET_MODE_CLASS (mode);
2638 machine_mode wider_mode;
2639 rtx temp;
2640 rtx libfunc;
2642 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2643 if (temp)
2644 return temp;
2646 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2648 /* Widening (or narrowing) clz needs special treatment. */
2649 if (unoptab == clz_optab)
2651 temp = widen_leading (mode, op0, target, unoptab);
2652 if (temp)
2653 return temp;
2655 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2656 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2658 temp = expand_doubleword_clz (mode, op0, target);
2659 if (temp)
2660 return temp;
2663 goto try_libcall;
2666 if (unoptab == clrsb_optab)
2668 temp = widen_leading (mode, op0, target, unoptab);
2669 if (temp)
2670 return temp;
2671 goto try_libcall;
2674 /* Widening (or narrowing) bswap needs special treatment. */
2675 if (unoptab == bswap_optab)
2677 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2678 or ROTATERT. First try these directly; if this fails, then try the
2679 obvious pair of shifts with allowed widening, as this will probably
2680 be always more efficient than the other fallback methods. */
2681 if (mode == HImode)
2683 rtx_insn *last;
2684 rtx temp1, temp2;
2686 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2688 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
2689 unsignedp, OPTAB_DIRECT);
2690 if (temp)
2691 return temp;
2694 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2696 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
2697 unsignedp, OPTAB_DIRECT);
2698 if (temp)
2699 return temp;
2702 last = get_last_insn ();
2704 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
2705 unsignedp, OPTAB_WIDEN);
2706 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
2707 unsignedp, OPTAB_WIDEN);
2708 if (temp1 && temp2)
2710 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2711 unsignedp, OPTAB_WIDEN);
2712 if (temp)
2713 return temp;
2716 delete_insns_since (last);
2719 temp = widen_bswap (mode, op0, target);
2720 if (temp)
2721 return temp;
2723 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2724 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2726 temp = expand_doubleword_bswap (mode, op0, target);
2727 if (temp)
2728 return temp;
2731 goto try_libcall;
2734 if (CLASS_HAS_WIDER_MODES_P (mclass))
2735 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2736 wider_mode != VOIDmode;
2737 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2739 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2741 rtx xop0 = op0;
2742 rtx_insn *last = get_last_insn ();
2744 /* For certain operations, we need not actually extend
2745 the narrow operand, as long as we will truncate the
2746 results to the same narrowness. */
2748 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2749 (unoptab == neg_optab
2750 || unoptab == one_cmpl_optab)
2751 && mclass == MODE_INT);
2753 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2754 unsignedp);
2756 if (temp)
2758 if (mclass != MODE_INT
2759 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2761 if (target == 0)
2762 target = gen_reg_rtx (mode);
2763 convert_move (target, temp, 0);
2764 return target;
2766 else
2767 return gen_lowpart (mode, temp);
2769 else
2770 delete_insns_since (last);
2774 /* These can be done a word at a time. */
2775 if (unoptab == one_cmpl_optab
2776 && mclass == MODE_INT
2777 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2778 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2780 int i;
2781 rtx_insn *insns;
2783 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2784 target = gen_reg_rtx (mode);
2786 start_sequence ();
2788 /* Do the actual arithmetic. */
2789 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2791 rtx target_piece = operand_subword (target, i, 1, mode);
2792 rtx x = expand_unop (word_mode, unoptab,
2793 operand_subword_force (op0, i, mode),
2794 target_piece, unsignedp);
2796 if (target_piece != x)
2797 emit_move_insn (target_piece, x);
2800 insns = get_insns ();
2801 end_sequence ();
2803 emit_insn (insns);
2804 return target;
2807 if (optab_to_code (unoptab) == NEG)
2809 /* Try negating floating point values by flipping the sign bit. */
2810 if (SCALAR_FLOAT_MODE_P (mode))
2812 temp = expand_absneg_bit (NEG, mode, op0, target);
2813 if (temp)
2814 return temp;
2817 /* If there is no negation pattern, and we have no negative zero,
2818 try subtracting from zero. */
2819 if (!HONOR_SIGNED_ZEROS (mode))
2821 temp = expand_binop (mode, (unoptab == negv_optab
2822 ? subv_optab : sub_optab),
2823 CONST0_RTX (mode), op0, target,
2824 unsignedp, OPTAB_DIRECT);
2825 if (temp)
2826 return temp;
2830 /* Try calculating parity (x) as popcount (x) % 2. */
2831 if (unoptab == parity_optab)
2833 temp = expand_parity (mode, op0, target);
2834 if (temp)
2835 return temp;
2838 /* Try implementing ffs (x) in terms of clz (x). */
2839 if (unoptab == ffs_optab)
2841 temp = expand_ffs (mode, op0, target);
2842 if (temp)
2843 return temp;
2846 /* Try implementing ctz (x) in terms of clz (x). */
2847 if (unoptab == ctz_optab)
2849 temp = expand_ctz (mode, op0, target);
2850 if (temp)
2851 return temp;
2854 try_libcall:
2855 /* Now try a library call in this mode. */
2856 libfunc = optab_libfunc (unoptab, mode);
2857 if (libfunc)
2859 rtx_insn *insns;
2860 rtx value;
2861 rtx eq_value;
2862 machine_mode outmode = mode;
2864 /* All of these functions return small values. Thus we choose to
2865 have them return something that isn't a double-word. */
2866 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2867 || unoptab == clrsb_optab || unoptab == popcount_optab
2868 || unoptab == parity_optab)
2869 outmode
2870 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
2871 optab_libfunc (unoptab, mode)));
2873 start_sequence ();
2875 /* Pass 1 for NO_QUEUE so we don't lose any increments
2876 if the libcall is cse'd or moved. */
2877 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
2878 1, op0, mode);
2879 insns = get_insns ();
2880 end_sequence ();
2882 target = gen_reg_rtx (outmode);
2883 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
2884 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
2885 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
2886 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
2887 eq_value = simplify_gen_unary (ZERO_EXTEND, outmode, eq_value, mode);
2888 emit_libcall_block_1 (insns, target, value, eq_value,
2889 trapv_unoptab_p (unoptab));
2891 return target;
2894 /* It can't be done in this mode. Can we do it in a wider mode? */
2896 if (CLASS_HAS_WIDER_MODES_P (mclass))
2898 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2899 wider_mode != VOIDmode;
2900 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2902 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
2903 || optab_libfunc (unoptab, wider_mode))
2905 rtx xop0 = op0;
2906 rtx_insn *last = get_last_insn ();
2908 /* For certain operations, we need not actually extend
2909 the narrow operand, as long as we will truncate the
2910 results to the same narrowness. */
2911 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2912 (unoptab == neg_optab
2913 || unoptab == one_cmpl_optab
2914 || unoptab == bswap_optab)
2915 && mclass == MODE_INT);
2917 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2918 unsignedp);
2920 /* If we are generating clz using wider mode, adjust the
2921 result. Similarly for clrsb. */
2922 if ((unoptab == clz_optab || unoptab == clrsb_optab)
2923 && temp != 0)
2924 temp = expand_binop
2925 (wider_mode, sub_optab, temp,
2926 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2927 - GET_MODE_PRECISION (mode),
2928 wider_mode),
2929 target, true, OPTAB_DIRECT);
2931 /* Likewise for bswap. */
2932 if (unoptab == bswap_optab && temp != 0)
2934 gcc_assert (GET_MODE_PRECISION (wider_mode)
2935 == GET_MODE_BITSIZE (wider_mode)
2936 && GET_MODE_PRECISION (mode)
2937 == GET_MODE_BITSIZE (mode));
2939 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
2940 GET_MODE_BITSIZE (wider_mode)
2941 - GET_MODE_BITSIZE (mode),
2942 NULL_RTX, true);
2945 if (temp)
2947 if (mclass != MODE_INT)
2949 if (target == 0)
2950 target = gen_reg_rtx (mode);
2951 convert_move (target, temp, 0);
2952 return target;
2954 else
2955 return gen_lowpart (mode, temp);
2957 else
2958 delete_insns_since (last);
2963 /* One final attempt at implementing negation via subtraction,
2964 this time allowing widening of the operand. */
2965 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
2967 rtx temp;
2968 temp = expand_binop (mode,
2969 unoptab == negv_optab ? subv_optab : sub_optab,
2970 CONST0_RTX (mode), op0,
2971 target, unsignedp, OPTAB_LIB_WIDEN);
2972 if (temp)
2973 return temp;
2976 return 0;
2979 /* Emit code to compute the absolute value of OP0, with result to
2980 TARGET if convenient. (TARGET may be 0.) The return value says
2981 where the result actually is to be found.
2983 MODE is the mode of the operand; the mode of the result is
2984 different but can be deduced from MODE.
2989 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
2990 int result_unsignedp)
2992 rtx temp;
2994 if (GET_MODE_CLASS (mode) != MODE_INT
2995 || ! flag_trapv)
2996 result_unsignedp = 1;
2998 /* First try to do it with a special abs instruction. */
2999 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3000 op0, target, 0);
3001 if (temp != 0)
3002 return temp;
3004 /* For floating point modes, try clearing the sign bit. */
3005 if (SCALAR_FLOAT_MODE_P (mode))
3007 temp = expand_absneg_bit (ABS, mode, op0, target);
3008 if (temp)
3009 return temp;
3012 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3013 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3014 && !HONOR_SIGNED_ZEROS (mode))
3016 rtx_insn *last = get_last_insn ();
3018 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3019 op0, NULL_RTX, 0);
3020 if (temp != 0)
3021 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3022 OPTAB_WIDEN);
3024 if (temp != 0)
3025 return temp;
3027 delete_insns_since (last);
3030 /* If this machine has expensive jumps, we can do integer absolute
3031 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3032 where W is the width of MODE. */
3034 if (GET_MODE_CLASS (mode) == MODE_INT
3035 && BRANCH_COST (optimize_insn_for_speed_p (),
3036 false) >= 2)
3038 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3039 GET_MODE_PRECISION (mode) - 1,
3040 NULL_RTX, 0);
3042 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3043 OPTAB_LIB_WIDEN);
3044 if (temp != 0)
3045 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3046 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3048 if (temp != 0)
3049 return temp;
3052 return NULL_RTX;
3056 expand_abs (machine_mode mode, rtx op0, rtx target,
3057 int result_unsignedp, int safe)
3059 rtx temp;
3060 rtx_code_label *op1;
3062 if (GET_MODE_CLASS (mode) != MODE_INT
3063 || ! flag_trapv)
3064 result_unsignedp = 1;
3066 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3067 if (temp != 0)
3068 return temp;
3070 /* If that does not win, use conditional jump and negate. */
3072 /* It is safe to use the target if it is the same
3073 as the source if this is also a pseudo register */
3074 if (op0 == target && REG_P (op0)
3075 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3076 safe = 1;
3078 op1 = gen_label_rtx ();
3079 if (target == 0 || ! safe
3080 || GET_MODE (target) != mode
3081 || (MEM_P (target) && MEM_VOLATILE_P (target))
3082 || (REG_P (target)
3083 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3084 target = gen_reg_rtx (mode);
3086 emit_move_insn (target, op0);
3087 NO_DEFER_POP;
3089 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3090 NULL_RTX, NULL, op1, -1);
3092 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3093 target, target, 0);
3094 if (op0 != target)
3095 emit_move_insn (target, op0);
3096 emit_label (op1);
3097 OK_DEFER_POP;
3098 return target;
3101 /* Emit code to compute the one's complement absolute value of OP0
3102 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3103 (TARGET may be NULL_RTX.) The return value says where the result
3104 actually is to be found.
3106 MODE is the mode of the operand; the mode of the result is
3107 different but can be deduced from MODE. */
3110 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3112 rtx temp;
3114 /* Not applicable for floating point modes. */
3115 if (FLOAT_MODE_P (mode))
3116 return NULL_RTX;
3118 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3119 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3121 rtx_insn *last = get_last_insn ();
3123 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3124 if (temp != 0)
3125 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3126 OPTAB_WIDEN);
3128 if (temp != 0)
3129 return temp;
3131 delete_insns_since (last);
3134 /* If this machine has expensive jumps, we can do one's complement
3135 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3137 if (GET_MODE_CLASS (mode) == MODE_INT
3138 && BRANCH_COST (optimize_insn_for_speed_p (),
3139 false) >= 2)
3141 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3142 GET_MODE_PRECISION (mode) - 1,
3143 NULL_RTX, 0);
3145 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3146 OPTAB_LIB_WIDEN);
3148 if (temp != 0)
3149 return temp;
3152 return NULL_RTX;
3155 /* A subroutine of expand_copysign, perform the copysign operation using the
3156 abs and neg primitives advertised to exist on the target. The assumption
3157 is that we have a split register file, and leaving op0 in fp registers,
3158 and not playing with subregs so much, will help the register allocator. */
3160 static rtx
3161 expand_copysign_absneg (machine_mode mode, rtx op0, rtx op1, rtx target,
3162 int bitpos, bool op0_is_abs)
3164 machine_mode imode;
3165 enum insn_code icode;
3166 rtx sign;
3167 rtx_code_label *label;
3169 if (target == op1)
3170 target = NULL_RTX;
3172 /* Check if the back end provides an insn that handles signbit for the
3173 argument's mode. */
3174 icode = optab_handler (signbit_optab, mode);
3175 if (icode != CODE_FOR_nothing)
3177 imode = insn_data[(int) icode].operand[0].mode;
3178 sign = gen_reg_rtx (imode);
3179 emit_unop_insn (icode, sign, op1, UNKNOWN);
3181 else
3183 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3185 imode = int_mode_for_mode (mode);
3186 if (imode == BLKmode)
3187 return NULL_RTX;
3188 op1 = gen_lowpart (imode, op1);
3190 else
3192 int word;
3194 imode = word_mode;
3195 if (FLOAT_WORDS_BIG_ENDIAN)
3196 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3197 else
3198 word = bitpos / BITS_PER_WORD;
3199 bitpos = bitpos % BITS_PER_WORD;
3200 op1 = operand_subword_force (op1, word, mode);
3203 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3204 sign = expand_binop (imode, and_optab, op1,
3205 immed_wide_int_const (mask, imode),
3206 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3209 if (!op0_is_abs)
3211 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3212 if (op0 == NULL)
3213 return NULL_RTX;
3214 target = op0;
3216 else
3218 if (target == NULL_RTX)
3219 target = copy_to_reg (op0);
3220 else
3221 emit_move_insn (target, op0);
3224 label = gen_label_rtx ();
3225 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3227 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3228 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3229 else
3230 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3231 if (op0 != target)
3232 emit_move_insn (target, op0);
3234 emit_label (label);
3236 return target;
3240 /* A subroutine of expand_copysign, perform the entire copysign operation
3241 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3242 is true if op0 is known to have its sign bit clear. */
3244 static rtx
3245 expand_copysign_bit (machine_mode mode, rtx op0, rtx op1, rtx target,
3246 int bitpos, bool op0_is_abs)
3248 machine_mode imode;
3249 int word, nwords, i;
3250 rtx temp;
3251 rtx_insn *insns;
3253 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3255 imode = int_mode_for_mode (mode);
3256 if (imode == BLKmode)
3257 return NULL_RTX;
3258 word = 0;
3259 nwords = 1;
3261 else
3263 imode = word_mode;
3265 if (FLOAT_WORDS_BIG_ENDIAN)
3266 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3267 else
3268 word = bitpos / BITS_PER_WORD;
3269 bitpos = bitpos % BITS_PER_WORD;
3270 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3273 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3275 if (target == 0
3276 || target == op0
3277 || target == op1
3278 || (nwords > 1 && !valid_multiword_target_p (target)))
3279 target = gen_reg_rtx (mode);
3281 if (nwords > 1)
3283 start_sequence ();
3285 for (i = 0; i < nwords; ++i)
3287 rtx targ_piece = operand_subword (target, i, 1, mode);
3288 rtx op0_piece = operand_subword_force (op0, i, mode);
3290 if (i == word)
3292 if (!op0_is_abs)
3293 op0_piece
3294 = expand_binop (imode, and_optab, op0_piece,
3295 immed_wide_int_const (~mask, imode),
3296 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3297 op1 = expand_binop (imode, and_optab,
3298 operand_subword_force (op1, i, mode),
3299 immed_wide_int_const (mask, imode),
3300 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3302 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3303 targ_piece, 1, OPTAB_LIB_WIDEN);
3304 if (temp != targ_piece)
3305 emit_move_insn (targ_piece, temp);
3307 else
3308 emit_move_insn (targ_piece, op0_piece);
3311 insns = get_insns ();
3312 end_sequence ();
3314 emit_insn (insns);
3316 else
3318 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3319 immed_wide_int_const (mask, imode),
3320 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3322 op0 = gen_lowpart (imode, op0);
3323 if (!op0_is_abs)
3324 op0 = expand_binop (imode, and_optab, op0,
3325 immed_wide_int_const (~mask, imode),
3326 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3328 temp = expand_binop (imode, ior_optab, op0, op1,
3329 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3330 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3333 return target;
3336 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3337 scalar floating point mode. Return NULL if we do not know how to
3338 expand the operation inline. */
3341 expand_copysign (rtx op0, rtx op1, rtx target)
3343 machine_mode mode = GET_MODE (op0);
3344 const struct real_format *fmt;
3345 bool op0_is_abs;
3346 rtx temp;
3348 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3349 gcc_assert (GET_MODE (op1) == mode);
3351 /* First try to do it with a special instruction. */
3352 temp = expand_binop (mode, copysign_optab, op0, op1,
3353 target, 0, OPTAB_DIRECT);
3354 if (temp)
3355 return temp;
3357 fmt = REAL_MODE_FORMAT (mode);
3358 if (fmt == NULL || !fmt->has_signed_zero)
3359 return NULL_RTX;
3361 op0_is_abs = false;
3362 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3364 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3365 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3366 op0_is_abs = true;
3369 if (fmt->signbit_ro >= 0
3370 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3371 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3372 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3374 temp = expand_copysign_absneg (mode, op0, op1, target,
3375 fmt->signbit_ro, op0_is_abs);
3376 if (temp)
3377 return temp;
3380 if (fmt->signbit_rw < 0)
3381 return NULL_RTX;
3382 return expand_copysign_bit (mode, op0, op1, target,
3383 fmt->signbit_rw, op0_is_abs);
3386 /* Generate an instruction whose insn-code is INSN_CODE,
3387 with two operands: an output TARGET and an input OP0.
3388 TARGET *must* be nonzero, and the output is always stored there.
3389 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3390 the value that is stored into TARGET.
3392 Return false if expansion failed. */
3394 bool
3395 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3396 enum rtx_code code)
3398 struct expand_operand ops[2];
3399 rtx_insn *pat;
3401 create_output_operand (&ops[0], target, GET_MODE (target));
3402 create_input_operand (&ops[1], op0, GET_MODE (op0));
3403 pat = maybe_gen_insn (icode, 2, ops);
3404 if (!pat)
3405 return false;
3407 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3408 && code != UNKNOWN)
3409 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3411 emit_insn (pat);
3413 if (ops[0].value != target)
3414 emit_move_insn (target, ops[0].value);
3415 return true;
3417 /* Generate an instruction whose insn-code is INSN_CODE,
3418 with two operands: an output TARGET and an input OP0.
3419 TARGET *must* be nonzero, and the output is always stored there.
3420 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3421 the value that is stored into TARGET. */
3423 void
3424 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3426 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3427 gcc_assert (ok);
3430 struct no_conflict_data
3432 rtx target;
3433 rtx_insn *first, *insn;
3434 bool must_stay;
3437 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3438 the currently examined clobber / store has to stay in the list of
3439 insns that constitute the actual libcall block. */
3440 static void
3441 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3443 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3445 /* If this inns directly contributes to setting the target, it must stay. */
3446 if (reg_overlap_mentioned_p (p->target, dest))
3447 p->must_stay = true;
3448 /* If we haven't committed to keeping any other insns in the list yet,
3449 there is nothing more to check. */
3450 else if (p->insn == p->first)
3451 return;
3452 /* If this insn sets / clobbers a register that feeds one of the insns
3453 already in the list, this insn has to stay too. */
3454 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3455 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3456 || reg_used_between_p (dest, p->first, p->insn)
3457 /* Likewise if this insn depends on a register set by a previous
3458 insn in the list, or if it sets a result (presumably a hard
3459 register) that is set or clobbered by a previous insn.
3460 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3461 SET_DEST perform the former check on the address, and the latter
3462 check on the MEM. */
3463 || (GET_CODE (set) == SET
3464 && (modified_in_p (SET_SRC (set), p->first)
3465 || modified_in_p (SET_DEST (set), p->first)
3466 || modified_between_p (SET_SRC (set), p->first, p->insn)
3467 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3468 p->must_stay = true;
3472 /* Emit code to make a call to a constant function or a library call.
3474 INSNS is a list containing all insns emitted in the call.
3475 These insns leave the result in RESULT. Our block is to copy RESULT
3476 to TARGET, which is logically equivalent to EQUIV.
3478 We first emit any insns that set a pseudo on the assumption that these are
3479 loading constants into registers; doing so allows them to be safely cse'ed
3480 between blocks. Then we emit all the other insns in the block, followed by
3481 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3482 note with an operand of EQUIV. */
3484 static void
3485 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3486 bool equiv_may_trap)
3488 rtx final_dest = target;
3489 rtx_insn *next, *last, *insn;
3491 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3492 into a MEM later. Protect the libcall block from this change. */
3493 if (! REG_P (target) || REG_USERVAR_P (target))
3494 target = gen_reg_rtx (GET_MODE (target));
3496 /* If we're using non-call exceptions, a libcall corresponding to an
3497 operation that may trap may also trap. */
3498 /* ??? See the comment in front of make_reg_eh_region_note. */
3499 if (cfun->can_throw_non_call_exceptions
3500 && (equiv_may_trap || may_trap_p (equiv)))
3502 for (insn = insns; insn; insn = NEXT_INSN (insn))
3503 if (CALL_P (insn))
3505 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3506 if (note)
3508 int lp_nr = INTVAL (XEXP (note, 0));
3509 if (lp_nr == 0 || lp_nr == INT_MIN)
3510 remove_note (insn, note);
3514 else
3516 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3517 reg note to indicate that this call cannot throw or execute a nonlocal
3518 goto (unless there is already a REG_EH_REGION note, in which case
3519 we update it). */
3520 for (insn = insns; insn; insn = NEXT_INSN (insn))
3521 if (CALL_P (insn))
3522 make_reg_eh_region_note_nothrow_nononlocal (insn);
3525 /* First emit all insns that set pseudos. Remove them from the list as
3526 we go. Avoid insns that set pseudos which were referenced in previous
3527 insns. These can be generated by move_by_pieces, for example,
3528 to update an address. Similarly, avoid insns that reference things
3529 set in previous insns. */
3531 for (insn = insns; insn; insn = next)
3533 rtx set = single_set (insn);
3535 next = NEXT_INSN (insn);
3537 if (set != 0 && REG_P (SET_DEST (set))
3538 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3540 struct no_conflict_data data;
3542 data.target = const0_rtx;
3543 data.first = insns;
3544 data.insn = insn;
3545 data.must_stay = 0;
3546 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3547 if (! data.must_stay)
3549 if (PREV_INSN (insn))
3550 SET_NEXT_INSN (PREV_INSN (insn)) = next;
3551 else
3552 insns = next;
3554 if (next)
3555 SET_PREV_INSN (next) = PREV_INSN (insn);
3557 add_insn (insn);
3561 /* Some ports use a loop to copy large arguments onto the stack.
3562 Don't move anything outside such a loop. */
3563 if (LABEL_P (insn))
3564 break;
3567 /* Write the remaining insns followed by the final copy. */
3568 for (insn = insns; insn; insn = next)
3570 next = NEXT_INSN (insn);
3572 add_insn (insn);
3575 last = emit_move_insn (target, result);
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 (!TYPE_UNSIGNED (TREE_TYPE (op0)));
5373 op0a = op0;
5374 op0b = build_zero_cst (TREE_TYPE (op0));
5375 tcode = LT_EXPR;
5377 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5378 cmp_op_mode = TYPE_MODE (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 to indicate that we do not care about
5805 that return value. Both target parameters are updated on success to
5806 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 == NULL
5832 || (target_oval = *ptarget_oval) == NULL
5833 || reg_overlap_mentioned_p (expected, target_oval))
5834 target_oval = gen_reg_rtx (mode);
5836 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
5837 if (icode != CODE_FOR_nothing)
5839 machine_mode bool_mode = insn_data[icode].operand[0].mode;
5841 /* Make sure we always have a place for the bool operand. */
5842 if (ptarget_bool == NULL
5843 || (target_bool = *ptarget_bool) == NULL
5844 || GET_MODE (target_bool) != bool_mode)
5845 target_bool = gen_reg_rtx (bool_mode);
5847 /* Emit the compare_and_swap. */
5848 create_output_operand (&ops[0], target_bool, bool_mode);
5849 create_output_operand (&ops[1], target_oval, mode);
5850 create_fixed_operand (&ops[2], mem);
5851 create_input_operand (&ops[3], expected, mode);
5852 create_input_operand (&ops[4], desired, mode);
5853 create_integer_operand (&ops[5], is_weak);
5854 create_integer_operand (&ops[6], succ_model);
5855 create_integer_operand (&ops[7], fail_model);
5856 if (maybe_expand_insn (icode, 8, ops))
5858 /* Return success/failure. */
5859 target_bool = ops[0].value;
5860 target_oval = ops[1].value;
5861 goto success;
5865 /* Otherwise fall back to the original __sync_val_compare_and_swap
5866 which is always seq-cst. */
5867 icode = optab_handler (sync_compare_and_swap_optab, mode);
5868 if (icode != CODE_FOR_nothing)
5870 rtx cc_reg;
5872 create_output_operand (&ops[0], target_oval, mode);
5873 create_fixed_operand (&ops[1], mem);
5874 create_input_operand (&ops[2], expected, mode);
5875 create_input_operand (&ops[3], desired, mode);
5876 if (!maybe_expand_insn (icode, 4, ops))
5877 return false;
5879 target_oval = ops[0].value;
5881 /* If the caller isn't interested in the boolean return value,
5882 skip the computation of it. */
5883 if (ptarget_bool == NULL)
5884 goto success;
5886 /* Otherwise, work out if the compare-and-swap succeeded. */
5887 cc_reg = NULL_RTX;
5888 if (have_insn_for (COMPARE, CCmode))
5889 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
5890 if (cc_reg)
5892 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
5893 const0_rtx, VOIDmode, 0, 1);
5894 goto success;
5896 goto success_bool_from_val;
5899 /* Also check for library support for __sync_val_compare_and_swap. */
5900 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
5901 if (libfunc != NULL)
5903 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5904 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5905 mode, 3, addr, ptr_mode,
5906 expected, mode, desired, mode);
5907 emit_move_insn (target_oval, target);
5909 /* Compute the boolean return value only if requested. */
5910 if (ptarget_bool)
5911 goto success_bool_from_val;
5912 else
5913 goto success;
5916 /* Failure. */
5917 return false;
5919 success_bool_from_val:
5920 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
5921 expected, VOIDmode, 1, 1);
5922 success:
5923 /* Make sure that the oval output winds up where the caller asked. */
5924 if (ptarget_oval)
5925 *ptarget_oval = target_oval;
5926 if (ptarget_bool)
5927 *ptarget_bool = target_bool;
5928 return true;
5931 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
5933 static void
5934 expand_asm_memory_barrier (void)
5936 rtx asm_op, clob;
5938 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
5939 rtvec_alloc (0), rtvec_alloc (0),
5940 rtvec_alloc (0), UNKNOWN_LOCATION);
5941 MEM_VOLATILE_P (asm_op) = 1;
5943 clob = gen_rtx_SCRATCH (VOIDmode);
5944 clob = gen_rtx_MEM (BLKmode, clob);
5945 clob = gen_rtx_CLOBBER (VOIDmode, clob);
5947 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
5950 /* This routine will either emit the mem_thread_fence pattern or issue a
5951 sync_synchronize to generate a fence for memory model MEMMODEL. */
5953 void
5954 expand_mem_thread_fence (enum memmodel model)
5956 if (targetm.have_mem_thread_fence ())
5957 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
5958 else if (!is_mm_relaxed (model))
5960 if (targetm.have_memory_barrier ())
5961 emit_insn (targetm.gen_memory_barrier ());
5962 else if (synchronize_libfunc != NULL_RTX)
5963 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
5964 else
5965 expand_asm_memory_barrier ();
5969 /* This routine will either emit the mem_signal_fence pattern or issue a
5970 sync_synchronize to generate a fence for memory model MEMMODEL. */
5972 void
5973 expand_mem_signal_fence (enum memmodel model)
5975 if (targetm.have_mem_signal_fence ())
5976 emit_insn (targetm.gen_mem_signal_fence (GEN_INT (model)));
5977 else if (!is_mm_relaxed (model))
5979 /* By default targets are coherent between a thread and the signal
5980 handler running on the same thread. Thus this really becomes a
5981 compiler barrier, in that stores must not be sunk past
5982 (or raised above) a given point. */
5983 expand_asm_memory_barrier ();
5987 /* This function expands the atomic load operation:
5988 return the atomically loaded value in MEM.
5990 MEMMODEL is the memory model variant to use.
5991 TARGET is an option place to stick the return value. */
5994 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
5996 machine_mode mode = GET_MODE (mem);
5997 enum insn_code icode;
5999 /* If the target supports the load directly, great. */
6000 icode = direct_optab_handler (atomic_load_optab, mode);
6001 if (icode != CODE_FOR_nothing)
6003 struct expand_operand ops[3];
6005 create_output_operand (&ops[0], target, mode);
6006 create_fixed_operand (&ops[1], mem);
6007 create_integer_operand (&ops[2], model);
6008 if (maybe_expand_insn (icode, 3, ops))
6009 return ops[0].value;
6012 /* If the size of the object is greater than word size on this target,
6013 then we assume that a load will not be atomic. */
6014 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6016 /* Issue val = compare_and_swap (mem, 0, 0).
6017 This may cause the occasional harmless store of 0 when the value is
6018 already 0, but it seems to be OK according to the standards guys. */
6019 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
6020 const0_rtx, false, model, model))
6021 return target;
6022 else
6023 /* Otherwise there is no atomic load, leave the library call. */
6024 return NULL_RTX;
6027 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6028 if (!target || target == const0_rtx)
6029 target = gen_reg_rtx (mode);
6031 /* For SEQ_CST, emit a barrier before the load. */
6032 if (is_mm_seq_cst (model))
6033 expand_mem_thread_fence (model);
6035 emit_move_insn (target, mem);
6037 /* Emit the appropriate barrier after the load. */
6038 expand_mem_thread_fence (model);
6040 return target;
6043 /* This function expands the atomic store operation:
6044 Atomically store VAL in MEM.
6045 MEMMODEL is the memory model variant to use.
6046 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6047 function returns const0_rtx if a pattern was emitted. */
6050 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6052 machine_mode mode = GET_MODE (mem);
6053 enum insn_code icode;
6054 struct expand_operand ops[3];
6056 /* If the target supports the store directly, great. */
6057 icode = direct_optab_handler (atomic_store_optab, mode);
6058 if (icode != CODE_FOR_nothing)
6060 create_fixed_operand (&ops[0], mem);
6061 create_input_operand (&ops[1], val, mode);
6062 create_integer_operand (&ops[2], model);
6063 if (maybe_expand_insn (icode, 3, ops))
6064 return const0_rtx;
6067 /* If using __sync_lock_release is a viable alternative, try it. */
6068 if (use_release)
6070 icode = direct_optab_handler (sync_lock_release_optab, mode);
6071 if (icode != CODE_FOR_nothing)
6073 create_fixed_operand (&ops[0], mem);
6074 create_input_operand (&ops[1], const0_rtx, mode);
6075 if (maybe_expand_insn (icode, 2, ops))
6077 /* lock_release is only a release barrier. */
6078 if (is_mm_seq_cst (model))
6079 expand_mem_thread_fence (model);
6080 return const0_rtx;
6085 /* If the size of the object is greater than word size on this target,
6086 a default store will not be atomic, Try a mem_exchange and throw away
6087 the result. If that doesn't work, don't do anything. */
6088 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6090 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6091 if (!target)
6092 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
6093 if (target)
6094 return const0_rtx;
6095 else
6096 return NULL_RTX;
6099 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6100 expand_mem_thread_fence (model);
6102 emit_move_insn (mem, val);
6104 /* For SEQ_CST, also emit a barrier after the store. */
6105 if (is_mm_seq_cst (model))
6106 expand_mem_thread_fence (model);
6108 return const0_rtx;
6112 /* Structure containing the pointers and values required to process the
6113 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6115 struct atomic_op_functions
6117 direct_optab mem_fetch_before;
6118 direct_optab mem_fetch_after;
6119 direct_optab mem_no_result;
6120 optab fetch_before;
6121 optab fetch_after;
6122 direct_optab no_result;
6123 enum rtx_code reverse_code;
6127 /* Fill in structure pointed to by OP with the various optab entries for an
6128 operation of type CODE. */
6130 static void
6131 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6133 gcc_assert (op!= NULL);
6135 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6136 in the source code during compilation, and the optab entries are not
6137 computable until runtime. Fill in the values at runtime. */
6138 switch (code)
6140 case PLUS:
6141 op->mem_fetch_before = atomic_fetch_add_optab;
6142 op->mem_fetch_after = atomic_add_fetch_optab;
6143 op->mem_no_result = atomic_add_optab;
6144 op->fetch_before = sync_old_add_optab;
6145 op->fetch_after = sync_new_add_optab;
6146 op->no_result = sync_add_optab;
6147 op->reverse_code = MINUS;
6148 break;
6149 case MINUS:
6150 op->mem_fetch_before = atomic_fetch_sub_optab;
6151 op->mem_fetch_after = atomic_sub_fetch_optab;
6152 op->mem_no_result = atomic_sub_optab;
6153 op->fetch_before = sync_old_sub_optab;
6154 op->fetch_after = sync_new_sub_optab;
6155 op->no_result = sync_sub_optab;
6156 op->reverse_code = PLUS;
6157 break;
6158 case XOR:
6159 op->mem_fetch_before = atomic_fetch_xor_optab;
6160 op->mem_fetch_after = atomic_xor_fetch_optab;
6161 op->mem_no_result = atomic_xor_optab;
6162 op->fetch_before = sync_old_xor_optab;
6163 op->fetch_after = sync_new_xor_optab;
6164 op->no_result = sync_xor_optab;
6165 op->reverse_code = XOR;
6166 break;
6167 case AND:
6168 op->mem_fetch_before = atomic_fetch_and_optab;
6169 op->mem_fetch_after = atomic_and_fetch_optab;
6170 op->mem_no_result = atomic_and_optab;
6171 op->fetch_before = sync_old_and_optab;
6172 op->fetch_after = sync_new_and_optab;
6173 op->no_result = sync_and_optab;
6174 op->reverse_code = UNKNOWN;
6175 break;
6176 case IOR:
6177 op->mem_fetch_before = atomic_fetch_or_optab;
6178 op->mem_fetch_after = atomic_or_fetch_optab;
6179 op->mem_no_result = atomic_or_optab;
6180 op->fetch_before = sync_old_ior_optab;
6181 op->fetch_after = sync_new_ior_optab;
6182 op->no_result = sync_ior_optab;
6183 op->reverse_code = UNKNOWN;
6184 break;
6185 case NOT:
6186 op->mem_fetch_before = atomic_fetch_nand_optab;
6187 op->mem_fetch_after = atomic_nand_fetch_optab;
6188 op->mem_no_result = atomic_nand_optab;
6189 op->fetch_before = sync_old_nand_optab;
6190 op->fetch_after = sync_new_nand_optab;
6191 op->no_result = sync_nand_optab;
6192 op->reverse_code = UNKNOWN;
6193 break;
6194 default:
6195 gcc_unreachable ();
6199 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6200 using memory order MODEL. If AFTER is true the operation needs to return
6201 the value of *MEM after the operation, otherwise the previous value.
6202 TARGET is an optional place to place the result. The result is unused if
6203 it is const0_rtx.
6204 Return the result if there is a better sequence, otherwise NULL_RTX. */
6206 static rtx
6207 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6208 enum memmodel model, bool after)
6210 /* If the value is prefetched, or not used, it may be possible to replace
6211 the sequence with a native exchange operation. */
6212 if (!after || target == const0_rtx)
6214 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6215 if (code == AND && val == const0_rtx)
6217 if (target == const0_rtx)
6218 target = gen_reg_rtx (GET_MODE (mem));
6219 return maybe_emit_atomic_exchange (target, mem, val, model);
6222 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6223 if (code == IOR && val == constm1_rtx)
6225 if (target == const0_rtx)
6226 target = gen_reg_rtx (GET_MODE (mem));
6227 return maybe_emit_atomic_exchange (target, mem, val, model);
6231 return NULL_RTX;
6234 /* Try to emit an instruction for a specific operation varaition.
6235 OPTAB contains the OP functions.
6236 TARGET is an optional place to return the result. const0_rtx means unused.
6237 MEM is the memory location to operate on.
6238 VAL is the value to use in the operation.
6239 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6240 MODEL is the memory model, if used.
6241 AFTER is true if the returned result is the value after the operation. */
6243 static rtx
6244 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6245 rtx val, bool use_memmodel, enum memmodel model, bool after)
6247 machine_mode mode = GET_MODE (mem);
6248 struct expand_operand ops[4];
6249 enum insn_code icode;
6250 int op_counter = 0;
6251 int num_ops;
6253 /* Check to see if there is a result returned. */
6254 if (target == const0_rtx)
6256 if (use_memmodel)
6258 icode = direct_optab_handler (optab->mem_no_result, mode);
6259 create_integer_operand (&ops[2], model);
6260 num_ops = 3;
6262 else
6264 icode = direct_optab_handler (optab->no_result, mode);
6265 num_ops = 2;
6268 /* Otherwise, we need to generate a result. */
6269 else
6271 if (use_memmodel)
6273 icode = direct_optab_handler (after ? optab->mem_fetch_after
6274 : optab->mem_fetch_before, mode);
6275 create_integer_operand (&ops[3], model);
6276 num_ops = 4;
6278 else
6280 icode = optab_handler (after ? optab->fetch_after
6281 : optab->fetch_before, mode);
6282 num_ops = 3;
6284 create_output_operand (&ops[op_counter++], target, mode);
6286 if (icode == CODE_FOR_nothing)
6287 return NULL_RTX;
6289 create_fixed_operand (&ops[op_counter++], mem);
6290 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6291 create_convert_operand_to (&ops[op_counter++], val, mode, true);
6293 if (maybe_expand_insn (icode, num_ops, ops))
6294 return (target == const0_rtx ? const0_rtx : ops[0].value);
6296 return NULL_RTX;
6300 /* This function expands an atomic fetch_OP or OP_fetch operation:
6301 TARGET is an option place to stick the return value. const0_rtx indicates
6302 the result is unused.
6303 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6304 CODE is the operation being performed (OP)
6305 MEMMODEL is the memory model variant to use.
6306 AFTER is true to return the result of the operation (OP_fetch).
6307 AFTER is false to return the value before the operation (fetch_OP).
6309 This function will *only* generate instructions if there is a direct
6310 optab. No compare and swap loops or libcalls will be generated. */
6312 static rtx
6313 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6314 enum rtx_code code, enum memmodel model,
6315 bool after)
6317 machine_mode mode = GET_MODE (mem);
6318 struct atomic_op_functions optab;
6319 rtx result;
6320 bool unused_result = (target == const0_rtx);
6322 get_atomic_op_for_code (&optab, code);
6324 /* Check to see if there are any better instructions. */
6325 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6326 if (result)
6327 return result;
6329 /* Check for the case where the result isn't used and try those patterns. */
6330 if (unused_result)
6332 /* Try the memory model variant first. */
6333 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6334 if (result)
6335 return result;
6337 /* Next try the old style withuot a memory model. */
6338 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6339 if (result)
6340 return result;
6342 /* There is no no-result pattern, so try patterns with a result. */
6343 target = NULL_RTX;
6346 /* Try the __atomic version. */
6347 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6348 if (result)
6349 return result;
6351 /* Try the older __sync version. */
6352 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6353 if (result)
6354 return result;
6356 /* If the fetch value can be calculated from the other variation of fetch,
6357 try that operation. */
6358 if (after || unused_result || optab.reverse_code != UNKNOWN)
6360 /* Try the __atomic version, then the older __sync version. */
6361 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6362 if (!result)
6363 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6365 if (result)
6367 /* If the result isn't used, no need to do compensation code. */
6368 if (unused_result)
6369 return result;
6371 /* Issue compensation code. Fetch_after == fetch_before OP val.
6372 Fetch_before == after REVERSE_OP val. */
6373 if (!after)
6374 code = optab.reverse_code;
6375 if (code == NOT)
6377 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6378 true, OPTAB_LIB_WIDEN);
6379 result = expand_simple_unop (mode, NOT, result, target, true);
6381 else
6382 result = expand_simple_binop (mode, code, result, val, target,
6383 true, OPTAB_LIB_WIDEN);
6384 return result;
6388 /* No direct opcode can be generated. */
6389 return NULL_RTX;
6394 /* This function expands an atomic fetch_OP or OP_fetch operation:
6395 TARGET is an option place to stick the return value. const0_rtx indicates
6396 the result is unused.
6397 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6398 CODE is the operation being performed (OP)
6399 MEMMODEL is the memory model variant to use.
6400 AFTER is true to return the result of the operation (OP_fetch).
6401 AFTER is false to return the value before the operation (fetch_OP). */
6403 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6404 enum memmodel model, bool after)
6406 machine_mode mode = GET_MODE (mem);
6407 rtx result;
6408 bool unused_result = (target == const0_rtx);
6410 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6411 after);
6413 if (result)
6414 return result;
6416 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6417 if (code == PLUS || code == MINUS)
6419 rtx tmp;
6420 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6422 start_sequence ();
6423 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6424 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6425 model, after);
6426 if (result)
6428 /* PLUS worked so emit the insns and return. */
6429 tmp = get_insns ();
6430 end_sequence ();
6431 emit_insn (tmp);
6432 return result;
6435 /* PLUS did not work, so throw away the negation code and continue. */
6436 end_sequence ();
6439 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6440 if (!can_compare_and_swap_p (mode, false))
6442 rtx libfunc;
6443 bool fixup = false;
6444 enum rtx_code orig_code = code;
6445 struct atomic_op_functions optab;
6447 get_atomic_op_for_code (&optab, code);
6448 libfunc = optab_libfunc (after ? optab.fetch_after
6449 : optab.fetch_before, mode);
6450 if (libfunc == NULL
6451 && (after || unused_result || optab.reverse_code != UNKNOWN))
6453 fixup = true;
6454 if (!after)
6455 code = optab.reverse_code;
6456 libfunc = optab_libfunc (after ? optab.fetch_before
6457 : optab.fetch_after, mode);
6459 if (libfunc != NULL)
6461 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6462 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
6463 2, addr, ptr_mode, val, mode);
6465 if (!unused_result && fixup)
6466 result = expand_simple_binop (mode, code, result, val, target,
6467 true, OPTAB_LIB_WIDEN);
6468 return result;
6471 /* We need the original code for any further attempts. */
6472 code = orig_code;
6475 /* If nothing else has succeeded, default to a compare and swap loop. */
6476 if (can_compare_and_swap_p (mode, true))
6478 rtx_insn *insn;
6479 rtx t0 = gen_reg_rtx (mode), t1;
6481 start_sequence ();
6483 /* If the result is used, get a register for it. */
6484 if (!unused_result)
6486 if (!target || !register_operand (target, mode))
6487 target = gen_reg_rtx (mode);
6488 /* If fetch_before, copy the value now. */
6489 if (!after)
6490 emit_move_insn (target, t0);
6492 else
6493 target = const0_rtx;
6495 t1 = t0;
6496 if (code == NOT)
6498 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
6499 true, OPTAB_LIB_WIDEN);
6500 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
6502 else
6503 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
6504 OPTAB_LIB_WIDEN);
6506 /* For after, copy the value now. */
6507 if (!unused_result && after)
6508 emit_move_insn (target, t1);
6509 insn = get_insns ();
6510 end_sequence ();
6512 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6513 return target;
6516 return NULL_RTX;
6519 /* Return true if OPERAND is suitable for operand number OPNO of
6520 instruction ICODE. */
6522 bool
6523 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
6525 return (!insn_data[(int) icode].operand[opno].predicate
6526 || (insn_data[(int) icode].operand[opno].predicate
6527 (operand, insn_data[(int) icode].operand[opno].mode)));
6530 /* TARGET is a target of a multiword operation that we are going to
6531 implement as a series of word-mode operations. Return true if
6532 TARGET is suitable for this purpose. */
6534 bool
6535 valid_multiword_target_p (rtx target)
6537 machine_mode mode;
6538 int i;
6540 mode = GET_MODE (target);
6541 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
6542 if (!validate_subreg (word_mode, mode, target, i))
6543 return false;
6544 return true;
6547 /* Like maybe_legitimize_operand, but do not change the code of the
6548 current rtx value. */
6550 static bool
6551 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
6552 struct expand_operand *op)
6554 /* See if the operand matches in its current form. */
6555 if (insn_operand_matches (icode, opno, op->value))
6556 return true;
6558 /* If the operand is a memory whose address has no side effects,
6559 try forcing the address into a non-virtual pseudo register.
6560 The check for side effects is important because copy_to_mode_reg
6561 cannot handle things like auto-modified addresses. */
6562 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
6564 rtx addr, mem;
6566 mem = op->value;
6567 addr = XEXP (mem, 0);
6568 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
6569 && !side_effects_p (addr))
6571 rtx_insn *last;
6572 machine_mode mode;
6574 last = get_last_insn ();
6575 mode = get_address_mode (mem);
6576 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
6577 if (insn_operand_matches (icode, opno, mem))
6579 op->value = mem;
6580 return true;
6582 delete_insns_since (last);
6586 return false;
6589 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6590 on success, storing the new operand value back in OP. */
6592 static bool
6593 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
6594 struct expand_operand *op)
6596 machine_mode mode, imode;
6597 bool old_volatile_ok, result;
6599 mode = op->mode;
6600 switch (op->type)
6602 case EXPAND_FIXED:
6603 old_volatile_ok = volatile_ok;
6604 volatile_ok = true;
6605 result = maybe_legitimize_operand_same_code (icode, opno, op);
6606 volatile_ok = old_volatile_ok;
6607 return result;
6609 case EXPAND_OUTPUT:
6610 gcc_assert (mode != VOIDmode);
6611 if (op->value
6612 && op->value != const0_rtx
6613 && GET_MODE (op->value) == mode
6614 && maybe_legitimize_operand_same_code (icode, opno, op))
6615 return true;
6617 op->value = gen_reg_rtx (mode);
6618 break;
6620 case EXPAND_INPUT:
6621 input:
6622 gcc_assert (mode != VOIDmode);
6623 gcc_assert (GET_MODE (op->value) == VOIDmode
6624 || GET_MODE (op->value) == mode);
6625 if (maybe_legitimize_operand_same_code (icode, opno, op))
6626 return true;
6628 op->value = copy_to_mode_reg (mode, op->value);
6629 break;
6631 case EXPAND_CONVERT_TO:
6632 gcc_assert (mode != VOIDmode);
6633 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
6634 goto input;
6636 case EXPAND_CONVERT_FROM:
6637 if (GET_MODE (op->value) != VOIDmode)
6638 mode = GET_MODE (op->value);
6639 else
6640 /* The caller must tell us what mode this value has. */
6641 gcc_assert (mode != VOIDmode);
6643 imode = insn_data[(int) icode].operand[opno].mode;
6644 if (imode != VOIDmode && imode != mode)
6646 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
6647 mode = imode;
6649 goto input;
6651 case EXPAND_ADDRESS:
6652 gcc_assert (mode != VOIDmode);
6653 op->value = convert_memory_address (mode, op->value);
6654 goto input;
6656 case EXPAND_INTEGER:
6657 mode = insn_data[(int) icode].operand[opno].mode;
6658 if (mode != VOIDmode && const_int_operand (op->value, mode))
6659 goto input;
6660 break;
6662 return insn_operand_matches (icode, opno, op->value);
6665 /* Make OP describe an input operand that should have the same value
6666 as VALUE, after any mode conversion that the target might request.
6667 TYPE is the type of VALUE. */
6669 void
6670 create_convert_operand_from_type (struct expand_operand *op,
6671 rtx value, tree type)
6673 create_convert_operand_from (op, value, TYPE_MODE (type),
6674 TYPE_UNSIGNED (type));
6677 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
6678 of instruction ICODE. Return true on success, leaving the new operand
6679 values in the OPS themselves. Emit no code on failure. */
6681 bool
6682 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
6683 unsigned int nops, struct expand_operand *ops)
6685 rtx_insn *last;
6686 unsigned int i;
6688 last = get_last_insn ();
6689 for (i = 0; i < nops; i++)
6690 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
6692 delete_insns_since (last);
6693 return false;
6695 return true;
6698 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
6699 as its operands. Return the instruction pattern on success,
6700 and emit any necessary set-up code. Return null and emit no
6701 code on failure. */
6703 rtx_insn *
6704 maybe_gen_insn (enum insn_code icode, unsigned int nops,
6705 struct expand_operand *ops)
6707 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
6708 if (!maybe_legitimize_operands (icode, 0, nops, ops))
6709 return NULL;
6711 switch (nops)
6713 case 1:
6714 return GEN_FCN (icode) (ops[0].value);
6715 case 2:
6716 return GEN_FCN (icode) (ops[0].value, ops[1].value);
6717 case 3:
6718 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
6719 case 4:
6720 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6721 ops[3].value);
6722 case 5:
6723 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6724 ops[3].value, ops[4].value);
6725 case 6:
6726 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6727 ops[3].value, ops[4].value, ops[5].value);
6728 case 7:
6729 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6730 ops[3].value, ops[4].value, ops[5].value,
6731 ops[6].value);
6732 case 8:
6733 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6734 ops[3].value, ops[4].value, ops[5].value,
6735 ops[6].value, ops[7].value);
6736 case 9:
6737 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6738 ops[3].value, ops[4].value, ops[5].value,
6739 ops[6].value, ops[7].value, ops[8].value);
6741 gcc_unreachable ();
6744 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
6745 as its operands. Return true on success and emit no code on failure. */
6747 bool
6748 maybe_expand_insn (enum insn_code icode, unsigned int nops,
6749 struct expand_operand *ops)
6751 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6752 if (pat)
6754 emit_insn (pat);
6755 return true;
6757 return false;
6760 /* Like maybe_expand_insn, but for jumps. */
6762 bool
6763 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
6764 struct expand_operand *ops)
6766 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6767 if (pat)
6769 emit_jump_insn (pat);
6770 return true;
6772 return false;
6775 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
6776 as its operands. */
6778 void
6779 expand_insn (enum insn_code icode, unsigned int nops,
6780 struct expand_operand *ops)
6782 if (!maybe_expand_insn (icode, nops, ops))
6783 gcc_unreachable ();
6786 /* Like expand_insn, but for jumps. */
6788 void
6789 expand_jump_insn (enum insn_code icode, unsigned int nops,
6790 struct expand_operand *ops)
6792 if (!maybe_expand_jump_insn (icode, nops, ops))
6793 gcc_unreachable ();