S/390: Deprecate g5 and g6 CPU levels
[official-gcc.git] / gcc / optabs.c
blob8cc4802f339f9d0cb6f51c018cfa539623f7556e
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 popcount of a double-word quantity as two popcount's of
2227 word-sized quantities and summing up the results. */
2228 static rtx
2229 expand_doubleword_popcount (machine_mode mode, rtx op0, rtx target)
2231 rtx t0, t1, t;
2232 rtx_insn *seq;
2234 start_sequence ();
2236 t0 = expand_unop_direct (word_mode, popcount_optab,
2237 operand_subword_force (op0, 0, mode), NULL_RTX,
2238 true);
2239 t1 = expand_unop_direct (word_mode, popcount_optab,
2240 operand_subword_force (op0, 1, mode), NULL_RTX,
2241 true);
2242 if (!t0 || !t1)
2244 end_sequence ();
2245 return NULL_RTX;
2248 /* If we were not given a target, use a word_mode register, not a
2249 'mode' register. The result will fit, and nobody is expecting
2250 anything bigger (the return type of __builtin_popcount* is int). */
2251 if (!target)
2252 target = gen_reg_rtx (word_mode);
2254 t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
2256 seq = get_insns ();
2257 end_sequence ();
2259 add_equal_note (seq, t, POPCOUNT, op0, 0);
2260 emit_insn (seq);
2261 return t;
2264 /* Try calculating
2265 (parity:wide x)
2267 (parity:narrow (low (x) ^ high (x))) */
2268 static rtx
2269 expand_doubleword_parity (machine_mode mode, rtx op0, rtx target)
2271 rtx t = expand_binop (word_mode, xor_optab,
2272 operand_subword_force (op0, 0, mode),
2273 operand_subword_force (op0, 1, mode),
2274 NULL_RTX, 0, OPTAB_DIRECT);
2275 return expand_unop (word_mode, parity_optab, t, target, true);
2278 /* Try calculating
2279 (bswap:narrow x)
2281 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2282 static rtx
2283 widen_bswap (machine_mode mode, rtx op0, rtx target)
2285 enum mode_class mclass = GET_MODE_CLASS (mode);
2286 machine_mode wider_mode;
2287 rtx x;
2288 rtx_insn *last;
2290 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2291 return NULL_RTX;
2293 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2294 wider_mode != VOIDmode;
2295 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2296 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2297 goto found;
2298 return NULL_RTX;
2300 found:
2301 last = get_last_insn ();
2303 x = widen_operand (op0, wider_mode, mode, true, true);
2304 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2306 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2307 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2308 if (x != 0)
2309 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2310 GET_MODE_BITSIZE (wider_mode)
2311 - GET_MODE_BITSIZE (mode),
2312 NULL_RTX, true);
2314 if (x != 0)
2316 if (target == 0)
2317 target = gen_reg_rtx (mode);
2318 emit_move_insn (target, gen_lowpart (mode, x));
2320 else
2321 delete_insns_since (last);
2323 return target;
2326 /* Try calculating bswap as two bswaps of two word-sized operands. */
2328 static rtx
2329 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2331 rtx t0, t1;
2333 t1 = expand_unop (word_mode, bswap_optab,
2334 operand_subword_force (op, 0, mode), NULL_RTX, true);
2335 t0 = expand_unop (word_mode, bswap_optab,
2336 operand_subword_force (op, 1, mode), NULL_RTX, true);
2338 if (target == 0 || !valid_multiword_target_p (target))
2339 target = gen_reg_rtx (mode);
2340 if (REG_P (target))
2341 emit_clobber (target);
2342 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2343 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2345 return target;
2348 /* Try calculating (parity x) as (and (popcount x) 1), where
2349 popcount can also be done in a wider mode. */
2350 static rtx
2351 expand_parity (machine_mode mode, rtx op0, rtx target)
2353 enum mode_class mclass = GET_MODE_CLASS (mode);
2354 if (CLASS_HAS_WIDER_MODES_P (mclass))
2356 machine_mode wider_mode;
2357 for (wider_mode = mode; wider_mode != VOIDmode;
2358 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2360 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2362 rtx xop0, temp;
2363 rtx_insn *last;
2365 last = get_last_insn ();
2367 if (target == 0)
2368 target = gen_reg_rtx (mode);
2369 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2370 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2371 true);
2372 if (temp != 0)
2373 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2374 target, true, OPTAB_DIRECT);
2375 if (temp == 0)
2376 delete_insns_since (last);
2378 return temp;
2382 return 0;
2385 /* Try calculating ctz(x) as K - clz(x & -x) ,
2386 where K is GET_MODE_PRECISION(mode) - 1.
2388 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2389 don't have to worry about what the hardware does in that case. (If
2390 the clz instruction produces the usual value at 0, which is K, the
2391 result of this code sequence will be -1; expand_ffs, below, relies
2392 on this. It might be nice to have it be K instead, for consistency
2393 with the (very few) processors that provide a ctz with a defined
2394 value, but that would take one more instruction, and it would be
2395 less convenient for expand_ffs anyway. */
2397 static rtx
2398 expand_ctz (machine_mode mode, rtx op0, rtx target)
2400 rtx_insn *seq;
2401 rtx temp;
2403 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2404 return 0;
2406 start_sequence ();
2408 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2409 if (temp)
2410 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2411 true, OPTAB_DIRECT);
2412 if (temp)
2413 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2414 if (temp)
2415 temp = expand_binop (mode, sub_optab,
2416 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2417 temp, target,
2418 true, OPTAB_DIRECT);
2419 if (temp == 0)
2421 end_sequence ();
2422 return 0;
2425 seq = get_insns ();
2426 end_sequence ();
2428 add_equal_note (seq, temp, CTZ, op0, 0);
2429 emit_insn (seq);
2430 return temp;
2434 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2435 else with the sequence used by expand_clz.
2437 The ffs builtin promises to return zero for a zero value and ctz/clz
2438 may have an undefined value in that case. If they do not give us a
2439 convenient value, we have to generate a test and branch. */
2440 static rtx
2441 expand_ffs (machine_mode mode, rtx op0, rtx target)
2443 HOST_WIDE_INT val = 0;
2444 bool defined_at_zero = false;
2445 rtx temp;
2446 rtx_insn *seq;
2448 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2450 start_sequence ();
2452 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2453 if (!temp)
2454 goto fail;
2456 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2458 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2460 start_sequence ();
2461 temp = expand_ctz (mode, op0, 0);
2462 if (!temp)
2463 goto fail;
2465 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2467 defined_at_zero = true;
2468 val = (GET_MODE_PRECISION (mode) - 1) - val;
2471 else
2472 return 0;
2474 if (defined_at_zero && val == -1)
2475 /* No correction needed at zero. */;
2476 else
2478 /* We don't try to do anything clever with the situation found
2479 on some processors (eg Alpha) where ctz(0:mode) ==
2480 bitsize(mode). If someone can think of a way to send N to -1
2481 and leave alone all values in the range 0..N-1 (where N is a
2482 power of two), cheaper than this test-and-branch, please add it.
2484 The test-and-branch is done after the operation itself, in case
2485 the operation sets condition codes that can be recycled for this.
2486 (This is true on i386, for instance.) */
2488 rtx_code_label *nonzero_label = gen_label_rtx ();
2489 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2490 mode, true, nonzero_label);
2492 convert_move (temp, GEN_INT (-1), false);
2493 emit_label (nonzero_label);
2496 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2497 to produce a value in the range 0..bitsize. */
2498 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2499 target, false, OPTAB_DIRECT);
2500 if (!temp)
2501 goto fail;
2503 seq = get_insns ();
2504 end_sequence ();
2506 add_equal_note (seq, temp, FFS, op0, 0);
2507 emit_insn (seq);
2508 return temp;
2510 fail:
2511 end_sequence ();
2512 return 0;
2515 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2516 conditions, VAL may already be a SUBREG against which we cannot generate
2517 a further SUBREG. In this case, we expect forcing the value into a
2518 register will work around the situation. */
2520 static rtx
2521 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2522 machine_mode imode)
2524 rtx ret;
2525 ret = lowpart_subreg (omode, val, imode);
2526 if (ret == NULL)
2528 val = force_reg (imode, val);
2529 ret = lowpart_subreg (omode, val, imode);
2530 gcc_assert (ret != NULL);
2532 return ret;
2535 /* Expand a floating point absolute value or negation operation via a
2536 logical operation on the sign bit. */
2538 static rtx
2539 expand_absneg_bit (enum rtx_code code, machine_mode mode,
2540 rtx op0, rtx target)
2542 const struct real_format *fmt;
2543 int bitpos, word, nwords, i;
2544 machine_mode imode;
2545 rtx temp;
2546 rtx_insn *insns;
2548 /* The format has to have a simple sign bit. */
2549 fmt = REAL_MODE_FORMAT (mode);
2550 if (fmt == NULL)
2551 return NULL_RTX;
2553 bitpos = fmt->signbit_rw;
2554 if (bitpos < 0)
2555 return NULL_RTX;
2557 /* Don't create negative zeros if the format doesn't support them. */
2558 if (code == NEG && !fmt->has_signed_zero)
2559 return NULL_RTX;
2561 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2563 imode = int_mode_for_mode (mode);
2564 if (imode == BLKmode)
2565 return NULL_RTX;
2566 word = 0;
2567 nwords = 1;
2569 else
2571 imode = word_mode;
2573 if (FLOAT_WORDS_BIG_ENDIAN)
2574 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2575 else
2576 word = bitpos / BITS_PER_WORD;
2577 bitpos = bitpos % BITS_PER_WORD;
2578 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2581 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2582 if (code == ABS)
2583 mask = ~mask;
2585 if (target == 0
2586 || target == op0
2587 || (nwords > 1 && !valid_multiword_target_p (target)))
2588 target = gen_reg_rtx (mode);
2590 if (nwords > 1)
2592 start_sequence ();
2594 for (i = 0; i < nwords; ++i)
2596 rtx targ_piece = operand_subword (target, i, 1, mode);
2597 rtx op0_piece = operand_subword_force (op0, i, mode);
2599 if (i == word)
2601 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2602 op0_piece,
2603 immed_wide_int_const (mask, imode),
2604 targ_piece, 1, OPTAB_LIB_WIDEN);
2605 if (temp != targ_piece)
2606 emit_move_insn (targ_piece, temp);
2608 else
2609 emit_move_insn (targ_piece, op0_piece);
2612 insns = get_insns ();
2613 end_sequence ();
2615 emit_insn (insns);
2617 else
2619 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2620 gen_lowpart (imode, op0),
2621 immed_wide_int_const (mask, imode),
2622 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2623 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2625 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2626 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2627 target);
2630 return target;
2633 /* As expand_unop, but will fail rather than attempt the operation in a
2634 different mode or with a libcall. */
2635 static rtx
2636 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2637 int unsignedp)
2639 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2641 struct expand_operand ops[2];
2642 enum insn_code icode = optab_handler (unoptab, mode);
2643 rtx_insn *last = get_last_insn ();
2644 rtx_insn *pat;
2646 create_output_operand (&ops[0], target, mode);
2647 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2648 pat = maybe_gen_insn (icode, 2, ops);
2649 if (pat)
2651 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2652 && ! add_equal_note (pat, ops[0].value,
2653 optab_to_code (unoptab),
2654 ops[1].value, NULL_RTX))
2656 delete_insns_since (last);
2657 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2660 emit_insn (pat);
2662 return ops[0].value;
2665 return 0;
2668 /* Generate code to perform an operation specified by UNOPTAB
2669 on operand OP0, with result having machine-mode MODE.
2671 UNSIGNEDP is for the case where we have to widen the operands
2672 to perform the operation. It says to use zero-extension.
2674 If TARGET is nonzero, the value
2675 is generated there, if it is convenient to do so.
2676 In all cases an rtx is returned for the locus of the value;
2677 this may or may not be TARGET. */
2680 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2681 int unsignedp)
2683 enum mode_class mclass = GET_MODE_CLASS (mode);
2684 machine_mode wider_mode;
2685 rtx temp;
2686 rtx libfunc;
2688 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2689 if (temp)
2690 return temp;
2692 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2694 /* Widening (or narrowing) clz needs special treatment. */
2695 if (unoptab == clz_optab)
2697 temp = widen_leading (mode, op0, target, unoptab);
2698 if (temp)
2699 return temp;
2701 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2702 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2704 temp = expand_doubleword_clz (mode, op0, target);
2705 if (temp)
2706 return temp;
2709 goto try_libcall;
2712 if (unoptab == clrsb_optab)
2714 temp = widen_leading (mode, op0, target, unoptab);
2715 if (temp)
2716 return temp;
2717 goto try_libcall;
2720 if (unoptab == popcount_optab
2721 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2722 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2723 && optimize_insn_for_speed_p ())
2725 temp = expand_doubleword_popcount (mode, op0, target);
2726 if (temp)
2727 return temp;
2730 if (unoptab == parity_optab
2731 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2732 && (optab_handler (unoptab, word_mode) != CODE_FOR_nothing
2733 || optab_handler (popcount_optab, word_mode) != CODE_FOR_nothing)
2734 && optimize_insn_for_speed_p ())
2736 temp = expand_doubleword_parity (mode, op0, target);
2737 if (temp)
2738 return temp;
2741 /* Widening (or narrowing) bswap needs special treatment. */
2742 if (unoptab == bswap_optab)
2744 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2745 or ROTATERT. First try these directly; if this fails, then try the
2746 obvious pair of shifts with allowed widening, as this will probably
2747 be always more efficient than the other fallback methods. */
2748 if (mode == HImode)
2750 rtx_insn *last;
2751 rtx temp1, temp2;
2753 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2755 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
2756 unsignedp, OPTAB_DIRECT);
2757 if (temp)
2758 return temp;
2761 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2763 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
2764 unsignedp, OPTAB_DIRECT);
2765 if (temp)
2766 return temp;
2769 last = get_last_insn ();
2771 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
2772 unsignedp, OPTAB_WIDEN);
2773 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
2774 unsignedp, OPTAB_WIDEN);
2775 if (temp1 && temp2)
2777 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2778 unsignedp, OPTAB_WIDEN);
2779 if (temp)
2780 return temp;
2783 delete_insns_since (last);
2786 temp = widen_bswap (mode, op0, target);
2787 if (temp)
2788 return temp;
2790 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2791 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2793 temp = expand_doubleword_bswap (mode, op0, target);
2794 if (temp)
2795 return temp;
2798 goto try_libcall;
2801 if (CLASS_HAS_WIDER_MODES_P (mclass))
2802 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2803 wider_mode != VOIDmode;
2804 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2806 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2808 rtx xop0 = op0;
2809 rtx_insn *last = get_last_insn ();
2811 /* For certain operations, we need not actually extend
2812 the narrow operand, as long as we will truncate the
2813 results to the same narrowness. */
2815 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2816 (unoptab == neg_optab
2817 || unoptab == one_cmpl_optab)
2818 && mclass == MODE_INT);
2820 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2821 unsignedp);
2823 if (temp)
2825 if (mclass != MODE_INT
2826 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2828 if (target == 0)
2829 target = gen_reg_rtx (mode);
2830 convert_move (target, temp, 0);
2831 return target;
2833 else
2834 return gen_lowpart (mode, temp);
2836 else
2837 delete_insns_since (last);
2841 /* These can be done a word at a time. */
2842 if (unoptab == one_cmpl_optab
2843 && mclass == MODE_INT
2844 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2845 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2847 int i;
2848 rtx_insn *insns;
2850 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2851 target = gen_reg_rtx (mode);
2853 start_sequence ();
2855 /* Do the actual arithmetic. */
2856 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2858 rtx target_piece = operand_subword (target, i, 1, mode);
2859 rtx x = expand_unop (word_mode, unoptab,
2860 operand_subword_force (op0, i, mode),
2861 target_piece, unsignedp);
2863 if (target_piece != x)
2864 emit_move_insn (target_piece, x);
2867 insns = get_insns ();
2868 end_sequence ();
2870 emit_insn (insns);
2871 return target;
2874 if (optab_to_code (unoptab) == NEG)
2876 /* Try negating floating point values by flipping the sign bit. */
2877 if (SCALAR_FLOAT_MODE_P (mode))
2879 temp = expand_absneg_bit (NEG, mode, op0, target);
2880 if (temp)
2881 return temp;
2884 /* If there is no negation pattern, and we have no negative zero,
2885 try subtracting from zero. */
2886 if (!HONOR_SIGNED_ZEROS (mode))
2888 temp = expand_binop (mode, (unoptab == negv_optab
2889 ? subv_optab : sub_optab),
2890 CONST0_RTX (mode), op0, target,
2891 unsignedp, OPTAB_DIRECT);
2892 if (temp)
2893 return temp;
2897 /* Try calculating parity (x) as popcount (x) % 2. */
2898 if (unoptab == parity_optab)
2900 temp = expand_parity (mode, op0, target);
2901 if (temp)
2902 return temp;
2905 /* Try implementing ffs (x) in terms of clz (x). */
2906 if (unoptab == ffs_optab)
2908 temp = expand_ffs (mode, op0, target);
2909 if (temp)
2910 return temp;
2913 /* Try implementing ctz (x) in terms of clz (x). */
2914 if (unoptab == ctz_optab)
2916 temp = expand_ctz (mode, op0, target);
2917 if (temp)
2918 return temp;
2921 try_libcall:
2922 /* Now try a library call in this mode. */
2923 libfunc = optab_libfunc (unoptab, mode);
2924 if (libfunc)
2926 rtx_insn *insns;
2927 rtx value;
2928 rtx eq_value;
2929 machine_mode outmode = mode;
2931 /* All of these functions return small values. Thus we choose to
2932 have them return something that isn't a double-word. */
2933 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2934 || unoptab == clrsb_optab || unoptab == popcount_optab
2935 || unoptab == parity_optab)
2936 outmode
2937 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
2938 optab_libfunc (unoptab, mode)));
2940 start_sequence ();
2942 /* Pass 1 for NO_QUEUE so we don't lose any increments
2943 if the libcall is cse'd or moved. */
2944 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
2945 1, op0, mode);
2946 insns = get_insns ();
2947 end_sequence ();
2949 target = gen_reg_rtx (outmode);
2950 bool trapv = trapv_unoptab_p (unoptab);
2951 if (trapv)
2952 eq_value = NULL_RTX;
2953 else
2955 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
2956 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
2957 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
2958 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
2959 eq_value = simplify_gen_unary (ZERO_EXTEND,
2960 outmode, eq_value, mode);
2962 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
2964 return target;
2967 /* It can't be done in this mode. Can we do it in a wider mode? */
2969 if (CLASS_HAS_WIDER_MODES_P (mclass))
2971 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2972 wider_mode != VOIDmode;
2973 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2975 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
2976 || optab_libfunc (unoptab, wider_mode))
2978 rtx xop0 = op0;
2979 rtx_insn *last = get_last_insn ();
2981 /* For certain operations, we need not actually extend
2982 the narrow operand, as long as we will truncate the
2983 results to the same narrowness. */
2984 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2985 (unoptab == neg_optab
2986 || unoptab == one_cmpl_optab
2987 || unoptab == bswap_optab)
2988 && mclass == MODE_INT);
2990 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2991 unsignedp);
2993 /* If we are generating clz using wider mode, adjust the
2994 result. Similarly for clrsb. */
2995 if ((unoptab == clz_optab || unoptab == clrsb_optab)
2996 && temp != 0)
2997 temp = expand_binop
2998 (wider_mode, sub_optab, temp,
2999 gen_int_mode (GET_MODE_PRECISION (wider_mode)
3000 - GET_MODE_PRECISION (mode),
3001 wider_mode),
3002 target, true, OPTAB_DIRECT);
3004 /* Likewise for bswap. */
3005 if (unoptab == bswap_optab && temp != 0)
3007 gcc_assert (GET_MODE_PRECISION (wider_mode)
3008 == GET_MODE_BITSIZE (wider_mode)
3009 && GET_MODE_PRECISION (mode)
3010 == GET_MODE_BITSIZE (mode));
3012 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
3013 GET_MODE_BITSIZE (wider_mode)
3014 - GET_MODE_BITSIZE (mode),
3015 NULL_RTX, true);
3018 if (temp)
3020 if (mclass != MODE_INT)
3022 if (target == 0)
3023 target = gen_reg_rtx (mode);
3024 convert_move (target, temp, 0);
3025 return target;
3027 else
3028 return gen_lowpart (mode, temp);
3030 else
3031 delete_insns_since (last);
3036 /* One final attempt at implementing negation via subtraction,
3037 this time allowing widening of the operand. */
3038 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
3040 rtx temp;
3041 temp = expand_binop (mode,
3042 unoptab == negv_optab ? subv_optab : sub_optab,
3043 CONST0_RTX (mode), op0,
3044 target, unsignedp, OPTAB_LIB_WIDEN);
3045 if (temp)
3046 return temp;
3049 return 0;
3052 /* Emit code to compute the absolute value of OP0, with result to
3053 TARGET if convenient. (TARGET may be 0.) The return value says
3054 where the result actually is to be found.
3056 MODE is the mode of the operand; the mode of the result is
3057 different but can be deduced from MODE.
3062 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
3063 int result_unsignedp)
3065 rtx temp;
3067 if (GET_MODE_CLASS (mode) != MODE_INT
3068 || ! flag_trapv)
3069 result_unsignedp = 1;
3071 /* First try to do it with a special abs instruction. */
3072 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3073 op0, target, 0);
3074 if (temp != 0)
3075 return temp;
3077 /* For floating point modes, try clearing the sign bit. */
3078 if (SCALAR_FLOAT_MODE_P (mode))
3080 temp = expand_absneg_bit (ABS, mode, op0, target);
3081 if (temp)
3082 return temp;
3085 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3086 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3087 && !HONOR_SIGNED_ZEROS (mode))
3089 rtx_insn *last = get_last_insn ();
3091 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3092 op0, NULL_RTX, 0);
3093 if (temp != 0)
3094 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3095 OPTAB_WIDEN);
3097 if (temp != 0)
3098 return temp;
3100 delete_insns_since (last);
3103 /* If this machine has expensive jumps, we can do integer absolute
3104 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3105 where W is the width of MODE. */
3107 if (GET_MODE_CLASS (mode) == MODE_INT
3108 && BRANCH_COST (optimize_insn_for_speed_p (),
3109 false) >= 2)
3111 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3112 GET_MODE_PRECISION (mode) - 1,
3113 NULL_RTX, 0);
3115 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3116 OPTAB_LIB_WIDEN);
3117 if (temp != 0)
3118 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3119 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3121 if (temp != 0)
3122 return temp;
3125 return NULL_RTX;
3129 expand_abs (machine_mode mode, rtx op0, rtx target,
3130 int result_unsignedp, int safe)
3132 rtx temp;
3133 rtx_code_label *op1;
3135 if (GET_MODE_CLASS (mode) != MODE_INT
3136 || ! flag_trapv)
3137 result_unsignedp = 1;
3139 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3140 if (temp != 0)
3141 return temp;
3143 /* If that does not win, use conditional jump and negate. */
3145 /* It is safe to use the target if it is the same
3146 as the source if this is also a pseudo register */
3147 if (op0 == target && REG_P (op0)
3148 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3149 safe = 1;
3151 op1 = gen_label_rtx ();
3152 if (target == 0 || ! safe
3153 || GET_MODE (target) != mode
3154 || (MEM_P (target) && MEM_VOLATILE_P (target))
3155 || (REG_P (target)
3156 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3157 target = gen_reg_rtx (mode);
3159 emit_move_insn (target, op0);
3160 NO_DEFER_POP;
3162 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3163 NULL_RTX, NULL, op1, -1);
3165 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3166 target, target, 0);
3167 if (op0 != target)
3168 emit_move_insn (target, op0);
3169 emit_label (op1);
3170 OK_DEFER_POP;
3171 return target;
3174 /* Emit code to compute the one's complement absolute value of OP0
3175 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3176 (TARGET may be NULL_RTX.) The return value says where the result
3177 actually is to be found.
3179 MODE is the mode of the operand; the mode of the result is
3180 different but can be deduced from MODE. */
3183 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3185 rtx temp;
3187 /* Not applicable for floating point modes. */
3188 if (FLOAT_MODE_P (mode))
3189 return NULL_RTX;
3191 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3192 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3194 rtx_insn *last = get_last_insn ();
3196 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3197 if (temp != 0)
3198 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3199 OPTAB_WIDEN);
3201 if (temp != 0)
3202 return temp;
3204 delete_insns_since (last);
3207 /* If this machine has expensive jumps, we can do one's complement
3208 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3210 if (GET_MODE_CLASS (mode) == MODE_INT
3211 && BRANCH_COST (optimize_insn_for_speed_p (),
3212 false) >= 2)
3214 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3215 GET_MODE_PRECISION (mode) - 1,
3216 NULL_RTX, 0);
3218 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3219 OPTAB_LIB_WIDEN);
3221 if (temp != 0)
3222 return temp;
3225 return NULL_RTX;
3228 /* A subroutine of expand_copysign, perform the copysign operation using the
3229 abs and neg primitives advertised to exist on the target. The assumption
3230 is that we have a split register file, and leaving op0 in fp registers,
3231 and not playing with subregs so much, will help the register allocator. */
3233 static rtx
3234 expand_copysign_absneg (machine_mode mode, rtx op0, rtx op1, rtx target,
3235 int bitpos, bool op0_is_abs)
3237 machine_mode imode;
3238 enum insn_code icode;
3239 rtx sign;
3240 rtx_code_label *label;
3242 if (target == op1)
3243 target = NULL_RTX;
3245 /* Check if the back end provides an insn that handles signbit for the
3246 argument's mode. */
3247 icode = optab_handler (signbit_optab, mode);
3248 if (icode != CODE_FOR_nothing)
3250 imode = insn_data[(int) icode].operand[0].mode;
3251 sign = gen_reg_rtx (imode);
3252 emit_unop_insn (icode, sign, op1, UNKNOWN);
3254 else
3256 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3258 imode = int_mode_for_mode (mode);
3259 if (imode == BLKmode)
3260 return NULL_RTX;
3261 op1 = gen_lowpart (imode, op1);
3263 else
3265 int word;
3267 imode = word_mode;
3268 if (FLOAT_WORDS_BIG_ENDIAN)
3269 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3270 else
3271 word = bitpos / BITS_PER_WORD;
3272 bitpos = bitpos % BITS_PER_WORD;
3273 op1 = operand_subword_force (op1, word, mode);
3276 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3277 sign = expand_binop (imode, and_optab, op1,
3278 immed_wide_int_const (mask, imode),
3279 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3282 if (!op0_is_abs)
3284 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3285 if (op0 == NULL)
3286 return NULL_RTX;
3287 target = op0;
3289 else
3291 if (target == NULL_RTX)
3292 target = copy_to_reg (op0);
3293 else
3294 emit_move_insn (target, op0);
3297 label = gen_label_rtx ();
3298 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3300 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3301 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3302 else
3303 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3304 if (op0 != target)
3305 emit_move_insn (target, op0);
3307 emit_label (label);
3309 return target;
3313 /* A subroutine of expand_copysign, perform the entire copysign operation
3314 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3315 is true if op0 is known to have its sign bit clear. */
3317 static rtx
3318 expand_copysign_bit (machine_mode mode, rtx op0, rtx op1, rtx target,
3319 int bitpos, bool op0_is_abs)
3321 machine_mode imode;
3322 int word, nwords, i;
3323 rtx temp;
3324 rtx_insn *insns;
3326 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3328 imode = int_mode_for_mode (mode);
3329 if (imode == BLKmode)
3330 return NULL_RTX;
3331 word = 0;
3332 nwords = 1;
3334 else
3336 imode = word_mode;
3338 if (FLOAT_WORDS_BIG_ENDIAN)
3339 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3340 else
3341 word = bitpos / BITS_PER_WORD;
3342 bitpos = bitpos % BITS_PER_WORD;
3343 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3346 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3348 if (target == 0
3349 || target == op0
3350 || target == op1
3351 || (nwords > 1 && !valid_multiword_target_p (target)))
3352 target = gen_reg_rtx (mode);
3354 if (nwords > 1)
3356 start_sequence ();
3358 for (i = 0; i < nwords; ++i)
3360 rtx targ_piece = operand_subword (target, i, 1, mode);
3361 rtx op0_piece = operand_subword_force (op0, i, mode);
3363 if (i == word)
3365 if (!op0_is_abs)
3366 op0_piece
3367 = expand_binop (imode, and_optab, op0_piece,
3368 immed_wide_int_const (~mask, imode),
3369 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3370 op1 = expand_binop (imode, and_optab,
3371 operand_subword_force (op1, i, mode),
3372 immed_wide_int_const (mask, imode),
3373 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3375 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3376 targ_piece, 1, OPTAB_LIB_WIDEN);
3377 if (temp != targ_piece)
3378 emit_move_insn (targ_piece, temp);
3380 else
3381 emit_move_insn (targ_piece, op0_piece);
3384 insns = get_insns ();
3385 end_sequence ();
3387 emit_insn (insns);
3389 else
3391 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3392 immed_wide_int_const (mask, imode),
3393 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3395 op0 = gen_lowpart (imode, op0);
3396 if (!op0_is_abs)
3397 op0 = expand_binop (imode, and_optab, op0,
3398 immed_wide_int_const (~mask, imode),
3399 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3401 temp = expand_binop (imode, ior_optab, op0, op1,
3402 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3403 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3406 return target;
3409 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3410 scalar floating point mode. Return NULL if we do not know how to
3411 expand the operation inline. */
3414 expand_copysign (rtx op0, rtx op1, rtx target)
3416 machine_mode mode = GET_MODE (op0);
3417 const struct real_format *fmt;
3418 bool op0_is_abs;
3419 rtx temp;
3421 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3422 gcc_assert (GET_MODE (op1) == mode);
3424 /* First try to do it with a special instruction. */
3425 temp = expand_binop (mode, copysign_optab, op0, op1,
3426 target, 0, OPTAB_DIRECT);
3427 if (temp)
3428 return temp;
3430 fmt = REAL_MODE_FORMAT (mode);
3431 if (fmt == NULL || !fmt->has_signed_zero)
3432 return NULL_RTX;
3434 op0_is_abs = false;
3435 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3437 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3438 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3439 op0_is_abs = true;
3442 if (fmt->signbit_ro >= 0
3443 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3444 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3445 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3447 temp = expand_copysign_absneg (mode, op0, op1, target,
3448 fmt->signbit_ro, op0_is_abs);
3449 if (temp)
3450 return temp;
3453 if (fmt->signbit_rw < 0)
3454 return NULL_RTX;
3455 return expand_copysign_bit (mode, op0, op1, target,
3456 fmt->signbit_rw, op0_is_abs);
3459 /* Generate an instruction whose insn-code is INSN_CODE,
3460 with two operands: an output TARGET and an input OP0.
3461 TARGET *must* be nonzero, and the output is always stored there.
3462 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3463 the value that is stored into TARGET.
3465 Return false if expansion failed. */
3467 bool
3468 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3469 enum rtx_code code)
3471 struct expand_operand ops[2];
3472 rtx_insn *pat;
3474 create_output_operand (&ops[0], target, GET_MODE (target));
3475 create_input_operand (&ops[1], op0, GET_MODE (op0));
3476 pat = maybe_gen_insn (icode, 2, ops);
3477 if (!pat)
3478 return false;
3480 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3481 && code != UNKNOWN)
3482 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3484 emit_insn (pat);
3486 if (ops[0].value != target)
3487 emit_move_insn (target, ops[0].value);
3488 return true;
3490 /* Generate an instruction whose insn-code is INSN_CODE,
3491 with two operands: an output TARGET and an input OP0.
3492 TARGET *must* be nonzero, and the output is always stored there.
3493 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3494 the value that is stored into TARGET. */
3496 void
3497 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3499 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3500 gcc_assert (ok);
3503 struct no_conflict_data
3505 rtx target;
3506 rtx_insn *first, *insn;
3507 bool must_stay;
3510 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3511 the currently examined clobber / store has to stay in the list of
3512 insns that constitute the actual libcall block. */
3513 static void
3514 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3516 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3518 /* If this inns directly contributes to setting the target, it must stay. */
3519 if (reg_overlap_mentioned_p (p->target, dest))
3520 p->must_stay = true;
3521 /* If we haven't committed to keeping any other insns in the list yet,
3522 there is nothing more to check. */
3523 else if (p->insn == p->first)
3524 return;
3525 /* If this insn sets / clobbers a register that feeds one of the insns
3526 already in the list, this insn has to stay too. */
3527 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3528 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3529 || reg_used_between_p (dest, p->first, p->insn)
3530 /* Likewise if this insn depends on a register set by a previous
3531 insn in the list, or if it sets a result (presumably a hard
3532 register) that is set or clobbered by a previous insn.
3533 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3534 SET_DEST perform the former check on the address, and the latter
3535 check on the MEM. */
3536 || (GET_CODE (set) == SET
3537 && (modified_in_p (SET_SRC (set), p->first)
3538 || modified_in_p (SET_DEST (set), p->first)
3539 || modified_between_p (SET_SRC (set), p->first, p->insn)
3540 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3541 p->must_stay = true;
3545 /* Emit code to make a call to a constant function or a library call.
3547 INSNS is a list containing all insns emitted in the call.
3548 These insns leave the result in RESULT. Our block is to copy RESULT
3549 to TARGET, which is logically equivalent to EQUIV.
3551 We first emit any insns that set a pseudo on the assumption that these are
3552 loading constants into registers; doing so allows them to be safely cse'ed
3553 between blocks. Then we emit all the other insns in the block, followed by
3554 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3555 note with an operand of EQUIV. */
3557 static void
3558 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3559 bool equiv_may_trap)
3561 rtx final_dest = target;
3562 rtx_insn *next, *last, *insn;
3564 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3565 into a MEM later. Protect the libcall block from this change. */
3566 if (! REG_P (target) || REG_USERVAR_P (target))
3567 target = gen_reg_rtx (GET_MODE (target));
3569 /* If we're using non-call exceptions, a libcall corresponding to an
3570 operation that may trap may also trap. */
3571 /* ??? See the comment in front of make_reg_eh_region_note. */
3572 if (cfun->can_throw_non_call_exceptions
3573 && (equiv_may_trap || may_trap_p (equiv)))
3575 for (insn = insns; insn; insn = NEXT_INSN (insn))
3576 if (CALL_P (insn))
3578 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3579 if (note)
3581 int lp_nr = INTVAL (XEXP (note, 0));
3582 if (lp_nr == 0 || lp_nr == INT_MIN)
3583 remove_note (insn, note);
3587 else
3589 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3590 reg note to indicate that this call cannot throw or execute a nonlocal
3591 goto (unless there is already a REG_EH_REGION note, in which case
3592 we update it). */
3593 for (insn = insns; insn; insn = NEXT_INSN (insn))
3594 if (CALL_P (insn))
3595 make_reg_eh_region_note_nothrow_nononlocal (insn);
3598 /* First emit all insns that set pseudos. Remove them from the list as
3599 we go. Avoid insns that set pseudos which were referenced in previous
3600 insns. These can be generated by move_by_pieces, for example,
3601 to update an address. Similarly, avoid insns that reference things
3602 set in previous insns. */
3604 for (insn = insns; insn; insn = next)
3606 rtx set = single_set (insn);
3608 next = NEXT_INSN (insn);
3610 if (set != 0 && REG_P (SET_DEST (set))
3611 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3613 struct no_conflict_data data;
3615 data.target = const0_rtx;
3616 data.first = insns;
3617 data.insn = insn;
3618 data.must_stay = 0;
3619 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3620 if (! data.must_stay)
3622 if (PREV_INSN (insn))
3623 SET_NEXT_INSN (PREV_INSN (insn)) = next;
3624 else
3625 insns = next;
3627 if (next)
3628 SET_PREV_INSN (next) = PREV_INSN (insn);
3630 add_insn (insn);
3634 /* Some ports use a loop to copy large arguments onto the stack.
3635 Don't move anything outside such a loop. */
3636 if (LABEL_P (insn))
3637 break;
3640 /* Write the remaining insns followed by the final copy. */
3641 for (insn = insns; insn; insn = next)
3643 next = NEXT_INSN (insn);
3645 add_insn (insn);
3648 last = emit_move_insn (target, result);
3649 if (equiv)
3650 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3652 if (final_dest != target)
3653 emit_move_insn (final_dest, target);
3656 void
3657 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3659 emit_libcall_block_1 (safe_as_a <rtx_insn *> (insns),
3660 target, result, equiv, false);
3663 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3664 PURPOSE describes how this comparison will be used. CODE is the rtx
3665 comparison code we will be using.
3667 ??? Actually, CODE is slightly weaker than that. A target is still
3668 required to implement all of the normal bcc operations, but not
3669 required to implement all (or any) of the unordered bcc operations. */
3672 can_compare_p (enum rtx_code code, machine_mode mode,
3673 enum can_compare_purpose purpose)
3675 rtx test;
3676 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3679 enum insn_code icode;
3681 if (purpose == ccp_jump
3682 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3683 && insn_operand_matches (icode, 0, test))
3684 return 1;
3685 if (purpose == ccp_store_flag
3686 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3687 && insn_operand_matches (icode, 1, test))
3688 return 1;
3689 if (purpose == ccp_cmov
3690 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3691 return 1;
3693 mode = GET_MODE_WIDER_MODE (mode);
3694 PUT_MODE (test, mode);
3696 while (mode != VOIDmode);
3698 return 0;
3701 /* This function is called when we are going to emit a compare instruction that
3702 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3704 *PMODE is the mode of the inputs (in case they are const_int).
3705 *PUNSIGNEDP nonzero says that the operands are unsigned;
3706 this matters if they need to be widened (as given by METHODS).
3708 If they have mode BLKmode, then SIZE specifies the size of both operands.
3710 This function performs all the setup necessary so that the caller only has
3711 to emit a single comparison insn. This setup can involve doing a BLKmode
3712 comparison or emitting a library call to perform the comparison if no insn
3713 is available to handle it.
3714 The values which are passed in through pointers can be modified; the caller
3715 should perform the comparison on the modified values. Constant
3716 comparisons must have already been folded. */
3718 static void
3719 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3720 int unsignedp, enum optab_methods methods,
3721 rtx *ptest, machine_mode *pmode)
3723 machine_mode mode = *pmode;
3724 rtx libfunc, test;
3725 machine_mode cmp_mode;
3726 enum mode_class mclass;
3728 /* The other methods are not needed. */
3729 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3730 || methods == OPTAB_LIB_WIDEN);
3732 /* If we are optimizing, force expensive constants into a register. */
3733 if (CONSTANT_P (x) && optimize
3734 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
3735 > COSTS_N_INSNS (1)))
3736 x = force_reg (mode, x);
3738 if (CONSTANT_P (y) && optimize
3739 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
3740 > COSTS_N_INSNS (1)))
3741 y = force_reg (mode, y);
3743 #if HAVE_cc0
3744 /* Make sure if we have a canonical comparison. The RTL
3745 documentation states that canonical comparisons are required only
3746 for targets which have cc0. */
3747 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3748 #endif
3750 /* Don't let both operands fail to indicate the mode. */
3751 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3752 x = force_reg (mode, x);
3753 if (mode == VOIDmode)
3754 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3756 /* Handle all BLKmode compares. */
3758 if (mode == BLKmode)
3760 machine_mode result_mode;
3761 enum insn_code cmp_code;
3762 tree length_type;
3763 rtx libfunc;
3764 rtx result;
3765 rtx opalign
3766 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3768 gcc_assert (size);
3770 /* Try to use a memory block compare insn - either cmpstr
3771 or cmpmem will do. */
3772 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3773 cmp_mode != VOIDmode;
3774 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3776 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3777 if (cmp_code == CODE_FOR_nothing)
3778 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3779 if (cmp_code == CODE_FOR_nothing)
3780 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3781 if (cmp_code == CODE_FOR_nothing)
3782 continue;
3784 /* Must make sure the size fits the insn's mode. */
3785 if ((CONST_INT_P (size)
3786 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3787 || (GET_MODE_BITSIZE (GET_MODE (size))
3788 > GET_MODE_BITSIZE (cmp_mode)))
3789 continue;
3791 result_mode = insn_data[cmp_code].operand[0].mode;
3792 result = gen_reg_rtx (result_mode);
3793 size = convert_to_mode (cmp_mode, size, 1);
3794 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3796 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3797 *pmode = result_mode;
3798 return;
3801 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3802 goto fail;
3804 /* Otherwise call a library function, memcmp. */
3805 libfunc = memcmp_libfunc;
3806 length_type = sizetype;
3807 result_mode = TYPE_MODE (integer_type_node);
3808 cmp_mode = TYPE_MODE (length_type);
3809 size = convert_to_mode (TYPE_MODE (length_type), size,
3810 TYPE_UNSIGNED (length_type));
3812 result = emit_library_call_value (libfunc, 0, LCT_PURE,
3813 result_mode, 3,
3814 XEXP (x, 0), Pmode,
3815 XEXP (y, 0), Pmode,
3816 size, cmp_mode);
3817 x = result;
3818 y = const0_rtx;
3819 mode = result_mode;
3820 methods = OPTAB_LIB_WIDEN;
3821 unsignedp = false;
3824 /* Don't allow operands to the compare to trap, as that can put the
3825 compare and branch in different basic blocks. */
3826 if (cfun->can_throw_non_call_exceptions)
3828 if (may_trap_p (x))
3829 x = force_reg (mode, x);
3830 if (may_trap_p (y))
3831 y = force_reg (mode, y);
3834 if (GET_MODE_CLASS (mode) == MODE_CC)
3836 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
3837 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3838 gcc_assert (icode != CODE_FOR_nothing
3839 && insn_operand_matches (icode, 0, test));
3840 *ptest = test;
3841 return;
3844 mclass = GET_MODE_CLASS (mode);
3845 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3846 cmp_mode = mode;
3849 enum insn_code icode;
3850 icode = optab_handler (cbranch_optab, cmp_mode);
3851 if (icode != CODE_FOR_nothing
3852 && insn_operand_matches (icode, 0, test))
3854 rtx_insn *last = get_last_insn ();
3855 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3856 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3857 if (op0 && op1
3858 && insn_operand_matches (icode, 1, op0)
3859 && insn_operand_matches (icode, 2, op1))
3861 XEXP (test, 0) = op0;
3862 XEXP (test, 1) = op1;
3863 *ptest = test;
3864 *pmode = cmp_mode;
3865 return;
3867 delete_insns_since (last);
3870 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3871 break;
3872 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
3874 while (cmp_mode != VOIDmode);
3876 if (methods != OPTAB_LIB_WIDEN)
3877 goto fail;
3879 if (!SCALAR_FLOAT_MODE_P (mode))
3881 rtx result;
3882 machine_mode ret_mode;
3884 /* Handle a libcall just for the mode we are using. */
3885 libfunc = optab_libfunc (cmp_optab, mode);
3886 gcc_assert (libfunc);
3888 /* If we want unsigned, and this mode has a distinct unsigned
3889 comparison routine, use that. */
3890 if (unsignedp)
3892 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
3893 if (ulibfunc)
3894 libfunc = ulibfunc;
3897 ret_mode = targetm.libgcc_cmp_return_mode ();
3898 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3899 ret_mode, 2, x, mode, y, mode);
3901 /* There are two kinds of comparison routines. Biased routines
3902 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3903 of gcc expect that the comparison operation is equivalent
3904 to the modified comparison. For signed comparisons compare the
3905 result against 1 in the biased case, and zero in the unbiased
3906 case. For unsigned comparisons always compare against 1 after
3907 biasing the unbiased result by adding 1. This gives us a way to
3908 represent LTU.
3909 The comparisons in the fixed-point helper library are always
3910 biased. */
3911 x = result;
3912 y = const1_rtx;
3914 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
3916 if (unsignedp)
3917 x = plus_constant (ret_mode, result, 1);
3918 else
3919 y = const0_rtx;
3922 *pmode = ret_mode;
3923 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
3924 ptest, pmode);
3926 else
3927 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
3929 return;
3931 fail:
3932 *ptest = NULL_RTX;
3935 /* Before emitting an insn with code ICODE, make sure that X, which is going
3936 to be used for operand OPNUM of the insn, is converted from mode MODE to
3937 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3938 that it is accepted by the operand predicate. Return the new value. */
3941 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
3942 machine_mode wider_mode, int unsignedp)
3944 if (mode != wider_mode)
3945 x = convert_modes (wider_mode, mode, x, unsignedp);
3947 if (!insn_operand_matches (icode, opnum, x))
3949 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
3950 if (reload_completed)
3951 return NULL_RTX;
3952 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
3953 return NULL_RTX;
3954 x = copy_to_mode_reg (op_mode, x);
3957 return x;
3960 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3961 we can do the branch. */
3963 static void
3964 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, int prob)
3966 machine_mode optab_mode;
3967 enum mode_class mclass;
3968 enum insn_code icode;
3969 rtx_insn *insn;
3971 mclass = GET_MODE_CLASS (mode);
3972 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
3973 icode = optab_handler (cbranch_optab, optab_mode);
3975 gcc_assert (icode != CODE_FOR_nothing);
3976 gcc_assert (insn_operand_matches (icode, 0, test));
3977 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
3978 XEXP (test, 1), label));
3979 if (prob != -1
3980 && profile_status_for_fn (cfun) != PROFILE_ABSENT
3981 && insn
3982 && JUMP_P (insn)
3983 && any_condjump_p (insn)
3984 && !find_reg_note (insn, REG_BR_PROB, 0))
3985 add_int_reg_note (insn, REG_BR_PROB, prob);
3988 /* Generate code to compare X with Y so that the condition codes are
3989 set and to jump to LABEL if the condition is true. If X is a
3990 constant and Y is not a constant, then the comparison is swapped to
3991 ensure that the comparison RTL has the canonical form.
3993 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3994 need to be widened. UNSIGNEDP is also used to select the proper
3995 branch condition code.
3997 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3999 MODE is the mode of the inputs (in case they are const_int).
4001 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
4002 It will be potentially converted into an unsigned variant based on
4003 UNSIGNEDP to select a proper jump instruction.
4005 PROB is the probability of jumping to LABEL. */
4007 void
4008 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4009 machine_mode mode, int unsignedp, rtx label,
4010 int prob)
4012 rtx op0 = x, op1 = y;
4013 rtx test;
4015 /* Swap operands and condition to ensure canonical RTL. */
4016 if (swap_commutative_operands_p (x, y)
4017 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
4019 op0 = y, op1 = x;
4020 comparison = swap_condition (comparison);
4023 /* If OP0 is still a constant, then both X and Y must be constants
4024 or the opposite comparison is not supported. Force X into a register
4025 to create canonical RTL. */
4026 if (CONSTANT_P (op0))
4027 op0 = force_reg (mode, op0);
4029 if (unsignedp)
4030 comparison = unsigned_condition (comparison);
4032 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
4033 &test, &mode);
4034 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
4038 /* Emit a library call comparison between floating point X and Y.
4039 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4041 static void
4042 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
4043 rtx *ptest, machine_mode *pmode)
4045 enum rtx_code swapped = swap_condition (comparison);
4046 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4047 machine_mode orig_mode = GET_MODE (x);
4048 machine_mode mode, cmp_mode;
4049 rtx true_rtx, false_rtx;
4050 rtx value, target, equiv;
4051 rtx_insn *insns;
4052 rtx libfunc = 0;
4053 bool reversed_p = false;
4054 cmp_mode = targetm.libgcc_cmp_return_mode ();
4056 for (mode = orig_mode;
4057 mode != VOIDmode;
4058 mode = GET_MODE_WIDER_MODE (mode))
4060 if (code_to_optab (comparison)
4061 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
4062 break;
4064 if (code_to_optab (swapped)
4065 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4067 std::swap (x, y);
4068 comparison = swapped;
4069 break;
4072 if (code_to_optab (reversed)
4073 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4075 comparison = reversed;
4076 reversed_p = true;
4077 break;
4081 gcc_assert (mode != VOIDmode);
4083 if (mode != orig_mode)
4085 x = convert_to_mode (mode, x, 0);
4086 y = convert_to_mode (mode, y, 0);
4089 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4090 the RTL. The allows the RTL optimizers to delete the libcall if the
4091 condition can be determined at compile-time. */
4092 if (comparison == UNORDERED
4093 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4095 true_rtx = const_true_rtx;
4096 false_rtx = const0_rtx;
4098 else
4100 switch (comparison)
4102 case EQ:
4103 true_rtx = const0_rtx;
4104 false_rtx = const_true_rtx;
4105 break;
4107 case NE:
4108 true_rtx = const_true_rtx;
4109 false_rtx = const0_rtx;
4110 break;
4112 case GT:
4113 true_rtx = const1_rtx;
4114 false_rtx = const0_rtx;
4115 break;
4117 case GE:
4118 true_rtx = const0_rtx;
4119 false_rtx = constm1_rtx;
4120 break;
4122 case LT:
4123 true_rtx = constm1_rtx;
4124 false_rtx = const0_rtx;
4125 break;
4127 case LE:
4128 true_rtx = const0_rtx;
4129 false_rtx = const1_rtx;
4130 break;
4132 default:
4133 gcc_unreachable ();
4137 if (comparison == UNORDERED)
4139 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4140 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4141 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4142 temp, const_true_rtx, equiv);
4144 else
4146 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4147 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4148 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4149 equiv, true_rtx, false_rtx);
4152 start_sequence ();
4153 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4154 cmp_mode, 2, x, mode, y, mode);
4155 insns = get_insns ();
4156 end_sequence ();
4158 target = gen_reg_rtx (cmp_mode);
4159 emit_libcall_block (insns, target, value, equiv);
4161 if (comparison == UNORDERED
4162 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4163 || reversed_p)
4164 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4165 else
4166 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4168 *pmode = cmp_mode;
4171 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4173 void
4174 emit_indirect_jump (rtx loc)
4176 if (!targetm.have_indirect_jump ())
4177 sorry ("indirect jumps are not available on this target");
4178 else
4180 struct expand_operand ops[1];
4181 create_address_operand (&ops[0], loc);
4182 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4183 emit_barrier ();
4188 /* Emit a conditional move instruction if the machine supports one for that
4189 condition and machine mode.
4191 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4192 the mode to use should they be constants. If it is VOIDmode, they cannot
4193 both be constants.
4195 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4196 should be stored there. MODE is the mode to use should they be constants.
4197 If it is VOIDmode, they cannot both be constants.
4199 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4200 is not supported. */
4203 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4204 machine_mode cmode, rtx op2, rtx op3,
4205 machine_mode mode, int unsignedp)
4207 rtx comparison;
4208 rtx_insn *last;
4209 enum insn_code icode;
4210 enum rtx_code reversed;
4212 /* If one operand is constant, make it the second one. Only do this
4213 if the other operand is not constant as well. */
4215 if (swap_commutative_operands_p (op0, op1))
4217 std::swap (op0, op1);
4218 code = swap_condition (code);
4221 /* get_condition will prefer to generate LT and GT even if the old
4222 comparison was against zero, so undo that canonicalization here since
4223 comparisons against zero are cheaper. */
4224 if (code == LT && op1 == const1_rtx)
4225 code = LE, op1 = const0_rtx;
4226 else if (code == GT && op1 == constm1_rtx)
4227 code = GE, op1 = const0_rtx;
4229 if (cmode == VOIDmode)
4230 cmode = GET_MODE (op0);
4232 if (swap_commutative_operands_p (op2, op3)
4233 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4234 != UNKNOWN))
4236 std::swap (op2, op3);
4237 code = reversed;
4240 if (mode == VOIDmode)
4241 mode = GET_MODE (op2);
4243 icode = direct_optab_handler (movcc_optab, mode);
4245 if (icode == CODE_FOR_nothing)
4246 return 0;
4248 if (!target)
4249 target = gen_reg_rtx (mode);
4251 code = unsignedp ? unsigned_condition (code) : code;
4252 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4254 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4255 return NULL and let the caller figure out how best to deal with this
4256 situation. */
4257 if (!COMPARISON_P (comparison))
4258 return NULL_RTX;
4260 saved_pending_stack_adjust save;
4261 save_pending_stack_adjust (&save);
4262 last = get_last_insn ();
4263 do_pending_stack_adjust ();
4264 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4265 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4266 &comparison, &cmode);
4267 if (comparison)
4269 struct expand_operand ops[4];
4271 create_output_operand (&ops[0], target, mode);
4272 create_fixed_operand (&ops[1], comparison);
4273 create_input_operand (&ops[2], op2, mode);
4274 create_input_operand (&ops[3], op3, mode);
4275 if (maybe_expand_insn (icode, 4, ops))
4277 if (ops[0].value != target)
4278 convert_move (target, ops[0].value, false);
4279 return target;
4282 delete_insns_since (last);
4283 restore_pending_stack_adjust (&save);
4284 return NULL_RTX;
4288 /* Emit a conditional negate or bitwise complement using the
4289 negcc or notcc optabs if available. Return NULL_RTX if such operations
4290 are not available. Otherwise return the RTX holding the result.
4291 TARGET is the desired destination of the result. COMP is the comparison
4292 on which to negate. If COND is true move into TARGET the negation
4293 or bitwise complement of OP1. Otherwise move OP2 into TARGET.
4294 CODE is either NEG or NOT. MODE is the machine mode in which the
4295 operation is performed. */
4298 emit_conditional_neg_or_complement (rtx target, rtx_code code,
4299 machine_mode mode, rtx cond, rtx op1,
4300 rtx op2)
4302 optab op = unknown_optab;
4303 if (code == NEG)
4304 op = negcc_optab;
4305 else if (code == NOT)
4306 op = notcc_optab;
4307 else
4308 gcc_unreachable ();
4310 insn_code icode = direct_optab_handler (op, mode);
4312 if (icode == CODE_FOR_nothing)
4313 return NULL_RTX;
4315 if (!target)
4316 target = gen_reg_rtx (mode);
4318 rtx_insn *last = get_last_insn ();
4319 struct expand_operand ops[4];
4321 create_output_operand (&ops[0], target, mode);
4322 create_fixed_operand (&ops[1], cond);
4323 create_input_operand (&ops[2], op1, mode);
4324 create_input_operand (&ops[3], op2, mode);
4326 if (maybe_expand_insn (icode, 4, ops))
4328 if (ops[0].value != target)
4329 convert_move (target, ops[0].value, false);
4331 return target;
4333 delete_insns_since (last);
4334 return NULL_RTX;
4337 /* Emit a conditional addition instruction if the machine supports one for that
4338 condition and machine mode.
4340 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4341 the mode to use should they be constants. If it is VOIDmode, they cannot
4342 both be constants.
4344 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4345 should be stored there. MODE is the mode to use should they be constants.
4346 If it is VOIDmode, they cannot both be constants.
4348 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4349 is not supported. */
4352 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4353 machine_mode cmode, rtx op2, rtx op3,
4354 machine_mode mode, int unsignedp)
4356 rtx comparison;
4357 rtx_insn *last;
4358 enum insn_code icode;
4360 /* If one operand is constant, make it the second one. Only do this
4361 if the other operand is not constant as well. */
4363 if (swap_commutative_operands_p (op0, op1))
4365 std::swap (op0, op1);
4366 code = swap_condition (code);
4369 /* get_condition will prefer to generate LT and GT even if the old
4370 comparison was against zero, so undo that canonicalization here since
4371 comparisons against zero are cheaper. */
4372 if (code == LT && op1 == const1_rtx)
4373 code = LE, op1 = const0_rtx;
4374 else if (code == GT && op1 == constm1_rtx)
4375 code = GE, op1 = const0_rtx;
4377 if (cmode == VOIDmode)
4378 cmode = GET_MODE (op0);
4380 if (mode == VOIDmode)
4381 mode = GET_MODE (op2);
4383 icode = optab_handler (addcc_optab, mode);
4385 if (icode == CODE_FOR_nothing)
4386 return 0;
4388 if (!target)
4389 target = gen_reg_rtx (mode);
4391 code = unsignedp ? unsigned_condition (code) : code;
4392 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4394 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4395 return NULL and let the caller figure out how best to deal with this
4396 situation. */
4397 if (!COMPARISON_P (comparison))
4398 return NULL_RTX;
4400 do_pending_stack_adjust ();
4401 last = get_last_insn ();
4402 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4403 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4404 &comparison, &cmode);
4405 if (comparison)
4407 struct expand_operand ops[4];
4409 create_output_operand (&ops[0], target, mode);
4410 create_fixed_operand (&ops[1], comparison);
4411 create_input_operand (&ops[2], op2, mode);
4412 create_input_operand (&ops[3], op3, mode);
4413 if (maybe_expand_insn (icode, 4, ops))
4415 if (ops[0].value != target)
4416 convert_move (target, ops[0].value, false);
4417 return target;
4420 delete_insns_since (last);
4421 return NULL_RTX;
4424 /* These functions attempt to generate an insn body, rather than
4425 emitting the insn, but if the gen function already emits them, we
4426 make no attempt to turn them back into naked patterns. */
4428 /* Generate and return an insn body to add Y to X. */
4430 rtx_insn *
4431 gen_add2_insn (rtx x, rtx y)
4433 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4435 gcc_assert (insn_operand_matches (icode, 0, x));
4436 gcc_assert (insn_operand_matches (icode, 1, x));
4437 gcc_assert (insn_operand_matches (icode, 2, y));
4439 return GEN_FCN (icode) (x, x, y);
4442 /* Generate and return an insn body to add r1 and c,
4443 storing the result in r0. */
4445 rtx_insn *
4446 gen_add3_insn (rtx r0, rtx r1, rtx c)
4448 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4450 if (icode == CODE_FOR_nothing
4451 || !insn_operand_matches (icode, 0, r0)
4452 || !insn_operand_matches (icode, 1, r1)
4453 || !insn_operand_matches (icode, 2, c))
4454 return NULL;
4456 return GEN_FCN (icode) (r0, r1, c);
4460 have_add2_insn (rtx x, rtx y)
4462 enum insn_code icode;
4464 gcc_assert (GET_MODE (x) != VOIDmode);
4466 icode = optab_handler (add_optab, GET_MODE (x));
4468 if (icode == CODE_FOR_nothing)
4469 return 0;
4471 if (!insn_operand_matches (icode, 0, x)
4472 || !insn_operand_matches (icode, 1, x)
4473 || !insn_operand_matches (icode, 2, y))
4474 return 0;
4476 return 1;
4479 /* Generate and return an insn body to add Y to X. */
4481 rtx_insn *
4482 gen_addptr3_insn (rtx x, rtx y, rtx z)
4484 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4486 gcc_assert (insn_operand_matches (icode, 0, x));
4487 gcc_assert (insn_operand_matches (icode, 1, y));
4488 gcc_assert (insn_operand_matches (icode, 2, z));
4490 return GEN_FCN (icode) (x, y, z);
4493 /* Return true if the target implements an addptr pattern and X, Y,
4494 and Z are valid for the pattern predicates. */
4497 have_addptr3_insn (rtx x, rtx y, rtx z)
4499 enum insn_code icode;
4501 gcc_assert (GET_MODE (x) != VOIDmode);
4503 icode = optab_handler (addptr3_optab, GET_MODE (x));
4505 if (icode == CODE_FOR_nothing)
4506 return 0;
4508 if (!insn_operand_matches (icode, 0, x)
4509 || !insn_operand_matches (icode, 1, y)
4510 || !insn_operand_matches (icode, 2, z))
4511 return 0;
4513 return 1;
4516 /* Generate and return an insn body to subtract Y from X. */
4518 rtx_insn *
4519 gen_sub2_insn (rtx x, rtx y)
4521 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4523 gcc_assert (insn_operand_matches (icode, 0, x));
4524 gcc_assert (insn_operand_matches (icode, 1, x));
4525 gcc_assert (insn_operand_matches (icode, 2, y));
4527 return GEN_FCN (icode) (x, x, y);
4530 /* Generate and return an insn body to subtract r1 and c,
4531 storing the result in r0. */
4533 rtx_insn *
4534 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4536 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4538 if (icode == CODE_FOR_nothing
4539 || !insn_operand_matches (icode, 0, r0)
4540 || !insn_operand_matches (icode, 1, r1)
4541 || !insn_operand_matches (icode, 2, c))
4542 return NULL;
4544 return GEN_FCN (icode) (r0, r1, c);
4548 have_sub2_insn (rtx x, rtx y)
4550 enum insn_code icode;
4552 gcc_assert (GET_MODE (x) != VOIDmode);
4554 icode = optab_handler (sub_optab, GET_MODE (x));
4556 if (icode == CODE_FOR_nothing)
4557 return 0;
4559 if (!insn_operand_matches (icode, 0, x)
4560 || !insn_operand_matches (icode, 1, x)
4561 || !insn_operand_matches (icode, 2, y))
4562 return 0;
4564 return 1;
4567 /* Generate the body of an insn to extend Y (with mode MFROM)
4568 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4570 rtx_insn *
4571 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4572 machine_mode mfrom, int unsignedp)
4574 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4575 return GEN_FCN (icode) (x, y);
4578 /* Generate code to convert FROM to floating point
4579 and store in TO. FROM must be fixed point and not VOIDmode.
4580 UNSIGNEDP nonzero means regard FROM as unsigned.
4581 Normally this is done by correcting the final value
4582 if it is negative. */
4584 void
4585 expand_float (rtx to, rtx from, int unsignedp)
4587 enum insn_code icode;
4588 rtx target = to;
4589 machine_mode fmode, imode;
4590 bool can_do_signed = false;
4592 /* Crash now, because we won't be able to decide which mode to use. */
4593 gcc_assert (GET_MODE (from) != VOIDmode);
4595 /* Look for an insn to do the conversion. Do it in the specified
4596 modes if possible; otherwise convert either input, output or both to
4597 wider mode. If the integer mode is wider than the mode of FROM,
4598 we can do the conversion signed even if the input is unsigned. */
4600 for (fmode = GET_MODE (to); fmode != VOIDmode;
4601 fmode = GET_MODE_WIDER_MODE (fmode))
4602 for (imode = GET_MODE (from); imode != VOIDmode;
4603 imode = GET_MODE_WIDER_MODE (imode))
4605 int doing_unsigned = unsignedp;
4607 if (fmode != GET_MODE (to)
4608 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
4609 continue;
4611 icode = can_float_p (fmode, imode, unsignedp);
4612 if (icode == CODE_FOR_nothing && unsignedp)
4614 enum insn_code scode = can_float_p (fmode, imode, 0);
4615 if (scode != CODE_FOR_nothing)
4616 can_do_signed = true;
4617 if (imode != GET_MODE (from))
4618 icode = scode, doing_unsigned = 0;
4621 if (icode != CODE_FOR_nothing)
4623 if (imode != GET_MODE (from))
4624 from = convert_to_mode (imode, from, unsignedp);
4626 if (fmode != GET_MODE (to))
4627 target = gen_reg_rtx (fmode);
4629 emit_unop_insn (icode, target, from,
4630 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4632 if (target != to)
4633 convert_move (to, target, 0);
4634 return;
4638 /* Unsigned integer, and no way to convert directly. Convert as signed,
4639 then unconditionally adjust the result. */
4640 if (unsignedp && can_do_signed)
4642 rtx_code_label *label = gen_label_rtx ();
4643 rtx temp;
4644 REAL_VALUE_TYPE offset;
4646 /* Look for a usable floating mode FMODE wider than the source and at
4647 least as wide as the target. Using FMODE will avoid rounding woes
4648 with unsigned values greater than the signed maximum value. */
4650 for (fmode = GET_MODE (to); fmode != VOIDmode;
4651 fmode = GET_MODE_WIDER_MODE (fmode))
4652 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4653 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4654 break;
4656 if (fmode == VOIDmode)
4658 /* There is no such mode. Pretend the target is wide enough. */
4659 fmode = GET_MODE (to);
4661 /* Avoid double-rounding when TO is narrower than FROM. */
4662 if ((significand_size (fmode) + 1)
4663 < GET_MODE_PRECISION (GET_MODE (from)))
4665 rtx temp1;
4666 rtx_code_label *neglabel = gen_label_rtx ();
4668 /* Don't use TARGET if it isn't a register, is a hard register,
4669 or is the wrong mode. */
4670 if (!REG_P (target)
4671 || REGNO (target) < FIRST_PSEUDO_REGISTER
4672 || GET_MODE (target) != fmode)
4673 target = gen_reg_rtx (fmode);
4675 imode = GET_MODE (from);
4676 do_pending_stack_adjust ();
4678 /* Test whether the sign bit is set. */
4679 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4680 0, neglabel);
4682 /* The sign bit is not set. Convert as signed. */
4683 expand_float (target, from, 0);
4684 emit_jump_insn (targetm.gen_jump (label));
4685 emit_barrier ();
4687 /* The sign bit is set.
4688 Convert to a usable (positive signed) value by shifting right
4689 one bit, while remembering if a nonzero bit was shifted
4690 out; i.e., compute (from & 1) | (from >> 1). */
4692 emit_label (neglabel);
4693 temp = expand_binop (imode, and_optab, from, const1_rtx,
4694 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4695 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4696 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4697 OPTAB_LIB_WIDEN);
4698 expand_float (target, temp, 0);
4700 /* Multiply by 2 to undo the shift above. */
4701 temp = expand_binop (fmode, add_optab, target, target,
4702 target, 0, OPTAB_LIB_WIDEN);
4703 if (temp != target)
4704 emit_move_insn (target, temp);
4706 do_pending_stack_adjust ();
4707 emit_label (label);
4708 goto done;
4712 /* If we are about to do some arithmetic to correct for an
4713 unsigned operand, do it in a pseudo-register. */
4715 if (GET_MODE (to) != fmode
4716 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4717 target = gen_reg_rtx (fmode);
4719 /* Convert as signed integer to floating. */
4720 expand_float (target, from, 0);
4722 /* If FROM is negative (and therefore TO is negative),
4723 correct its value by 2**bitwidth. */
4725 do_pending_stack_adjust ();
4726 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4727 0, label);
4730 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
4731 temp = expand_binop (fmode, add_optab, target,
4732 const_double_from_real_value (offset, fmode),
4733 target, 0, OPTAB_LIB_WIDEN);
4734 if (temp != target)
4735 emit_move_insn (target, temp);
4737 do_pending_stack_adjust ();
4738 emit_label (label);
4739 goto done;
4742 /* No hardware instruction available; call a library routine. */
4744 rtx libfunc;
4745 rtx_insn *insns;
4746 rtx value;
4747 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4749 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_PRECISION (SImode))
4750 from = convert_to_mode (SImode, from, unsignedp);
4752 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4753 gcc_assert (libfunc);
4755 start_sequence ();
4757 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4758 GET_MODE (to), 1, from,
4759 GET_MODE (from));
4760 insns = get_insns ();
4761 end_sequence ();
4763 emit_libcall_block (insns, target, value,
4764 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4765 GET_MODE (to), from));
4768 done:
4770 /* Copy result to requested destination
4771 if we have been computing in a temp location. */
4773 if (target != to)
4775 if (GET_MODE (target) == GET_MODE (to))
4776 emit_move_insn (to, target);
4777 else
4778 convert_move (to, target, 0);
4782 /* Generate code to convert FROM to fixed point and store in TO. FROM
4783 must be floating point. */
4785 void
4786 expand_fix (rtx to, rtx from, int unsignedp)
4788 enum insn_code icode;
4789 rtx target = to;
4790 machine_mode fmode, imode;
4791 bool must_trunc = false;
4793 /* We first try to find a pair of modes, one real and one integer, at
4794 least as wide as FROM and TO, respectively, in which we can open-code
4795 this conversion. If the integer mode is wider than the mode of TO,
4796 we can do the conversion either signed or unsigned. */
4798 for (fmode = GET_MODE (from); fmode != VOIDmode;
4799 fmode = GET_MODE_WIDER_MODE (fmode))
4800 for (imode = GET_MODE (to); imode != VOIDmode;
4801 imode = GET_MODE_WIDER_MODE (imode))
4803 int doing_unsigned = unsignedp;
4805 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4806 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4807 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4809 if (icode != CODE_FOR_nothing)
4811 rtx_insn *last = get_last_insn ();
4812 if (fmode != GET_MODE (from))
4813 from = convert_to_mode (fmode, from, 0);
4815 if (must_trunc)
4817 rtx temp = gen_reg_rtx (GET_MODE (from));
4818 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4819 temp, 0);
4822 if (imode != GET_MODE (to))
4823 target = gen_reg_rtx (imode);
4825 if (maybe_emit_unop_insn (icode, target, from,
4826 doing_unsigned ? UNSIGNED_FIX : FIX))
4828 if (target != to)
4829 convert_move (to, target, unsignedp);
4830 return;
4832 delete_insns_since (last);
4836 /* For an unsigned conversion, there is one more way to do it.
4837 If we have a signed conversion, we generate code that compares
4838 the real value to the largest representable positive number. If if
4839 is smaller, the conversion is done normally. Otherwise, subtract
4840 one plus the highest signed number, convert, and add it back.
4842 We only need to check all real modes, since we know we didn't find
4843 anything with a wider integer mode.
4845 This code used to extend FP value into mode wider than the destination.
4846 This is needed for decimal float modes which cannot accurately
4847 represent one plus the highest signed number of the same size, but
4848 not for binary modes. Consider, for instance conversion from SFmode
4849 into DImode.
4851 The hot path through the code is dealing with inputs smaller than 2^63
4852 and doing just the conversion, so there is no bits to lose.
4854 In the other path we know the value is positive in the range 2^63..2^64-1
4855 inclusive. (as for other input overflow happens and result is undefined)
4856 So we know that the most important bit set in mantissa corresponds to
4857 2^63. The subtraction of 2^63 should not generate any rounding as it
4858 simply clears out that bit. The rest is trivial. */
4860 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4861 for (fmode = GET_MODE (from); fmode != VOIDmode;
4862 fmode = GET_MODE_WIDER_MODE (fmode))
4863 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
4864 && (!DECIMAL_FLOAT_MODE_P (fmode)
4865 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
4867 int bitsize;
4868 REAL_VALUE_TYPE offset;
4869 rtx limit;
4870 rtx_code_label *lab1, *lab2;
4871 rtx_insn *insn;
4873 bitsize = GET_MODE_PRECISION (GET_MODE (to));
4874 real_2expN (&offset, bitsize - 1, fmode);
4875 limit = const_double_from_real_value (offset, fmode);
4876 lab1 = gen_label_rtx ();
4877 lab2 = gen_label_rtx ();
4879 if (fmode != GET_MODE (from))
4880 from = convert_to_mode (fmode, from, 0);
4882 /* See if we need to do the subtraction. */
4883 do_pending_stack_adjust ();
4884 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4885 0, lab1);
4887 /* If not, do the signed "fix" and branch around fixup code. */
4888 expand_fix (to, from, 0);
4889 emit_jump_insn (targetm.gen_jump (lab2));
4890 emit_barrier ();
4892 /* Otherwise, subtract 2**(N-1), convert to signed number,
4893 then add 2**(N-1). Do the addition using XOR since this
4894 will often generate better code. */
4895 emit_label (lab1);
4896 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4897 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4898 expand_fix (to, target, 0);
4899 target = expand_binop (GET_MODE (to), xor_optab, to,
4900 gen_int_mode
4901 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4902 GET_MODE (to)),
4903 to, 1, OPTAB_LIB_WIDEN);
4905 if (target != to)
4906 emit_move_insn (to, target);
4908 emit_label (lab2);
4910 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
4912 /* Make a place for a REG_NOTE and add it. */
4913 insn = emit_move_insn (to, to);
4914 set_dst_reg_note (insn, REG_EQUAL,
4915 gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
4916 copy_rtx (from)),
4917 to);
4920 return;
4923 /* We can't do it with an insn, so use a library call. But first ensure
4924 that the mode of TO is at least as wide as SImode, since those are the
4925 only library calls we know about. */
4927 if (GET_MODE_PRECISION (GET_MODE (to)) < GET_MODE_PRECISION (SImode))
4929 target = gen_reg_rtx (SImode);
4931 expand_fix (target, from, unsignedp);
4933 else
4935 rtx_insn *insns;
4936 rtx value;
4937 rtx libfunc;
4939 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4940 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4941 gcc_assert (libfunc);
4943 start_sequence ();
4945 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4946 GET_MODE (to), 1, from,
4947 GET_MODE (from));
4948 insns = get_insns ();
4949 end_sequence ();
4951 emit_libcall_block (insns, target, value,
4952 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4953 GET_MODE (to), from));
4956 if (target != to)
4958 if (GET_MODE (to) == GET_MODE (target))
4959 emit_move_insn (to, target);
4960 else
4961 convert_move (to, target, 0);
4966 /* Promote integer arguments for a libcall if necessary.
4967 emit_library_call_value cannot do the promotion because it does not
4968 know if it should do a signed or unsigned promotion. This is because
4969 there are no tree types defined for libcalls. */
4971 static rtx
4972 prepare_libcall_arg (rtx arg, int uintp)
4974 machine_mode mode = GET_MODE (arg);
4975 machine_mode arg_mode;
4976 if (SCALAR_INT_MODE_P (mode))
4978 /* If we need to promote the integer function argument we need to do
4979 it here instead of inside emit_library_call_value because in
4980 emit_library_call_value we don't know if we should do a signed or
4981 unsigned promotion. */
4983 int unsigned_p = 0;
4984 arg_mode = promote_function_mode (NULL_TREE, mode,
4985 &unsigned_p, NULL_TREE, 0);
4986 if (arg_mode != mode)
4987 return convert_to_mode (arg_mode, arg, uintp);
4989 return arg;
4992 /* Generate code to convert FROM or TO a fixed-point.
4993 If UINTP is true, either TO or FROM is an unsigned integer.
4994 If SATP is true, we need to saturate the result. */
4996 void
4997 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
4999 machine_mode to_mode = GET_MODE (to);
5000 machine_mode from_mode = GET_MODE (from);
5001 convert_optab tab;
5002 enum rtx_code this_code;
5003 enum insn_code code;
5004 rtx_insn *insns;
5005 rtx value;
5006 rtx libfunc;
5008 if (to_mode == from_mode)
5010 emit_move_insn (to, from);
5011 return;
5014 if (uintp)
5016 tab = satp ? satfractuns_optab : fractuns_optab;
5017 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
5019 else
5021 tab = satp ? satfract_optab : fract_optab;
5022 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
5024 code = convert_optab_handler (tab, to_mode, from_mode);
5025 if (code != CODE_FOR_nothing)
5027 emit_unop_insn (code, to, from, this_code);
5028 return;
5031 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
5032 gcc_assert (libfunc);
5034 from = prepare_libcall_arg (from, uintp);
5035 from_mode = GET_MODE (from);
5037 start_sequence ();
5038 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
5039 1, from, from_mode);
5040 insns = get_insns ();
5041 end_sequence ();
5043 emit_libcall_block (insns, to, value,
5044 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
5047 /* Generate code to convert FROM to fixed point and store in TO. FROM
5048 must be floating point, TO must be signed. Use the conversion optab
5049 TAB to do the conversion. */
5051 bool
5052 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5054 enum insn_code icode;
5055 rtx target = to;
5056 machine_mode fmode, imode;
5058 /* We first try to find a pair of modes, one real and one integer, at
5059 least as wide as FROM and TO, respectively, in which we can open-code
5060 this conversion. If the integer mode is wider than the mode of TO,
5061 we can do the conversion either signed or unsigned. */
5063 for (fmode = GET_MODE (from); fmode != VOIDmode;
5064 fmode = GET_MODE_WIDER_MODE (fmode))
5065 for (imode = GET_MODE (to); imode != VOIDmode;
5066 imode = GET_MODE_WIDER_MODE (imode))
5068 icode = convert_optab_handler (tab, imode, fmode);
5069 if (icode != CODE_FOR_nothing)
5071 rtx_insn *last = get_last_insn ();
5072 if (fmode != GET_MODE (from))
5073 from = convert_to_mode (fmode, from, 0);
5075 if (imode != GET_MODE (to))
5076 target = gen_reg_rtx (imode);
5078 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
5080 delete_insns_since (last);
5081 continue;
5083 if (target != to)
5084 convert_move (to, target, 0);
5085 return true;
5089 return false;
5092 /* Report whether we have an instruction to perform the operation
5093 specified by CODE on operands of mode MODE. */
5095 have_insn_for (enum rtx_code code, machine_mode mode)
5097 return (code_to_optab (code)
5098 && (optab_handler (code_to_optab (code), mode)
5099 != CODE_FOR_nothing));
5102 /* Print information about the current contents of the optabs on
5103 STDERR. */
5105 DEBUG_FUNCTION void
5106 debug_optab_libfuncs (void)
5108 int i, j, k;
5110 /* Dump the arithmetic optabs. */
5111 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
5112 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5114 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
5115 if (l)
5117 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5118 fprintf (stderr, "%s\t%s:\t%s\n",
5119 GET_RTX_NAME (optab_to_code ((optab) i)),
5120 GET_MODE_NAME (j),
5121 XSTR (l, 0));
5125 /* Dump the conversion optabs. */
5126 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
5127 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5128 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5130 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
5131 (machine_mode) k);
5132 if (l)
5134 gcc_assert (GET_CODE (l) == SYMBOL_REF);
5135 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5136 GET_RTX_NAME (optab_to_code ((optab) i)),
5137 GET_MODE_NAME (j),
5138 GET_MODE_NAME (k),
5139 XSTR (l, 0));
5144 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5145 CODE. Return 0 on failure. */
5147 rtx_insn *
5148 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5150 machine_mode mode = GET_MODE (op1);
5151 enum insn_code icode;
5152 rtx_insn *insn;
5153 rtx trap_rtx;
5155 if (mode == VOIDmode)
5156 return 0;
5158 icode = optab_handler (ctrap_optab, mode);
5159 if (icode == CODE_FOR_nothing)
5160 return 0;
5162 /* Some targets only accept a zero trap code. */
5163 if (!insn_operand_matches (icode, 3, tcode))
5164 return 0;
5166 do_pending_stack_adjust ();
5167 start_sequence ();
5168 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5169 &trap_rtx, &mode);
5170 if (!trap_rtx)
5171 insn = NULL;
5172 else
5173 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5174 tcode);
5176 /* If that failed, then give up. */
5177 if (insn == 0)
5179 end_sequence ();
5180 return 0;
5183 emit_insn (insn);
5184 insn = get_insns ();
5185 end_sequence ();
5186 return insn;
5189 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5190 or unsigned operation code. */
5192 enum rtx_code
5193 get_rtx_code (enum tree_code tcode, bool unsignedp)
5195 enum rtx_code code;
5196 switch (tcode)
5198 case EQ_EXPR:
5199 code = EQ;
5200 break;
5201 case NE_EXPR:
5202 code = NE;
5203 break;
5204 case LT_EXPR:
5205 code = unsignedp ? LTU : LT;
5206 break;
5207 case LE_EXPR:
5208 code = unsignedp ? LEU : LE;
5209 break;
5210 case GT_EXPR:
5211 code = unsignedp ? GTU : GT;
5212 break;
5213 case GE_EXPR:
5214 code = unsignedp ? GEU : GE;
5215 break;
5217 case UNORDERED_EXPR:
5218 code = UNORDERED;
5219 break;
5220 case ORDERED_EXPR:
5221 code = ORDERED;
5222 break;
5223 case UNLT_EXPR:
5224 code = UNLT;
5225 break;
5226 case UNLE_EXPR:
5227 code = UNLE;
5228 break;
5229 case UNGT_EXPR:
5230 code = UNGT;
5231 break;
5232 case UNGE_EXPR:
5233 code = UNGE;
5234 break;
5235 case UNEQ_EXPR:
5236 code = UNEQ;
5237 break;
5238 case LTGT_EXPR:
5239 code = LTGT;
5240 break;
5242 case BIT_AND_EXPR:
5243 code = AND;
5244 break;
5246 case BIT_IOR_EXPR:
5247 code = IOR;
5248 break;
5250 default:
5251 gcc_unreachable ();
5253 return code;
5256 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5257 unsigned operators. OPNO holds an index of the first comparison
5258 operand in insn with code ICODE. Do not generate compare instruction. */
5260 static rtx
5261 vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
5262 bool unsignedp, enum insn_code icode,
5263 unsigned int opno)
5265 struct expand_operand ops[2];
5266 rtx rtx_op0, rtx_op1;
5267 machine_mode m0, m1;
5268 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5270 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5272 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5273 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5274 cases, use the original mode. */
5275 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5276 EXPAND_STACK_PARM);
5277 m0 = GET_MODE (rtx_op0);
5278 if (m0 == VOIDmode)
5279 m0 = TYPE_MODE (TREE_TYPE (t_op0));
5281 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5282 EXPAND_STACK_PARM);
5283 m1 = GET_MODE (rtx_op1);
5284 if (m1 == VOIDmode)
5285 m1 = TYPE_MODE (TREE_TYPE (t_op1));
5287 create_input_operand (&ops[0], rtx_op0, m0);
5288 create_input_operand (&ops[1], rtx_op1, m1);
5289 if (!maybe_legitimize_operands (icode, opno, 2, ops))
5290 gcc_unreachable ();
5291 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
5294 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
5295 vec_perm operand, assuming the second operand is a constant vector of zeroes.
5296 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
5297 shift. */
5298 static rtx
5299 shift_amt_for_vec_perm_mask (rtx sel)
5301 unsigned int i, first, nelt = GET_MODE_NUNITS (GET_MODE (sel));
5302 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (GET_MODE (sel));
5304 if (GET_CODE (sel) != CONST_VECTOR)
5305 return NULL_RTX;
5307 first = INTVAL (CONST_VECTOR_ELT (sel, 0));
5308 if (first >= nelt)
5309 return NULL_RTX;
5310 for (i = 1; i < nelt; i++)
5312 int idx = INTVAL (CONST_VECTOR_ELT (sel, i));
5313 unsigned int expected = i + first;
5314 /* Indices into the second vector are all equivalent. */
5315 if (idx < 0 || (MIN (nelt, (unsigned) idx) != MIN (nelt, expected)))
5316 return NULL_RTX;
5319 return GEN_INT (first * bitsize);
5322 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
5324 static rtx
5325 expand_vec_perm_1 (enum insn_code icode, rtx target,
5326 rtx v0, rtx v1, rtx sel)
5328 machine_mode tmode = GET_MODE (target);
5329 machine_mode smode = GET_MODE (sel);
5330 struct expand_operand ops[4];
5332 create_output_operand (&ops[0], target, tmode);
5333 create_input_operand (&ops[3], sel, smode);
5335 /* Make an effort to preserve v0 == v1. The target expander is able to
5336 rely on this to determine if we're permuting a single input operand. */
5337 if (rtx_equal_p (v0, v1))
5339 if (!insn_operand_matches (icode, 1, v0))
5340 v0 = force_reg (tmode, v0);
5341 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5342 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5344 create_fixed_operand (&ops[1], v0);
5345 create_fixed_operand (&ops[2], v0);
5347 else
5349 create_input_operand (&ops[1], v0, tmode);
5350 create_input_operand (&ops[2], v1, tmode);
5353 if (maybe_expand_insn (icode, 4, ops))
5354 return ops[0].value;
5355 return NULL_RTX;
5358 /* Generate instructions for vec_perm optab given its mode
5359 and three operands. */
5362 expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
5364 enum insn_code icode;
5365 machine_mode qimode;
5366 unsigned int i, w, e, u;
5367 rtx tmp, sel_qi = NULL;
5368 rtvec vec;
5370 if (!target || GET_MODE (target) != mode)
5371 target = gen_reg_rtx (mode);
5373 w = GET_MODE_SIZE (mode);
5374 e = GET_MODE_NUNITS (mode);
5375 u = GET_MODE_UNIT_SIZE (mode);
5377 /* Set QIMODE to a different vector mode with byte elements.
5378 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5379 qimode = VOIDmode;
5380 if (GET_MODE_INNER (mode) != QImode)
5382 qimode = mode_for_vector (QImode, w);
5383 if (!VECTOR_MODE_P (qimode))
5384 qimode = VOIDmode;
5387 /* If the input is a constant, expand it specially. */
5388 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
5389 if (GET_CODE (sel) == CONST_VECTOR)
5391 /* See if this can be handled with a vec_shr. We only do this if the
5392 second vector is all zeroes. */
5393 enum insn_code shift_code = optab_handler (vec_shr_optab, mode);
5394 enum insn_code shift_code_qi = ((qimode != VOIDmode && qimode != mode)
5395 ? optab_handler (vec_shr_optab, qimode)
5396 : CODE_FOR_nothing);
5397 rtx shift_amt = NULL_RTX;
5398 if (v1 == CONST0_RTX (GET_MODE (v1))
5399 && (shift_code != CODE_FOR_nothing
5400 || shift_code_qi != CODE_FOR_nothing))
5402 shift_amt = shift_amt_for_vec_perm_mask (sel);
5403 if (shift_amt)
5405 struct expand_operand ops[3];
5406 if (shift_code != CODE_FOR_nothing)
5408 create_output_operand (&ops[0], target, mode);
5409 create_input_operand (&ops[1], v0, mode);
5410 create_convert_operand_from_type (&ops[2], shift_amt,
5411 sizetype);
5412 if (maybe_expand_insn (shift_code, 3, ops))
5413 return ops[0].value;
5415 if (shift_code_qi != CODE_FOR_nothing)
5417 tmp = gen_reg_rtx (qimode);
5418 create_output_operand (&ops[0], tmp, qimode);
5419 create_input_operand (&ops[1], gen_lowpart (qimode, v0),
5420 qimode);
5421 create_convert_operand_from_type (&ops[2], shift_amt,
5422 sizetype);
5423 if (maybe_expand_insn (shift_code_qi, 3, ops))
5424 return gen_lowpart (mode, ops[0].value);
5429 icode = direct_optab_handler (vec_perm_const_optab, mode);
5430 if (icode != CODE_FOR_nothing)
5432 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5433 if (tmp)
5434 return tmp;
5437 /* Fall back to a constant byte-based permutation. */
5438 if (qimode != VOIDmode)
5440 vec = rtvec_alloc (w);
5441 for (i = 0; i < e; ++i)
5443 unsigned int j, this_e;
5445 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
5446 this_e &= 2 * e - 1;
5447 this_e *= u;
5449 for (j = 0; j < u; ++j)
5450 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
5452 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
5454 icode = direct_optab_handler (vec_perm_const_optab, qimode);
5455 if (icode != CODE_FOR_nothing)
5457 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5458 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5459 gen_lowpart (qimode, v1), sel_qi);
5460 if (tmp)
5461 return gen_lowpart (mode, tmp);
5466 /* Otherwise expand as a fully variable permuation. */
5467 icode = direct_optab_handler (vec_perm_optab, mode);
5468 if (icode != CODE_FOR_nothing)
5470 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5471 if (tmp)
5472 return tmp;
5475 /* As a special case to aid several targets, lower the element-based
5476 permutation to a byte-based permutation and try again. */
5477 if (qimode == VOIDmode)
5478 return NULL_RTX;
5479 icode = direct_optab_handler (vec_perm_optab, qimode);
5480 if (icode == CODE_FOR_nothing)
5481 return NULL_RTX;
5483 if (sel_qi == NULL)
5485 /* Multiply each element by its byte size. */
5486 machine_mode selmode = GET_MODE (sel);
5487 if (u == 2)
5488 sel = expand_simple_binop (selmode, PLUS, sel, sel,
5489 NULL, 0, OPTAB_DIRECT);
5490 else
5491 sel = expand_simple_binop (selmode, ASHIFT, sel,
5492 GEN_INT (exact_log2 (u)),
5493 NULL, 0, OPTAB_DIRECT);
5494 gcc_assert (sel != NULL);
5496 /* Broadcast the low byte each element into each of its bytes. */
5497 vec = rtvec_alloc (w);
5498 for (i = 0; i < w; ++i)
5500 int this_e = i / u * u;
5501 if (BYTES_BIG_ENDIAN)
5502 this_e += u - 1;
5503 RTVEC_ELT (vec, i) = GEN_INT (this_e);
5505 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5506 sel = gen_lowpart (qimode, sel);
5507 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
5508 gcc_assert (sel != NULL);
5510 /* Add the byte offset to each byte element. */
5511 /* Note that the definition of the indicies here is memory ordering,
5512 so there should be no difference between big and little endian. */
5513 vec = rtvec_alloc (w);
5514 for (i = 0; i < w; ++i)
5515 RTVEC_ELT (vec, i) = GEN_INT (i % u);
5516 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5517 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
5518 sel, 0, OPTAB_DIRECT);
5519 gcc_assert (sel_qi != NULL);
5522 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5523 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5524 gen_lowpart (qimode, v1), sel_qi);
5525 if (tmp)
5526 tmp = gen_lowpart (mode, tmp);
5527 return tmp;
5530 /* Generate insns for a VEC_COND_EXPR with mask, given its TYPE and its
5531 three operands. */
5534 expand_vec_cond_mask_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5535 rtx target)
5537 struct expand_operand ops[4];
5538 machine_mode mode = TYPE_MODE (vec_cond_type);
5539 machine_mode mask_mode = TYPE_MODE (TREE_TYPE (op0));
5540 enum insn_code icode = get_vcond_mask_icode (mode, mask_mode);
5541 rtx mask, rtx_op1, rtx_op2;
5543 if (icode == CODE_FOR_nothing)
5544 return 0;
5546 mask = expand_normal (op0);
5547 rtx_op1 = expand_normal (op1);
5548 rtx_op2 = expand_normal (op2);
5550 mask = force_reg (GET_MODE (mask), mask);
5551 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5553 create_output_operand (&ops[0], target, mode);
5554 create_input_operand (&ops[1], rtx_op1, mode);
5555 create_input_operand (&ops[2], rtx_op2, mode);
5556 create_input_operand (&ops[3], mask, mask_mode);
5557 expand_insn (icode, 4, ops);
5559 return ops[0].value;
5562 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5563 three operands. */
5566 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5567 rtx target)
5569 struct expand_operand ops[6];
5570 enum insn_code icode;
5571 rtx comparison, rtx_op1, rtx_op2;
5572 machine_mode mode = TYPE_MODE (vec_cond_type);
5573 machine_mode cmp_op_mode;
5574 bool unsignedp;
5575 tree op0a, op0b;
5576 enum tree_code tcode;
5578 if (COMPARISON_CLASS_P (op0))
5580 op0a = TREE_OPERAND (op0, 0);
5581 op0b = TREE_OPERAND (op0, 1);
5582 tcode = TREE_CODE (op0);
5584 else
5586 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
5587 if (get_vcond_mask_icode (mode, TYPE_MODE (TREE_TYPE (op0)))
5588 != CODE_FOR_nothing)
5589 return expand_vec_cond_mask_expr (vec_cond_type, op0, op1,
5590 op2, target);
5591 /* Fake op0 < 0. */
5592 else
5594 gcc_assert (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (op0)))
5595 == MODE_VECTOR_INT);
5596 op0a = op0;
5597 op0b = build_zero_cst (TREE_TYPE (op0));
5598 tcode = LT_EXPR;
5601 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
5602 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5605 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
5606 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
5608 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
5609 if (icode == CODE_FOR_nothing)
5610 return 0;
5612 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode, 4);
5613 rtx_op1 = expand_normal (op1);
5614 rtx_op2 = expand_normal (op2);
5616 create_output_operand (&ops[0], target, mode);
5617 create_input_operand (&ops[1], rtx_op1, mode);
5618 create_input_operand (&ops[2], rtx_op2, mode);
5619 create_fixed_operand (&ops[3], comparison);
5620 create_fixed_operand (&ops[4], XEXP (comparison, 0));
5621 create_fixed_operand (&ops[5], XEXP (comparison, 1));
5622 expand_insn (icode, 6, ops);
5623 return ops[0].value;
5626 /* Generate insns for a vector comparison into a mask. */
5629 expand_vec_cmp_expr (tree type, tree exp, rtx target)
5631 struct expand_operand ops[4];
5632 enum insn_code icode;
5633 rtx comparison;
5634 machine_mode mask_mode = TYPE_MODE (type);
5635 machine_mode vmode;
5636 bool unsignedp;
5637 tree op0a, op0b;
5638 enum tree_code tcode;
5640 op0a = TREE_OPERAND (exp, 0);
5641 op0b = TREE_OPERAND (exp, 1);
5642 tcode = TREE_CODE (exp);
5644 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5645 vmode = TYPE_MODE (TREE_TYPE (op0a));
5647 icode = get_vec_cmp_icode (vmode, mask_mode, unsignedp);
5648 if (icode == CODE_FOR_nothing)
5649 return 0;
5651 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode, 2);
5652 create_output_operand (&ops[0], target, mask_mode);
5653 create_fixed_operand (&ops[1], comparison);
5654 create_fixed_operand (&ops[2], XEXP (comparison, 0));
5655 create_fixed_operand (&ops[3], XEXP (comparison, 1));
5656 expand_insn (icode, 4, ops);
5657 return ops[0].value;
5660 /* Expand a highpart multiply. */
5663 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
5664 rtx target, bool uns_p)
5666 struct expand_operand eops[3];
5667 enum insn_code icode;
5668 int method, i, nunits;
5669 machine_mode wmode;
5670 rtx m1, m2, perm;
5671 optab tab1, tab2;
5672 rtvec v;
5674 method = can_mult_highpart_p (mode, uns_p);
5675 switch (method)
5677 case 0:
5678 return NULL_RTX;
5679 case 1:
5680 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
5681 return expand_binop (mode, tab1, op0, op1, target, uns_p,
5682 OPTAB_LIB_WIDEN);
5683 case 2:
5684 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
5685 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
5686 break;
5687 case 3:
5688 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
5689 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
5690 if (BYTES_BIG_ENDIAN)
5691 std::swap (tab1, tab2);
5692 break;
5693 default:
5694 gcc_unreachable ();
5697 icode = optab_handler (tab1, mode);
5698 nunits = GET_MODE_NUNITS (mode);
5699 wmode = insn_data[icode].operand[0].mode;
5700 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
5701 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
5703 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5704 create_input_operand (&eops[1], op0, mode);
5705 create_input_operand (&eops[2], op1, mode);
5706 expand_insn (icode, 3, eops);
5707 m1 = gen_lowpart (mode, eops[0].value);
5709 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5710 create_input_operand (&eops[1], op0, mode);
5711 create_input_operand (&eops[2], op1, mode);
5712 expand_insn (optab_handler (tab2, mode), 3, eops);
5713 m2 = gen_lowpart (mode, eops[0].value);
5715 v = rtvec_alloc (nunits);
5716 if (method == 2)
5718 for (i = 0; i < nunits; ++i)
5719 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
5720 + ((i & 1) ? nunits : 0));
5722 else
5724 for (i = 0; i < nunits; ++i)
5725 RTVEC_ELT (v, i) = GEN_INT (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
5727 perm = gen_rtx_CONST_VECTOR (mode, v);
5729 return expand_vec_perm (mode, m1, m2, perm, target);
5732 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5733 pattern. */
5735 static void
5736 find_cc_set (rtx x, const_rtx pat, void *data)
5738 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
5739 && GET_CODE (pat) == SET)
5741 rtx *p_cc_reg = (rtx *) data;
5742 gcc_assert (!*p_cc_reg);
5743 *p_cc_reg = x;
5747 /* This is a helper function for the other atomic operations. This function
5748 emits a loop that contains SEQ that iterates until a compare-and-swap
5749 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5750 a set of instructions that takes a value from OLD_REG as an input and
5751 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5752 set to the current contents of MEM. After SEQ, a compare-and-swap will
5753 attempt to update MEM with NEW_REG. The function returns true when the
5754 loop was generated successfully. */
5756 static bool
5757 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5759 machine_mode mode = GET_MODE (mem);
5760 rtx_code_label *label;
5761 rtx cmp_reg, success, oldval;
5763 /* The loop we want to generate looks like
5765 cmp_reg = mem;
5766 label:
5767 old_reg = cmp_reg;
5768 seq;
5769 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5770 if (success)
5771 goto label;
5773 Note that we only do the plain load from memory once. Subsequent
5774 iterations use the value loaded by the compare-and-swap pattern. */
5776 label = gen_label_rtx ();
5777 cmp_reg = gen_reg_rtx (mode);
5779 emit_move_insn (cmp_reg, mem);
5780 emit_label (label);
5781 emit_move_insn (old_reg, cmp_reg);
5782 if (seq)
5783 emit_insn (seq);
5785 success = NULL_RTX;
5786 oldval = cmp_reg;
5787 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
5788 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
5789 MEMMODEL_RELAXED))
5790 return false;
5792 if (oldval != cmp_reg)
5793 emit_move_insn (cmp_reg, oldval);
5795 /* Mark this jump predicted not taken. */
5796 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
5797 GET_MODE (success), 1, label, 0);
5798 return true;
5802 /* This function tries to emit an atomic_exchange intruction. VAL is written
5803 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
5804 using TARGET if possible. */
5806 static rtx
5807 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5809 machine_mode mode = GET_MODE (mem);
5810 enum insn_code icode;
5812 /* If the target supports the exchange directly, great. */
5813 icode = direct_optab_handler (atomic_exchange_optab, mode);
5814 if (icode != CODE_FOR_nothing)
5816 struct expand_operand ops[4];
5818 create_output_operand (&ops[0], target, mode);
5819 create_fixed_operand (&ops[1], mem);
5820 create_input_operand (&ops[2], val, mode);
5821 create_integer_operand (&ops[3], model);
5822 if (maybe_expand_insn (icode, 4, ops))
5823 return ops[0].value;
5826 return NULL_RTX;
5829 /* This function tries to implement an atomic exchange operation using
5830 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
5831 The previous contents of *MEM are returned, using TARGET if possible.
5832 Since this instructionn is an acquire barrier only, stronger memory
5833 models may require additional barriers to be emitted. */
5835 static rtx
5836 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
5837 enum memmodel model)
5839 machine_mode mode = GET_MODE (mem);
5840 enum insn_code icode;
5841 rtx_insn *last_insn = get_last_insn ();
5843 icode = optab_handler (sync_lock_test_and_set_optab, mode);
5845 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
5846 exists, and the memory model is stronger than acquire, add a release
5847 barrier before the instruction. */
5849 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
5850 expand_mem_thread_fence (model);
5852 if (icode != CODE_FOR_nothing)
5854 struct expand_operand ops[3];
5855 create_output_operand (&ops[0], target, mode);
5856 create_fixed_operand (&ops[1], mem);
5857 create_input_operand (&ops[2], val, mode);
5858 if (maybe_expand_insn (icode, 3, ops))
5859 return ops[0].value;
5862 /* If an external test-and-set libcall is provided, use that instead of
5863 any external compare-and-swap that we might get from the compare-and-
5864 swap-loop expansion later. */
5865 if (!can_compare_and_swap_p (mode, false))
5867 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
5868 if (libfunc != NULL)
5870 rtx addr;
5872 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5873 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5874 mode, 2, addr, ptr_mode,
5875 val, mode);
5879 /* If the test_and_set can't be emitted, eliminate any barrier that might
5880 have been emitted. */
5881 delete_insns_since (last_insn);
5882 return NULL_RTX;
5885 /* This function tries to implement an atomic exchange operation using a
5886 compare_and_swap loop. VAL is written to *MEM. The previous contents of
5887 *MEM are returned, using TARGET if possible. No memory model is required
5888 since a compare_and_swap loop is seq-cst. */
5890 static rtx
5891 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
5893 machine_mode mode = GET_MODE (mem);
5895 if (can_compare_and_swap_p (mode, true))
5897 if (!target || !register_operand (target, mode))
5898 target = gen_reg_rtx (mode);
5899 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
5900 return target;
5903 return NULL_RTX;
5906 /* This function tries to implement an atomic test-and-set operation
5907 using the atomic_test_and_set instruction pattern. A boolean value
5908 is returned from the operation, using TARGET if possible. */
5910 static rtx
5911 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5913 machine_mode pat_bool_mode;
5914 struct expand_operand ops[3];
5916 if (!targetm.have_atomic_test_and_set ())
5917 return NULL_RTX;
5919 /* While we always get QImode from __atomic_test_and_set, we get
5920 other memory modes from __sync_lock_test_and_set. Note that we
5921 use no endian adjustment here. This matches the 4.6 behavior
5922 in the Sparc backend. */
5923 enum insn_code icode = targetm.code_for_atomic_test_and_set;
5924 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
5925 if (GET_MODE (mem) != QImode)
5926 mem = adjust_address_nv (mem, QImode, 0);
5928 pat_bool_mode = insn_data[icode].operand[0].mode;
5929 create_output_operand (&ops[0], target, pat_bool_mode);
5930 create_fixed_operand (&ops[1], mem);
5931 create_integer_operand (&ops[2], model);
5933 if (maybe_expand_insn (icode, 3, ops))
5934 return ops[0].value;
5935 return NULL_RTX;
5938 /* This function expands the legacy _sync_lock test_and_set operation which is
5939 generally an atomic exchange. Some limited targets only allow the
5940 constant 1 to be stored. This is an ACQUIRE operation.
5942 TARGET is an optional place to stick the return value.
5943 MEM is where VAL is stored. */
5946 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
5948 rtx ret;
5950 /* Try an atomic_exchange first. */
5951 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
5952 if (ret)
5953 return ret;
5955 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
5956 MEMMODEL_SYNC_ACQUIRE);
5957 if (ret)
5958 return ret;
5960 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
5961 if (ret)
5962 return ret;
5964 /* If there are no other options, try atomic_test_and_set if the value
5965 being stored is 1. */
5966 if (val == const1_rtx)
5967 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
5969 return ret;
5972 /* This function expands the atomic test_and_set operation:
5973 atomically store a boolean TRUE into MEM and return the previous value.
5975 MEMMODEL is the memory model variant to use.
5976 TARGET is an optional place to stick the return value. */
5979 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5981 machine_mode mode = GET_MODE (mem);
5982 rtx ret, trueval, subtarget;
5984 ret = maybe_emit_atomic_test_and_set (target, mem, model);
5985 if (ret)
5986 return ret;
5988 /* Be binary compatible with non-default settings of trueval, and different
5989 cpu revisions. E.g. one revision may have atomic-test-and-set, but
5990 another only has atomic-exchange. */
5991 if (targetm.atomic_test_and_set_trueval == 1)
5993 trueval = const1_rtx;
5994 subtarget = target ? target : gen_reg_rtx (mode);
5996 else
5998 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
5999 subtarget = gen_reg_rtx (mode);
6002 /* Try the atomic-exchange optab... */
6003 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
6005 /* ... then an atomic-compare-and-swap loop ... */
6006 if (!ret)
6007 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
6009 /* ... before trying the vaguely defined legacy lock_test_and_set. */
6010 if (!ret)
6011 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
6013 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
6014 things with the value 1. Thus we try again without trueval. */
6015 if (!ret && targetm.atomic_test_and_set_trueval != 1)
6016 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
6018 /* Failing all else, assume a single threaded environment and simply
6019 perform the operation. */
6020 if (!ret)
6022 /* If the result is ignored skip the move to target. */
6023 if (subtarget != const0_rtx)
6024 emit_move_insn (subtarget, mem);
6026 emit_move_insn (mem, trueval);
6027 ret = subtarget;
6030 /* Recall that have to return a boolean value; rectify if trueval
6031 is not exactly one. */
6032 if (targetm.atomic_test_and_set_trueval != 1)
6033 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
6035 return ret;
6038 /* This function expands the atomic exchange operation:
6039 atomically store VAL in MEM and return the previous value in MEM.
6041 MEMMODEL is the memory model variant to use.
6042 TARGET is an optional place to stick the return value. */
6045 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
6047 rtx ret;
6049 ret = maybe_emit_atomic_exchange (target, mem, val, model);
6051 /* Next try a compare-and-swap loop for the exchange. */
6052 if (!ret)
6053 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
6055 return ret;
6058 /* This function expands the atomic compare exchange operation:
6060 *PTARGET_BOOL is an optional place to store the boolean success/failure.
6061 *PTARGET_OVAL is an optional place to store the old value from memory.
6062 Both target parameters may be NULL or const0_rtx to indicate that we do
6063 not care about that return value. Both target parameters are updated on
6064 success to the actual location of the corresponding result.
6066 MEMMODEL is the memory model variant to use.
6068 The return value of the function is true for success. */
6070 bool
6071 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
6072 rtx mem, rtx expected, rtx desired,
6073 bool is_weak, enum memmodel succ_model,
6074 enum memmodel fail_model)
6076 machine_mode mode = GET_MODE (mem);
6077 struct expand_operand ops[8];
6078 enum insn_code icode;
6079 rtx target_oval, target_bool = NULL_RTX;
6080 rtx libfunc;
6082 /* Load expected into a register for the compare and swap. */
6083 if (MEM_P (expected))
6084 expected = copy_to_reg (expected);
6086 /* Make sure we always have some place to put the return oldval.
6087 Further, make sure that place is distinct from the input expected,
6088 just in case we need that path down below. */
6089 if (ptarget_oval && *ptarget_oval == const0_rtx)
6090 ptarget_oval = NULL;
6092 if (ptarget_oval == NULL
6093 || (target_oval = *ptarget_oval) == NULL
6094 || reg_overlap_mentioned_p (expected, target_oval))
6095 target_oval = gen_reg_rtx (mode);
6097 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
6098 if (icode != CODE_FOR_nothing)
6100 machine_mode bool_mode = insn_data[icode].operand[0].mode;
6102 if (ptarget_bool && *ptarget_bool == const0_rtx)
6103 ptarget_bool = NULL;
6105 /* Make sure we always have a place for the bool operand. */
6106 if (ptarget_bool == NULL
6107 || (target_bool = *ptarget_bool) == NULL
6108 || GET_MODE (target_bool) != bool_mode)
6109 target_bool = gen_reg_rtx (bool_mode);
6111 /* Emit the compare_and_swap. */
6112 create_output_operand (&ops[0], target_bool, bool_mode);
6113 create_output_operand (&ops[1], target_oval, mode);
6114 create_fixed_operand (&ops[2], mem);
6115 create_input_operand (&ops[3], expected, mode);
6116 create_input_operand (&ops[4], desired, mode);
6117 create_integer_operand (&ops[5], is_weak);
6118 create_integer_operand (&ops[6], succ_model);
6119 create_integer_operand (&ops[7], fail_model);
6120 if (maybe_expand_insn (icode, 8, ops))
6122 /* Return success/failure. */
6123 target_bool = ops[0].value;
6124 target_oval = ops[1].value;
6125 goto success;
6129 /* Otherwise fall back to the original __sync_val_compare_and_swap
6130 which is always seq-cst. */
6131 icode = optab_handler (sync_compare_and_swap_optab, mode);
6132 if (icode != CODE_FOR_nothing)
6134 rtx cc_reg;
6136 create_output_operand (&ops[0], target_oval, mode);
6137 create_fixed_operand (&ops[1], mem);
6138 create_input_operand (&ops[2], expected, mode);
6139 create_input_operand (&ops[3], desired, mode);
6140 if (!maybe_expand_insn (icode, 4, ops))
6141 return false;
6143 target_oval = ops[0].value;
6145 /* If the caller isn't interested in the boolean return value,
6146 skip the computation of it. */
6147 if (ptarget_bool == NULL)
6148 goto success;
6150 /* Otherwise, work out if the compare-and-swap succeeded. */
6151 cc_reg = NULL_RTX;
6152 if (have_insn_for (COMPARE, CCmode))
6153 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
6154 if (cc_reg)
6156 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
6157 const0_rtx, VOIDmode, 0, 1);
6158 goto success;
6160 goto success_bool_from_val;
6163 /* Also check for library support for __sync_val_compare_and_swap. */
6164 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
6165 if (libfunc != NULL)
6167 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6168 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
6169 mode, 3, addr, ptr_mode,
6170 expected, mode, desired, mode);
6171 emit_move_insn (target_oval, target);
6173 /* Compute the boolean return value only if requested. */
6174 if (ptarget_bool)
6175 goto success_bool_from_val;
6176 else
6177 goto success;
6180 /* Failure. */
6181 return false;
6183 success_bool_from_val:
6184 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
6185 expected, VOIDmode, 1, 1);
6186 success:
6187 /* Make sure that the oval output winds up where the caller asked. */
6188 if (ptarget_oval)
6189 *ptarget_oval = target_oval;
6190 if (ptarget_bool)
6191 *ptarget_bool = target_bool;
6192 return true;
6195 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
6197 static void
6198 expand_asm_memory_barrier (void)
6200 rtx asm_op, clob;
6202 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
6203 rtvec_alloc (0), rtvec_alloc (0),
6204 rtvec_alloc (0), UNKNOWN_LOCATION);
6205 MEM_VOLATILE_P (asm_op) = 1;
6207 clob = gen_rtx_SCRATCH (VOIDmode);
6208 clob = gen_rtx_MEM (BLKmode, clob);
6209 clob = gen_rtx_CLOBBER (VOIDmode, clob);
6211 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
6214 /* This routine will either emit the mem_thread_fence pattern or issue a
6215 sync_synchronize to generate a fence for memory model MEMMODEL. */
6217 void
6218 expand_mem_thread_fence (enum memmodel model)
6220 if (targetm.have_mem_thread_fence ())
6221 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
6222 else if (!is_mm_relaxed (model))
6224 if (targetm.have_memory_barrier ())
6225 emit_insn (targetm.gen_memory_barrier ());
6226 else if (synchronize_libfunc != NULL_RTX)
6227 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
6228 else
6229 expand_asm_memory_barrier ();
6233 /* This routine will either emit the mem_signal_fence pattern or issue a
6234 sync_synchronize to generate a fence for memory model MEMMODEL. */
6236 void
6237 expand_mem_signal_fence (enum memmodel model)
6239 if (targetm.have_mem_signal_fence ())
6240 emit_insn (targetm.gen_mem_signal_fence (GEN_INT (model)));
6241 else if (!is_mm_relaxed (model))
6243 /* By default targets are coherent between a thread and the signal
6244 handler running on the same thread. Thus this really becomes a
6245 compiler barrier, in that stores must not be sunk past
6246 (or raised above) a given point. */
6247 expand_asm_memory_barrier ();
6251 /* This function expands the atomic load operation:
6252 return the atomically loaded value in MEM.
6254 MEMMODEL is the memory model variant to use.
6255 TARGET is an option place to stick the return value. */
6258 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6260 machine_mode mode = GET_MODE (mem);
6261 enum insn_code icode;
6263 /* If the target supports the load directly, great. */
6264 icode = direct_optab_handler (atomic_load_optab, mode);
6265 if (icode != CODE_FOR_nothing)
6267 struct expand_operand ops[3];
6269 create_output_operand (&ops[0], target, mode);
6270 create_fixed_operand (&ops[1], mem);
6271 create_integer_operand (&ops[2], model);
6272 if (maybe_expand_insn (icode, 3, ops))
6273 return ops[0].value;
6276 /* If the size of the object is greater than word size on this target,
6277 then we assume that a load will not be atomic. */
6278 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6280 /* Issue val = compare_and_swap (mem, 0, 0).
6281 This may cause the occasional harmless store of 0 when the value is
6282 already 0, but it seems to be OK according to the standards guys. */
6283 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
6284 const0_rtx, false, model, model))
6285 return target;
6286 else
6287 /* Otherwise there is no atomic load, leave the library call. */
6288 return NULL_RTX;
6291 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6292 if (!target || target == const0_rtx)
6293 target = gen_reg_rtx (mode);
6295 /* For SEQ_CST, emit a barrier before the load. */
6296 if (is_mm_seq_cst (model))
6297 expand_mem_thread_fence (model);
6299 emit_move_insn (target, mem);
6301 /* Emit the appropriate barrier after the load. */
6302 expand_mem_thread_fence (model);
6304 return target;
6307 /* This function expands the atomic store operation:
6308 Atomically store VAL in MEM.
6309 MEMMODEL is the memory model variant to use.
6310 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6311 function returns const0_rtx if a pattern was emitted. */
6314 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6316 machine_mode mode = GET_MODE (mem);
6317 enum insn_code icode;
6318 struct expand_operand ops[3];
6320 /* If the target supports the store directly, great. */
6321 icode = direct_optab_handler (atomic_store_optab, mode);
6322 if (icode != CODE_FOR_nothing)
6324 create_fixed_operand (&ops[0], mem);
6325 create_input_operand (&ops[1], val, mode);
6326 create_integer_operand (&ops[2], model);
6327 if (maybe_expand_insn (icode, 3, ops))
6328 return const0_rtx;
6331 /* If using __sync_lock_release is a viable alternative, try it. */
6332 if (use_release)
6334 icode = direct_optab_handler (sync_lock_release_optab, mode);
6335 if (icode != CODE_FOR_nothing)
6337 create_fixed_operand (&ops[0], mem);
6338 create_input_operand (&ops[1], const0_rtx, mode);
6339 if (maybe_expand_insn (icode, 2, ops))
6341 /* lock_release is only a release barrier. */
6342 if (is_mm_seq_cst (model))
6343 expand_mem_thread_fence (model);
6344 return const0_rtx;
6349 /* If the size of the object is greater than word size on this target,
6350 a default store will not be atomic, Try a mem_exchange and throw away
6351 the result. If that doesn't work, don't do anything. */
6352 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6354 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6355 if (!target)
6356 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
6357 if (target)
6358 return const0_rtx;
6359 else
6360 return NULL_RTX;
6363 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6364 expand_mem_thread_fence (model);
6366 emit_move_insn (mem, val);
6368 /* For SEQ_CST, also emit a barrier after the store. */
6369 if (is_mm_seq_cst (model))
6370 expand_mem_thread_fence (model);
6372 return const0_rtx;
6376 /* Structure containing the pointers and values required to process the
6377 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6379 struct atomic_op_functions
6381 direct_optab mem_fetch_before;
6382 direct_optab mem_fetch_after;
6383 direct_optab mem_no_result;
6384 optab fetch_before;
6385 optab fetch_after;
6386 direct_optab no_result;
6387 enum rtx_code reverse_code;
6391 /* Fill in structure pointed to by OP with the various optab entries for an
6392 operation of type CODE. */
6394 static void
6395 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6397 gcc_assert (op!= NULL);
6399 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6400 in the source code during compilation, and the optab entries are not
6401 computable until runtime. Fill in the values at runtime. */
6402 switch (code)
6404 case PLUS:
6405 op->mem_fetch_before = atomic_fetch_add_optab;
6406 op->mem_fetch_after = atomic_add_fetch_optab;
6407 op->mem_no_result = atomic_add_optab;
6408 op->fetch_before = sync_old_add_optab;
6409 op->fetch_after = sync_new_add_optab;
6410 op->no_result = sync_add_optab;
6411 op->reverse_code = MINUS;
6412 break;
6413 case MINUS:
6414 op->mem_fetch_before = atomic_fetch_sub_optab;
6415 op->mem_fetch_after = atomic_sub_fetch_optab;
6416 op->mem_no_result = atomic_sub_optab;
6417 op->fetch_before = sync_old_sub_optab;
6418 op->fetch_after = sync_new_sub_optab;
6419 op->no_result = sync_sub_optab;
6420 op->reverse_code = PLUS;
6421 break;
6422 case XOR:
6423 op->mem_fetch_before = atomic_fetch_xor_optab;
6424 op->mem_fetch_after = atomic_xor_fetch_optab;
6425 op->mem_no_result = atomic_xor_optab;
6426 op->fetch_before = sync_old_xor_optab;
6427 op->fetch_after = sync_new_xor_optab;
6428 op->no_result = sync_xor_optab;
6429 op->reverse_code = XOR;
6430 break;
6431 case AND:
6432 op->mem_fetch_before = atomic_fetch_and_optab;
6433 op->mem_fetch_after = atomic_and_fetch_optab;
6434 op->mem_no_result = atomic_and_optab;
6435 op->fetch_before = sync_old_and_optab;
6436 op->fetch_after = sync_new_and_optab;
6437 op->no_result = sync_and_optab;
6438 op->reverse_code = UNKNOWN;
6439 break;
6440 case IOR:
6441 op->mem_fetch_before = atomic_fetch_or_optab;
6442 op->mem_fetch_after = atomic_or_fetch_optab;
6443 op->mem_no_result = atomic_or_optab;
6444 op->fetch_before = sync_old_ior_optab;
6445 op->fetch_after = sync_new_ior_optab;
6446 op->no_result = sync_ior_optab;
6447 op->reverse_code = UNKNOWN;
6448 break;
6449 case NOT:
6450 op->mem_fetch_before = atomic_fetch_nand_optab;
6451 op->mem_fetch_after = atomic_nand_fetch_optab;
6452 op->mem_no_result = atomic_nand_optab;
6453 op->fetch_before = sync_old_nand_optab;
6454 op->fetch_after = sync_new_nand_optab;
6455 op->no_result = sync_nand_optab;
6456 op->reverse_code = UNKNOWN;
6457 break;
6458 default:
6459 gcc_unreachable ();
6463 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6464 using memory order MODEL. If AFTER is true the operation needs to return
6465 the value of *MEM after the operation, otherwise the previous value.
6466 TARGET is an optional place to place the result. The result is unused if
6467 it is const0_rtx.
6468 Return the result if there is a better sequence, otherwise NULL_RTX. */
6470 static rtx
6471 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6472 enum memmodel model, bool after)
6474 /* If the value is prefetched, or not used, it may be possible to replace
6475 the sequence with a native exchange operation. */
6476 if (!after || target == const0_rtx)
6478 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6479 if (code == AND && val == const0_rtx)
6481 if (target == const0_rtx)
6482 target = gen_reg_rtx (GET_MODE (mem));
6483 return maybe_emit_atomic_exchange (target, mem, val, model);
6486 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6487 if (code == IOR && val == constm1_rtx)
6489 if (target == const0_rtx)
6490 target = gen_reg_rtx (GET_MODE (mem));
6491 return maybe_emit_atomic_exchange (target, mem, val, model);
6495 return NULL_RTX;
6498 /* Try to emit an instruction for a specific operation varaition.
6499 OPTAB contains the OP functions.
6500 TARGET is an optional place to return the result. const0_rtx means unused.
6501 MEM is the memory location to operate on.
6502 VAL is the value to use in the operation.
6503 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6504 MODEL is the memory model, if used.
6505 AFTER is true if the returned result is the value after the operation. */
6507 static rtx
6508 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6509 rtx val, bool use_memmodel, enum memmodel model, bool after)
6511 machine_mode mode = GET_MODE (mem);
6512 struct expand_operand ops[4];
6513 enum insn_code icode;
6514 int op_counter = 0;
6515 int num_ops;
6517 /* Check to see if there is a result returned. */
6518 if (target == const0_rtx)
6520 if (use_memmodel)
6522 icode = direct_optab_handler (optab->mem_no_result, mode);
6523 create_integer_operand (&ops[2], model);
6524 num_ops = 3;
6526 else
6528 icode = direct_optab_handler (optab->no_result, mode);
6529 num_ops = 2;
6532 /* Otherwise, we need to generate a result. */
6533 else
6535 if (use_memmodel)
6537 icode = direct_optab_handler (after ? optab->mem_fetch_after
6538 : optab->mem_fetch_before, mode);
6539 create_integer_operand (&ops[3], model);
6540 num_ops = 4;
6542 else
6544 icode = optab_handler (after ? optab->fetch_after
6545 : optab->fetch_before, mode);
6546 num_ops = 3;
6548 create_output_operand (&ops[op_counter++], target, mode);
6550 if (icode == CODE_FOR_nothing)
6551 return NULL_RTX;
6553 create_fixed_operand (&ops[op_counter++], mem);
6554 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6555 create_convert_operand_to (&ops[op_counter++], val, mode, true);
6557 if (maybe_expand_insn (icode, num_ops, ops))
6558 return (target == const0_rtx ? const0_rtx : ops[0].value);
6560 return NULL_RTX;
6564 /* This function expands an atomic fetch_OP or OP_fetch operation:
6565 TARGET is an option place to stick the return value. const0_rtx indicates
6566 the result is unused.
6567 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6568 CODE is the operation being performed (OP)
6569 MEMMODEL is the memory model variant to use.
6570 AFTER is true to return the result of the operation (OP_fetch).
6571 AFTER is false to return the value before the operation (fetch_OP).
6573 This function will *only* generate instructions if there is a direct
6574 optab. No compare and swap loops or libcalls will be generated. */
6576 static rtx
6577 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6578 enum rtx_code code, enum memmodel model,
6579 bool after)
6581 machine_mode mode = GET_MODE (mem);
6582 struct atomic_op_functions optab;
6583 rtx result;
6584 bool unused_result = (target == const0_rtx);
6586 get_atomic_op_for_code (&optab, code);
6588 /* Check to see if there are any better instructions. */
6589 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6590 if (result)
6591 return result;
6593 /* Check for the case where the result isn't used and try those patterns. */
6594 if (unused_result)
6596 /* Try the memory model variant first. */
6597 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6598 if (result)
6599 return result;
6601 /* Next try the old style withuot a memory model. */
6602 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6603 if (result)
6604 return result;
6606 /* There is no no-result pattern, so try patterns with a result. */
6607 target = NULL_RTX;
6610 /* Try the __atomic version. */
6611 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6612 if (result)
6613 return result;
6615 /* Try the older __sync version. */
6616 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6617 if (result)
6618 return result;
6620 /* If the fetch value can be calculated from the other variation of fetch,
6621 try that operation. */
6622 if (after || unused_result || optab.reverse_code != UNKNOWN)
6624 /* Try the __atomic version, then the older __sync version. */
6625 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6626 if (!result)
6627 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6629 if (result)
6631 /* If the result isn't used, no need to do compensation code. */
6632 if (unused_result)
6633 return result;
6635 /* Issue compensation code. Fetch_after == fetch_before OP val.
6636 Fetch_before == after REVERSE_OP val. */
6637 if (!after)
6638 code = optab.reverse_code;
6639 if (code == NOT)
6641 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6642 true, OPTAB_LIB_WIDEN);
6643 result = expand_simple_unop (mode, NOT, result, target, true);
6645 else
6646 result = expand_simple_binop (mode, code, result, val, target,
6647 true, OPTAB_LIB_WIDEN);
6648 return result;
6652 /* No direct opcode can be generated. */
6653 return NULL_RTX;
6658 /* This function expands an atomic fetch_OP or OP_fetch operation:
6659 TARGET is an option place to stick the return value. const0_rtx indicates
6660 the result is unused.
6661 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6662 CODE is the operation being performed (OP)
6663 MEMMODEL is the memory model variant to use.
6664 AFTER is true to return the result of the operation (OP_fetch).
6665 AFTER is false to return the value before the operation (fetch_OP). */
6667 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6668 enum memmodel model, bool after)
6670 machine_mode mode = GET_MODE (mem);
6671 rtx result;
6672 bool unused_result = (target == const0_rtx);
6674 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6675 after);
6677 if (result)
6678 return result;
6680 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6681 if (code == PLUS || code == MINUS)
6683 rtx tmp;
6684 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6686 start_sequence ();
6687 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6688 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6689 model, after);
6690 if (result)
6692 /* PLUS worked so emit the insns and return. */
6693 tmp = get_insns ();
6694 end_sequence ();
6695 emit_insn (tmp);
6696 return result;
6699 /* PLUS did not work, so throw away the negation code and continue. */
6700 end_sequence ();
6703 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6704 if (!can_compare_and_swap_p (mode, false))
6706 rtx libfunc;
6707 bool fixup = false;
6708 enum rtx_code orig_code = code;
6709 struct atomic_op_functions optab;
6711 get_atomic_op_for_code (&optab, code);
6712 libfunc = optab_libfunc (after ? optab.fetch_after
6713 : optab.fetch_before, mode);
6714 if (libfunc == NULL
6715 && (after || unused_result || optab.reverse_code != UNKNOWN))
6717 fixup = true;
6718 if (!after)
6719 code = optab.reverse_code;
6720 libfunc = optab_libfunc (after ? optab.fetch_before
6721 : optab.fetch_after, mode);
6723 if (libfunc != NULL)
6725 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6726 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
6727 2, addr, ptr_mode, val, mode);
6729 if (!unused_result && fixup)
6730 result = expand_simple_binop (mode, code, result, val, target,
6731 true, OPTAB_LIB_WIDEN);
6732 return result;
6735 /* We need the original code for any further attempts. */
6736 code = orig_code;
6739 /* If nothing else has succeeded, default to a compare and swap loop. */
6740 if (can_compare_and_swap_p (mode, true))
6742 rtx_insn *insn;
6743 rtx t0 = gen_reg_rtx (mode), t1;
6745 start_sequence ();
6747 /* If the result is used, get a register for it. */
6748 if (!unused_result)
6750 if (!target || !register_operand (target, mode))
6751 target = gen_reg_rtx (mode);
6752 /* If fetch_before, copy the value now. */
6753 if (!after)
6754 emit_move_insn (target, t0);
6756 else
6757 target = const0_rtx;
6759 t1 = t0;
6760 if (code == NOT)
6762 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
6763 true, OPTAB_LIB_WIDEN);
6764 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
6766 else
6767 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
6768 OPTAB_LIB_WIDEN);
6770 /* For after, copy the value now. */
6771 if (!unused_result && after)
6772 emit_move_insn (target, t1);
6773 insn = get_insns ();
6774 end_sequence ();
6776 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6777 return target;
6780 return NULL_RTX;
6783 /* Return true if OPERAND is suitable for operand number OPNO of
6784 instruction ICODE. */
6786 bool
6787 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
6789 return (!insn_data[(int) icode].operand[opno].predicate
6790 || (insn_data[(int) icode].operand[opno].predicate
6791 (operand, insn_data[(int) icode].operand[opno].mode)));
6794 /* TARGET is a target of a multiword operation that we are going to
6795 implement as a series of word-mode operations. Return true if
6796 TARGET is suitable for this purpose. */
6798 bool
6799 valid_multiword_target_p (rtx target)
6801 machine_mode mode;
6802 int i;
6804 mode = GET_MODE (target);
6805 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
6806 if (!validate_subreg (word_mode, mode, target, i))
6807 return false;
6808 return true;
6811 /* Like maybe_legitimize_operand, but do not change the code of the
6812 current rtx value. */
6814 static bool
6815 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
6816 struct expand_operand *op)
6818 /* See if the operand matches in its current form. */
6819 if (insn_operand_matches (icode, opno, op->value))
6820 return true;
6822 /* If the operand is a memory whose address has no side effects,
6823 try forcing the address into a non-virtual pseudo register.
6824 The check for side effects is important because copy_to_mode_reg
6825 cannot handle things like auto-modified addresses. */
6826 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
6828 rtx addr, mem;
6830 mem = op->value;
6831 addr = XEXP (mem, 0);
6832 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
6833 && !side_effects_p (addr))
6835 rtx_insn *last;
6836 machine_mode mode;
6838 last = get_last_insn ();
6839 mode = get_address_mode (mem);
6840 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
6841 if (insn_operand_matches (icode, opno, mem))
6843 op->value = mem;
6844 return true;
6846 delete_insns_since (last);
6850 return false;
6853 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6854 on success, storing the new operand value back in OP. */
6856 static bool
6857 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
6858 struct expand_operand *op)
6860 machine_mode mode, imode;
6861 bool old_volatile_ok, result;
6863 mode = op->mode;
6864 switch (op->type)
6866 case EXPAND_FIXED:
6867 old_volatile_ok = volatile_ok;
6868 volatile_ok = true;
6869 result = maybe_legitimize_operand_same_code (icode, opno, op);
6870 volatile_ok = old_volatile_ok;
6871 return result;
6873 case EXPAND_OUTPUT:
6874 gcc_assert (mode != VOIDmode);
6875 if (op->value
6876 && op->value != const0_rtx
6877 && GET_MODE (op->value) == mode
6878 && maybe_legitimize_operand_same_code (icode, opno, op))
6879 return true;
6881 op->value = gen_reg_rtx (mode);
6882 break;
6884 case EXPAND_INPUT:
6885 input:
6886 gcc_assert (mode != VOIDmode);
6887 gcc_assert (GET_MODE (op->value) == VOIDmode
6888 || GET_MODE (op->value) == mode);
6889 if (maybe_legitimize_operand_same_code (icode, opno, op))
6890 return true;
6892 op->value = copy_to_mode_reg (mode, op->value);
6893 break;
6895 case EXPAND_CONVERT_TO:
6896 gcc_assert (mode != VOIDmode);
6897 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
6898 goto input;
6900 case EXPAND_CONVERT_FROM:
6901 if (GET_MODE (op->value) != VOIDmode)
6902 mode = GET_MODE (op->value);
6903 else
6904 /* The caller must tell us what mode this value has. */
6905 gcc_assert (mode != VOIDmode);
6907 imode = insn_data[(int) icode].operand[opno].mode;
6908 if (imode != VOIDmode && imode != mode)
6910 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
6911 mode = imode;
6913 goto input;
6915 case EXPAND_ADDRESS:
6916 gcc_assert (mode != VOIDmode);
6917 op->value = convert_memory_address (mode, op->value);
6918 goto input;
6920 case EXPAND_INTEGER:
6921 mode = insn_data[(int) icode].operand[opno].mode;
6922 if (mode != VOIDmode && const_int_operand (op->value, mode))
6923 goto input;
6924 break;
6926 return insn_operand_matches (icode, opno, op->value);
6929 /* Make OP describe an input operand that should have the same value
6930 as VALUE, after any mode conversion that the target might request.
6931 TYPE is the type of VALUE. */
6933 void
6934 create_convert_operand_from_type (struct expand_operand *op,
6935 rtx value, tree type)
6937 create_convert_operand_from (op, value, TYPE_MODE (type),
6938 TYPE_UNSIGNED (type));
6941 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
6942 of instruction ICODE. Return true on success, leaving the new operand
6943 values in the OPS themselves. Emit no code on failure. */
6945 bool
6946 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
6947 unsigned int nops, struct expand_operand *ops)
6949 rtx_insn *last;
6950 unsigned int i;
6952 last = get_last_insn ();
6953 for (i = 0; i < nops; i++)
6954 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
6956 delete_insns_since (last);
6957 return false;
6959 return true;
6962 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
6963 as its operands. Return the instruction pattern on success,
6964 and emit any necessary set-up code. Return null and emit no
6965 code on failure. */
6967 rtx_insn *
6968 maybe_gen_insn (enum insn_code icode, unsigned int nops,
6969 struct expand_operand *ops)
6971 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
6972 if (!maybe_legitimize_operands (icode, 0, nops, ops))
6973 return NULL;
6975 switch (nops)
6977 case 1:
6978 return GEN_FCN (icode) (ops[0].value);
6979 case 2:
6980 return GEN_FCN (icode) (ops[0].value, ops[1].value);
6981 case 3:
6982 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
6983 case 4:
6984 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6985 ops[3].value);
6986 case 5:
6987 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6988 ops[3].value, ops[4].value);
6989 case 6:
6990 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6991 ops[3].value, ops[4].value, ops[5].value);
6992 case 7:
6993 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6994 ops[3].value, ops[4].value, ops[5].value,
6995 ops[6].value);
6996 case 8:
6997 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6998 ops[3].value, ops[4].value, ops[5].value,
6999 ops[6].value, ops[7].value);
7000 case 9:
7001 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
7002 ops[3].value, ops[4].value, ops[5].value,
7003 ops[6].value, ops[7].value, ops[8].value);
7005 gcc_unreachable ();
7008 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
7009 as its operands. Return true on success and emit no code on failure. */
7011 bool
7012 maybe_expand_insn (enum insn_code icode, unsigned int nops,
7013 struct expand_operand *ops)
7015 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7016 if (pat)
7018 emit_insn (pat);
7019 return true;
7021 return false;
7024 /* Like maybe_expand_insn, but for jumps. */
7026 bool
7027 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
7028 struct expand_operand *ops)
7030 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
7031 if (pat)
7033 emit_jump_insn (pat);
7034 return true;
7036 return false;
7039 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
7040 as its operands. */
7042 void
7043 expand_insn (enum insn_code icode, unsigned int nops,
7044 struct expand_operand *ops)
7046 if (!maybe_expand_insn (icode, nops, ops))
7047 gcc_unreachable ();
7050 /* Like expand_insn, but for jumps. */
7052 void
7053 expand_jump_insn (enum insn_code icode, unsigned int nops,
7054 struct expand_operand *ops)
7056 if (!maybe_expand_jump_insn (icode, nops, ops))
7057 gcc_unreachable ();