libsanitizer merge from upstream r253555.
[official-gcc.git] / gcc / optabs.c
blob554530282db8cbb0a889262c8d40492d85794418
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "predict.h"
29 #include "tm_p.h"
30 #include "expmed.h"
31 #include "optabs.h"
32 #include "emit-rtl.h"
33 #include "recog.h"
34 #include "diagnostic-core.h"
36 /* Include insn-config.h before expr.h so that HAVE_conditional_move
37 is properly defined. */
38 #include "stor-layout.h"
39 #include "except.h"
40 #include "dojump.h"
41 #include "explow.h"
42 #include "expr.h"
43 #include "optabs-tree.h"
44 #include "libfuncs.h"
46 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
47 machine_mode *);
48 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
49 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
51 /* Debug facility for use in GDB. */
52 void debug_optab_libfuncs (void);
54 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
55 the result of operation CODE applied to OP0 (and OP1 if it is a binary
56 operation).
58 If the last insn does not set TARGET, don't do anything, but return 1.
60 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
61 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
62 try again, ensuring that TARGET is not one of the operands. */
64 static int
65 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
67 rtx_insn *last_insn;
68 rtx set;
69 rtx note;
71 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
73 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
74 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
75 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
76 && GET_RTX_CLASS (code) != RTX_COMPARE
77 && GET_RTX_CLASS (code) != RTX_UNARY)
78 return 1;
80 if (GET_CODE (target) == ZERO_EXTRACT)
81 return 1;
83 for (last_insn = insns;
84 NEXT_INSN (last_insn) != NULL_RTX;
85 last_insn = NEXT_INSN (last_insn))
88 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
89 a value changing in the insn, so the note would be invalid for CSE. */
90 if (reg_overlap_mentioned_p (target, op0)
91 || (op1 && reg_overlap_mentioned_p (target, op1)))
93 if (MEM_P (target)
94 && (rtx_equal_p (target, op0)
95 || (op1 && rtx_equal_p (target, op1))))
97 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
98 over expanding it as temp = MEM op X, MEM = temp. If the target
99 supports MEM = MEM op X instructions, it is sometimes too hard
100 to reconstruct that form later, especially if X is also a memory,
101 and due to multiple occurrences of addresses the address might
102 be forced into register unnecessarily.
103 Note that not emitting the REG_EQUIV note might inhibit
104 CSE in some cases. */
105 set = single_set (last_insn);
106 if (set
107 && GET_CODE (SET_SRC (set)) == code
108 && MEM_P (SET_DEST (set))
109 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
110 || (op1 && rtx_equal_p (SET_DEST (set),
111 XEXP (SET_SRC (set), 1)))))
112 return 1;
114 return 0;
117 set = set_for_reg_notes (last_insn);
118 if (set == NULL_RTX)
119 return 1;
121 if (! rtx_equal_p (SET_DEST (set), target)
122 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
123 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
124 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
125 return 1;
127 if (GET_RTX_CLASS (code) == RTX_UNARY)
128 switch (code)
130 case FFS:
131 case CLZ:
132 case CTZ:
133 case CLRSB:
134 case POPCOUNT:
135 case PARITY:
136 case BSWAP:
137 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
139 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
140 if (GET_MODE_SIZE (GET_MODE (op0))
141 > GET_MODE_SIZE (GET_MODE (target)))
142 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
143 note, GET_MODE (op0));
144 else
145 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
146 note, GET_MODE (op0));
147 break;
149 /* FALLTHRU */
150 default:
151 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
152 break;
154 else
155 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
157 set_unique_reg_note (last_insn, REG_EQUAL, note);
159 return 1;
162 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
163 for a widening operation would be. In most cases this would be OP0, but if
164 that's a constant it'll be VOIDmode, which isn't useful. */
166 static machine_mode
167 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
169 machine_mode m0 = GET_MODE (op0);
170 machine_mode m1 = GET_MODE (op1);
171 machine_mode result;
173 if (m0 == VOIDmode && m1 == VOIDmode)
174 return to_mode;
175 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
176 result = m1;
177 else
178 result = m0;
180 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
181 return to_mode;
183 return result;
186 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
187 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
188 not actually do a sign-extend or zero-extend, but can leave the
189 higher-order bits of the result rtx undefined, for example, in the case
190 of logical operations, but not right shifts. */
192 static rtx
193 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
194 int unsignedp, int no_extend)
196 rtx result;
198 /* If we don't have to extend and this is a constant, return it. */
199 if (no_extend && GET_MODE (op) == VOIDmode)
200 return op;
202 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
203 extend since it will be more efficient to do so unless the signedness of
204 a promoted object differs from our extension. */
205 if (! no_extend
206 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
207 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
208 return convert_modes (mode, oldmode, op, unsignedp);
210 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
211 SUBREG. */
212 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
213 return gen_lowpart (mode, force_reg (GET_MODE (op), op));
215 /* Otherwise, get an object of MODE, clobber it, and set the low-order
216 part to OP. */
218 result = gen_reg_rtx (mode);
219 emit_clobber (result);
220 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
221 return result;
224 /* Expand vector widening operations.
226 There are two different classes of operations handled here:
227 1) Operations whose result is wider than all the arguments to the operation.
228 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
229 In this case OP0 and optionally OP1 would be initialized,
230 but WIDE_OP wouldn't (not relevant for this case).
231 2) Operations whose result is of the same size as the last argument to the
232 operation, but wider than all the other arguments to the operation.
233 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
234 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
236 E.g, when called to expand the following operations, this is how
237 the arguments will be initialized:
238 nops OP0 OP1 WIDE_OP
239 widening-sum 2 oprnd0 - oprnd1
240 widening-dot-product 3 oprnd0 oprnd1 oprnd2
241 widening-mult 2 oprnd0 oprnd1 -
242 type-promotion (vec-unpack) 1 oprnd0 - - */
245 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
246 rtx target, int unsignedp)
248 struct expand_operand eops[4];
249 tree oprnd0, oprnd1, oprnd2;
250 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
251 optab widen_pattern_optab;
252 enum insn_code icode;
253 int nops = TREE_CODE_LENGTH (ops->code);
254 int op;
256 oprnd0 = ops->op0;
257 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
258 widen_pattern_optab =
259 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
260 if (ops->code == WIDEN_MULT_PLUS_EXPR
261 || ops->code == WIDEN_MULT_MINUS_EXPR)
262 icode = find_widening_optab_handler (widen_pattern_optab,
263 TYPE_MODE (TREE_TYPE (ops->op2)),
264 tmode0, 0);
265 else
266 icode = optab_handler (widen_pattern_optab, tmode0);
267 gcc_assert (icode != CODE_FOR_nothing);
269 if (nops >= 2)
271 oprnd1 = ops->op1;
272 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
275 /* The last operand is of a wider mode than the rest of the operands. */
276 if (nops == 2)
277 wmode = tmode1;
278 else if (nops == 3)
280 gcc_assert (tmode1 == tmode0);
281 gcc_assert (op1);
282 oprnd2 = ops->op2;
283 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
286 op = 0;
287 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
288 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
289 if (op1)
290 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
291 if (wide_op)
292 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
293 expand_insn (icode, op, eops);
294 return eops[0].value;
297 /* Generate code to perform an operation specified by TERNARY_OPTAB
298 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
300 UNSIGNEDP is for the case where we have to widen the operands
301 to perform the operation. It says to use zero-extension.
303 If TARGET is nonzero, the value
304 is generated there, if it is convenient to do so.
305 In all cases an rtx is returned for the locus of the value;
306 this may or may not be TARGET. */
309 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
310 rtx op1, rtx op2, rtx target, int unsignedp)
312 struct expand_operand ops[4];
313 enum insn_code icode = optab_handler (ternary_optab, mode);
315 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
317 create_output_operand (&ops[0], target, mode);
318 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
319 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
320 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
321 expand_insn (icode, 4, ops);
322 return ops[0].value;
326 /* Like expand_binop, but return a constant rtx if the result can be
327 calculated at compile time. The arguments and return value are
328 otherwise the same as for expand_binop. */
331 simplify_expand_binop (machine_mode mode, optab binoptab,
332 rtx op0, rtx op1, rtx target, int unsignedp,
333 enum optab_methods methods)
335 if (CONSTANT_P (op0) && CONSTANT_P (op1))
337 rtx x = simplify_binary_operation (optab_to_code (binoptab),
338 mode, op0, op1);
339 if (x)
340 return x;
343 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
346 /* Like simplify_expand_binop, but always put the result in TARGET.
347 Return true if the expansion succeeded. */
349 bool
350 force_expand_binop (machine_mode mode, optab binoptab,
351 rtx op0, rtx op1, rtx target, int unsignedp,
352 enum optab_methods methods)
354 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
355 target, unsignedp, methods);
356 if (x == 0)
357 return false;
358 if (x != target)
359 emit_move_insn (target, x);
360 return true;
363 /* Create a new vector value in VMODE with all elements set to OP. The
364 mode of OP must be the element mode of VMODE. If OP is a constant,
365 then the return value will be a constant. */
367 static rtx
368 expand_vector_broadcast (machine_mode vmode, rtx op)
370 enum insn_code icode;
371 rtvec vec;
372 rtx ret;
373 int i, n;
375 gcc_checking_assert (VECTOR_MODE_P (vmode));
377 n = GET_MODE_NUNITS (vmode);
378 vec = rtvec_alloc (n);
379 for (i = 0; i < n; ++i)
380 RTVEC_ELT (vec, i) = op;
382 if (CONSTANT_P (op))
383 return gen_rtx_CONST_VECTOR (vmode, vec);
385 /* ??? If the target doesn't have a vec_init, then we have no easy way
386 of performing this operation. Most of this sort of generic support
387 is hidden away in the vector lowering support in gimple. */
388 icode = optab_handler (vec_init_optab, vmode);
389 if (icode == CODE_FOR_nothing)
390 return NULL;
392 ret = gen_reg_rtx (vmode);
393 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
395 return ret;
398 /* This subroutine of expand_doubleword_shift handles the cases in which
399 the effective shift value is >= BITS_PER_WORD. The arguments and return
400 value are the same as for the parent routine, except that SUPERWORD_OP1
401 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
402 INTO_TARGET may be null if the caller has decided to calculate it. */
404 static bool
405 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
406 rtx outof_target, rtx into_target,
407 int unsignedp, enum optab_methods methods)
409 if (into_target != 0)
410 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
411 into_target, unsignedp, methods))
412 return false;
414 if (outof_target != 0)
416 /* For a signed right shift, we must fill OUTOF_TARGET with copies
417 of the sign bit, otherwise we must fill it with zeros. */
418 if (binoptab != ashr_optab)
419 emit_move_insn (outof_target, CONST0_RTX (word_mode));
420 else
421 if (!force_expand_binop (word_mode, binoptab,
422 outof_input, GEN_INT (BITS_PER_WORD - 1),
423 outof_target, unsignedp, methods))
424 return false;
426 return true;
429 /* This subroutine of expand_doubleword_shift handles the cases in which
430 the effective shift value is < BITS_PER_WORD. The arguments and return
431 value are the same as for the parent routine. */
433 static bool
434 expand_subword_shift (machine_mode op1_mode, optab binoptab,
435 rtx outof_input, rtx into_input, rtx op1,
436 rtx outof_target, rtx into_target,
437 int unsignedp, enum optab_methods methods,
438 unsigned HOST_WIDE_INT shift_mask)
440 optab reverse_unsigned_shift, unsigned_shift;
441 rtx tmp, carries;
443 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
444 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
446 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
447 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
448 the opposite direction to BINOPTAB. */
449 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
451 carries = outof_input;
452 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
453 op1_mode), op1_mode);
454 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
455 0, true, methods);
457 else
459 /* We must avoid shifting by BITS_PER_WORD bits since that is either
460 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
461 has unknown behavior. Do a single shift first, then shift by the
462 remainder. It's OK to use ~OP1 as the remainder if shift counts
463 are truncated to the mode size. */
464 carries = expand_binop (word_mode, reverse_unsigned_shift,
465 outof_input, const1_rtx, 0, unsignedp, methods);
466 if (shift_mask == BITS_PER_WORD - 1)
468 tmp = immed_wide_int_const
469 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
470 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
471 0, true, methods);
473 else
475 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
476 op1_mode), op1_mode);
477 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
478 0, true, methods);
481 if (tmp == 0 || carries == 0)
482 return false;
483 carries = expand_binop (word_mode, reverse_unsigned_shift,
484 carries, tmp, 0, unsignedp, methods);
485 if (carries == 0)
486 return false;
488 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
489 so the result can go directly into INTO_TARGET if convenient. */
490 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
491 into_target, unsignedp, methods);
492 if (tmp == 0)
493 return false;
495 /* Now OR in the bits carried over from OUTOF_INPUT. */
496 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
497 into_target, unsignedp, methods))
498 return false;
500 /* Use a standard word_mode shift for the out-of half. */
501 if (outof_target != 0)
502 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
503 outof_target, unsignedp, methods))
504 return false;
506 return true;
510 /* Try implementing expand_doubleword_shift using conditional moves.
511 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
512 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
513 are the shift counts to use in the former and latter case. All other
514 arguments are the same as the parent routine. */
516 static bool
517 expand_doubleword_shift_condmove (machine_mode op1_mode, optab binoptab,
518 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
519 rtx outof_input, rtx into_input,
520 rtx subword_op1, rtx superword_op1,
521 rtx outof_target, rtx into_target,
522 int unsignedp, enum optab_methods methods,
523 unsigned HOST_WIDE_INT shift_mask)
525 rtx outof_superword, into_superword;
527 /* Put the superword version of the output into OUTOF_SUPERWORD and
528 INTO_SUPERWORD. */
529 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
530 if (outof_target != 0 && subword_op1 == superword_op1)
532 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
533 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
534 into_superword = outof_target;
535 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
536 outof_superword, 0, unsignedp, methods))
537 return false;
539 else
541 into_superword = gen_reg_rtx (word_mode);
542 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
543 outof_superword, into_superword,
544 unsignedp, methods))
545 return false;
548 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
549 if (!expand_subword_shift (op1_mode, binoptab,
550 outof_input, into_input, subword_op1,
551 outof_target, into_target,
552 unsignedp, methods, shift_mask))
553 return false;
555 /* Select between them. Do the INTO half first because INTO_SUPERWORD
556 might be the current value of OUTOF_TARGET. */
557 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
558 into_target, into_superword, word_mode, false))
559 return false;
561 if (outof_target != 0)
562 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
563 outof_target, outof_superword,
564 word_mode, false))
565 return false;
567 return true;
570 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
571 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
572 input operand; the shift moves bits in the direction OUTOF_INPUT->
573 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
574 of the target. OP1 is the shift count and OP1_MODE is its mode.
575 If OP1 is constant, it will have been truncated as appropriate
576 and is known to be nonzero.
578 If SHIFT_MASK is zero, the result of word shifts is undefined when the
579 shift count is outside the range [0, BITS_PER_WORD). This routine must
580 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
582 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
583 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
584 fill with zeros or sign bits as appropriate.
586 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
587 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
588 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
589 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
590 are undefined.
592 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
593 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
594 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
595 function wants to calculate it itself.
597 Return true if the shift could be successfully synthesized. */
599 static bool
600 expand_doubleword_shift (machine_mode op1_mode, optab binoptab,
601 rtx outof_input, rtx into_input, rtx op1,
602 rtx outof_target, rtx into_target,
603 int unsignedp, enum optab_methods methods,
604 unsigned HOST_WIDE_INT shift_mask)
606 rtx superword_op1, tmp, cmp1, cmp2;
607 enum rtx_code cmp_code;
609 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
610 fill the result with sign or zero bits as appropriate. If so, the value
611 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
612 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
613 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
615 This isn't worthwhile for constant shifts since the optimizers will
616 cope better with in-range shift counts. */
617 if (shift_mask >= BITS_PER_WORD
618 && outof_target != 0
619 && !CONSTANT_P (op1))
621 if (!expand_doubleword_shift (op1_mode, binoptab,
622 outof_input, into_input, op1,
623 0, into_target,
624 unsignedp, methods, shift_mask))
625 return false;
626 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
627 outof_target, unsignedp, methods))
628 return false;
629 return true;
632 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
633 is true when the effective shift value is less than BITS_PER_WORD.
634 Set SUPERWORD_OP1 to the shift count that should be used to shift
635 OUTOF_INPUT into INTO_TARGET when the condition is false. */
636 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
637 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
639 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
640 is a subword shift count. */
641 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
642 0, true, methods);
643 cmp2 = CONST0_RTX (op1_mode);
644 cmp_code = EQ;
645 superword_op1 = op1;
647 else
649 /* Set CMP1 to OP1 - BITS_PER_WORD. */
650 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
651 0, true, methods);
652 cmp2 = CONST0_RTX (op1_mode);
653 cmp_code = LT;
654 superword_op1 = cmp1;
656 if (cmp1 == 0)
657 return false;
659 /* If we can compute the condition at compile time, pick the
660 appropriate subroutine. */
661 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
662 if (tmp != 0 && CONST_INT_P (tmp))
664 if (tmp == const0_rtx)
665 return expand_superword_shift (binoptab, outof_input, superword_op1,
666 outof_target, into_target,
667 unsignedp, methods);
668 else
669 return expand_subword_shift (op1_mode, binoptab,
670 outof_input, into_input, op1,
671 outof_target, into_target,
672 unsignedp, methods, shift_mask);
675 /* Try using conditional moves to generate straight-line code. */
676 if (HAVE_conditional_move)
678 rtx_insn *start = get_last_insn ();
679 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
680 cmp_code, cmp1, cmp2,
681 outof_input, into_input,
682 op1, superword_op1,
683 outof_target, into_target,
684 unsignedp, methods, shift_mask))
685 return true;
686 delete_insns_since (start);
689 /* As a last resort, use branches to select the correct alternative. */
690 rtx_code_label *subword_label = gen_label_rtx ();
691 rtx_code_label *done_label = gen_label_rtx ();
693 NO_DEFER_POP;
694 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
695 0, 0, subword_label, -1);
696 OK_DEFER_POP;
698 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
699 outof_target, into_target,
700 unsignedp, methods))
701 return false;
703 emit_jump_insn (targetm.gen_jump (done_label));
704 emit_barrier ();
705 emit_label (subword_label);
707 if (!expand_subword_shift (op1_mode, binoptab,
708 outof_input, into_input, op1,
709 outof_target, into_target,
710 unsignedp, methods, shift_mask))
711 return false;
713 emit_label (done_label);
714 return true;
717 /* Subroutine of expand_binop. Perform a double word multiplication of
718 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
719 as the target's word_mode. This function return NULL_RTX if anything
720 goes wrong, in which case it may have already emitted instructions
721 which need to be deleted.
723 If we want to multiply two two-word values and have normal and widening
724 multiplies of single-word values, we can do this with three smaller
725 multiplications.
727 The multiplication proceeds as follows:
728 _______________________
729 [__op0_high_|__op0_low__]
730 _______________________
731 * [__op1_high_|__op1_low__]
732 _______________________________________________
733 _______________________
734 (1) [__op0_low__*__op1_low__]
735 _______________________
736 (2a) [__op0_low__*__op1_high_]
737 _______________________
738 (2b) [__op0_high_*__op1_low__]
739 _______________________
740 (3) [__op0_high_*__op1_high_]
743 This gives a 4-word result. Since we are only interested in the
744 lower 2 words, partial result (3) and the upper words of (2a) and
745 (2b) don't need to be calculated. Hence (2a) and (2b) can be
746 calculated using non-widening multiplication.
748 (1), however, needs to be calculated with an unsigned widening
749 multiplication. If this operation is not directly supported we
750 try using a signed widening multiplication and adjust the result.
751 This adjustment works as follows:
753 If both operands are positive then no adjustment is needed.
755 If the operands have different signs, for example op0_low < 0 and
756 op1_low >= 0, the instruction treats the most significant bit of
757 op0_low as a sign bit instead of a bit with significance
758 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
759 with 2**BITS_PER_WORD - op0_low, and two's complements the
760 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
761 the result.
763 Similarly, if both operands are negative, we need to add
764 (op0_low + op1_low) * 2**BITS_PER_WORD.
766 We use a trick to adjust quickly. We logically shift op0_low right
767 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
768 op0_high (op1_high) before it is used to calculate 2b (2a). If no
769 logical shift exists, we do an arithmetic right shift and subtract
770 the 0 or -1. */
772 static rtx
773 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
774 bool umulp, enum optab_methods methods)
776 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
777 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
778 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
779 rtx product, adjust, product_high, temp;
781 rtx op0_high = operand_subword_force (op0, high, mode);
782 rtx op0_low = operand_subword_force (op0, low, mode);
783 rtx op1_high = operand_subword_force (op1, high, mode);
784 rtx op1_low = operand_subword_force (op1, low, mode);
786 /* If we're using an unsigned multiply to directly compute the product
787 of the low-order words of the operands and perform any required
788 adjustments of the operands, we begin by trying two more multiplications
789 and then computing the appropriate sum.
791 We have checked above that the required addition is provided.
792 Full-word addition will normally always succeed, especially if
793 it is provided at all, so we don't worry about its failure. The
794 multiplication may well fail, however, so we do handle that. */
796 if (!umulp)
798 /* ??? This could be done with emit_store_flag where available. */
799 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
800 NULL_RTX, 1, methods);
801 if (temp)
802 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
803 NULL_RTX, 0, OPTAB_DIRECT);
804 else
806 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
807 NULL_RTX, 0, methods);
808 if (!temp)
809 return NULL_RTX;
810 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
811 NULL_RTX, 0, OPTAB_DIRECT);
814 if (!op0_high)
815 return NULL_RTX;
818 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
819 NULL_RTX, 0, OPTAB_DIRECT);
820 if (!adjust)
821 return NULL_RTX;
823 /* OP0_HIGH should now be dead. */
825 if (!umulp)
827 /* ??? This could be done with emit_store_flag where available. */
828 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
829 NULL_RTX, 1, methods);
830 if (temp)
831 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
832 NULL_RTX, 0, OPTAB_DIRECT);
833 else
835 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
836 NULL_RTX, 0, methods);
837 if (!temp)
838 return NULL_RTX;
839 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
840 NULL_RTX, 0, OPTAB_DIRECT);
843 if (!op1_high)
844 return NULL_RTX;
847 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
848 NULL_RTX, 0, OPTAB_DIRECT);
849 if (!temp)
850 return NULL_RTX;
852 /* OP1_HIGH should now be dead. */
854 adjust = expand_binop (word_mode, add_optab, adjust, temp,
855 NULL_RTX, 0, OPTAB_DIRECT);
857 if (target && !REG_P (target))
858 target = NULL_RTX;
860 if (umulp)
861 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
862 target, 1, OPTAB_DIRECT);
863 else
864 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
865 target, 1, OPTAB_DIRECT);
867 if (!product)
868 return NULL_RTX;
870 product_high = operand_subword (product, high, 1, mode);
871 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
872 NULL_RTX, 0, OPTAB_DIRECT);
873 emit_move_insn (product_high, adjust);
874 return product;
877 /* Wrapper around expand_binop which takes an rtx code to specify
878 the operation to perform, not an optab pointer. All other
879 arguments are the same. */
881 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
882 rtx op1, rtx target, int unsignedp,
883 enum optab_methods methods)
885 optab binop = code_to_optab (code);
886 gcc_assert (binop);
888 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
891 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
892 binop. Order them according to commutative_operand_precedence and, if
893 possible, try to put TARGET or a pseudo first. */
894 static bool
895 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
897 int op0_prec = commutative_operand_precedence (op0);
898 int op1_prec = commutative_operand_precedence (op1);
900 if (op0_prec < op1_prec)
901 return true;
903 if (op0_prec > op1_prec)
904 return false;
906 /* With equal precedence, both orders are ok, but it is better if the
907 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
908 if (target == 0 || REG_P (target))
909 return (REG_P (op1) && !REG_P (op0)) || target == op1;
910 else
911 return rtx_equal_p (op1, target);
914 /* Return true if BINOPTAB implements a shift operation. */
916 static bool
917 shift_optab_p (optab binoptab)
919 switch (optab_to_code (binoptab))
921 case ASHIFT:
922 case SS_ASHIFT:
923 case US_ASHIFT:
924 case ASHIFTRT:
925 case LSHIFTRT:
926 case ROTATE:
927 case ROTATERT:
928 return true;
930 default:
931 return false;
935 /* Return true if BINOPTAB implements a commutative binary operation. */
937 static bool
938 commutative_optab_p (optab binoptab)
940 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
941 || binoptab == smul_widen_optab
942 || binoptab == umul_widen_optab
943 || binoptab == smul_highpart_optab
944 || binoptab == umul_highpart_optab);
947 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
948 optimizing, and if the operand is a constant that costs more than
949 1 instruction, force the constant into a register and return that
950 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
952 static rtx
953 avoid_expensive_constant (machine_mode mode, optab binoptab,
954 int opn, rtx x, bool unsignedp)
956 bool speed = optimize_insn_for_speed_p ();
958 if (mode != VOIDmode
959 && optimize
960 && CONSTANT_P (x)
961 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
962 > set_src_cost (x, mode, speed)))
964 if (CONST_INT_P (x))
966 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
967 if (intval != INTVAL (x))
968 x = GEN_INT (intval);
970 else
971 x = convert_modes (mode, VOIDmode, x, unsignedp);
972 x = force_reg (mode, x);
974 return x;
977 /* Helper function for expand_binop: handle the case where there
978 is an insn that directly implements the indicated operation.
979 Returns null if this is not possible. */
980 static rtx
981 expand_binop_directly (machine_mode mode, optab binoptab,
982 rtx op0, rtx op1,
983 rtx target, int unsignedp, enum optab_methods methods,
984 rtx_insn *last)
986 machine_mode from_mode = widened_mode (mode, op0, op1);
987 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
988 from_mode, 1);
989 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
990 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
991 machine_mode mode0, mode1, tmp_mode;
992 struct expand_operand ops[3];
993 bool commutative_p;
994 rtx_insn *pat;
995 rtx xop0 = op0, xop1 = op1;
997 /* If it is a commutative operator and the modes would match
998 if we would swap the operands, we can save the conversions. */
999 commutative_p = commutative_optab_p (binoptab);
1000 if (commutative_p
1001 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1002 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1003 std::swap (xop0, xop1);
1005 /* If we are optimizing, force expensive constants into a register. */
1006 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1007 if (!shift_optab_p (binoptab))
1008 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1010 /* In case the insn wants input operands in modes different from
1011 those of the actual operands, convert the operands. It would
1012 seem that we don't need to convert CONST_INTs, but we do, so
1013 that they're properly zero-extended, sign-extended or truncated
1014 for their mode. */
1016 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1017 if (xmode0 != VOIDmode && xmode0 != mode0)
1019 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1020 mode0 = xmode0;
1023 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1024 if (xmode1 != VOIDmode && xmode1 != mode1)
1026 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1027 mode1 = xmode1;
1030 /* If operation is commutative,
1031 try to make the first operand a register.
1032 Even better, try to make it the same as the target.
1033 Also try to make the last operand a constant. */
1034 if (commutative_p
1035 && swap_commutative_operands_with_target (target, xop0, xop1))
1036 std::swap (xop0, xop1);
1038 /* Now, if insn's predicates don't allow our operands, put them into
1039 pseudo regs. */
1041 if (binoptab == vec_pack_trunc_optab
1042 || binoptab == vec_pack_usat_optab
1043 || binoptab == vec_pack_ssat_optab
1044 || binoptab == vec_pack_ufix_trunc_optab
1045 || binoptab == vec_pack_sfix_trunc_optab)
1047 /* The mode of the result is different then the mode of the
1048 arguments. */
1049 tmp_mode = insn_data[(int) icode].operand[0].mode;
1050 if (VECTOR_MODE_P (mode)
1051 && GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1053 delete_insns_since (last);
1054 return NULL_RTX;
1057 else
1058 tmp_mode = mode;
1060 create_output_operand (&ops[0], target, tmp_mode);
1061 create_input_operand (&ops[1], xop0, mode0);
1062 create_input_operand (&ops[2], xop1, mode1);
1063 pat = maybe_gen_insn (icode, 3, ops);
1064 if (pat)
1066 /* If PAT is composed of more than one insn, try to add an appropriate
1067 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1068 operand, call expand_binop again, this time without a target. */
1069 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1070 && ! add_equal_note (pat, ops[0].value,
1071 optab_to_code (binoptab),
1072 ops[1].value, ops[2].value))
1074 delete_insns_since (last);
1075 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1076 unsignedp, methods);
1079 emit_insn (pat);
1080 return ops[0].value;
1082 delete_insns_since (last);
1083 return NULL_RTX;
1086 /* Generate code to perform an operation specified by BINOPTAB
1087 on operands OP0 and OP1, with result having machine-mode MODE.
1089 UNSIGNEDP is for the case where we have to widen the operands
1090 to perform the operation. It says to use zero-extension.
1092 If TARGET is nonzero, the value
1093 is generated there, if it is convenient to do so.
1094 In all cases an rtx is returned for the locus of the value;
1095 this may or may not be TARGET. */
1098 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1099 rtx target, int unsignedp, enum optab_methods methods)
1101 enum optab_methods next_methods
1102 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1103 ? OPTAB_WIDEN : methods);
1104 enum mode_class mclass;
1105 machine_mode wider_mode;
1106 rtx libfunc;
1107 rtx temp;
1108 rtx_insn *entry_last = get_last_insn ();
1109 rtx_insn *last;
1111 mclass = GET_MODE_CLASS (mode);
1113 /* If subtracting an integer constant, convert this into an addition of
1114 the negated constant. */
1116 if (binoptab == sub_optab && CONST_INT_P (op1))
1118 op1 = negate_rtx (mode, op1);
1119 binoptab = add_optab;
1122 /* Record where to delete back to if we backtrack. */
1123 last = get_last_insn ();
1125 /* If we can do it with a three-operand insn, do so. */
1127 if (methods != OPTAB_MUST_WIDEN
1128 && find_widening_optab_handler (binoptab, mode,
1129 widened_mode (mode, op0, op1), 1)
1130 != CODE_FOR_nothing)
1132 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1133 unsignedp, methods, last);
1134 if (temp)
1135 return temp;
1138 /* If we were trying to rotate, and that didn't work, try rotating
1139 the other direction before falling back to shifts and bitwise-or. */
1140 if (((binoptab == rotl_optab
1141 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1142 || (binoptab == rotr_optab
1143 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1144 && mclass == MODE_INT)
1146 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1147 rtx newop1;
1148 unsigned int bits = GET_MODE_PRECISION (mode);
1150 if (CONST_INT_P (op1))
1151 newop1 = GEN_INT (bits - INTVAL (op1));
1152 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1153 newop1 = negate_rtx (GET_MODE (op1), op1);
1154 else
1155 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1156 gen_int_mode (bits, GET_MODE (op1)), op1,
1157 NULL_RTX, unsignedp, OPTAB_DIRECT);
1159 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1160 target, unsignedp, methods, last);
1161 if (temp)
1162 return temp;
1165 /* If this is a multiply, see if we can do a widening operation that
1166 takes operands of this mode and makes a wider mode. */
1168 if (binoptab == smul_optab
1169 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1170 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1171 : smul_widen_optab),
1172 GET_MODE_2XWIDER_MODE (mode), mode)
1173 != CODE_FOR_nothing))
1175 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1176 unsignedp ? umul_widen_optab : smul_widen_optab,
1177 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1179 if (temp != 0)
1181 if (GET_MODE_CLASS (mode) == MODE_INT
1182 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1183 return gen_lowpart (mode, temp);
1184 else
1185 return convert_to_mode (mode, temp, unsignedp);
1189 /* If this is a vector shift by a scalar, see if we can do a vector
1190 shift by a vector. If so, broadcast the scalar into a vector. */
1191 if (mclass == MODE_VECTOR_INT)
1193 optab otheroptab = unknown_optab;
1195 if (binoptab == ashl_optab)
1196 otheroptab = vashl_optab;
1197 else if (binoptab == ashr_optab)
1198 otheroptab = vashr_optab;
1199 else if (binoptab == lshr_optab)
1200 otheroptab = vlshr_optab;
1201 else if (binoptab == rotl_optab)
1202 otheroptab = vrotl_optab;
1203 else if (binoptab == rotr_optab)
1204 otheroptab = vrotr_optab;
1206 if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing)
1208 /* The scalar may have been extended to be too wide. Truncate
1209 it back to the proper size to fit in the broadcast vector. */
1210 machine_mode inner_mode = GET_MODE_INNER (mode);
1211 if (!CONST_INT_P (op1)
1212 && (GET_MODE_BITSIZE (inner_mode)
1213 < GET_MODE_BITSIZE (GET_MODE (op1))))
1214 op1 = force_reg (inner_mode,
1215 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1216 GET_MODE (op1)));
1217 rtx vop1 = expand_vector_broadcast (mode, op1);
1218 if (vop1)
1220 temp = expand_binop_directly (mode, otheroptab, op0, vop1,
1221 target, unsignedp, methods, last);
1222 if (temp)
1223 return temp;
1228 /* Look for a wider mode of the same class for which we think we
1229 can open-code the operation. Check for a widening multiply at the
1230 wider mode as well. */
1232 if (CLASS_HAS_WIDER_MODES_P (mclass)
1233 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1234 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1235 wider_mode != VOIDmode;
1236 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1238 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1239 || (binoptab == smul_optab
1240 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1241 && (find_widening_optab_handler ((unsignedp
1242 ? umul_widen_optab
1243 : smul_widen_optab),
1244 GET_MODE_WIDER_MODE (wider_mode),
1245 mode, 0)
1246 != CODE_FOR_nothing)))
1248 rtx xop0 = op0, xop1 = op1;
1249 int no_extend = 0;
1251 /* For certain integer operations, we need not actually extend
1252 the narrow operands, as long as we will truncate
1253 the results to the same narrowness. */
1255 if ((binoptab == ior_optab || binoptab == and_optab
1256 || binoptab == xor_optab
1257 || binoptab == add_optab || binoptab == sub_optab
1258 || binoptab == smul_optab || binoptab == ashl_optab)
1259 && mclass == MODE_INT)
1261 no_extend = 1;
1262 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1263 xop0, unsignedp);
1264 if (binoptab != ashl_optab)
1265 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1266 xop1, unsignedp);
1269 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1271 /* The second operand of a shift must always be extended. */
1272 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1273 no_extend && binoptab != ashl_optab);
1275 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1276 unsignedp, OPTAB_DIRECT);
1277 if (temp)
1279 if (mclass != MODE_INT
1280 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1282 if (target == 0)
1283 target = gen_reg_rtx (mode);
1284 convert_move (target, temp, 0);
1285 return target;
1287 else
1288 return gen_lowpart (mode, temp);
1290 else
1291 delete_insns_since (last);
1295 /* If operation is commutative,
1296 try to make the first operand a register.
1297 Even better, try to make it the same as the target.
1298 Also try to make the last operand a constant. */
1299 if (commutative_optab_p (binoptab)
1300 && swap_commutative_operands_with_target (target, op0, op1))
1301 std::swap (op0, op1);
1303 /* These can be done a word at a time. */
1304 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1305 && mclass == MODE_INT
1306 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1307 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1309 int i;
1310 rtx_insn *insns;
1312 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1313 won't be accurate, so use a new target. */
1314 if (target == 0
1315 || target == op0
1316 || target == op1
1317 || !valid_multiword_target_p (target))
1318 target = gen_reg_rtx (mode);
1320 start_sequence ();
1322 /* Do the actual arithmetic. */
1323 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1325 rtx target_piece = operand_subword (target, i, 1, mode);
1326 rtx x = expand_binop (word_mode, binoptab,
1327 operand_subword_force (op0, i, mode),
1328 operand_subword_force (op1, i, mode),
1329 target_piece, unsignedp, next_methods);
1331 if (x == 0)
1332 break;
1334 if (target_piece != x)
1335 emit_move_insn (target_piece, x);
1338 insns = get_insns ();
1339 end_sequence ();
1341 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1343 emit_insn (insns);
1344 return target;
1348 /* Synthesize double word shifts from single word shifts. */
1349 if ((binoptab == lshr_optab || binoptab == ashl_optab
1350 || binoptab == ashr_optab)
1351 && mclass == MODE_INT
1352 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1353 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1354 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1355 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1356 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1357 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1359 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1360 machine_mode op1_mode;
1362 double_shift_mask = targetm.shift_truncation_mask (mode);
1363 shift_mask = targetm.shift_truncation_mask (word_mode);
1364 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1366 /* Apply the truncation to constant shifts. */
1367 if (double_shift_mask > 0 && CONST_INT_P (op1))
1368 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1370 if (op1 == CONST0_RTX (op1_mode))
1371 return op0;
1373 /* Make sure that this is a combination that expand_doubleword_shift
1374 can handle. See the comments there for details. */
1375 if (double_shift_mask == 0
1376 || (shift_mask == BITS_PER_WORD - 1
1377 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1379 rtx_insn *insns;
1380 rtx into_target, outof_target;
1381 rtx into_input, outof_input;
1382 int left_shift, outof_word;
1384 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1385 won't be accurate, so use a new target. */
1386 if (target == 0
1387 || target == op0
1388 || target == op1
1389 || !valid_multiword_target_p (target))
1390 target = gen_reg_rtx (mode);
1392 start_sequence ();
1394 /* OUTOF_* is the word we are shifting bits away from, and
1395 INTO_* is the word that we are shifting bits towards, thus
1396 they differ depending on the direction of the shift and
1397 WORDS_BIG_ENDIAN. */
1399 left_shift = binoptab == ashl_optab;
1400 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1402 outof_target = operand_subword (target, outof_word, 1, mode);
1403 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1405 outof_input = operand_subword_force (op0, outof_word, mode);
1406 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1408 if (expand_doubleword_shift (op1_mode, binoptab,
1409 outof_input, into_input, op1,
1410 outof_target, into_target,
1411 unsignedp, next_methods, shift_mask))
1413 insns = get_insns ();
1414 end_sequence ();
1416 emit_insn (insns);
1417 return target;
1419 end_sequence ();
1423 /* Synthesize double word rotates from single word shifts. */
1424 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1425 && mclass == MODE_INT
1426 && CONST_INT_P (op1)
1427 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1428 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1429 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1431 rtx_insn *insns;
1432 rtx into_target, outof_target;
1433 rtx into_input, outof_input;
1434 rtx inter;
1435 int shift_count, left_shift, outof_word;
1437 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1438 won't be accurate, so use a new target. Do this also if target is not
1439 a REG, first because having a register instead may open optimization
1440 opportunities, and second because if target and op0 happen to be MEMs
1441 designating the same location, we would risk clobbering it too early
1442 in the code sequence we generate below. */
1443 if (target == 0
1444 || target == op0
1445 || target == op1
1446 || !REG_P (target)
1447 || !valid_multiword_target_p (target))
1448 target = gen_reg_rtx (mode);
1450 start_sequence ();
1452 shift_count = INTVAL (op1);
1454 /* OUTOF_* is the word we are shifting bits away from, and
1455 INTO_* is the word that we are shifting bits towards, thus
1456 they differ depending on the direction of the shift and
1457 WORDS_BIG_ENDIAN. */
1459 left_shift = (binoptab == rotl_optab);
1460 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1462 outof_target = operand_subword (target, outof_word, 1, mode);
1463 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1465 outof_input = operand_subword_force (op0, outof_word, mode);
1466 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1468 if (shift_count == BITS_PER_WORD)
1470 /* This is just a word swap. */
1471 emit_move_insn (outof_target, into_input);
1472 emit_move_insn (into_target, outof_input);
1473 inter = const0_rtx;
1475 else
1477 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1478 rtx first_shift_count, second_shift_count;
1479 optab reverse_unsigned_shift, unsigned_shift;
1481 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1482 ? lshr_optab : ashl_optab);
1484 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1485 ? ashl_optab : lshr_optab);
1487 if (shift_count > BITS_PER_WORD)
1489 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1490 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1492 else
1494 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1495 second_shift_count = GEN_INT (shift_count);
1498 into_temp1 = expand_binop (word_mode, unsigned_shift,
1499 outof_input, first_shift_count,
1500 NULL_RTX, unsignedp, next_methods);
1501 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1502 into_input, second_shift_count,
1503 NULL_RTX, unsignedp, next_methods);
1505 if (into_temp1 != 0 && into_temp2 != 0)
1506 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1507 into_target, unsignedp, next_methods);
1508 else
1509 inter = 0;
1511 if (inter != 0 && inter != into_target)
1512 emit_move_insn (into_target, inter);
1514 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1515 into_input, first_shift_count,
1516 NULL_RTX, unsignedp, next_methods);
1517 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1518 outof_input, second_shift_count,
1519 NULL_RTX, unsignedp, next_methods);
1521 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1522 inter = expand_binop (word_mode, ior_optab,
1523 outof_temp1, outof_temp2,
1524 outof_target, unsignedp, next_methods);
1526 if (inter != 0 && inter != outof_target)
1527 emit_move_insn (outof_target, inter);
1530 insns = get_insns ();
1531 end_sequence ();
1533 if (inter != 0)
1535 emit_insn (insns);
1536 return target;
1540 /* These can be done a word at a time by propagating carries. */
1541 if ((binoptab == add_optab || binoptab == sub_optab)
1542 && mclass == MODE_INT
1543 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1544 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1546 unsigned int i;
1547 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1548 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1549 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1550 rtx xop0, xop1, xtarget;
1552 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1553 value is one of those, use it. Otherwise, use 1 since it is the
1554 one easiest to get. */
1555 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1556 int normalizep = STORE_FLAG_VALUE;
1557 #else
1558 int normalizep = 1;
1559 #endif
1561 /* Prepare the operands. */
1562 xop0 = force_reg (mode, op0);
1563 xop1 = force_reg (mode, op1);
1565 xtarget = gen_reg_rtx (mode);
1567 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1568 target = xtarget;
1570 /* Indicate for flow that the entire target reg is being set. */
1571 if (REG_P (target))
1572 emit_clobber (xtarget);
1574 /* Do the actual arithmetic. */
1575 for (i = 0; i < nwords; i++)
1577 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1578 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1579 rtx op0_piece = operand_subword_force (xop0, index, mode);
1580 rtx op1_piece = operand_subword_force (xop1, index, mode);
1581 rtx x;
1583 /* Main add/subtract of the input operands. */
1584 x = expand_binop (word_mode, binoptab,
1585 op0_piece, op1_piece,
1586 target_piece, unsignedp, next_methods);
1587 if (x == 0)
1588 break;
1590 if (i + 1 < nwords)
1592 /* Store carry from main add/subtract. */
1593 carry_out = gen_reg_rtx (word_mode);
1594 carry_out = emit_store_flag_force (carry_out,
1595 (binoptab == add_optab
1596 ? LT : GT),
1597 x, op0_piece,
1598 word_mode, 1, normalizep);
1601 if (i > 0)
1603 rtx newx;
1605 /* Add/subtract previous carry to main result. */
1606 newx = expand_binop (word_mode,
1607 normalizep == 1 ? binoptab : otheroptab,
1608 x, carry_in,
1609 NULL_RTX, 1, next_methods);
1611 if (i + 1 < nwords)
1613 /* Get out carry from adding/subtracting carry in. */
1614 rtx carry_tmp = gen_reg_rtx (word_mode);
1615 carry_tmp = emit_store_flag_force (carry_tmp,
1616 (binoptab == add_optab
1617 ? LT : GT),
1618 newx, x,
1619 word_mode, 1, normalizep);
1621 /* Logical-ior the two poss. carry together. */
1622 carry_out = expand_binop (word_mode, ior_optab,
1623 carry_out, carry_tmp,
1624 carry_out, 0, next_methods);
1625 if (carry_out == 0)
1626 break;
1628 emit_move_insn (target_piece, newx);
1630 else
1632 if (x != target_piece)
1633 emit_move_insn (target_piece, x);
1636 carry_in = carry_out;
1639 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1641 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
1642 || ! rtx_equal_p (target, xtarget))
1644 rtx_insn *temp = emit_move_insn (target, xtarget);
1646 set_dst_reg_note (temp, REG_EQUAL,
1647 gen_rtx_fmt_ee (optab_to_code (binoptab),
1648 mode, copy_rtx (xop0),
1649 copy_rtx (xop1)),
1650 target);
1652 else
1653 target = xtarget;
1655 return target;
1658 else
1659 delete_insns_since (last);
1662 /* Attempt to synthesize double word multiplies using a sequence of word
1663 mode multiplications. We first attempt to generate a sequence using a
1664 more efficient unsigned widening multiply, and if that fails we then
1665 try using a signed widening multiply. */
1667 if (binoptab == smul_optab
1668 && mclass == MODE_INT
1669 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1670 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1671 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1673 rtx product = NULL_RTX;
1674 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
1675 != CODE_FOR_nothing)
1677 product = expand_doubleword_mult (mode, op0, op1, target,
1678 true, methods);
1679 if (!product)
1680 delete_insns_since (last);
1683 if (product == NULL_RTX
1684 && widening_optab_handler (smul_widen_optab, mode, word_mode)
1685 != CODE_FOR_nothing)
1687 product = expand_doubleword_mult (mode, op0, op1, target,
1688 false, methods);
1689 if (!product)
1690 delete_insns_since (last);
1693 if (product != NULL_RTX)
1695 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
1697 temp = emit_move_insn (target ? target : product, product);
1698 set_dst_reg_note (temp,
1699 REG_EQUAL,
1700 gen_rtx_fmt_ee (MULT, mode,
1701 copy_rtx (op0),
1702 copy_rtx (op1)),
1703 target ? target : product);
1705 return product;
1709 /* It can't be open-coded in this mode.
1710 Use a library call if one is available and caller says that's ok. */
1712 libfunc = optab_libfunc (binoptab, mode);
1713 if (libfunc
1714 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1716 rtx_insn *insns;
1717 rtx op1x = op1;
1718 machine_mode op1_mode = mode;
1719 rtx value;
1721 start_sequence ();
1723 if (shift_optab_p (binoptab))
1725 op1_mode = targetm.libgcc_shift_count_mode ();
1726 /* Specify unsigned here,
1727 since negative shift counts are meaningless. */
1728 op1x = convert_to_mode (op1_mode, op1, 1);
1731 if (GET_MODE (op0) != VOIDmode
1732 && GET_MODE (op0) != mode)
1733 op0 = convert_to_mode (mode, op0, unsignedp);
1735 /* Pass 1 for NO_QUEUE so we don't lose any increments
1736 if the libcall is cse'd or moved. */
1737 value = emit_library_call_value (libfunc,
1738 NULL_RTX, LCT_CONST, mode, 2,
1739 op0, mode, op1x, op1_mode);
1741 insns = get_insns ();
1742 end_sequence ();
1744 bool trapv = trapv_binoptab_p (binoptab);
1745 target = gen_reg_rtx (mode);
1746 emit_libcall_block_1 (insns, target, value,
1747 trapv ? NULL_RTX
1748 : gen_rtx_fmt_ee (optab_to_code (binoptab),
1749 mode, op0, op1), trapv);
1751 return target;
1754 delete_insns_since (last);
1756 /* It can't be done in this mode. Can we do it in a wider mode? */
1758 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1759 || methods == OPTAB_MUST_WIDEN))
1761 /* Caller says, don't even try. */
1762 delete_insns_since (entry_last);
1763 return 0;
1766 /* Compute the value of METHODS to pass to recursive calls.
1767 Don't allow widening to be tried recursively. */
1769 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1771 /* Look for a wider mode of the same class for which it appears we can do
1772 the operation. */
1774 if (CLASS_HAS_WIDER_MODES_P (mclass))
1776 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1777 wider_mode != VOIDmode;
1778 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1780 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
1781 != CODE_FOR_nothing
1782 || (methods == OPTAB_LIB
1783 && optab_libfunc (binoptab, wider_mode)))
1785 rtx xop0 = op0, xop1 = op1;
1786 int no_extend = 0;
1788 /* For certain integer operations, we need not actually extend
1789 the narrow operands, as long as we will truncate
1790 the results to the same narrowness. */
1792 if ((binoptab == ior_optab || binoptab == and_optab
1793 || binoptab == xor_optab
1794 || binoptab == add_optab || binoptab == sub_optab
1795 || binoptab == smul_optab || binoptab == ashl_optab)
1796 && mclass == MODE_INT)
1797 no_extend = 1;
1799 xop0 = widen_operand (xop0, wider_mode, mode,
1800 unsignedp, no_extend);
1802 /* The second operand of a shift must always be extended. */
1803 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1804 no_extend && binoptab != ashl_optab);
1806 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1807 unsignedp, methods);
1808 if (temp)
1810 if (mclass != MODE_INT
1811 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1813 if (target == 0)
1814 target = gen_reg_rtx (mode);
1815 convert_move (target, temp, 0);
1816 return target;
1818 else
1819 return gen_lowpart (mode, temp);
1821 else
1822 delete_insns_since (last);
1827 delete_insns_since (entry_last);
1828 return 0;
1831 /* Expand a binary operator which has both signed and unsigned forms.
1832 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1833 signed operations.
1835 If we widen unsigned operands, we may use a signed wider operation instead
1836 of an unsigned wider operation, since the result would be the same. */
1839 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
1840 rtx op0, rtx op1, rtx target, int unsignedp,
1841 enum optab_methods methods)
1843 rtx temp;
1844 optab direct_optab = unsignedp ? uoptab : soptab;
1845 bool save_enable;
1847 /* Do it without widening, if possible. */
1848 temp = expand_binop (mode, direct_optab, op0, op1, target,
1849 unsignedp, OPTAB_DIRECT);
1850 if (temp || methods == OPTAB_DIRECT)
1851 return temp;
1853 /* Try widening to a signed int. Disable any direct use of any
1854 signed insn in the current mode. */
1855 save_enable = swap_optab_enable (soptab, mode, false);
1857 temp = expand_binop (mode, soptab, op0, op1, target,
1858 unsignedp, OPTAB_WIDEN);
1860 /* For unsigned operands, try widening to an unsigned int. */
1861 if (!temp && unsignedp)
1862 temp = expand_binop (mode, uoptab, op0, op1, target,
1863 unsignedp, OPTAB_WIDEN);
1864 if (temp || methods == OPTAB_WIDEN)
1865 goto egress;
1867 /* Use the right width libcall if that exists. */
1868 temp = expand_binop (mode, direct_optab, op0, op1, target,
1869 unsignedp, OPTAB_LIB);
1870 if (temp || methods == OPTAB_LIB)
1871 goto egress;
1873 /* Must widen and use a libcall, use either signed or unsigned. */
1874 temp = expand_binop (mode, soptab, op0, op1, target,
1875 unsignedp, methods);
1876 if (!temp && unsignedp)
1877 temp = expand_binop (mode, uoptab, op0, op1, target,
1878 unsignedp, methods);
1880 egress:
1881 /* Undo the fiddling above. */
1882 if (save_enable)
1883 swap_optab_enable (soptab, mode, true);
1884 return temp;
1887 /* Generate code to perform an operation specified by UNOPPTAB
1888 on operand OP0, with two results to TARG0 and TARG1.
1889 We assume that the order of the operands for the instruction
1890 is TARG0, TARG1, OP0.
1892 Either TARG0 or TARG1 may be zero, but what that means is that
1893 the result is not actually wanted. We will generate it into
1894 a dummy pseudo-reg and discard it. They may not both be zero.
1896 Returns 1 if this operation can be performed; 0 if not. */
1899 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1900 int unsignedp)
1902 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1903 enum mode_class mclass;
1904 machine_mode wider_mode;
1905 rtx_insn *entry_last = get_last_insn ();
1906 rtx_insn *last;
1908 mclass = GET_MODE_CLASS (mode);
1910 if (!targ0)
1911 targ0 = gen_reg_rtx (mode);
1912 if (!targ1)
1913 targ1 = gen_reg_rtx (mode);
1915 /* Record where to go back to if we fail. */
1916 last = get_last_insn ();
1918 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
1920 struct expand_operand ops[3];
1921 enum insn_code icode = optab_handler (unoptab, mode);
1923 create_fixed_operand (&ops[0], targ0);
1924 create_fixed_operand (&ops[1], targ1);
1925 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
1926 if (maybe_expand_insn (icode, 3, ops))
1927 return 1;
1930 /* It can't be done in this mode. Can we do it in a wider mode? */
1932 if (CLASS_HAS_WIDER_MODES_P (mclass))
1934 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1935 wider_mode != VOIDmode;
1936 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1938 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
1940 rtx t0 = gen_reg_rtx (wider_mode);
1941 rtx t1 = gen_reg_rtx (wider_mode);
1942 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1944 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
1946 convert_move (targ0, t0, unsignedp);
1947 convert_move (targ1, t1, unsignedp);
1948 return 1;
1950 else
1951 delete_insns_since (last);
1956 delete_insns_since (entry_last);
1957 return 0;
1960 /* Generate code to perform an operation specified by BINOPTAB
1961 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1962 We assume that the order of the operands for the instruction
1963 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1964 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1966 Either TARG0 or TARG1 may be zero, but what that means is that
1967 the result is not actually wanted. We will generate it into
1968 a dummy pseudo-reg and discard it. They may not both be zero.
1970 Returns 1 if this operation can be performed; 0 if not. */
1973 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
1974 int unsignedp)
1976 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1977 enum mode_class mclass;
1978 machine_mode wider_mode;
1979 rtx_insn *entry_last = get_last_insn ();
1980 rtx_insn *last;
1982 mclass = GET_MODE_CLASS (mode);
1984 if (!targ0)
1985 targ0 = gen_reg_rtx (mode);
1986 if (!targ1)
1987 targ1 = gen_reg_rtx (mode);
1989 /* Record where to go back to if we fail. */
1990 last = get_last_insn ();
1992 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
1994 struct expand_operand ops[4];
1995 enum insn_code icode = optab_handler (binoptab, mode);
1996 machine_mode mode0 = insn_data[icode].operand[1].mode;
1997 machine_mode mode1 = insn_data[icode].operand[2].mode;
1998 rtx xop0 = op0, xop1 = op1;
2000 /* If we are optimizing, force expensive constants into a register. */
2001 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2002 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2004 create_fixed_operand (&ops[0], targ0);
2005 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2006 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2007 create_fixed_operand (&ops[3], targ1);
2008 if (maybe_expand_insn (icode, 4, ops))
2009 return 1;
2010 delete_insns_since (last);
2013 /* It can't be done in this mode. Can we do it in a wider mode? */
2015 if (CLASS_HAS_WIDER_MODES_P (mclass))
2017 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2018 wider_mode != VOIDmode;
2019 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2021 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2023 rtx t0 = gen_reg_rtx (wider_mode);
2024 rtx t1 = gen_reg_rtx (wider_mode);
2025 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2026 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2028 if (expand_twoval_binop (binoptab, cop0, cop1,
2029 t0, t1, unsignedp))
2031 convert_move (targ0, t0, unsignedp);
2032 convert_move (targ1, t1, unsignedp);
2033 return 1;
2035 else
2036 delete_insns_since (last);
2041 delete_insns_since (entry_last);
2042 return 0;
2045 /* Expand the two-valued library call indicated by BINOPTAB, but
2046 preserve only one of the values. If TARG0 is non-NULL, the first
2047 value is placed into TARG0; otherwise the second value is placed
2048 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2049 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2050 This routine assumes that the value returned by the library call is
2051 as if the return value was of an integral mode twice as wide as the
2052 mode of OP0. Returns 1 if the call was successful. */
2054 bool
2055 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2056 rtx targ0, rtx targ1, enum rtx_code code)
2058 machine_mode mode;
2059 machine_mode libval_mode;
2060 rtx libval;
2061 rtx_insn *insns;
2062 rtx libfunc;
2064 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2065 gcc_assert (!targ0 != !targ1);
2067 mode = GET_MODE (op0);
2068 libfunc = optab_libfunc (binoptab, mode);
2069 if (!libfunc)
2070 return false;
2072 /* The value returned by the library function will have twice as
2073 many bits as the nominal MODE. */
2074 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2075 MODE_INT);
2076 start_sequence ();
2077 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2078 libval_mode, 2,
2079 op0, mode,
2080 op1, mode);
2081 /* Get the part of VAL containing the value that we want. */
2082 libval = simplify_gen_subreg (mode, libval, libval_mode,
2083 targ0 ? 0 : GET_MODE_SIZE (mode));
2084 insns = get_insns ();
2085 end_sequence ();
2086 /* Move the into the desired location. */
2087 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2088 gen_rtx_fmt_ee (code, mode, op0, op1));
2090 return true;
2094 /* Wrapper around expand_unop which takes an rtx code to specify
2095 the operation to perform, not an optab pointer. All other
2096 arguments are the same. */
2098 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2099 rtx target, int unsignedp)
2101 optab unop = code_to_optab (code);
2102 gcc_assert (unop);
2104 return expand_unop (mode, unop, op0, target, unsignedp);
2107 /* Try calculating
2108 (clz:narrow x)
2110 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2112 A similar operation can be used for clrsb. UNOPTAB says which operation
2113 we are trying to expand. */
2114 static rtx
2115 widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab)
2117 enum mode_class mclass = GET_MODE_CLASS (mode);
2118 if (CLASS_HAS_WIDER_MODES_P (mclass))
2120 machine_mode wider_mode;
2121 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2122 wider_mode != VOIDmode;
2123 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2125 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2127 rtx xop0, temp;
2128 rtx_insn *last;
2130 last = get_last_insn ();
2132 if (target == 0)
2133 target = gen_reg_rtx (mode);
2134 xop0 = widen_operand (op0, wider_mode, mode,
2135 unoptab != clrsb_optab, false);
2136 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2137 unoptab != clrsb_optab);
2138 if (temp != 0)
2139 temp = expand_binop
2140 (wider_mode, sub_optab, temp,
2141 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2142 - GET_MODE_PRECISION (mode),
2143 wider_mode),
2144 target, true, OPTAB_DIRECT);
2145 if (temp == 0)
2146 delete_insns_since (last);
2148 return temp;
2152 return 0;
2155 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2156 quantities, choosing which based on whether the high word is nonzero. */
2157 static rtx
2158 expand_doubleword_clz (machine_mode mode, rtx op0, rtx target)
2160 rtx xop0 = force_reg (mode, op0);
2161 rtx subhi = gen_highpart (word_mode, xop0);
2162 rtx sublo = gen_lowpart (word_mode, xop0);
2163 rtx_code_label *hi0_label = gen_label_rtx ();
2164 rtx_code_label *after_label = gen_label_rtx ();
2165 rtx_insn *seq;
2166 rtx temp, result;
2168 /* If we were not given a target, use a word_mode register, not a
2169 'mode' register. The result will fit, and nobody is expecting
2170 anything bigger (the return type of __builtin_clz* is int). */
2171 if (!target)
2172 target = gen_reg_rtx (word_mode);
2174 /* In any case, write to a word_mode scratch in both branches of the
2175 conditional, so we can ensure there is a single move insn setting
2176 'target' to tag a REG_EQUAL note on. */
2177 result = gen_reg_rtx (word_mode);
2179 start_sequence ();
2181 /* If the high word is not equal to zero,
2182 then clz of the full value is clz of the high word. */
2183 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2184 word_mode, true, hi0_label);
2186 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2187 if (!temp)
2188 goto fail;
2190 if (temp != result)
2191 convert_move (result, temp, true);
2193 emit_jump_insn (targetm.gen_jump (after_label));
2194 emit_barrier ();
2196 /* Else clz of the full value is clz of the low word plus the number
2197 of bits in the high word. */
2198 emit_label (hi0_label);
2200 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2201 if (!temp)
2202 goto fail;
2203 temp = expand_binop (word_mode, add_optab, temp,
2204 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2205 result, true, OPTAB_DIRECT);
2206 if (!temp)
2207 goto fail;
2208 if (temp != result)
2209 convert_move (result, temp, true);
2211 emit_label (after_label);
2212 convert_move (target, result, true);
2214 seq = get_insns ();
2215 end_sequence ();
2217 add_equal_note (seq, target, CLZ, xop0, 0);
2218 emit_insn (seq);
2219 return target;
2221 fail:
2222 end_sequence ();
2223 return 0;
2226 /* Try calculating
2227 (bswap:narrow x)
2229 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2230 static rtx
2231 widen_bswap (machine_mode mode, rtx op0, rtx target)
2233 enum mode_class mclass = GET_MODE_CLASS (mode);
2234 machine_mode wider_mode;
2235 rtx x;
2236 rtx_insn *last;
2238 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2239 return NULL_RTX;
2241 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2242 wider_mode != VOIDmode;
2243 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2244 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2245 goto found;
2246 return NULL_RTX;
2248 found:
2249 last = get_last_insn ();
2251 x = widen_operand (op0, wider_mode, mode, true, true);
2252 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2254 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2255 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2256 if (x != 0)
2257 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2258 GET_MODE_BITSIZE (wider_mode)
2259 - GET_MODE_BITSIZE (mode),
2260 NULL_RTX, true);
2262 if (x != 0)
2264 if (target == 0)
2265 target = gen_reg_rtx (mode);
2266 emit_move_insn (target, gen_lowpart (mode, x));
2268 else
2269 delete_insns_since (last);
2271 return target;
2274 /* Try calculating bswap as two bswaps of two word-sized operands. */
2276 static rtx
2277 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2279 rtx t0, t1;
2281 t1 = expand_unop (word_mode, bswap_optab,
2282 operand_subword_force (op, 0, mode), NULL_RTX, true);
2283 t0 = expand_unop (word_mode, bswap_optab,
2284 operand_subword_force (op, 1, mode), NULL_RTX, true);
2286 if (target == 0 || !valid_multiword_target_p (target))
2287 target = gen_reg_rtx (mode);
2288 if (REG_P (target))
2289 emit_clobber (target);
2290 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2291 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2293 return target;
2296 /* Try calculating (parity x) as (and (popcount x) 1), where
2297 popcount can also be done in a wider mode. */
2298 static rtx
2299 expand_parity (machine_mode mode, rtx op0, rtx target)
2301 enum mode_class mclass = GET_MODE_CLASS (mode);
2302 if (CLASS_HAS_WIDER_MODES_P (mclass))
2304 machine_mode wider_mode;
2305 for (wider_mode = mode; wider_mode != VOIDmode;
2306 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2308 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2310 rtx xop0, temp;
2311 rtx_insn *last;
2313 last = get_last_insn ();
2315 if (target == 0)
2316 target = gen_reg_rtx (mode);
2317 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2318 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2319 true);
2320 if (temp != 0)
2321 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2322 target, true, OPTAB_DIRECT);
2323 if (temp == 0)
2324 delete_insns_since (last);
2326 return temp;
2330 return 0;
2333 /* Try calculating ctz(x) as K - clz(x & -x) ,
2334 where K is GET_MODE_PRECISION(mode) - 1.
2336 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2337 don't have to worry about what the hardware does in that case. (If
2338 the clz instruction produces the usual value at 0, which is K, the
2339 result of this code sequence will be -1; expand_ffs, below, relies
2340 on this. It might be nice to have it be K instead, for consistency
2341 with the (very few) processors that provide a ctz with a defined
2342 value, but that would take one more instruction, and it would be
2343 less convenient for expand_ffs anyway. */
2345 static rtx
2346 expand_ctz (machine_mode mode, rtx op0, rtx target)
2348 rtx_insn *seq;
2349 rtx temp;
2351 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2352 return 0;
2354 start_sequence ();
2356 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2357 if (temp)
2358 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2359 true, OPTAB_DIRECT);
2360 if (temp)
2361 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2362 if (temp)
2363 temp = expand_binop (mode, sub_optab,
2364 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2365 temp, target,
2366 true, OPTAB_DIRECT);
2367 if (temp == 0)
2369 end_sequence ();
2370 return 0;
2373 seq = get_insns ();
2374 end_sequence ();
2376 add_equal_note (seq, temp, CTZ, op0, 0);
2377 emit_insn (seq);
2378 return temp;
2382 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2383 else with the sequence used by expand_clz.
2385 The ffs builtin promises to return zero for a zero value and ctz/clz
2386 may have an undefined value in that case. If they do not give us a
2387 convenient value, we have to generate a test and branch. */
2388 static rtx
2389 expand_ffs (machine_mode mode, rtx op0, rtx target)
2391 HOST_WIDE_INT val = 0;
2392 bool defined_at_zero = false;
2393 rtx temp;
2394 rtx_insn *seq;
2396 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2398 start_sequence ();
2400 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2401 if (!temp)
2402 goto fail;
2404 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2406 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2408 start_sequence ();
2409 temp = expand_ctz (mode, op0, 0);
2410 if (!temp)
2411 goto fail;
2413 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2415 defined_at_zero = true;
2416 val = (GET_MODE_PRECISION (mode) - 1) - val;
2419 else
2420 return 0;
2422 if (defined_at_zero && val == -1)
2423 /* No correction needed at zero. */;
2424 else
2426 /* We don't try to do anything clever with the situation found
2427 on some processors (eg Alpha) where ctz(0:mode) ==
2428 bitsize(mode). If someone can think of a way to send N to -1
2429 and leave alone all values in the range 0..N-1 (where N is a
2430 power of two), cheaper than this test-and-branch, please add it.
2432 The test-and-branch is done after the operation itself, in case
2433 the operation sets condition codes that can be recycled for this.
2434 (This is true on i386, for instance.) */
2436 rtx_code_label *nonzero_label = gen_label_rtx ();
2437 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2438 mode, true, nonzero_label);
2440 convert_move (temp, GEN_INT (-1), false);
2441 emit_label (nonzero_label);
2444 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2445 to produce a value in the range 0..bitsize. */
2446 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2447 target, false, OPTAB_DIRECT);
2448 if (!temp)
2449 goto fail;
2451 seq = get_insns ();
2452 end_sequence ();
2454 add_equal_note (seq, temp, FFS, op0, 0);
2455 emit_insn (seq);
2456 return temp;
2458 fail:
2459 end_sequence ();
2460 return 0;
2463 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2464 conditions, VAL may already be a SUBREG against which we cannot generate
2465 a further SUBREG. In this case, we expect forcing the value into a
2466 register will work around the situation. */
2468 static rtx
2469 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2470 machine_mode imode)
2472 rtx ret;
2473 ret = lowpart_subreg (omode, val, imode);
2474 if (ret == NULL)
2476 val = force_reg (imode, val);
2477 ret = lowpart_subreg (omode, val, imode);
2478 gcc_assert (ret != NULL);
2480 return ret;
2483 /* Expand a floating point absolute value or negation operation via a
2484 logical operation on the sign bit. */
2486 static rtx
2487 expand_absneg_bit (enum rtx_code code, machine_mode mode,
2488 rtx op0, rtx target)
2490 const struct real_format *fmt;
2491 int bitpos, word, nwords, i;
2492 machine_mode imode;
2493 rtx temp;
2494 rtx_insn *insns;
2496 /* The format has to have a simple sign bit. */
2497 fmt = REAL_MODE_FORMAT (mode);
2498 if (fmt == NULL)
2499 return NULL_RTX;
2501 bitpos = fmt->signbit_rw;
2502 if (bitpos < 0)
2503 return NULL_RTX;
2505 /* Don't create negative zeros if the format doesn't support them. */
2506 if (code == NEG && !fmt->has_signed_zero)
2507 return NULL_RTX;
2509 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2511 imode = int_mode_for_mode (mode);
2512 if (imode == BLKmode)
2513 return NULL_RTX;
2514 word = 0;
2515 nwords = 1;
2517 else
2519 imode = word_mode;
2521 if (FLOAT_WORDS_BIG_ENDIAN)
2522 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2523 else
2524 word = bitpos / BITS_PER_WORD;
2525 bitpos = bitpos % BITS_PER_WORD;
2526 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2529 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2530 if (code == ABS)
2531 mask = ~mask;
2533 if (target == 0
2534 || target == op0
2535 || (nwords > 1 && !valid_multiword_target_p (target)))
2536 target = gen_reg_rtx (mode);
2538 if (nwords > 1)
2540 start_sequence ();
2542 for (i = 0; i < nwords; ++i)
2544 rtx targ_piece = operand_subword (target, i, 1, mode);
2545 rtx op0_piece = operand_subword_force (op0, i, mode);
2547 if (i == word)
2549 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2550 op0_piece,
2551 immed_wide_int_const (mask, imode),
2552 targ_piece, 1, OPTAB_LIB_WIDEN);
2553 if (temp != targ_piece)
2554 emit_move_insn (targ_piece, temp);
2556 else
2557 emit_move_insn (targ_piece, op0_piece);
2560 insns = get_insns ();
2561 end_sequence ();
2563 emit_insn (insns);
2565 else
2567 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2568 gen_lowpart (imode, op0),
2569 immed_wide_int_const (mask, imode),
2570 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2571 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2573 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2574 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2575 target);
2578 return target;
2581 /* As expand_unop, but will fail rather than attempt the operation in a
2582 different mode or with a libcall. */
2583 static rtx
2584 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2585 int unsignedp)
2587 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2589 struct expand_operand ops[2];
2590 enum insn_code icode = optab_handler (unoptab, mode);
2591 rtx_insn *last = get_last_insn ();
2592 rtx_insn *pat;
2594 create_output_operand (&ops[0], target, mode);
2595 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2596 pat = maybe_gen_insn (icode, 2, ops);
2597 if (pat)
2599 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2600 && ! add_equal_note (pat, ops[0].value,
2601 optab_to_code (unoptab),
2602 ops[1].value, NULL_RTX))
2604 delete_insns_since (last);
2605 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2608 emit_insn (pat);
2610 return ops[0].value;
2613 return 0;
2616 /* Generate code to perform an operation specified by UNOPTAB
2617 on operand OP0, with result having machine-mode MODE.
2619 UNSIGNEDP is for the case where we have to widen the operands
2620 to perform the operation. It says to use zero-extension.
2622 If TARGET is nonzero, the value
2623 is generated there, if it is convenient to do so.
2624 In all cases an rtx is returned for the locus of the value;
2625 this may or may not be TARGET. */
2628 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2629 int unsignedp)
2631 enum mode_class mclass = GET_MODE_CLASS (mode);
2632 machine_mode wider_mode;
2633 rtx temp;
2634 rtx libfunc;
2636 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2637 if (temp)
2638 return temp;
2640 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2642 /* Widening (or narrowing) clz needs special treatment. */
2643 if (unoptab == clz_optab)
2645 temp = widen_leading (mode, op0, target, unoptab);
2646 if (temp)
2647 return temp;
2649 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2650 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2652 temp = expand_doubleword_clz (mode, op0, target);
2653 if (temp)
2654 return temp;
2657 goto try_libcall;
2660 if (unoptab == clrsb_optab)
2662 temp = widen_leading (mode, op0, target, unoptab);
2663 if (temp)
2664 return temp;
2665 goto try_libcall;
2668 /* Widening (or narrowing) bswap needs special treatment. */
2669 if (unoptab == bswap_optab)
2671 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2672 or ROTATERT. First try these directly; if this fails, then try the
2673 obvious pair of shifts with allowed widening, as this will probably
2674 be always more efficient than the other fallback methods. */
2675 if (mode == HImode)
2677 rtx_insn *last;
2678 rtx temp1, temp2;
2680 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2682 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
2683 unsignedp, OPTAB_DIRECT);
2684 if (temp)
2685 return temp;
2688 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2690 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
2691 unsignedp, OPTAB_DIRECT);
2692 if (temp)
2693 return temp;
2696 last = get_last_insn ();
2698 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
2699 unsignedp, OPTAB_WIDEN);
2700 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
2701 unsignedp, OPTAB_WIDEN);
2702 if (temp1 && temp2)
2704 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2705 unsignedp, OPTAB_WIDEN);
2706 if (temp)
2707 return temp;
2710 delete_insns_since (last);
2713 temp = widen_bswap (mode, op0, target);
2714 if (temp)
2715 return temp;
2717 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2718 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2720 temp = expand_doubleword_bswap (mode, op0, target);
2721 if (temp)
2722 return temp;
2725 goto try_libcall;
2728 if (CLASS_HAS_WIDER_MODES_P (mclass))
2729 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2730 wider_mode != VOIDmode;
2731 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2733 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2735 rtx xop0 = op0;
2736 rtx_insn *last = get_last_insn ();
2738 /* For certain operations, we need not actually extend
2739 the narrow operand, as long as we will truncate the
2740 results to the same narrowness. */
2742 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2743 (unoptab == neg_optab
2744 || unoptab == one_cmpl_optab)
2745 && mclass == MODE_INT);
2747 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2748 unsignedp);
2750 if (temp)
2752 if (mclass != MODE_INT
2753 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2755 if (target == 0)
2756 target = gen_reg_rtx (mode);
2757 convert_move (target, temp, 0);
2758 return target;
2760 else
2761 return gen_lowpart (mode, temp);
2763 else
2764 delete_insns_since (last);
2768 /* These can be done a word at a time. */
2769 if (unoptab == one_cmpl_optab
2770 && mclass == MODE_INT
2771 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2772 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2774 int i;
2775 rtx_insn *insns;
2777 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2778 target = gen_reg_rtx (mode);
2780 start_sequence ();
2782 /* Do the actual arithmetic. */
2783 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2785 rtx target_piece = operand_subword (target, i, 1, mode);
2786 rtx x = expand_unop (word_mode, unoptab,
2787 operand_subword_force (op0, i, mode),
2788 target_piece, unsignedp);
2790 if (target_piece != x)
2791 emit_move_insn (target_piece, x);
2794 insns = get_insns ();
2795 end_sequence ();
2797 emit_insn (insns);
2798 return target;
2801 if (optab_to_code (unoptab) == NEG)
2803 /* Try negating floating point values by flipping the sign bit. */
2804 if (SCALAR_FLOAT_MODE_P (mode))
2806 temp = expand_absneg_bit (NEG, mode, op0, target);
2807 if (temp)
2808 return temp;
2811 /* If there is no negation pattern, and we have no negative zero,
2812 try subtracting from zero. */
2813 if (!HONOR_SIGNED_ZEROS (mode))
2815 temp = expand_binop (mode, (unoptab == negv_optab
2816 ? subv_optab : sub_optab),
2817 CONST0_RTX (mode), op0, target,
2818 unsignedp, OPTAB_DIRECT);
2819 if (temp)
2820 return temp;
2824 /* Try calculating parity (x) as popcount (x) % 2. */
2825 if (unoptab == parity_optab)
2827 temp = expand_parity (mode, op0, target);
2828 if (temp)
2829 return temp;
2832 /* Try implementing ffs (x) in terms of clz (x). */
2833 if (unoptab == ffs_optab)
2835 temp = expand_ffs (mode, op0, target);
2836 if (temp)
2837 return temp;
2840 /* Try implementing ctz (x) in terms of clz (x). */
2841 if (unoptab == ctz_optab)
2843 temp = expand_ctz (mode, op0, target);
2844 if (temp)
2845 return temp;
2848 try_libcall:
2849 /* Now try a library call in this mode. */
2850 libfunc = optab_libfunc (unoptab, mode);
2851 if (libfunc)
2853 rtx_insn *insns;
2854 rtx value;
2855 rtx eq_value;
2856 machine_mode outmode = mode;
2858 /* All of these functions return small values. Thus we choose to
2859 have them return something that isn't a double-word. */
2860 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2861 || unoptab == clrsb_optab || unoptab == popcount_optab
2862 || unoptab == parity_optab)
2863 outmode
2864 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
2865 optab_libfunc (unoptab, mode)));
2867 start_sequence ();
2869 /* Pass 1 for NO_QUEUE so we don't lose any increments
2870 if the libcall is cse'd or moved. */
2871 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
2872 1, op0, mode);
2873 insns = get_insns ();
2874 end_sequence ();
2876 target = gen_reg_rtx (outmode);
2877 bool trapv = trapv_unoptab_p (unoptab);
2878 if (trapv)
2879 eq_value = NULL_RTX;
2880 else
2882 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
2883 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
2884 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
2885 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
2886 eq_value = simplify_gen_unary (ZERO_EXTEND,
2887 outmode, eq_value, mode);
2889 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
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 if (equiv)
3577 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3579 if (final_dest != target)
3580 emit_move_insn (final_dest, target);
3583 void
3584 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3586 emit_libcall_block_1 (safe_as_a <rtx_insn *> (insns),
3587 target, result, equiv, false);
3590 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3591 PURPOSE describes how this comparison will be used. CODE is the rtx
3592 comparison code we will be using.
3594 ??? Actually, CODE is slightly weaker than that. A target is still
3595 required to implement all of the normal bcc operations, but not
3596 required to implement all (or any) of the unordered bcc operations. */
3599 can_compare_p (enum rtx_code code, machine_mode mode,
3600 enum can_compare_purpose purpose)
3602 rtx test;
3603 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3606 enum insn_code icode;
3608 if (purpose == ccp_jump
3609 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3610 && insn_operand_matches (icode, 0, test))
3611 return 1;
3612 if (purpose == ccp_store_flag
3613 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3614 && insn_operand_matches (icode, 1, test))
3615 return 1;
3616 if (purpose == ccp_cmov
3617 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3618 return 1;
3620 mode = GET_MODE_WIDER_MODE (mode);
3621 PUT_MODE (test, mode);
3623 while (mode != VOIDmode);
3625 return 0;
3628 /* This function is called when we are going to emit a compare instruction that
3629 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3631 *PMODE is the mode of the inputs (in case they are const_int).
3632 *PUNSIGNEDP nonzero says that the operands are unsigned;
3633 this matters if they need to be widened (as given by METHODS).
3635 If they have mode BLKmode, then SIZE specifies the size of both operands.
3637 This function performs all the setup necessary so that the caller only has
3638 to emit a single comparison insn. This setup can involve doing a BLKmode
3639 comparison or emitting a library call to perform the comparison if no insn
3640 is available to handle it.
3641 The values which are passed in through pointers can be modified; the caller
3642 should perform the comparison on the modified values. Constant
3643 comparisons must have already been folded. */
3645 static void
3646 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3647 int unsignedp, enum optab_methods methods,
3648 rtx *ptest, machine_mode *pmode)
3650 machine_mode mode = *pmode;
3651 rtx libfunc, test;
3652 machine_mode cmp_mode;
3653 enum mode_class mclass;
3655 /* The other methods are not needed. */
3656 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3657 || methods == OPTAB_LIB_WIDEN);
3659 /* If we are optimizing, force expensive constants into a register. */
3660 if (CONSTANT_P (x) && optimize
3661 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
3662 > COSTS_N_INSNS (1)))
3663 x = force_reg (mode, x);
3665 if (CONSTANT_P (y) && optimize
3666 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
3667 > COSTS_N_INSNS (1)))
3668 y = force_reg (mode, y);
3670 #if HAVE_cc0
3671 /* Make sure if we have a canonical comparison. The RTL
3672 documentation states that canonical comparisons are required only
3673 for targets which have cc0. */
3674 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3675 #endif
3677 /* Don't let both operands fail to indicate the mode. */
3678 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3679 x = force_reg (mode, x);
3680 if (mode == VOIDmode)
3681 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3683 /* Handle all BLKmode compares. */
3685 if (mode == BLKmode)
3687 machine_mode result_mode;
3688 enum insn_code cmp_code;
3689 tree length_type;
3690 rtx libfunc;
3691 rtx result;
3692 rtx opalign
3693 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3695 gcc_assert (size);
3697 /* Try to use a memory block compare insn - either cmpstr
3698 or cmpmem will do. */
3699 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3700 cmp_mode != VOIDmode;
3701 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3703 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3704 if (cmp_code == CODE_FOR_nothing)
3705 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3706 if (cmp_code == CODE_FOR_nothing)
3707 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3708 if (cmp_code == CODE_FOR_nothing)
3709 continue;
3711 /* Must make sure the size fits the insn's mode. */
3712 if ((CONST_INT_P (size)
3713 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3714 || (GET_MODE_BITSIZE (GET_MODE (size))
3715 > GET_MODE_BITSIZE (cmp_mode)))
3716 continue;
3718 result_mode = insn_data[cmp_code].operand[0].mode;
3719 result = gen_reg_rtx (result_mode);
3720 size = convert_to_mode (cmp_mode, size, 1);
3721 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3723 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3724 *pmode = result_mode;
3725 return;
3728 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3729 goto fail;
3731 /* Otherwise call a library function, memcmp. */
3732 libfunc = memcmp_libfunc;
3733 length_type = sizetype;
3734 result_mode = TYPE_MODE (integer_type_node);
3735 cmp_mode = TYPE_MODE (length_type);
3736 size = convert_to_mode (TYPE_MODE (length_type), size,
3737 TYPE_UNSIGNED (length_type));
3739 result = emit_library_call_value (libfunc, 0, LCT_PURE,
3740 result_mode, 3,
3741 XEXP (x, 0), Pmode,
3742 XEXP (y, 0), Pmode,
3743 size, cmp_mode);
3744 x = result;
3745 y = const0_rtx;
3746 mode = result_mode;
3747 methods = OPTAB_LIB_WIDEN;
3748 unsignedp = false;
3751 /* Don't allow operands to the compare to trap, as that can put the
3752 compare and branch in different basic blocks. */
3753 if (cfun->can_throw_non_call_exceptions)
3755 if (may_trap_p (x))
3756 x = force_reg (mode, x);
3757 if (may_trap_p (y))
3758 y = force_reg (mode, y);
3761 if (GET_MODE_CLASS (mode) == MODE_CC)
3763 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
3764 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3765 gcc_assert (icode != CODE_FOR_nothing
3766 && insn_operand_matches (icode, 0, test));
3767 *ptest = test;
3768 return;
3771 mclass = GET_MODE_CLASS (mode);
3772 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3773 cmp_mode = mode;
3776 enum insn_code icode;
3777 icode = optab_handler (cbranch_optab, cmp_mode);
3778 if (icode != CODE_FOR_nothing
3779 && insn_operand_matches (icode, 0, test))
3781 rtx_insn *last = get_last_insn ();
3782 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3783 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3784 if (op0 && op1
3785 && insn_operand_matches (icode, 1, op0)
3786 && insn_operand_matches (icode, 2, op1))
3788 XEXP (test, 0) = op0;
3789 XEXP (test, 1) = op1;
3790 *ptest = test;
3791 *pmode = cmp_mode;
3792 return;
3794 delete_insns_since (last);
3797 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3798 break;
3799 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
3801 while (cmp_mode != VOIDmode);
3803 if (methods != OPTAB_LIB_WIDEN)
3804 goto fail;
3806 if (!SCALAR_FLOAT_MODE_P (mode))
3808 rtx result;
3809 machine_mode ret_mode;
3811 /* Handle a libcall just for the mode we are using. */
3812 libfunc = optab_libfunc (cmp_optab, mode);
3813 gcc_assert (libfunc);
3815 /* If we want unsigned, and this mode has a distinct unsigned
3816 comparison routine, use that. */
3817 if (unsignedp)
3819 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
3820 if (ulibfunc)
3821 libfunc = ulibfunc;
3824 ret_mode = targetm.libgcc_cmp_return_mode ();
3825 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3826 ret_mode, 2, x, mode, y, mode);
3828 /* There are two kinds of comparison routines. Biased routines
3829 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3830 of gcc expect that the comparison operation is equivalent
3831 to the modified comparison. For signed comparisons compare the
3832 result against 1 in the biased case, and zero in the unbiased
3833 case. For unsigned comparisons always compare against 1 after
3834 biasing the unbiased result by adding 1. This gives us a way to
3835 represent LTU.
3836 The comparisons in the fixed-point helper library are always
3837 biased. */
3838 x = result;
3839 y = const1_rtx;
3841 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
3843 if (unsignedp)
3844 x = plus_constant (ret_mode, result, 1);
3845 else
3846 y = const0_rtx;
3849 *pmode = ret_mode;
3850 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
3851 ptest, pmode);
3853 else
3854 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
3856 return;
3858 fail:
3859 *ptest = NULL_RTX;
3862 /* Before emitting an insn with code ICODE, make sure that X, which is going
3863 to be used for operand OPNUM of the insn, is converted from mode MODE to
3864 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3865 that it is accepted by the operand predicate. Return the new value. */
3868 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
3869 machine_mode wider_mode, int unsignedp)
3871 if (mode != wider_mode)
3872 x = convert_modes (wider_mode, mode, x, unsignedp);
3874 if (!insn_operand_matches (icode, opnum, x))
3876 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
3877 if (reload_completed)
3878 return NULL_RTX;
3879 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
3880 return NULL_RTX;
3881 x = copy_to_mode_reg (op_mode, x);
3884 return x;
3887 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3888 we can do the branch. */
3890 static void
3891 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, int prob)
3893 machine_mode optab_mode;
3894 enum mode_class mclass;
3895 enum insn_code icode;
3896 rtx_insn *insn;
3898 mclass = GET_MODE_CLASS (mode);
3899 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
3900 icode = optab_handler (cbranch_optab, optab_mode);
3902 gcc_assert (icode != CODE_FOR_nothing);
3903 gcc_assert (insn_operand_matches (icode, 0, test));
3904 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
3905 XEXP (test, 1), label));
3906 if (prob != -1
3907 && profile_status_for_fn (cfun) != PROFILE_ABSENT
3908 && insn
3909 && JUMP_P (insn)
3910 && any_condjump_p (insn)
3911 && !find_reg_note (insn, REG_BR_PROB, 0))
3912 add_int_reg_note (insn, REG_BR_PROB, prob);
3915 /* Generate code to compare X with Y so that the condition codes are
3916 set and to jump to LABEL if the condition is true. If X is a
3917 constant and Y is not a constant, then the comparison is swapped to
3918 ensure that the comparison RTL has the canonical form.
3920 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3921 need to be widened. UNSIGNEDP is also used to select the proper
3922 branch condition code.
3924 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3926 MODE is the mode of the inputs (in case they are const_int).
3928 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
3929 It will be potentially converted into an unsigned variant based on
3930 UNSIGNEDP to select a proper jump instruction.
3932 PROB is the probability of jumping to LABEL. */
3934 void
3935 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3936 machine_mode mode, int unsignedp, rtx label,
3937 int prob)
3939 rtx op0 = x, op1 = y;
3940 rtx test;
3942 /* Swap operands and condition to ensure canonical RTL. */
3943 if (swap_commutative_operands_p (x, y)
3944 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
3946 op0 = y, op1 = x;
3947 comparison = swap_condition (comparison);
3950 /* If OP0 is still a constant, then both X and Y must be constants
3951 or the opposite comparison is not supported. Force X into a register
3952 to create canonical RTL. */
3953 if (CONSTANT_P (op0))
3954 op0 = force_reg (mode, op0);
3956 if (unsignedp)
3957 comparison = unsigned_condition (comparison);
3959 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
3960 &test, &mode);
3961 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
3965 /* Emit a library call comparison between floating point X and Y.
3966 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3968 static void
3969 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
3970 rtx *ptest, machine_mode *pmode)
3972 enum rtx_code swapped = swap_condition (comparison);
3973 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3974 machine_mode orig_mode = GET_MODE (x);
3975 machine_mode mode, cmp_mode;
3976 rtx true_rtx, false_rtx;
3977 rtx value, target, equiv;
3978 rtx_insn *insns;
3979 rtx libfunc = 0;
3980 bool reversed_p = false;
3981 cmp_mode = targetm.libgcc_cmp_return_mode ();
3983 for (mode = orig_mode;
3984 mode != VOIDmode;
3985 mode = GET_MODE_WIDER_MODE (mode))
3987 if (code_to_optab (comparison)
3988 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
3989 break;
3991 if (code_to_optab (swapped)
3992 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
3994 std::swap (x, y);
3995 comparison = swapped;
3996 break;
3999 if (code_to_optab (reversed)
4000 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4002 comparison = reversed;
4003 reversed_p = true;
4004 break;
4008 gcc_assert (mode != VOIDmode);
4010 if (mode != orig_mode)
4012 x = convert_to_mode (mode, x, 0);
4013 y = convert_to_mode (mode, y, 0);
4016 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4017 the RTL. The allows the RTL optimizers to delete the libcall if the
4018 condition can be determined at compile-time. */
4019 if (comparison == UNORDERED
4020 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4022 true_rtx = const_true_rtx;
4023 false_rtx = const0_rtx;
4025 else
4027 switch (comparison)
4029 case EQ:
4030 true_rtx = const0_rtx;
4031 false_rtx = const_true_rtx;
4032 break;
4034 case NE:
4035 true_rtx = const_true_rtx;
4036 false_rtx = const0_rtx;
4037 break;
4039 case GT:
4040 true_rtx = const1_rtx;
4041 false_rtx = const0_rtx;
4042 break;
4044 case GE:
4045 true_rtx = const0_rtx;
4046 false_rtx = constm1_rtx;
4047 break;
4049 case LT:
4050 true_rtx = constm1_rtx;
4051 false_rtx = const0_rtx;
4052 break;
4054 case LE:
4055 true_rtx = const0_rtx;
4056 false_rtx = const1_rtx;
4057 break;
4059 default:
4060 gcc_unreachable ();
4064 if (comparison == UNORDERED)
4066 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4067 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4068 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4069 temp, const_true_rtx, equiv);
4071 else
4073 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4074 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4075 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4076 equiv, true_rtx, false_rtx);
4079 start_sequence ();
4080 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4081 cmp_mode, 2, x, mode, y, mode);
4082 insns = get_insns ();
4083 end_sequence ();
4085 target = gen_reg_rtx (cmp_mode);
4086 emit_libcall_block (insns, target, value, equiv);
4088 if (comparison == UNORDERED
4089 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4090 || reversed_p)
4091 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4092 else
4093 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4095 *pmode = cmp_mode;
4098 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4100 void
4101 emit_indirect_jump (rtx loc)
4103 if (!targetm.have_indirect_jump ())
4104 sorry ("indirect jumps are not available on this target");
4105 else
4107 struct expand_operand ops[1];
4108 create_address_operand (&ops[0], loc);
4109 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4110 emit_barrier ();
4115 /* Emit a conditional move instruction if the machine supports one for that
4116 condition and machine mode.
4118 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4119 the mode to use should they be constants. If it is VOIDmode, they cannot
4120 both be constants.
4122 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4123 should be stored there. MODE is the mode to use should they be constants.
4124 If it is VOIDmode, they cannot both be constants.
4126 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4127 is not supported. */
4130 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4131 machine_mode cmode, rtx op2, rtx op3,
4132 machine_mode mode, int unsignedp)
4134 rtx comparison;
4135 rtx_insn *last;
4136 enum insn_code icode;
4137 enum rtx_code reversed;
4139 /* If one operand is constant, make it the second one. Only do this
4140 if the other operand is not constant as well. */
4142 if (swap_commutative_operands_p (op0, op1))
4144 std::swap (op0, op1);
4145 code = swap_condition (code);
4148 /* get_condition will prefer to generate LT and GT even if the old
4149 comparison was against zero, so undo that canonicalization here since
4150 comparisons against zero are cheaper. */
4151 if (code == LT && op1 == const1_rtx)
4152 code = LE, op1 = const0_rtx;
4153 else if (code == GT && op1 == constm1_rtx)
4154 code = GE, op1 = const0_rtx;
4156 if (cmode == VOIDmode)
4157 cmode = GET_MODE (op0);
4159 if (swap_commutative_operands_p (op2, op3)
4160 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4161 != UNKNOWN))
4163 std::swap (op2, op3);
4164 code = reversed;
4167 if (mode == VOIDmode)
4168 mode = GET_MODE (op2);
4170 icode = direct_optab_handler (movcc_optab, mode);
4172 if (icode == CODE_FOR_nothing)
4173 return 0;
4175 if (!target)
4176 target = gen_reg_rtx (mode);
4178 code = unsignedp ? unsigned_condition (code) : code;
4179 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4181 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4182 return NULL and let the caller figure out how best to deal with this
4183 situation. */
4184 if (!COMPARISON_P (comparison))
4185 return NULL_RTX;
4187 saved_pending_stack_adjust save;
4188 save_pending_stack_adjust (&save);
4189 last = get_last_insn ();
4190 do_pending_stack_adjust ();
4191 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4192 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4193 &comparison, &cmode);
4194 if (comparison)
4196 struct expand_operand ops[4];
4198 create_output_operand (&ops[0], target, mode);
4199 create_fixed_operand (&ops[1], comparison);
4200 create_input_operand (&ops[2], op2, mode);
4201 create_input_operand (&ops[3], op3, mode);
4202 if (maybe_expand_insn (icode, 4, ops))
4204 if (ops[0].value != target)
4205 convert_move (target, ops[0].value, false);
4206 return target;
4209 delete_insns_since (last);
4210 restore_pending_stack_adjust (&save);
4211 return NULL_RTX;
4215 /* Emit a conditional negate or bitwise complement using the
4216 negcc or notcc optabs if available. Return NULL_RTX if such operations
4217 are not available. Otherwise return the RTX holding the result.
4218 TARGET is the desired destination of the result. COMP is the comparison
4219 on which to negate. If COND is true move into TARGET the negation
4220 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4221 CODE is either NEG or NOT. MODE is the machine mode in which the
4222 operation is performed. */
4225 emit_conditional_neg_or_complement (rtx target, rtx_code code,
4226 machine_mode mode, rtx cond, rtx op1,
4227 rtx op2)
4229 optab op = unknown_optab;
4230 if (code == NEG)
4231 op = negcc_optab;
4232 else if (code == NOT)
4233 op = notcc_optab;
4234 else
4235 gcc_unreachable ();
4237 insn_code icode = direct_optab_handler (op, mode);
4239 if (icode == CODE_FOR_nothing)
4240 return NULL_RTX;
4242 if (!target)
4243 target = gen_reg_rtx (mode);
4245 rtx_insn *last = get_last_insn ();
4246 struct expand_operand ops[4];
4248 create_output_operand (&ops[0], target, mode);
4249 create_fixed_operand (&ops[1], cond);
4250 create_input_operand (&ops[2], op1, mode);
4251 create_input_operand (&ops[3], op2, mode);
4253 if (maybe_expand_insn (icode, 4, ops))
4255 if (ops[0].value != target)
4256 convert_move (target, ops[0].value, false);
4258 return target;
4260 delete_insns_since (last);
4261 return NULL_RTX;
4264 /* Emit a conditional addition instruction if the machine supports one for that
4265 condition and machine mode.
4267 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4268 the mode to use should they be constants. If it is VOIDmode, they cannot
4269 both be constants.
4271 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4272 should be stored there. MODE is the mode to use should they be constants.
4273 If it is VOIDmode, they cannot both be constants.
4275 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4276 is not supported. */
4279 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4280 machine_mode cmode, rtx op2, rtx op3,
4281 machine_mode mode, int unsignedp)
4283 rtx comparison;
4284 rtx_insn *last;
4285 enum insn_code icode;
4287 /* If one operand is constant, make it the second one. Only do this
4288 if the other operand is not constant as well. */
4290 if (swap_commutative_operands_p (op0, op1))
4292 std::swap (op0, op1);
4293 code = swap_condition (code);
4296 /* get_condition will prefer to generate LT and GT even if the old
4297 comparison was against zero, so undo that canonicalization here since
4298 comparisons against zero are cheaper. */
4299 if (code == LT && op1 == const1_rtx)
4300 code = LE, op1 = const0_rtx;
4301 else if (code == GT && op1 == constm1_rtx)
4302 code = GE, op1 = const0_rtx;
4304 if (cmode == VOIDmode)
4305 cmode = GET_MODE (op0);
4307 if (mode == VOIDmode)
4308 mode = GET_MODE (op2);
4310 icode = optab_handler (addcc_optab, mode);
4312 if (icode == CODE_FOR_nothing)
4313 return 0;
4315 if (!target)
4316 target = gen_reg_rtx (mode);
4318 code = unsignedp ? unsigned_condition (code) : code;
4319 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4321 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4322 return NULL and let the caller figure out how best to deal with this
4323 situation. */
4324 if (!COMPARISON_P (comparison))
4325 return NULL_RTX;
4327 do_pending_stack_adjust ();
4328 last = get_last_insn ();
4329 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4330 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4331 &comparison, &cmode);
4332 if (comparison)
4334 struct expand_operand ops[4];
4336 create_output_operand (&ops[0], target, mode);
4337 create_fixed_operand (&ops[1], comparison);
4338 create_input_operand (&ops[2], op2, mode);
4339 create_input_operand (&ops[3], op3, mode);
4340 if (maybe_expand_insn (icode, 4, ops))
4342 if (ops[0].value != target)
4343 convert_move (target, ops[0].value, false);
4344 return target;
4347 delete_insns_since (last);
4348 return NULL_RTX;
4351 /* These functions attempt to generate an insn body, rather than
4352 emitting the insn, but if the gen function already emits them, we
4353 make no attempt to turn them back into naked patterns. */
4355 /* Generate and return an insn body to add Y to X. */
4357 rtx_insn *
4358 gen_add2_insn (rtx x, rtx y)
4360 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4362 gcc_assert (insn_operand_matches (icode, 0, x));
4363 gcc_assert (insn_operand_matches (icode, 1, x));
4364 gcc_assert (insn_operand_matches (icode, 2, y));
4366 return GEN_FCN (icode) (x, x, y);
4369 /* Generate and return an insn body to add r1 and c,
4370 storing the result in r0. */
4372 rtx_insn *
4373 gen_add3_insn (rtx r0, rtx r1, rtx c)
4375 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4377 if (icode == CODE_FOR_nothing
4378 || !insn_operand_matches (icode, 0, r0)
4379 || !insn_operand_matches (icode, 1, r1)
4380 || !insn_operand_matches (icode, 2, c))
4381 return NULL;
4383 return GEN_FCN (icode) (r0, r1, c);
4387 have_add2_insn (rtx x, rtx y)
4389 enum insn_code icode;
4391 gcc_assert (GET_MODE (x) != VOIDmode);
4393 icode = optab_handler (add_optab, GET_MODE (x));
4395 if (icode == CODE_FOR_nothing)
4396 return 0;
4398 if (!insn_operand_matches (icode, 0, x)
4399 || !insn_operand_matches (icode, 1, x)
4400 || !insn_operand_matches (icode, 2, y))
4401 return 0;
4403 return 1;
4406 /* Generate and return an insn body to add Y to X. */
4408 rtx_insn *
4409 gen_addptr3_insn (rtx x, rtx y, rtx z)
4411 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4413 gcc_assert (insn_operand_matches (icode, 0, x));
4414 gcc_assert (insn_operand_matches (icode, 1, y));
4415 gcc_assert (insn_operand_matches (icode, 2, z));
4417 return GEN_FCN (icode) (x, y, z);
4420 /* Return true if the target implements an addptr pattern and X, Y,
4421 and Z are valid for the pattern predicates. */
4424 have_addptr3_insn (rtx x, rtx y, rtx z)
4426 enum insn_code icode;
4428 gcc_assert (GET_MODE (x) != VOIDmode);
4430 icode = optab_handler (addptr3_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, y)
4437 || !insn_operand_matches (icode, 2, z))
4438 return 0;
4440 return 1;
4443 /* Generate and return an insn body to subtract Y from X. */
4445 rtx_insn *
4446 gen_sub2_insn (rtx x, rtx y)
4448 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4450 gcc_assert (insn_operand_matches (icode, 0, x));
4451 gcc_assert (insn_operand_matches (icode, 1, x));
4452 gcc_assert (insn_operand_matches (icode, 2, y));
4454 return GEN_FCN (icode) (x, x, y);
4457 /* Generate and return an insn body to subtract r1 and c,
4458 storing the result in r0. */
4460 rtx_insn *
4461 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4463 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4465 if (icode == CODE_FOR_nothing
4466 || !insn_operand_matches (icode, 0, r0)
4467 || !insn_operand_matches (icode, 1, r1)
4468 || !insn_operand_matches (icode, 2, c))
4469 return NULL;
4471 return GEN_FCN (icode) (r0, r1, c);
4475 have_sub2_insn (rtx x, rtx y)
4477 enum insn_code icode;
4479 gcc_assert (GET_MODE (x) != VOIDmode);
4481 icode = optab_handler (sub_optab, GET_MODE (x));
4483 if (icode == CODE_FOR_nothing)
4484 return 0;
4486 if (!insn_operand_matches (icode, 0, x)
4487 || !insn_operand_matches (icode, 1, x)
4488 || !insn_operand_matches (icode, 2, y))
4489 return 0;
4491 return 1;
4494 /* Generate the body of an insn to extend Y (with mode MFROM)
4495 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4497 rtx_insn *
4498 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4499 machine_mode mfrom, int unsignedp)
4501 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4502 return GEN_FCN (icode) (x, y);
4505 /* Generate code to convert FROM to floating point
4506 and store in TO. FROM must be fixed point and not VOIDmode.
4507 UNSIGNEDP nonzero means regard FROM as unsigned.
4508 Normally this is done by correcting the final value
4509 if it is negative. */
4511 void
4512 expand_float (rtx to, rtx from, int unsignedp)
4514 enum insn_code icode;
4515 rtx target = to;
4516 machine_mode fmode, imode;
4517 bool can_do_signed = false;
4519 /* Crash now, because we won't be able to decide which mode to use. */
4520 gcc_assert (GET_MODE (from) != VOIDmode);
4522 /* Look for an insn to do the conversion. Do it in the specified
4523 modes if possible; otherwise convert either input, output or both to
4524 wider mode. If the integer mode is wider than the mode of FROM,
4525 we can do the conversion signed even if the input is unsigned. */
4527 for (fmode = GET_MODE (to); fmode != VOIDmode;
4528 fmode = GET_MODE_WIDER_MODE (fmode))
4529 for (imode = GET_MODE (from); imode != VOIDmode;
4530 imode = GET_MODE_WIDER_MODE (imode))
4532 int doing_unsigned = unsignedp;
4534 if (fmode != GET_MODE (to)
4535 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
4536 continue;
4538 icode = can_float_p (fmode, imode, unsignedp);
4539 if (icode == CODE_FOR_nothing && unsignedp)
4541 enum insn_code scode = can_float_p (fmode, imode, 0);
4542 if (scode != CODE_FOR_nothing)
4543 can_do_signed = true;
4544 if (imode != GET_MODE (from))
4545 icode = scode, doing_unsigned = 0;
4548 if (icode != CODE_FOR_nothing)
4550 if (imode != GET_MODE (from))
4551 from = convert_to_mode (imode, from, unsignedp);
4553 if (fmode != GET_MODE (to))
4554 target = gen_reg_rtx (fmode);
4556 emit_unop_insn (icode, target, from,
4557 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4559 if (target != to)
4560 convert_move (to, target, 0);
4561 return;
4565 /* Unsigned integer, and no way to convert directly. Convert as signed,
4566 then unconditionally adjust the result. */
4567 if (unsignedp && can_do_signed)
4569 rtx_code_label *label = gen_label_rtx ();
4570 rtx temp;
4571 REAL_VALUE_TYPE offset;
4573 /* Look for a usable floating mode FMODE wider than the source and at
4574 least as wide as the target. Using FMODE will avoid rounding woes
4575 with unsigned values greater than the signed maximum value. */
4577 for (fmode = GET_MODE (to); fmode != VOIDmode;
4578 fmode = GET_MODE_WIDER_MODE (fmode))
4579 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4580 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4581 break;
4583 if (fmode == VOIDmode)
4585 /* There is no such mode. Pretend the target is wide enough. */
4586 fmode = GET_MODE (to);
4588 /* Avoid double-rounding when TO is narrower than FROM. */
4589 if ((significand_size (fmode) + 1)
4590 < GET_MODE_PRECISION (GET_MODE (from)))
4592 rtx temp1;
4593 rtx_code_label *neglabel = gen_label_rtx ();
4595 /* Don't use TARGET if it isn't a register, is a hard register,
4596 or is the wrong mode. */
4597 if (!REG_P (target)
4598 || REGNO (target) < FIRST_PSEUDO_REGISTER
4599 || GET_MODE (target) != fmode)
4600 target = gen_reg_rtx (fmode);
4602 imode = GET_MODE (from);
4603 do_pending_stack_adjust ();
4605 /* Test whether the sign bit is set. */
4606 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4607 0, neglabel);
4609 /* The sign bit is not set. Convert as signed. */
4610 expand_float (target, from, 0);
4611 emit_jump_insn (targetm.gen_jump (label));
4612 emit_barrier ();
4614 /* The sign bit is set.
4615 Convert to a usable (positive signed) value by shifting right
4616 one bit, while remembering if a nonzero bit was shifted
4617 out; i.e., compute (from & 1) | (from >> 1). */
4619 emit_label (neglabel);
4620 temp = expand_binop (imode, and_optab, from, const1_rtx,
4621 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4622 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4623 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4624 OPTAB_LIB_WIDEN);
4625 expand_float (target, temp, 0);
4627 /* Multiply by 2 to undo the shift above. */
4628 temp = expand_binop (fmode, add_optab, target, target,
4629 target, 0, OPTAB_LIB_WIDEN);
4630 if (temp != target)
4631 emit_move_insn (target, temp);
4633 do_pending_stack_adjust ();
4634 emit_label (label);
4635 goto done;
4639 /* If we are about to do some arithmetic to correct for an
4640 unsigned operand, do it in a pseudo-register. */
4642 if (GET_MODE (to) != fmode
4643 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4644 target = gen_reg_rtx (fmode);
4646 /* Convert as signed integer to floating. */
4647 expand_float (target, from, 0);
4649 /* If FROM is negative (and therefore TO is negative),
4650 correct its value by 2**bitwidth. */
4652 do_pending_stack_adjust ();
4653 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4654 0, label);
4657 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
4658 temp = expand_binop (fmode, add_optab, target,
4659 const_double_from_real_value (offset, fmode),
4660 target, 0, OPTAB_LIB_WIDEN);
4661 if (temp != target)
4662 emit_move_insn (target, temp);
4664 do_pending_stack_adjust ();
4665 emit_label (label);
4666 goto done;
4669 /* No hardware instruction available; call a library routine. */
4671 rtx libfunc;
4672 rtx_insn *insns;
4673 rtx value;
4674 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4676 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_PRECISION (SImode))
4677 from = convert_to_mode (SImode, from, unsignedp);
4679 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4680 gcc_assert (libfunc);
4682 start_sequence ();
4684 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4685 GET_MODE (to), 1, from,
4686 GET_MODE (from));
4687 insns = get_insns ();
4688 end_sequence ();
4690 emit_libcall_block (insns, target, value,
4691 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4692 GET_MODE (to), from));
4695 done:
4697 /* Copy result to requested destination
4698 if we have been computing in a temp location. */
4700 if (target != to)
4702 if (GET_MODE (target) == GET_MODE (to))
4703 emit_move_insn (to, target);
4704 else
4705 convert_move (to, target, 0);
4709 /* Generate code to convert FROM to fixed point and store in TO. FROM
4710 must be floating point. */
4712 void
4713 expand_fix (rtx to, rtx from, int unsignedp)
4715 enum insn_code icode;
4716 rtx target = to;
4717 machine_mode fmode, imode;
4718 bool must_trunc = false;
4720 /* We first try to find a pair of modes, one real and one integer, at
4721 least as wide as FROM and TO, respectively, in which we can open-code
4722 this conversion. If the integer mode is wider than the mode of TO,
4723 we can do the conversion either signed or unsigned. */
4725 for (fmode = GET_MODE (from); fmode != VOIDmode;
4726 fmode = GET_MODE_WIDER_MODE (fmode))
4727 for (imode = GET_MODE (to); imode != VOIDmode;
4728 imode = GET_MODE_WIDER_MODE (imode))
4730 int doing_unsigned = unsignedp;
4732 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4733 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4734 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4736 if (icode != CODE_FOR_nothing)
4738 rtx_insn *last = get_last_insn ();
4739 if (fmode != GET_MODE (from))
4740 from = convert_to_mode (fmode, from, 0);
4742 if (must_trunc)
4744 rtx temp = gen_reg_rtx (GET_MODE (from));
4745 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4746 temp, 0);
4749 if (imode != GET_MODE (to))
4750 target = gen_reg_rtx (imode);
4752 if (maybe_emit_unop_insn (icode, target, from,
4753 doing_unsigned ? UNSIGNED_FIX : FIX))
4755 if (target != to)
4756 convert_move (to, target, unsignedp);
4757 return;
4759 delete_insns_since (last);
4763 /* For an unsigned conversion, there is one more way to do it.
4764 If we have a signed conversion, we generate code that compares
4765 the real value to the largest representable positive number. If if
4766 is smaller, the conversion is done normally. Otherwise, subtract
4767 one plus the highest signed number, convert, and add it back.
4769 We only need to check all real modes, since we know we didn't find
4770 anything with a wider integer mode.
4772 This code used to extend FP value into mode wider than the destination.
4773 This is needed for decimal float modes which cannot accurately
4774 represent one plus the highest signed number of the same size, but
4775 not for binary modes. Consider, for instance conversion from SFmode
4776 into DImode.
4778 The hot path through the code is dealing with inputs smaller than 2^63
4779 and doing just the conversion, so there is no bits to lose.
4781 In the other path we know the value is positive in the range 2^63..2^64-1
4782 inclusive. (as for other input overflow happens and result is undefined)
4783 So we know that the most important bit set in mantissa corresponds to
4784 2^63. The subtraction of 2^63 should not generate any rounding as it
4785 simply clears out that bit. The rest is trivial. */
4787 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4788 for (fmode = GET_MODE (from); fmode != VOIDmode;
4789 fmode = GET_MODE_WIDER_MODE (fmode))
4790 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
4791 && (!DECIMAL_FLOAT_MODE_P (fmode)
4792 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
4794 int bitsize;
4795 REAL_VALUE_TYPE offset;
4796 rtx limit;
4797 rtx_code_label *lab1, *lab2;
4798 rtx_insn *insn;
4800 bitsize = GET_MODE_PRECISION (GET_MODE (to));
4801 real_2expN (&offset, bitsize - 1, fmode);
4802 limit = const_double_from_real_value (offset, fmode);
4803 lab1 = gen_label_rtx ();
4804 lab2 = gen_label_rtx ();
4806 if (fmode != GET_MODE (from))
4807 from = convert_to_mode (fmode, from, 0);
4809 /* See if we need to do the subtraction. */
4810 do_pending_stack_adjust ();
4811 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4812 0, lab1);
4814 /* If not, do the signed "fix" and branch around fixup code. */
4815 expand_fix (to, from, 0);
4816 emit_jump_insn (targetm.gen_jump (lab2));
4817 emit_barrier ();
4819 /* Otherwise, subtract 2**(N-1), convert to signed number,
4820 then add 2**(N-1). Do the addition using XOR since this
4821 will often generate better code. */
4822 emit_label (lab1);
4823 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4824 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4825 expand_fix (to, target, 0);
4826 target = expand_binop (GET_MODE (to), xor_optab, to,
4827 gen_int_mode
4828 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4829 GET_MODE (to)),
4830 to, 1, OPTAB_LIB_WIDEN);
4832 if (target != to)
4833 emit_move_insn (to, target);
4835 emit_label (lab2);
4837 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
4839 /* Make a place for a REG_NOTE and add it. */
4840 insn = emit_move_insn (to, to);
4841 set_dst_reg_note (insn, REG_EQUAL,
4842 gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
4843 copy_rtx (from)),
4844 to);
4847 return;
4850 /* We can't do it with an insn, so use a library call. But first ensure
4851 that the mode of TO is at least as wide as SImode, since those are the
4852 only library calls we know about. */
4854 if (GET_MODE_PRECISION (GET_MODE (to)) < GET_MODE_PRECISION (SImode))
4856 target = gen_reg_rtx (SImode);
4858 expand_fix (target, from, unsignedp);
4860 else
4862 rtx_insn *insns;
4863 rtx value;
4864 rtx libfunc;
4866 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4867 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4868 gcc_assert (libfunc);
4870 start_sequence ();
4872 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4873 GET_MODE (to), 1, from,
4874 GET_MODE (from));
4875 insns = get_insns ();
4876 end_sequence ();
4878 emit_libcall_block (insns, target, value,
4879 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4880 GET_MODE (to), from));
4883 if (target != to)
4885 if (GET_MODE (to) == GET_MODE (target))
4886 emit_move_insn (to, target);
4887 else
4888 convert_move (to, target, 0);
4893 /* Promote integer arguments for a libcall if necessary.
4894 emit_library_call_value cannot do the promotion because it does not
4895 know if it should do a signed or unsigned promotion. This is because
4896 there are no tree types defined for libcalls. */
4898 static rtx
4899 prepare_libcall_arg (rtx arg, int uintp)
4901 machine_mode mode = GET_MODE (arg);
4902 machine_mode arg_mode;
4903 if (SCALAR_INT_MODE_P (mode))
4905 /* If we need to promote the integer function argument we need to do
4906 it here instead of inside emit_library_call_value because in
4907 emit_library_call_value we don't know if we should do a signed or
4908 unsigned promotion. */
4910 int unsigned_p = 0;
4911 arg_mode = promote_function_mode (NULL_TREE, mode,
4912 &unsigned_p, NULL_TREE, 0);
4913 if (arg_mode != mode)
4914 return convert_to_mode (arg_mode, arg, uintp);
4916 return arg;
4919 /* Generate code to convert FROM or TO a fixed-point.
4920 If UINTP is true, either TO or FROM is an unsigned integer.
4921 If SATP is true, we need to saturate the result. */
4923 void
4924 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
4926 machine_mode to_mode = GET_MODE (to);
4927 machine_mode from_mode = GET_MODE (from);
4928 convert_optab tab;
4929 enum rtx_code this_code;
4930 enum insn_code code;
4931 rtx_insn *insns;
4932 rtx value;
4933 rtx libfunc;
4935 if (to_mode == from_mode)
4937 emit_move_insn (to, from);
4938 return;
4941 if (uintp)
4943 tab = satp ? satfractuns_optab : fractuns_optab;
4944 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
4946 else
4948 tab = satp ? satfract_optab : fract_optab;
4949 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
4951 code = convert_optab_handler (tab, to_mode, from_mode);
4952 if (code != CODE_FOR_nothing)
4954 emit_unop_insn (code, to, from, this_code);
4955 return;
4958 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
4959 gcc_assert (libfunc);
4961 from = prepare_libcall_arg (from, uintp);
4962 from_mode = GET_MODE (from);
4964 start_sequence ();
4965 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
4966 1, from, from_mode);
4967 insns = get_insns ();
4968 end_sequence ();
4970 emit_libcall_block (insns, to, value,
4971 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
4974 /* Generate code to convert FROM to fixed point and store in TO. FROM
4975 must be floating point, TO must be signed. Use the conversion optab
4976 TAB to do the conversion. */
4978 bool
4979 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
4981 enum insn_code icode;
4982 rtx target = to;
4983 machine_mode fmode, imode;
4985 /* We first try to find a pair of modes, one real and one integer, at
4986 least as wide as FROM and TO, respectively, in which we can open-code
4987 this conversion. If the integer mode is wider than the mode of TO,
4988 we can do the conversion either signed or unsigned. */
4990 for (fmode = GET_MODE (from); fmode != VOIDmode;
4991 fmode = GET_MODE_WIDER_MODE (fmode))
4992 for (imode = GET_MODE (to); imode != VOIDmode;
4993 imode = GET_MODE_WIDER_MODE (imode))
4995 icode = convert_optab_handler (tab, imode, fmode);
4996 if (icode != CODE_FOR_nothing)
4998 rtx_insn *last = get_last_insn ();
4999 if (fmode != GET_MODE (from))
5000 from = convert_to_mode (fmode, from, 0);
5002 if (imode != GET_MODE (to))
5003 target = gen_reg_rtx (imode);
5005 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5007 delete_insns_since (last);
5008 continue;
5010 if (target != to)
5011 convert_move (to, target, 0);
5012 return true;
5016 return false;
5019 /* Report whether we have an instruction to perform the operation
5020 specified by CODE on operands of mode MODE. */
5022 have_insn_for (enum rtx_code code, machine_mode mode)
5024 return (code_to_optab (code)
5025 && (optab_handler (code_to_optab (code), mode)
5026 != CODE_FOR_nothing));
5029 /* Print information about the current contents of the optabs on
5030 STDERR. */
5032 DEBUG_FUNCTION void
5033 debug_optab_libfuncs (void)
5035 int i, j, k;
5037 /* Dump the arithmetic optabs. */
5038 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5039 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5041 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5042 if (l)
5044 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5045 fprintf (stderr, "%s\t%s:\t%s\n",
5046 GET_RTX_NAME (optab_to_code ((optab) i)),
5047 GET_MODE_NAME (j),
5048 XSTR (l, 0));
5052 /* Dump the conversion optabs. */
5053 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5054 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5055 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5057 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5058 (machine_mode) k);
5059 if (l)
5061 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5062 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5063 GET_RTX_NAME (optab_to_code ((optab) i)),
5064 GET_MODE_NAME (j),
5065 GET_MODE_NAME (k),
5066 XSTR (l, 0));
5071 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5072 CODE. Return 0 on failure. */
5074 rtx_insn *
5075 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5077 machine_mode mode = GET_MODE (op1);
5078 enum insn_code icode;
5079 rtx_insn *insn;
5080 rtx trap_rtx;
5082 if (mode == VOIDmode)
5083 return 0;
5085 icode = optab_handler (ctrap_optab, mode);
5086 if (icode == CODE_FOR_nothing)
5087 return 0;
5089 /* Some targets only accept a zero trap code. */
5090 if (!insn_operand_matches (icode, 3, tcode))
5091 return 0;
5093 do_pending_stack_adjust ();
5094 start_sequence ();
5095 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5096 &trap_rtx, &mode);
5097 if (!trap_rtx)
5098 insn = NULL;
5099 else
5100 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5101 tcode);
5103 /* If that failed, then give up. */
5104 if (insn == 0)
5106 end_sequence ();
5107 return 0;
5110 emit_insn (insn);
5111 insn = get_insns ();
5112 end_sequence ();
5113 return insn;
5116 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5117 or unsigned operation code. */
5119 enum rtx_code
5120 get_rtx_code (enum tree_code tcode, bool unsignedp)
5122 enum rtx_code code;
5123 switch (tcode)
5125 case EQ_EXPR:
5126 code = EQ;
5127 break;
5128 case NE_EXPR:
5129 code = NE;
5130 break;
5131 case LT_EXPR:
5132 code = unsignedp ? LTU : LT;
5133 break;
5134 case LE_EXPR:
5135 code = unsignedp ? LEU : LE;
5136 break;
5137 case GT_EXPR:
5138 code = unsignedp ? GTU : GT;
5139 break;
5140 case GE_EXPR:
5141 code = unsignedp ? GEU : GE;
5142 break;
5144 case UNORDERED_EXPR:
5145 code = UNORDERED;
5146 break;
5147 case ORDERED_EXPR:
5148 code = ORDERED;
5149 break;
5150 case UNLT_EXPR:
5151 code = UNLT;
5152 break;
5153 case UNLE_EXPR:
5154 code = UNLE;
5155 break;
5156 case UNGT_EXPR:
5157 code = UNGT;
5158 break;
5159 case UNGE_EXPR:
5160 code = UNGE;
5161 break;
5162 case UNEQ_EXPR:
5163 code = UNEQ;
5164 break;
5165 case LTGT_EXPR:
5166 code = LTGT;
5167 break;
5169 case BIT_AND_EXPR:
5170 code = AND;
5171 break;
5173 case BIT_IOR_EXPR:
5174 code = IOR;
5175 break;
5177 default:
5178 gcc_unreachable ();
5180 return code;
5183 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5184 unsigned operators. OPNO holds an index of the first comparison
5185 operand in insn with code ICODE. Do not generate compare instruction. */
5187 static rtx
5188 vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
5189 bool unsignedp, enum insn_code icode,
5190 unsigned int opno)
5192 struct expand_operand ops[2];
5193 rtx rtx_op0, rtx_op1;
5194 machine_mode m0, m1;
5195 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5197 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5199 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5200 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5201 cases, use the original mode. */
5202 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5203 EXPAND_STACK_PARM);
5204 m0 = GET_MODE (rtx_op0);
5205 if (m0 == VOIDmode)
5206 m0 = TYPE_MODE (TREE_TYPE (t_op0));
5208 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5209 EXPAND_STACK_PARM);
5210 m1 = GET_MODE (rtx_op1);
5211 if (m1 == VOIDmode)
5212 m1 = TYPE_MODE (TREE_TYPE (t_op1));
5214 create_input_operand (&ops[0], rtx_op0, m0);
5215 create_input_operand (&ops[1], rtx_op1, m1);
5216 if (!maybe_legitimize_operands (icode, opno, 2, ops))
5217 gcc_unreachable ();
5218 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
5221 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
5222 vec_perm operand, assuming the second operand is a constant vector of zeroes.
5223 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
5224 shift. */
5225 static rtx
5226 shift_amt_for_vec_perm_mask (rtx sel)
5228 unsigned int i, first, nelt = GET_MODE_NUNITS (GET_MODE (sel));
5229 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (GET_MODE (sel));
5231 if (GET_CODE (sel) != CONST_VECTOR)
5232 return NULL_RTX;
5234 first = INTVAL (CONST_VECTOR_ELT (sel, 0));
5235 if (first >= 2*nelt)
5236 return NULL_RTX;
5237 for (i = 1; i < nelt; i++)
5239 int idx = INTVAL (CONST_VECTOR_ELT (sel, i));
5240 unsigned int expected = (i + first) & (2 * nelt - 1);
5241 /* Indices into the second vector are all equivalent. */
5242 if (idx < 0 || (MIN (nelt, (unsigned) idx) != MIN (nelt, expected)))
5243 return NULL_RTX;
5246 return GEN_INT (first * bitsize);
5249 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
5251 static rtx
5252 expand_vec_perm_1 (enum insn_code icode, rtx target,
5253 rtx v0, rtx v1, rtx sel)
5255 machine_mode tmode = GET_MODE (target);
5256 machine_mode smode = GET_MODE (sel);
5257 struct expand_operand ops[4];
5259 create_output_operand (&ops[0], target, tmode);
5260 create_input_operand (&ops[3], sel, smode);
5262 /* Make an effort to preserve v0 == v1. The target expander is able to
5263 rely on this to determine if we're permuting a single input operand. */
5264 if (rtx_equal_p (v0, v1))
5266 if (!insn_operand_matches (icode, 1, v0))
5267 v0 = force_reg (tmode, v0);
5268 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5269 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5271 create_fixed_operand (&ops[1], v0);
5272 create_fixed_operand (&ops[2], v0);
5274 else
5276 create_input_operand (&ops[1], v0, tmode);
5277 /* See if this can be handled with a vec_shr. We only do this if the
5278 second vector is all zeroes. */
5279 enum insn_code shift_code = optab_handler (vec_shr_optab, GET_MODE (v0));
5280 if (v1 == CONST0_RTX (GET_MODE (v1)) && shift_code)
5281 if (rtx shift_amt = shift_amt_for_vec_perm_mask (sel))
5283 create_convert_operand_from_type (&ops[2], shift_amt,
5284 sizetype_tab[(int) stk_sizetype]);
5285 if (maybe_expand_insn (shift_code, 3, ops))
5286 return ops[0].value;
5288 create_input_operand (&ops[2], v1, tmode);
5291 if (maybe_expand_insn (icode, 4, ops))
5292 return ops[0].value;
5293 return NULL_RTX;
5296 /* Generate instructions for vec_perm optab given its mode
5297 and three operands. */
5300 expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
5302 enum insn_code icode;
5303 machine_mode qimode;
5304 unsigned int i, w, e, u;
5305 rtx tmp, sel_qi = NULL;
5306 rtvec vec;
5308 if (!target || GET_MODE (target) != mode)
5309 target = gen_reg_rtx (mode);
5311 w = GET_MODE_SIZE (mode);
5312 e = GET_MODE_NUNITS (mode);
5313 u = GET_MODE_UNIT_SIZE (mode);
5315 /* Set QIMODE to a different vector mode with byte elements.
5316 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5317 qimode = VOIDmode;
5318 if (GET_MODE_INNER (mode) != QImode)
5320 qimode = mode_for_vector (QImode, w);
5321 if (!VECTOR_MODE_P (qimode))
5322 qimode = VOIDmode;
5325 /* If the input is a constant, expand it specially. */
5326 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
5327 if (GET_CODE (sel) == CONST_VECTOR)
5329 icode = direct_optab_handler (vec_perm_const_optab, mode);
5330 if (icode != CODE_FOR_nothing)
5332 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5333 if (tmp)
5334 return tmp;
5337 /* Fall back to a constant byte-based permutation. */
5338 if (qimode != VOIDmode)
5340 vec = rtvec_alloc (w);
5341 for (i = 0; i < e; ++i)
5343 unsigned int j, this_e;
5345 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
5346 this_e &= 2 * e - 1;
5347 this_e *= u;
5349 for (j = 0; j < u; ++j)
5350 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
5352 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
5354 icode = direct_optab_handler (vec_perm_const_optab, qimode);
5355 if (icode != CODE_FOR_nothing)
5357 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5358 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5359 gen_lowpart (qimode, v1), sel_qi);
5360 if (tmp)
5361 return gen_lowpart (mode, tmp);
5366 /* Otherwise expand as a fully variable permuation. */
5367 icode = direct_optab_handler (vec_perm_optab, mode);
5368 if (icode != CODE_FOR_nothing)
5370 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5371 if (tmp)
5372 return tmp;
5375 /* As a special case to aid several targets, lower the element-based
5376 permutation to a byte-based permutation and try again. */
5377 if (qimode == VOIDmode)
5378 return NULL_RTX;
5379 icode = direct_optab_handler (vec_perm_optab, qimode);
5380 if (icode == CODE_FOR_nothing)
5381 return NULL_RTX;
5383 if (sel_qi == NULL)
5385 /* Multiply each element by its byte size. */
5386 machine_mode selmode = GET_MODE (sel);
5387 if (u == 2)
5388 sel = expand_simple_binop (selmode, PLUS, sel, sel,
5389 NULL, 0, OPTAB_DIRECT);
5390 else
5391 sel = expand_simple_binop (selmode, ASHIFT, sel,
5392 GEN_INT (exact_log2 (u)),
5393 NULL, 0, OPTAB_DIRECT);
5394 gcc_assert (sel != NULL);
5396 /* Broadcast the low byte each element into each of its bytes. */
5397 vec = rtvec_alloc (w);
5398 for (i = 0; i < w; ++i)
5400 int this_e = i / u * u;
5401 if (BYTES_BIG_ENDIAN)
5402 this_e += u - 1;
5403 RTVEC_ELT (vec, i) = GEN_INT (this_e);
5405 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5406 sel = gen_lowpart (qimode, sel);
5407 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
5408 gcc_assert (sel != NULL);
5410 /* Add the byte offset to each byte element. */
5411 /* Note that the definition of the indicies here is memory ordering,
5412 so there should be no difference between big and little endian. */
5413 vec = rtvec_alloc (w);
5414 for (i = 0; i < w; ++i)
5415 RTVEC_ELT (vec, i) = GEN_INT (i % u);
5416 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5417 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
5418 sel, 0, OPTAB_DIRECT);
5419 gcc_assert (sel_qi != NULL);
5422 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5423 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5424 gen_lowpart (qimode, v1), sel_qi);
5425 if (tmp)
5426 tmp = gen_lowpart (mode, tmp);
5427 return tmp;
5430 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5431 three operands. */
5434 expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5435 rtx target)
5437 struct expand_operand ops[4];
5438 machine_mode mode = TYPE_MODE (vec_cond_type);
5439 machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0));
5440 enum insn_code icode = get_vcond_mask_icode (mode, mask_mode);
5441 rtx mask, rtx_op1, rtx_op2;
5443 if (icode == CODE_FOR_nothing)
5444 return 0;
5446 mask = expand_normal (op0);
5447 rtx_op1 = expand_normal (op1);
5448 rtx_op2 = expand_normal (op2);
5450 mask = force_reg (GET_MODE (mask), mask);
5451 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5453 create_output_operand (&ops[0], target, mode);
5454 create_input_operand (&ops[1], rtx_op1, mode);
5455 create_input_operand (&ops[2], rtx_op2, mode);
5456 create_input_operand (&ops[3], mask, mask_mode);
5457 expand_insn (icode, 4, ops);
5459 return ops[0].value;
5462 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5463 three operands. */
5466 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5467 rtx target)
5469 struct expand_operand ops[6];
5470 enum insn_code icode;
5471 rtx comparison, rtx_op1, rtx_op2;
5472 machine_mode mode = TYPE_MODE (vec_cond_type);
5473 machine_mode cmp_op_mode;
5474 bool unsignedp;
5475 tree op0a, op0b;
5476 enum tree_code tcode;
5478 if (COMPARISON_CLASS_P (op0))
5480 op0a = TREE_OPERAND (op0, 0);
5481 op0b = TREE_OPERAND (op0, 1);
5482 tcode = TREE_CODE (op0);
5484 else
5486 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
5487 if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0)))
5488 != CODE_FOR_nothing)
5489 return expand_vec_cond_mask_expr (vec_cond_type, op0, op1,
5490 op2, target);
5491 /* Fake op0 < 0. */
5492 else
5494 gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0)))
5495 == MODE_VECTOR_INT);
5496 op0a = op0;
5497 op0b = build_zero_cst (TREE_TYPE (op0));
5498 tcode = LT_EXPR;
5501 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
5502 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5505 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
5506 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
5508 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
5509 if (icode == CODE_FOR_nothing)
5510 return 0;
5512 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode, 4);
5513 rtx_op1 = expand_normal (op1);
5514 rtx_op2 = expand_normal (op2);
5516 create_output_operand (&ops[0], target, mode);
5517 create_input_operand (&ops[1], rtx_op1, mode);
5518 create_input_operand (&ops[2], rtx_op2, mode);
5519 create_fixed_operand (&ops[3], comparison);
5520 create_fixed_operand (&ops[4], XEXP (comparison, 0));
5521 create_fixed_operand (&ops[5], XEXP (comparison, 1));
5522 expand_insn (icode, 6, ops);
5523 return ops[0].value;
5526 /* Generate insns for a vector comparison into a mask. */
5529 expand_vec_cmp_expr (tree type, tree exp, rtx target)
5531 struct expand_operand ops[4];
5532 enum insn_code icode;
5533 rtx comparison;
5534 machine_mode mask_mode = TYPE_MODE (type);
5535 machine_mode vmode;
5536 bool unsignedp;
5537 tree op0a, op0b;
5538 enum tree_code tcode;
5540 op0a = TREE_OPERAND (exp, 0);
5541 op0b = TREE_OPERAND (exp, 1);
5542 tcode = TREE_CODE (exp);
5544 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5545 vmode = TYPE_MODE (TREE_TYPE (op0a));
5547 icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
5548 if (icode == CODE_FOR_nothing)
5549 return 0;
5551 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode, 2);
5552 create_output_operand (&ops[0], target, mask_mode);
5553 create_fixed_operand (&ops[1], comparison);
5554 create_fixed_operand (&ops[2], XEXP (comparison, 0));
5555 create_fixed_operand (&ops[3], XEXP (comparison, 1));
5556 expand_insn (icode, 4, ops);
5557 return ops[0].value;
5560 /* Expand a highpart multiply. */
5563 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
5564 rtx target, bool uns_p)
5566 struct expand_operand eops[3];
5567 enum insn_code icode;
5568 int method, i, nunits;
5569 machine_mode wmode;
5570 rtx m1, m2, perm;
5571 optab tab1, tab2;
5572 rtvec v;
5574 method = can_mult_highpart_p (mode, uns_p);
5575 switch (method)
5577 case 0:
5578 return NULL_RTX;
5579 case 1:
5580 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
5581 return expand_binop (mode, tab1, op0, op1, target, uns_p,
5582 OPTAB_LIB_WIDEN);
5583 case 2:
5584 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
5585 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
5586 break;
5587 case 3:
5588 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
5589 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
5590 if (BYTES_BIG_ENDIAN)
5591 std::swap (tab1, tab2);
5592 break;
5593 default:
5594 gcc_unreachable ();
5597 icode = optab_handler (tab1, mode);
5598 nunits = GET_MODE_NUNITS (mode);
5599 wmode = insn_data[icode].operand[0].mode;
5600 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
5601 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
5603 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5604 create_input_operand (&eops[1], op0, mode);
5605 create_input_operand (&eops[2], op1, mode);
5606 expand_insn (icode, 3, eops);
5607 m1 = gen_lowpart (mode, eops[0].value);
5609 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5610 create_input_operand (&eops[1], op0, mode);
5611 create_input_operand (&eops[2], op1, mode);
5612 expand_insn (optab_handler (tab2, mode), 3, eops);
5613 m2 = gen_lowpart (mode, eops[0].value);
5615 v = rtvec_alloc (nunits);
5616 if (method == 2)
5618 for (i = 0; i < nunits; ++i)
5619 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
5620 + ((i & 1) ? nunits : 0));
5622 else
5624 for (i = 0; i < nunits; ++i)
5625 RTVEC_ELT (v, i) = GEN_INT (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
5627 perm = gen_rtx_CONST_VECTOR (mode, v);
5629 return expand_vec_perm (mode, m1, m2, perm, target);
5632 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5633 pattern. */
5635 static void
5636 find_cc_set (rtx x, const_rtx pat, void *data)
5638 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
5639 && GET_CODE (pat) == SET)
5641 rtx *p_cc_reg = (rtx *) data;
5642 gcc_assert (!*p_cc_reg);
5643 *p_cc_reg = x;
5647 /* This is a helper function for the other atomic operations. This function
5648 emits a loop that contains SEQ that iterates until a compare-and-swap
5649 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5650 a set of instructions that takes a value from OLD_REG as an input and
5651 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5652 set to the current contents of MEM. After SEQ, a compare-and-swap will
5653 attempt to update MEM with NEW_REG. The function returns true when the
5654 loop was generated successfully. */
5656 static bool
5657 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5659 machine_mode mode = GET_MODE (mem);
5660 rtx_code_label *label;
5661 rtx cmp_reg, success, oldval;
5663 /* The loop we want to generate looks like
5665 cmp_reg = mem;
5666 label:
5667 old_reg = cmp_reg;
5668 seq;
5669 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5670 if (success)
5671 goto label;
5673 Note that we only do the plain load from memory once. Subsequent
5674 iterations use the value loaded by the compare-and-swap pattern. */
5676 label = gen_label_rtx ();
5677 cmp_reg = gen_reg_rtx (mode);
5679 emit_move_insn (cmp_reg, mem);
5680 emit_label (label);
5681 emit_move_insn (old_reg, cmp_reg);
5682 if (seq)
5683 emit_insn (seq);
5685 success = NULL_RTX;
5686 oldval = cmp_reg;
5687 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
5688 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
5689 MEMMODEL_RELAXED))
5690 return false;
5692 if (oldval != cmp_reg)
5693 emit_move_insn (cmp_reg, oldval);
5695 /* Mark this jump predicted not taken. */
5696 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
5697 GET_MODE (success), 1, label, 0);
5698 return true;
5702 /* This function tries to emit an atomic_exchange intruction. VAL is written
5703 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
5704 using TARGET if possible. */
5706 static rtx
5707 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5709 machine_mode mode = GET_MODE (mem);
5710 enum insn_code icode;
5712 /* If the target supports the exchange directly, great. */
5713 icode = direct_optab_handler (atomic_exchange_optab, mode);
5714 if (icode != CODE_FOR_nothing)
5716 struct expand_operand ops[4];
5718 create_output_operand (&ops[0], target, mode);
5719 create_fixed_operand (&ops[1], mem);
5720 create_input_operand (&ops[2], val, mode);
5721 create_integer_operand (&ops[3], model);
5722 if (maybe_expand_insn (icode, 4, ops))
5723 return ops[0].value;
5726 return NULL_RTX;
5729 /* This function tries to implement an atomic exchange operation using
5730 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
5731 The previous contents of *MEM are returned, using TARGET if possible.
5732 Since this instructionn is an acquire barrier only, stronger memory
5733 models may require additional barriers to be emitted. */
5735 static rtx
5736 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
5737 enum memmodel model)
5739 machine_mode mode = GET_MODE (mem);
5740 enum insn_code icode;
5741 rtx_insn *last_insn = get_last_insn ();
5743 icode = optab_handler (sync_lock_test_and_set_optab, mode);
5745 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
5746 exists, and the memory model is stronger than acquire, add a release
5747 barrier before the instruction. */
5749 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
5750 expand_mem_thread_fence (model);
5752 if (icode != CODE_FOR_nothing)
5754 struct expand_operand ops[3];
5755 create_output_operand (&ops[0], target, mode);
5756 create_fixed_operand (&ops[1], mem);
5757 create_input_operand (&ops[2], val, mode);
5758 if (maybe_expand_insn (icode, 3, ops))
5759 return ops[0].value;
5762 /* If an external test-and-set libcall is provided, use that instead of
5763 any external compare-and-swap that we might get from the compare-and-
5764 swap-loop expansion later. */
5765 if (!can_compare_and_swap_p (mode, false))
5767 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
5768 if (libfunc != NULL)
5770 rtx addr;
5772 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5773 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5774 mode, 2, addr, ptr_mode,
5775 val, mode);
5779 /* If the test_and_set can't be emitted, eliminate any barrier that might
5780 have been emitted. */
5781 delete_insns_since (last_insn);
5782 return NULL_RTX;
5785 /* This function tries to implement an atomic exchange operation using a
5786 compare_and_swap loop. VAL is written to *MEM. The previous contents of
5787 *MEM are returned, using TARGET if possible. No memory model is required
5788 since a compare_and_swap loop is seq-cst. */
5790 static rtx
5791 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
5793 machine_mode mode = GET_MODE (mem);
5795 if (can_compare_and_swap_p (mode, true))
5797 if (!target || !register_operand (target, mode))
5798 target = gen_reg_rtx (mode);
5799 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
5800 return target;
5803 return NULL_RTX;
5806 /* This function tries to implement an atomic test-and-set operation
5807 using the atomic_test_and_set instruction pattern. A boolean value
5808 is returned from the operation, using TARGET if possible. */
5810 static rtx
5811 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5813 machine_mode pat_bool_mode;
5814 struct expand_operand ops[3];
5816 if (!targetm.have_atomic_test_and_set ())
5817 return NULL_RTX;
5819 /* While we always get QImode from __atomic_test_and_set, we get
5820 other memory modes from __sync_lock_test_and_set. Note that we
5821 use no endian adjustment here. This matches the 4.6 behavior
5822 in the Sparc backend. */
5823 enum insn_code icode = targetm.code_for_atomic_test_and_set;
5824 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
5825 if (GET_MODE (mem) != QImode)
5826 mem = adjust_address_nv (mem, QImode, 0);
5828 pat_bool_mode = insn_data[icode].operand[0].mode;
5829 create_output_operand (&ops[0], target, pat_bool_mode);
5830 create_fixed_operand (&ops[1], mem);
5831 create_integer_operand (&ops[2], model);
5833 if (maybe_expand_insn (icode, 3, ops))
5834 return ops[0].value;
5835 return NULL_RTX;
5838 /* This function expands the legacy _sync_lock test_and_set operation which is
5839 generally an atomic exchange. Some limited targets only allow the
5840 constant 1 to be stored. This is an ACQUIRE operation.
5842 TARGET is an optional place to stick the return value.
5843 MEM is where VAL is stored. */
5846 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
5848 rtx ret;
5850 /* Try an atomic_exchange first. */
5851 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
5852 if (ret)
5853 return ret;
5855 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
5856 MEMMODEL_SYNC_ACQUIRE);
5857 if (ret)
5858 return ret;
5860 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
5861 if (ret)
5862 return ret;
5864 /* If there are no other options, try atomic_test_and_set if the value
5865 being stored is 1. */
5866 if (val == const1_rtx)
5867 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
5869 return ret;
5872 /* This function expands the atomic test_and_set operation:
5873 atomically store a boolean TRUE into MEM and return the previous value.
5875 MEMMODEL is the memory model variant to use.
5876 TARGET is an optional place to stick the return value. */
5879 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5881 machine_mode mode = GET_MODE (mem);
5882 rtx ret, trueval, subtarget;
5884 ret = maybe_emit_atomic_test_and_set (target, mem, model);
5885 if (ret)
5886 return ret;
5888 /* Be binary compatible with non-default settings of trueval, and different
5889 cpu revisions. E.g. one revision may have atomic-test-and-set, but
5890 another only has atomic-exchange. */
5891 if (targetm.atomic_test_and_set_trueval == 1)
5893 trueval = const1_rtx;
5894 subtarget = target ? target : gen_reg_rtx (mode);
5896 else
5898 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
5899 subtarget = gen_reg_rtx (mode);
5902 /* Try the atomic-exchange optab... */
5903 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
5905 /* ... then an atomic-compare-and-swap loop ... */
5906 if (!ret)
5907 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
5909 /* ... before trying the vaguely defined legacy lock_test_and_set. */
5910 if (!ret)
5911 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
5913 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
5914 things with the value 1. Thus we try again without trueval. */
5915 if (!ret && targetm.atomic_test_and_set_trueval != 1)
5916 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
5918 /* Failing all else, assume a single threaded environment and simply
5919 perform the operation. */
5920 if (!ret)
5922 /* If the result is ignored skip the move to target. */
5923 if (subtarget != const0_rtx)
5924 emit_move_insn (subtarget, mem);
5926 emit_move_insn (mem, trueval);
5927 ret = subtarget;
5930 /* Recall that have to return a boolean value; rectify if trueval
5931 is not exactly one. */
5932 if (targetm.atomic_test_and_set_trueval != 1)
5933 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
5935 return ret;
5938 /* This function expands the atomic exchange operation:
5939 atomically store VAL in MEM and return the previous value in MEM.
5941 MEMMODEL is the memory model variant to use.
5942 TARGET is an optional place to stick the return value. */
5945 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5947 rtx ret;
5949 ret = maybe_emit_atomic_exchange (target, mem, val, model);
5951 /* Next try a compare-and-swap loop for the exchange. */
5952 if (!ret)
5953 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
5955 return ret;
5958 /* This function expands the atomic compare exchange operation:
5960 *PTARGET_BOOL is an optional place to store the boolean success/failure.
5961 *PTARGET_OVAL is an optional place to store the old value from memory.
5962 Both target parameters may be NULL or const0_rtx to indicate that we do
5963 not care about that return value. Both target parameters are updated on
5964 success to the actual location of the corresponding result.
5966 MEMMODEL is the memory model variant to use.
5968 The return value of the function is true for success. */
5970 bool
5971 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
5972 rtx mem, rtx expected, rtx desired,
5973 bool is_weak, enum memmodel succ_model,
5974 enum memmodel fail_model)
5976 machine_mode mode = GET_MODE (mem);
5977 struct expand_operand ops[8];
5978 enum insn_code icode;
5979 rtx target_oval, target_bool = NULL_RTX;
5980 rtx libfunc;
5982 /* Load expected into a register for the compare and swap. */
5983 if (MEM_P (expected))
5984 expected = copy_to_reg (expected);
5986 /* Make sure we always have some place to put the return oldval.
5987 Further, make sure that place is distinct from the input expected,
5988 just in case we need that path down below. */
5989 if (ptarget_oval && *ptarget_oval == const0_rtx)
5990 ptarget_oval = NULL;
5992 if (ptarget_oval == NULL
5993 || (target_oval = *ptarget_oval) == NULL
5994 || reg_overlap_mentioned_p (expected, target_oval))
5995 target_oval = gen_reg_rtx (mode);
5997 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
5998 if (icode != CODE_FOR_nothing)
6000 machine_mode bool_mode = insn_data[icode].operand[0].mode;
6002 if (ptarget_bool && *ptarget_bool == const0_rtx)
6003 ptarget_bool = NULL;
6005 /* Make sure we always have a place for the bool operand. */
6006 if (ptarget_bool == NULL
6007 || (target_bool = *ptarget_bool) == NULL
6008 || GET_MODE (target_bool) != bool_mode)
6009 target_bool = gen_reg_rtx (bool_mode);
6011 /* Emit the compare_and_swap. */
6012 create_output_operand (&ops[0], target_bool, bool_mode);
6013 create_output_operand (&ops[1], target_oval, mode);
6014 create_fixed_operand (&ops[2], mem);
6015 create_input_operand (&ops[3], expected, mode);
6016 create_input_operand (&ops[4], desired, mode);
6017 create_integer_operand (&ops[5], is_weak);
6018 create_integer_operand (&ops[6], succ_model);
6019 create_integer_operand (&ops[7], fail_model);
6020 if (maybe_expand_insn (icode, 8, ops))
6022 /* Return success/failure. */
6023 target_bool = ops[0].value;
6024 target_oval = ops[1].value;
6025 goto success;
6029 /* Otherwise fall back to the original __sync_val_compare_and_swap
6030 which is always seq-cst. */
6031 icode = optab_handler (sync_compare_and_swap_optab, mode);
6032 if (icode != CODE_FOR_nothing)
6034 rtx cc_reg;
6036 create_output_operand (&ops[0], target_oval, mode);
6037 create_fixed_operand (&ops[1], mem);
6038 create_input_operand (&ops[2], expected, mode);
6039 create_input_operand (&ops[3], desired, mode);
6040 if (!maybe_expand_insn (icode, 4, ops))
6041 return false;
6043 target_oval = ops[0].value;
6045 /* If the caller isn't interested in the boolean return value,
6046 skip the computation of it. */
6047 if (ptarget_bool == NULL)
6048 goto success;
6050 /* Otherwise, work out if the compare-and-swap succeeded. */
6051 cc_reg = NULL_RTX;
6052 if (have_insn_for (COMPARE, CCmode))
6053 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
6054 if (cc_reg)
6056 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6057 const0_rtx, VOIDmode, 0, 1);
6058 goto success;
6060 goto success_bool_from_val;
6063 /* Also check for library support for __sync_val_compare_and_swap. */
6064 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6065 if (libfunc != NULL)
6067 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6068 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6069 mode, 3, addr, ptr_mode,
6070 expected, mode, desired, mode);
6071 emit_move_insn (target_oval, target);
6073 /* Compute the boolean return value only if requested. */
6074 if (ptarget_bool)
6075 goto success_bool_from_val;
6076 else
6077 goto success;
6080 /* Failure. */
6081 return false;
6083 success_bool_from_val:
6084 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
6085 expected, VOIDmode, 1, 1);
6086 success:
6087 /* Make sure that the oval output winds up where the caller asked. */
6088 if (ptarget_oval)
6089 *ptarget_oval = target_oval;
6090 if (ptarget_bool)
6091 *ptarget_bool = target_bool;
6092 return true;
6095 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
6097 static void
6098 expand_asm_memory_barrier (void)
6100 rtx asm_op, clob;
6102 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
6103 rtvec_alloc (0), rtvec_alloc (0),
6104 rtvec_alloc (0), UNKNOWN_LOCATION);
6105 MEM_VOLATILE_P (asm_op) = 1;
6107 clob = gen_rtx_SCRATCH (VOIDmode);
6108 clob = gen_rtx_MEM (BLKmode, clob);
6109 clob = gen_rtx_CLOBBER (VOIDmode, clob);
6111 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
6114 /* This routine will either emit the mem_thread_fence pattern or issue a
6115 sync_synchronize to generate a fence for memory model MEMMODEL. */
6117 void
6118 expand_mem_thread_fence (enum memmodel model)
6120 if (targetm.have_mem_thread_fence ())
6121 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
6122 else if (!is_mm_relaxed (model))
6124 if (targetm.have_memory_barrier ())
6125 emit_insn (targetm.gen_memory_barrier ());
6126 else if (synchronize_libfunc != NULL_RTX)
6127 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6128 else
6129 expand_asm_memory_barrier ();
6133 /* This routine will either emit the mem_signal_fence pattern or issue a
6134 sync_synchronize to generate a fence for memory model MEMMODEL. */
6136 void
6137 expand_mem_signal_fence (enum memmodel model)
6139 if (targetm.have_mem_signal_fence ())
6140 emit_insn (targetm.gen_mem_signal_fence (GEN_INT (model)));
6141 else if (!is_mm_relaxed (model))
6143 /* By default targets are coherent between a thread and the signal
6144 handler running on the same thread. Thus this really becomes a
6145 compiler barrier, in that stores must not be sunk past
6146 (or raised above) a given point. */
6147 expand_asm_memory_barrier ();
6151 /* This function expands the atomic load operation:
6152 return the atomically loaded value in MEM.
6154 MEMMODEL is the memory model variant to use.
6155 TARGET is an option place to stick the return value. */
6158 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6160 machine_mode mode = GET_MODE (mem);
6161 enum insn_code icode;
6163 /* If the target supports the load directly, great. */
6164 icode = direct_optab_handler (atomic_load_optab, mode);
6165 if (icode != CODE_FOR_nothing)
6167 struct expand_operand ops[3];
6169 create_output_operand (&ops[0], target, mode);
6170 create_fixed_operand (&ops[1], mem);
6171 create_integer_operand (&ops[2], model);
6172 if (maybe_expand_insn (icode, 3, ops))
6173 return ops[0].value;
6176 /* If the size of the object is greater than word size on this target,
6177 then we assume that a load will not be atomic. */
6178 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6180 /* Issue val = compare_and_swap (mem, 0, 0).
6181 This may cause the occasional harmless store of 0 when the value is
6182 already 0, but it seems to be OK according to the standards guys. */
6183 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
6184 const0_rtx, false, model, model))
6185 return target;
6186 else
6187 /* Otherwise there is no atomic load, leave the library call. */
6188 return NULL_RTX;
6191 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6192 if (!target || target == const0_rtx)
6193 target = gen_reg_rtx (mode);
6195 /* For SEQ_CST, emit a barrier before the load. */
6196 if (is_mm_seq_cst (model))
6197 expand_mem_thread_fence (model);
6199 emit_move_insn (target, mem);
6201 /* Emit the appropriate barrier after the load. */
6202 expand_mem_thread_fence (model);
6204 return target;
6207 /* This function expands the atomic store operation:
6208 Atomically store VAL in MEM.
6209 MEMMODEL is the memory model variant to use.
6210 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6211 function returns const0_rtx if a pattern was emitted. */
6214 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6216 machine_mode mode = GET_MODE (mem);
6217 enum insn_code icode;
6218 struct expand_operand ops[3];
6220 /* If the target supports the store directly, great. */
6221 icode = direct_optab_handler (atomic_store_optab, mode);
6222 if (icode != CODE_FOR_nothing)
6224 create_fixed_operand (&ops[0], mem);
6225 create_input_operand (&ops[1], val, mode);
6226 create_integer_operand (&ops[2], model);
6227 if (maybe_expand_insn (icode, 3, ops))
6228 return const0_rtx;
6231 /* If using __sync_lock_release is a viable alternative, try it. */
6232 if (use_release)
6234 icode = direct_optab_handler (sync_lock_release_optab, mode);
6235 if (icode != CODE_FOR_nothing)
6237 create_fixed_operand (&ops[0], mem);
6238 create_input_operand (&ops[1], const0_rtx, mode);
6239 if (maybe_expand_insn (icode, 2, ops))
6241 /* lock_release is only a release barrier. */
6242 if (is_mm_seq_cst (model))
6243 expand_mem_thread_fence (model);
6244 return const0_rtx;
6249 /* If the size of the object is greater than word size on this target,
6250 a default store will not be atomic, Try a mem_exchange and throw away
6251 the result. If that doesn't work, don't do anything. */
6252 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6254 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6255 if (!target)
6256 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
6257 if (target)
6258 return const0_rtx;
6259 else
6260 return NULL_RTX;
6263 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6264 expand_mem_thread_fence (model);
6266 emit_move_insn (mem, val);
6268 /* For SEQ_CST, also emit a barrier after the store. */
6269 if (is_mm_seq_cst (model))
6270 expand_mem_thread_fence (model);
6272 return const0_rtx;
6276 /* Structure containing the pointers and values required to process the
6277 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6279 struct atomic_op_functions
6281 direct_optab mem_fetch_before;
6282 direct_optab mem_fetch_after;
6283 direct_optab mem_no_result;
6284 optab fetch_before;
6285 optab fetch_after;
6286 direct_optab no_result;
6287 enum rtx_code reverse_code;
6291 /* Fill in structure pointed to by OP with the various optab entries for an
6292 operation of type CODE. */
6294 static void
6295 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6297 gcc_assert (op!= NULL);
6299 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6300 in the source code during compilation, and the optab entries are not
6301 computable until runtime. Fill in the values at runtime. */
6302 switch (code)
6304 case PLUS:
6305 op->mem_fetch_before = atomic_fetch_add_optab;
6306 op->mem_fetch_after = atomic_add_fetch_optab;
6307 op->mem_no_result = atomic_add_optab;
6308 op->fetch_before = sync_old_add_optab;
6309 op->fetch_after = sync_new_add_optab;
6310 op->no_result = sync_add_optab;
6311 op->reverse_code = MINUS;
6312 break;
6313 case MINUS:
6314 op->mem_fetch_before = atomic_fetch_sub_optab;
6315 op->mem_fetch_after = atomic_sub_fetch_optab;
6316 op->mem_no_result = atomic_sub_optab;
6317 op->fetch_before = sync_old_sub_optab;
6318 op->fetch_after = sync_new_sub_optab;
6319 op->no_result = sync_sub_optab;
6320 op->reverse_code = PLUS;
6321 break;
6322 case XOR:
6323 op->mem_fetch_before = atomic_fetch_xor_optab;
6324 op->mem_fetch_after = atomic_xor_fetch_optab;
6325 op->mem_no_result = atomic_xor_optab;
6326 op->fetch_before = sync_old_xor_optab;
6327 op->fetch_after = sync_new_xor_optab;
6328 op->no_result = sync_xor_optab;
6329 op->reverse_code = XOR;
6330 break;
6331 case AND:
6332 op->mem_fetch_before = atomic_fetch_and_optab;
6333 op->mem_fetch_after = atomic_and_fetch_optab;
6334 op->mem_no_result = atomic_and_optab;
6335 op->fetch_before = sync_old_and_optab;
6336 op->fetch_after = sync_new_and_optab;
6337 op->no_result = sync_and_optab;
6338 op->reverse_code = UNKNOWN;
6339 break;
6340 case IOR:
6341 op->mem_fetch_before = atomic_fetch_or_optab;
6342 op->mem_fetch_after = atomic_or_fetch_optab;
6343 op->mem_no_result = atomic_or_optab;
6344 op->fetch_before = sync_old_ior_optab;
6345 op->fetch_after = sync_new_ior_optab;
6346 op->no_result = sync_ior_optab;
6347 op->reverse_code = UNKNOWN;
6348 break;
6349 case NOT:
6350 op->mem_fetch_before = atomic_fetch_nand_optab;
6351 op->mem_fetch_after = atomic_nand_fetch_optab;
6352 op->mem_no_result = atomic_nand_optab;
6353 op->fetch_before = sync_old_nand_optab;
6354 op->fetch_after = sync_new_nand_optab;
6355 op->no_result = sync_nand_optab;
6356 op->reverse_code = UNKNOWN;
6357 break;
6358 default:
6359 gcc_unreachable ();
6363 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6364 using memory order MODEL. If AFTER is true the operation needs to return
6365 the value of *MEM after the operation, otherwise the previous value.
6366 TARGET is an optional place to place the result. The result is unused if
6367 it is const0_rtx.
6368 Return the result if there is a better sequence, otherwise NULL_RTX. */
6370 static rtx
6371 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6372 enum memmodel model, bool after)
6374 /* If the value is prefetched, or not used, it may be possible to replace
6375 the sequence with a native exchange operation. */
6376 if (!after || target == const0_rtx)
6378 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6379 if (code == AND && val == const0_rtx)
6381 if (target == const0_rtx)
6382 target = gen_reg_rtx (GET_MODE (mem));
6383 return maybe_emit_atomic_exchange (target, mem, val, model);
6386 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6387 if (code == IOR && val == constm1_rtx)
6389 if (target == const0_rtx)
6390 target = gen_reg_rtx (GET_MODE (mem));
6391 return maybe_emit_atomic_exchange (target, mem, val, model);
6395 return NULL_RTX;
6398 /* Try to emit an instruction for a specific operation varaition.
6399 OPTAB contains the OP functions.
6400 TARGET is an optional place to return the result. const0_rtx means unused.
6401 MEM is the memory location to operate on.
6402 VAL is the value to use in the operation.
6403 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6404 MODEL is the memory model, if used.
6405 AFTER is true if the returned result is the value after the operation. */
6407 static rtx
6408 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6409 rtx val, bool use_memmodel, enum memmodel model, bool after)
6411 machine_mode mode = GET_MODE (mem);
6412 struct expand_operand ops[4];
6413 enum insn_code icode;
6414 int op_counter = 0;
6415 int num_ops;
6417 /* Check to see if there is a result returned. */
6418 if (target == const0_rtx)
6420 if (use_memmodel)
6422 icode = direct_optab_handler (optab->mem_no_result, mode);
6423 create_integer_operand (&ops[2], model);
6424 num_ops = 3;
6426 else
6428 icode = direct_optab_handler (optab->no_result, mode);
6429 num_ops = 2;
6432 /* Otherwise, we need to generate a result. */
6433 else
6435 if (use_memmodel)
6437 icode = direct_optab_handler (after ? optab->mem_fetch_after
6438 : optab->mem_fetch_before, mode);
6439 create_integer_operand (&ops[3], model);
6440 num_ops = 4;
6442 else
6444 icode = optab_handler (after ? optab->fetch_after
6445 : optab->fetch_before, mode);
6446 num_ops = 3;
6448 create_output_operand (&ops[op_counter++], target, mode);
6450 if (icode == CODE_FOR_nothing)
6451 return NULL_RTX;
6453 create_fixed_operand (&ops[op_counter++], mem);
6454 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6455 create_convert_operand_to (&ops[op_counter++], val, mode, true);
6457 if (maybe_expand_insn (icode, num_ops, ops))
6458 return (target == const0_rtx ? const0_rtx : ops[0].value);
6460 return NULL_RTX;
6464 /* This function expands an atomic fetch_OP or OP_fetch operation:
6465 TARGET is an option place to stick the return value. const0_rtx indicates
6466 the result is unused.
6467 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6468 CODE is the operation being performed (OP)
6469 MEMMODEL is the memory model variant to use.
6470 AFTER is true to return the result of the operation (OP_fetch).
6471 AFTER is false to return the value before the operation (fetch_OP).
6473 This function will *only* generate instructions if there is a direct
6474 optab. No compare and swap loops or libcalls will be generated. */
6476 static rtx
6477 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6478 enum rtx_code code, enum memmodel model,
6479 bool after)
6481 machine_mode mode = GET_MODE (mem);
6482 struct atomic_op_functions optab;
6483 rtx result;
6484 bool unused_result = (target == const0_rtx);
6486 get_atomic_op_for_code (&optab, code);
6488 /* Check to see if there are any better instructions. */
6489 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6490 if (result)
6491 return result;
6493 /* Check for the case where the result isn't used and try those patterns. */
6494 if (unused_result)
6496 /* Try the memory model variant first. */
6497 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6498 if (result)
6499 return result;
6501 /* Next try the old style withuot a memory model. */
6502 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6503 if (result)
6504 return result;
6506 /* There is no no-result pattern, so try patterns with a result. */
6507 target = NULL_RTX;
6510 /* Try the __atomic version. */
6511 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6512 if (result)
6513 return result;
6515 /* Try the older __sync version. */
6516 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6517 if (result)
6518 return result;
6520 /* If the fetch value can be calculated from the other variation of fetch,
6521 try that operation. */
6522 if (after || unused_result || optab.reverse_code != UNKNOWN)
6524 /* Try the __atomic version, then the older __sync version. */
6525 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6526 if (!result)
6527 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6529 if (result)
6531 /* If the result isn't used, no need to do compensation code. */
6532 if (unused_result)
6533 return result;
6535 /* Issue compensation code. Fetch_after == fetch_before OP val.
6536 Fetch_before == after REVERSE_OP val. */
6537 if (!after)
6538 code = optab.reverse_code;
6539 if (code == NOT)
6541 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6542 true, OPTAB_LIB_WIDEN);
6543 result = expand_simple_unop (mode, NOT, result, target, true);
6545 else
6546 result = expand_simple_binop (mode, code, result, val, target,
6547 true, OPTAB_LIB_WIDEN);
6548 return result;
6552 /* No direct opcode can be generated. */
6553 return NULL_RTX;
6558 /* This function expands an atomic fetch_OP or OP_fetch operation:
6559 TARGET is an option place to stick the return value. const0_rtx indicates
6560 the result is unused.
6561 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6562 CODE is the operation being performed (OP)
6563 MEMMODEL is the memory model variant to use.
6564 AFTER is true to return the result of the operation (OP_fetch).
6565 AFTER is false to return the value before the operation (fetch_OP). */
6567 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6568 enum memmodel model, bool after)
6570 machine_mode mode = GET_MODE (mem);
6571 rtx result;
6572 bool unused_result = (target == const0_rtx);
6574 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6575 after);
6577 if (result)
6578 return result;
6580 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6581 if (code == PLUS || code == MINUS)
6583 rtx tmp;
6584 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6586 start_sequence ();
6587 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6588 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6589 model, after);
6590 if (result)
6592 /* PLUS worked so emit the insns and return. */
6593 tmp = get_insns ();
6594 end_sequence ();
6595 emit_insn (tmp);
6596 return result;
6599 /* PLUS did not work, so throw away the negation code and continue. */
6600 end_sequence ();
6603 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6604 if (!can_compare_and_swap_p (mode, false))
6606 rtx libfunc;
6607 bool fixup = false;
6608 enum rtx_code orig_code = code;
6609 struct atomic_op_functions optab;
6611 get_atomic_op_for_code (&optab, code);
6612 libfunc = optab_libfunc (after ? optab.fetch_after
6613 : optab.fetch_before, mode);
6614 if (libfunc == NULL
6615 && (after || unused_result || optab.reverse_code != UNKNOWN))
6617 fixup = true;
6618 if (!after)
6619 code = optab.reverse_code;
6620 libfunc = optab_libfunc (after ? optab.fetch_before
6621 : optab.fetch_after, mode);
6623 if (libfunc != NULL)
6625 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6626 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
6627 2, addr, ptr_mode, val, mode);
6629 if (!unused_result && fixup)
6630 result = expand_simple_binop (mode, code, result, val, target,
6631 true, OPTAB_LIB_WIDEN);
6632 return result;
6635 /* We need the original code for any further attempts. */
6636 code = orig_code;
6639 /* If nothing else has succeeded, default to a compare and swap loop. */
6640 if (can_compare_and_swap_p (mode, true))
6642 rtx_insn *insn;
6643 rtx t0 = gen_reg_rtx (mode), t1;
6645 start_sequence ();
6647 /* If the result is used, get a register for it. */
6648 if (!unused_result)
6650 if (!target || !register_operand (target, mode))
6651 target = gen_reg_rtx (mode);
6652 /* If fetch_before, copy the value now. */
6653 if (!after)
6654 emit_move_insn (target, t0);
6656 else
6657 target = const0_rtx;
6659 t1 = t0;
6660 if (code == NOT)
6662 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
6663 true, OPTAB_LIB_WIDEN);
6664 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
6666 else
6667 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
6668 OPTAB_LIB_WIDEN);
6670 /* For after, copy the value now. */
6671 if (!unused_result && after)
6672 emit_move_insn (target, t1);
6673 insn = get_insns ();
6674 end_sequence ();
6676 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6677 return target;
6680 return NULL_RTX;
6683 /* Return true if OPERAND is suitable for operand number OPNO of
6684 instruction ICODE. */
6686 bool
6687 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
6689 return (!insn_data[(int) icode].operand[opno].predicate
6690 || (insn_data[(int) icode].operand[opno].predicate
6691 (operand, insn_data[(int) icode].operand[opno].mode)));
6694 /* TARGET is a target of a multiword operation that we are going to
6695 implement as a series of word-mode operations. Return true if
6696 TARGET is suitable for this purpose. */
6698 bool
6699 valid_multiword_target_p (rtx target)
6701 machine_mode mode;
6702 int i;
6704 mode = GET_MODE (target);
6705 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
6706 if (!validate_subreg (word_mode, mode, target, i))
6707 return false;
6708 return true;
6711 /* Like maybe_legitimize_operand, but do not change the code of the
6712 current rtx value. */
6714 static bool
6715 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
6716 struct expand_operand *op)
6718 /* See if the operand matches in its current form. */
6719 if (insn_operand_matches (icode, opno, op->value))
6720 return true;
6722 /* If the operand is a memory whose address has no side effects,
6723 try forcing the address into a non-virtual pseudo register.
6724 The check for side effects is important because copy_to_mode_reg
6725 cannot handle things like auto-modified addresses. */
6726 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
6728 rtx addr, mem;
6730 mem = op->value;
6731 addr = XEXP (mem, 0);
6732 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
6733 && !side_effects_p (addr))
6735 rtx_insn *last;
6736 machine_mode mode;
6738 last = get_last_insn ();
6739 mode = get_address_mode (mem);
6740 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
6741 if (insn_operand_matches (icode, opno, mem))
6743 op->value = mem;
6744 return true;
6746 delete_insns_since (last);
6750 return false;
6753 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6754 on success, storing the new operand value back in OP. */
6756 static bool
6757 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
6758 struct expand_operand *op)
6760 machine_mode mode, imode;
6761 bool old_volatile_ok, result;
6763 mode = op->mode;
6764 switch (op->type)
6766 case EXPAND_FIXED:
6767 old_volatile_ok = volatile_ok;
6768 volatile_ok = true;
6769 result = maybe_legitimize_operand_same_code (icode, opno, op);
6770 volatile_ok = old_volatile_ok;
6771 return result;
6773 case EXPAND_OUTPUT:
6774 gcc_assert (mode != VOIDmode);
6775 if (op->value
6776 && op->value != const0_rtx
6777 && GET_MODE (op->value) == mode
6778 && maybe_legitimize_operand_same_code (icode, opno, op))
6779 return true;
6781 op->value = gen_reg_rtx (mode);
6782 break;
6784 case EXPAND_INPUT:
6785 input:
6786 gcc_assert (mode != VOIDmode);
6787 gcc_assert (GET_MODE (op->value) == VOIDmode
6788 || GET_MODE (op->value) == mode);
6789 if (maybe_legitimize_operand_same_code (icode, opno, op))
6790 return true;
6792 op->value = copy_to_mode_reg (mode, op->value);
6793 break;
6795 case EXPAND_CONVERT_TO:
6796 gcc_assert (mode != VOIDmode);
6797 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
6798 goto input;
6800 case EXPAND_CONVERT_FROM:
6801 if (GET_MODE (op->value) != VOIDmode)
6802 mode = GET_MODE (op->value);
6803 else
6804 /* The caller must tell us what mode this value has. */
6805 gcc_assert (mode != VOIDmode);
6807 imode = insn_data[(int) icode].operand[opno].mode;
6808 if (imode != VOIDmode && imode != mode)
6810 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
6811 mode = imode;
6813 goto input;
6815 case EXPAND_ADDRESS:
6816 gcc_assert (mode != VOIDmode);
6817 op->value = convert_memory_address (mode, op->value);
6818 goto input;
6820 case EXPAND_INTEGER:
6821 mode = insn_data[(int) icode].operand[opno].mode;
6822 if (mode != VOIDmode && const_int_operand (op->value, mode))
6823 goto input;
6824 break;
6826 return insn_operand_matches (icode, opno, op->value);
6829 /* Make OP describe an input operand that should have the same value
6830 as VALUE, after any mode conversion that the target might request.
6831 TYPE is the type of VALUE. */
6833 void
6834 create_convert_operand_from_type (struct expand_operand *op,
6835 rtx value, tree type)
6837 create_convert_operand_from (op, value, TYPE_MODE (type),
6838 TYPE_UNSIGNED (type));
6841 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
6842 of instruction ICODE. Return true on success, leaving the new operand
6843 values in the OPS themselves. Emit no code on failure. */
6845 bool
6846 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
6847 unsigned int nops, struct expand_operand *ops)
6849 rtx_insn *last;
6850 unsigned int i;
6852 last = get_last_insn ();
6853 for (i = 0; i < nops; i++)
6854 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
6856 delete_insns_since (last);
6857 return false;
6859 return true;
6862 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
6863 as its operands. Return the instruction pattern on success,
6864 and emit any necessary set-up code. Return null and emit no
6865 code on failure. */
6867 rtx_insn *
6868 maybe_gen_insn (enum insn_code icode, unsigned int nops,
6869 struct expand_operand *ops)
6871 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
6872 if (!maybe_legitimize_operands (icode, 0, nops, ops))
6873 return NULL;
6875 switch (nops)
6877 case 1:
6878 return GEN_FCN (icode) (ops[0].value);
6879 case 2:
6880 return GEN_FCN (icode) (ops[0].value, ops[1].value);
6881 case 3:
6882 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
6883 case 4:
6884 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6885 ops[3].value);
6886 case 5:
6887 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6888 ops[3].value, ops[4].value);
6889 case 6:
6890 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6891 ops[3].value, ops[4].value, ops[5].value);
6892 case 7:
6893 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6894 ops[3].value, ops[4].value, ops[5].value,
6895 ops[6].value);
6896 case 8:
6897 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6898 ops[3].value, ops[4].value, ops[5].value,
6899 ops[6].value, ops[7].value);
6900 case 9:
6901 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6902 ops[3].value, ops[4].value, ops[5].value,
6903 ops[6].value, ops[7].value, ops[8].value);
6905 gcc_unreachable ();
6908 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
6909 as its operands. Return true on success and emit no code on failure. */
6911 bool
6912 maybe_expand_insn (enum insn_code icode, unsigned int nops,
6913 struct expand_operand *ops)
6915 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6916 if (pat)
6918 emit_insn (pat);
6919 return true;
6921 return false;
6924 /* Like maybe_expand_insn, but for jumps. */
6926 bool
6927 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
6928 struct expand_operand *ops)
6930 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6931 if (pat)
6933 emit_jump_insn (pat);
6934 return true;
6936 return false;
6939 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
6940 as its operands. */
6942 void
6943 expand_insn (enum insn_code icode, unsigned int nops,
6944 struct expand_operand *ops)
6946 if (!maybe_expand_insn (icode, nops, ops))
6947 gcc_unreachable ();
6950 /* Like expand_insn, but for jumps. */
6952 void
6953 expand_jump_insn (enum insn_code icode, unsigned int nops,
6954 struct expand_operand *ops)
6956 if (!maybe_expand_jump_insn (icode, nops, ops))
6957 gcc_unreachable ();