re PR middle-end/68046 (-ftrapv doesn't catch leaq-based overflows on x86-64)
[gcc.git] / gcc / optabs.c
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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/>. */
19
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "predict.h"
26 #include "diagnostic-core.h"
27
28 /* Include insn-config.h before expr.h so that HAVE_conditional_move
29 is properly defined. */
30 #include "insn-config.h"
31 #include "rtl.h"
32 #include "alias.h"
33 #include "tree.h"
34 #include "tree-hasher.h"
35 #include "stor-layout.h"
36 #include "tm_p.h"
37 #include "flags.h"
38 #include "except.h"
39 #include "expmed.h"
40 #include "dojump.h"
41 #include "explow.h"
42 #include "calls.h"
43 #include "emit-rtl.h"
44 #include "stmt.h"
45 #include "expr.h"
46 #include "insn-codes.h"
47 #include "optabs.h"
48 #include "optabs-tree.h"
49 #include "libfuncs.h"
50 #include "recog.h"
51 #include "reload.h"
52 #include "target.h"
53
54 static void prepare_float_lib_cmp (rtx, rtx, enum rtx_code, rtx *,
55 machine_mode *);
56 static rtx expand_unop_direct (machine_mode, optab, rtx, rtx, int);
57 static void emit_libcall_block_1 (rtx_insn *, rtx, rtx, rtx, bool);
58
59 /* Debug facility for use in GDB. */
60 void debug_optab_libfuncs (void);
61 \f
62 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
63 the result of operation CODE applied to OP0 (and OP1 if it is a binary
64 operation).
65
66 If the last insn does not set TARGET, don't do anything, but return 1.
67
68 If the last insn or a previous insn sets TARGET and TARGET is one of OP0
69 or OP1, don't add the REG_EQUAL note but return 0. Our caller can then
70 try again, ensuring that TARGET is not one of the operands. */
71
72 static int
73 add_equal_note (rtx_insn *insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
74 {
75 rtx_insn *last_insn;
76 rtx set;
77 rtx note;
78
79 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
80
81 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
82 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
83 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
84 && GET_RTX_CLASS (code) != RTX_COMPARE
85 && GET_RTX_CLASS (code) != RTX_UNARY)
86 return 1;
87
88 if (GET_CODE (target) == ZERO_EXTRACT)
89 return 1;
90
91 for (last_insn = insns;
92 NEXT_INSN (last_insn) != NULL_RTX;
93 last_insn = NEXT_INSN (last_insn))
94 ;
95
96 /* If TARGET is in OP0 or OP1, punt. We'd end up with a note referencing
97 a value changing in the insn, so the note would be invalid for CSE. */
98 if (reg_overlap_mentioned_p (target, op0)
99 || (op1 && reg_overlap_mentioned_p (target, op1)))
100 {
101 if (MEM_P (target)
102 && (rtx_equal_p (target, op0)
103 || (op1 && rtx_equal_p (target, op1))))
104 {
105 /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
106 over expanding it as temp = MEM op X, MEM = temp. If the target
107 supports MEM = MEM op X instructions, it is sometimes too hard
108 to reconstruct that form later, especially if X is also a memory,
109 and due to multiple occurrences of addresses the address might
110 be forced into register unnecessarily.
111 Note that not emitting the REG_EQUIV note might inhibit
112 CSE in some cases. */
113 set = single_set (last_insn);
114 if (set
115 && GET_CODE (SET_SRC (set)) == code
116 && MEM_P (SET_DEST (set))
117 && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
118 || (op1 && rtx_equal_p (SET_DEST (set),
119 XEXP (SET_SRC (set), 1)))))
120 return 1;
121 }
122 return 0;
123 }
124
125 set = set_for_reg_notes (last_insn);
126 if (set == NULL_RTX)
127 return 1;
128
129 if (! rtx_equal_p (SET_DEST (set), target)
130 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
131 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
132 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
133 return 1;
134
135 if (GET_RTX_CLASS (code) == RTX_UNARY)
136 switch (code)
137 {
138 case FFS:
139 case CLZ:
140 case CTZ:
141 case CLRSB:
142 case POPCOUNT:
143 case PARITY:
144 case BSWAP:
145 if (GET_MODE (op0) != VOIDmode && GET_MODE (target) != GET_MODE (op0))
146 {
147 note = gen_rtx_fmt_e (code, GET_MODE (op0), copy_rtx (op0));
148 if (GET_MODE_SIZE (GET_MODE (op0))
149 > GET_MODE_SIZE (GET_MODE (target)))
150 note = simplify_gen_unary (TRUNCATE, GET_MODE (target),
151 note, GET_MODE (op0));
152 else
153 note = simplify_gen_unary (ZERO_EXTEND, GET_MODE (target),
154 note, GET_MODE (op0));
155 break;
156 }
157 /* FALLTHRU */
158 default:
159 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
160 break;
161 }
162 else
163 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
164
165 set_unique_reg_note (last_insn, REG_EQUAL, note);
166
167 return 1;
168 }
169 \f
170 /* Given two input operands, OP0 and OP1, determine what the correct from_mode
171 for a widening operation would be. In most cases this would be OP0, but if
172 that's a constant it'll be VOIDmode, which isn't useful. */
173
174 static machine_mode
175 widened_mode (machine_mode to_mode, rtx op0, rtx op1)
176 {
177 machine_mode m0 = GET_MODE (op0);
178 machine_mode m1 = GET_MODE (op1);
179 machine_mode result;
180
181 if (m0 == VOIDmode && m1 == VOIDmode)
182 return to_mode;
183 else if (m0 == VOIDmode || GET_MODE_SIZE (m0) < GET_MODE_SIZE (m1))
184 result = m1;
185 else
186 result = m0;
187
188 if (GET_MODE_SIZE (result) > GET_MODE_SIZE (to_mode))
189 return to_mode;
190
191 return result;
192 }
193 \f
194 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
195 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
196 not actually do a sign-extend or zero-extend, but can leave the
197 higher-order bits of the result rtx undefined, for example, in the case
198 of logical operations, but not right shifts. */
199
200 static rtx
201 widen_operand (rtx op, machine_mode mode, machine_mode oldmode,
202 int unsignedp, int no_extend)
203 {
204 rtx result;
205
206 /* If we don't have to extend and this is a constant, return it. */
207 if (no_extend && GET_MODE (op) == VOIDmode)
208 return op;
209
210 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
211 extend since it will be more efficient to do so unless the signedness of
212 a promoted object differs from our extension. */
213 if (! no_extend
214 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
215 && SUBREG_CHECK_PROMOTED_SIGN (op, unsignedp)))
216 return convert_modes (mode, oldmode, op, unsignedp);
217
218 /* If MODE is no wider than a single word, we return a lowpart or paradoxical
219 SUBREG. */
220 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
221 return gen_lowpart (mode, force_reg (GET_MODE (op), op));
222
223 /* Otherwise, get an object of MODE, clobber it, and set the low-order
224 part to OP. */
225
226 result = gen_reg_rtx (mode);
227 emit_clobber (result);
228 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
229 return result;
230 }
231 \f
232 /* Expand vector widening operations.
233
234 There are two different classes of operations handled here:
235 1) Operations whose result is wider than all the arguments to the operation.
236 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
237 In this case OP0 and optionally OP1 would be initialized,
238 but WIDE_OP wouldn't (not relevant for this case).
239 2) Operations whose result is of the same size as the last argument to the
240 operation, but wider than all the other arguments to the operation.
241 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
242 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
243
244 E.g, when called to expand the following operations, this is how
245 the arguments will be initialized:
246 nops OP0 OP1 WIDE_OP
247 widening-sum 2 oprnd0 - oprnd1
248 widening-dot-product 3 oprnd0 oprnd1 oprnd2
249 widening-mult 2 oprnd0 oprnd1 -
250 type-promotion (vec-unpack) 1 oprnd0 - - */
251
252 rtx
253 expand_widen_pattern_expr (sepops ops, rtx op0, rtx op1, rtx wide_op,
254 rtx target, int unsignedp)
255 {
256 struct expand_operand eops[4];
257 tree oprnd0, oprnd1, oprnd2;
258 machine_mode wmode = VOIDmode, tmode0, tmode1 = VOIDmode;
259 optab widen_pattern_optab;
260 enum insn_code icode;
261 int nops = TREE_CODE_LENGTH (ops->code);
262 int op;
263
264 oprnd0 = ops->op0;
265 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
266 widen_pattern_optab =
267 optab_for_tree_code (ops->code, TREE_TYPE (oprnd0), optab_default);
268 if (ops->code == WIDEN_MULT_PLUS_EXPR
269 || ops->code == WIDEN_MULT_MINUS_EXPR)
270 icode = find_widening_optab_handler (widen_pattern_optab,
271 TYPE_MODE (TREE_TYPE (ops->op2)),
272 tmode0, 0);
273 else
274 icode = optab_handler (widen_pattern_optab, tmode0);
275 gcc_assert (icode != CODE_FOR_nothing);
276
277 if (nops >= 2)
278 {
279 oprnd1 = ops->op1;
280 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
281 }
282
283 /* The last operand is of a wider mode than the rest of the operands. */
284 if (nops == 2)
285 wmode = tmode1;
286 else if (nops == 3)
287 {
288 gcc_assert (tmode1 == tmode0);
289 gcc_assert (op1);
290 oprnd2 = ops->op2;
291 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
292 }
293
294 op = 0;
295 create_output_operand (&eops[op++], target, TYPE_MODE (ops->type));
296 create_convert_operand_from (&eops[op++], op0, tmode0, unsignedp);
297 if (op1)
298 create_convert_operand_from (&eops[op++], op1, tmode1, unsignedp);
299 if (wide_op)
300 create_convert_operand_from (&eops[op++], wide_op, wmode, unsignedp);
301 expand_insn (icode, op, eops);
302 return eops[0].value;
303 }
304
305 /* Generate code to perform an operation specified by TERNARY_OPTAB
306 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
307
308 UNSIGNEDP is for the case where we have to widen the operands
309 to perform the operation. It says to use zero-extension.
310
311 If TARGET is nonzero, the value
312 is generated there, if it is convenient to do so.
313 In all cases an rtx is returned for the locus of the value;
314 this may or may not be TARGET. */
315
316 rtx
317 expand_ternary_op (machine_mode mode, optab ternary_optab, rtx op0,
318 rtx op1, rtx op2, rtx target, int unsignedp)
319 {
320 struct expand_operand ops[4];
321 enum insn_code icode = optab_handler (ternary_optab, mode);
322
323 gcc_assert (optab_handler (ternary_optab, mode) != CODE_FOR_nothing);
324
325 create_output_operand (&ops[0], target, mode);
326 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
327 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
328 create_convert_operand_from (&ops[3], op2, mode, unsignedp);
329 expand_insn (icode, 4, ops);
330 return ops[0].value;
331 }
332
333
334 /* Like expand_binop, but return a constant rtx if the result can be
335 calculated at compile time. The arguments and return value are
336 otherwise the same as for expand_binop. */
337
338 rtx
339 simplify_expand_binop (machine_mode mode, optab binoptab,
340 rtx op0, rtx op1, rtx target, int unsignedp,
341 enum optab_methods methods)
342 {
343 if (CONSTANT_P (op0) && CONSTANT_P (op1))
344 {
345 rtx x = simplify_binary_operation (optab_to_code (binoptab),
346 mode, op0, op1);
347 if (x)
348 return x;
349 }
350
351 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
352 }
353
354 /* Like simplify_expand_binop, but always put the result in TARGET.
355 Return true if the expansion succeeded. */
356
357 bool
358 force_expand_binop (machine_mode mode, optab binoptab,
359 rtx op0, rtx op1, rtx target, int unsignedp,
360 enum optab_methods methods)
361 {
362 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
363 target, unsignedp, methods);
364 if (x == 0)
365 return false;
366 if (x != target)
367 emit_move_insn (target, x);
368 return true;
369 }
370
371 /* Create a new vector value in VMODE with all elements set to OP. The
372 mode of OP must be the element mode of VMODE. If OP is a constant,
373 then the return value will be a constant. */
374
375 static rtx
376 expand_vector_broadcast (machine_mode vmode, rtx op)
377 {
378 enum insn_code icode;
379 rtvec vec;
380 rtx ret;
381 int i, n;
382
383 gcc_checking_assert (VECTOR_MODE_P (vmode));
384
385 n = GET_MODE_NUNITS (vmode);
386 vec = rtvec_alloc (n);
387 for (i = 0; i < n; ++i)
388 RTVEC_ELT (vec, i) = op;
389
390 if (CONSTANT_P (op))
391 return gen_rtx_CONST_VECTOR (vmode, vec);
392
393 /* ??? If the target doesn't have a vec_init, then we have no easy way
394 of performing this operation. Most of this sort of generic support
395 is hidden away in the vector lowering support in gimple. */
396 icode = optab_handler (vec_init_optab, vmode);
397 if (icode == CODE_FOR_nothing)
398 return NULL;
399
400 ret = gen_reg_rtx (vmode);
401 emit_insn (GEN_FCN (icode) (ret, gen_rtx_PARALLEL (vmode, vec)));
402
403 return ret;
404 }
405
406 /* This subroutine of expand_doubleword_shift handles the cases in which
407 the effective shift value is >= BITS_PER_WORD. The arguments and return
408 value are the same as for the parent routine, except that SUPERWORD_OP1
409 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
410 INTO_TARGET may be null if the caller has decided to calculate it. */
411
412 static bool
413 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
414 rtx outof_target, rtx into_target,
415 int unsignedp, enum optab_methods methods)
416 {
417 if (into_target != 0)
418 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
419 into_target, unsignedp, methods))
420 return false;
421
422 if (outof_target != 0)
423 {
424 /* For a signed right shift, we must fill OUTOF_TARGET with copies
425 of the sign bit, otherwise we must fill it with zeros. */
426 if (binoptab != ashr_optab)
427 emit_move_insn (outof_target, CONST0_RTX (word_mode));
428 else
429 if (!force_expand_binop (word_mode, binoptab,
430 outof_input, GEN_INT (BITS_PER_WORD - 1),
431 outof_target, unsignedp, methods))
432 return false;
433 }
434 return true;
435 }
436
437 /* This subroutine of expand_doubleword_shift handles the cases in which
438 the effective shift value is < BITS_PER_WORD. The arguments and return
439 value are the same as for the parent routine. */
440
441 static bool
442 expand_subword_shift (machine_mode op1_mode, optab binoptab,
443 rtx outof_input, rtx into_input, rtx op1,
444 rtx outof_target, rtx into_target,
445 int unsignedp, enum optab_methods methods,
446 unsigned HOST_WIDE_INT shift_mask)
447 {
448 optab reverse_unsigned_shift, unsigned_shift;
449 rtx tmp, carries;
450
451 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
452 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
453
454 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
455 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
456 the opposite direction to BINOPTAB. */
457 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
458 {
459 carries = outof_input;
460 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD,
461 op1_mode), op1_mode);
462 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
463 0, true, methods);
464 }
465 else
466 {
467 /* We must avoid shifting by BITS_PER_WORD bits since that is either
468 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
469 has unknown behavior. Do a single shift first, then shift by the
470 remainder. It's OK to use ~OP1 as the remainder if shift counts
471 are truncated to the mode size. */
472 carries = expand_binop (word_mode, reverse_unsigned_shift,
473 outof_input, const1_rtx, 0, unsignedp, methods);
474 if (shift_mask == BITS_PER_WORD - 1)
475 {
476 tmp = immed_wide_int_const
477 (wi::minus_one (GET_MODE_PRECISION (op1_mode)), op1_mode);
478 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
479 0, true, methods);
480 }
481 else
482 {
483 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD - 1,
484 op1_mode), op1_mode);
485 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
486 0, true, methods);
487 }
488 }
489 if (tmp == 0 || carries == 0)
490 return false;
491 carries = expand_binop (word_mode, reverse_unsigned_shift,
492 carries, tmp, 0, unsignedp, methods);
493 if (carries == 0)
494 return false;
495
496 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
497 so the result can go directly into INTO_TARGET if convenient. */
498 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
499 into_target, unsignedp, methods);
500 if (tmp == 0)
501 return false;
502
503 /* Now OR in the bits carried over from OUTOF_INPUT. */
504 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
505 into_target, unsignedp, methods))
506 return false;
507
508 /* Use a standard word_mode shift for the out-of half. */
509 if (outof_target != 0)
510 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
511 outof_target, unsignedp, methods))
512 return false;
513
514 return true;
515 }
516
517
518 /* Try implementing expand_doubleword_shift using conditional moves.
519 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
520 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
521 are the shift counts to use in the former and latter case. All other
522 arguments are the same as the parent routine. */
523
524 static bool
525 expand_doubleword_shift_condmove (machine_mode op1_mode, optab binoptab,
526 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
527 rtx outof_input, rtx into_input,
528 rtx subword_op1, rtx superword_op1,
529 rtx outof_target, rtx into_target,
530 int unsignedp, enum optab_methods methods,
531 unsigned HOST_WIDE_INT shift_mask)
532 {
533 rtx outof_superword, into_superword;
534
535 /* Put the superword version of the output into OUTOF_SUPERWORD and
536 INTO_SUPERWORD. */
537 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
538 if (outof_target != 0 && subword_op1 == superword_op1)
539 {
540 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
541 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
542 into_superword = outof_target;
543 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
544 outof_superword, 0, unsignedp, methods))
545 return false;
546 }
547 else
548 {
549 into_superword = gen_reg_rtx (word_mode);
550 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
551 outof_superword, into_superword,
552 unsignedp, methods))
553 return false;
554 }
555
556 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
557 if (!expand_subword_shift (op1_mode, binoptab,
558 outof_input, into_input, subword_op1,
559 outof_target, into_target,
560 unsignedp, methods, shift_mask))
561 return false;
562
563 /* Select between them. Do the INTO half first because INTO_SUPERWORD
564 might be the current value of OUTOF_TARGET. */
565 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
566 into_target, into_superword, word_mode, false))
567 return false;
568
569 if (outof_target != 0)
570 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
571 outof_target, outof_superword,
572 word_mode, false))
573 return false;
574
575 return true;
576 }
577
578 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
579 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
580 input operand; the shift moves bits in the direction OUTOF_INPUT->
581 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
582 of the target. OP1 is the shift count and OP1_MODE is its mode.
583 If OP1 is constant, it will have been truncated as appropriate
584 and is known to be nonzero.
585
586 If SHIFT_MASK is zero, the result of word shifts is undefined when the
587 shift count is outside the range [0, BITS_PER_WORD). This routine must
588 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
589
590 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
591 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
592 fill with zeros or sign bits as appropriate.
593
594 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
595 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
596 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
597 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
598 are undefined.
599
600 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
601 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
602 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
603 function wants to calculate it itself.
604
605 Return true if the shift could be successfully synthesized. */
606
607 static bool
608 expand_doubleword_shift (machine_mode op1_mode, optab binoptab,
609 rtx outof_input, rtx into_input, rtx op1,
610 rtx outof_target, rtx into_target,
611 int unsignedp, enum optab_methods methods,
612 unsigned HOST_WIDE_INT shift_mask)
613 {
614 rtx superword_op1, tmp, cmp1, cmp2;
615 enum rtx_code cmp_code;
616
617 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
618 fill the result with sign or zero bits as appropriate. If so, the value
619 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
620 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
621 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
622
623 This isn't worthwhile for constant shifts since the optimizers will
624 cope better with in-range shift counts. */
625 if (shift_mask >= BITS_PER_WORD
626 && outof_target != 0
627 && !CONSTANT_P (op1))
628 {
629 if (!expand_doubleword_shift (op1_mode, binoptab,
630 outof_input, into_input, op1,
631 0, into_target,
632 unsignedp, methods, shift_mask))
633 return false;
634 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
635 outof_target, unsignedp, methods))
636 return false;
637 return true;
638 }
639
640 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
641 is true when the effective shift value is less than BITS_PER_WORD.
642 Set SUPERWORD_OP1 to the shift count that should be used to shift
643 OUTOF_INPUT into INTO_TARGET when the condition is false. */
644 tmp = immed_wide_int_const (wi::shwi (BITS_PER_WORD, op1_mode), op1_mode);
645 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
646 {
647 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
648 is a subword shift count. */
649 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
650 0, true, methods);
651 cmp2 = CONST0_RTX (op1_mode);
652 cmp_code = EQ;
653 superword_op1 = op1;
654 }
655 else
656 {
657 /* Set CMP1 to OP1 - BITS_PER_WORD. */
658 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
659 0, true, methods);
660 cmp2 = CONST0_RTX (op1_mode);
661 cmp_code = LT;
662 superword_op1 = cmp1;
663 }
664 if (cmp1 == 0)
665 return false;
666
667 /* If we can compute the condition at compile time, pick the
668 appropriate subroutine. */
669 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
670 if (tmp != 0 && CONST_INT_P (tmp))
671 {
672 if (tmp == const0_rtx)
673 return expand_superword_shift (binoptab, outof_input, superword_op1,
674 outof_target, into_target,
675 unsignedp, methods);
676 else
677 return expand_subword_shift (op1_mode, binoptab,
678 outof_input, into_input, op1,
679 outof_target, into_target,
680 unsignedp, methods, shift_mask);
681 }
682
683 /* Try using conditional moves to generate straight-line code. */
684 if (HAVE_conditional_move)
685 {
686 rtx_insn *start = get_last_insn ();
687 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
688 cmp_code, cmp1, cmp2,
689 outof_input, into_input,
690 op1, superword_op1,
691 outof_target, into_target,
692 unsignedp, methods, shift_mask))
693 return true;
694 delete_insns_since (start);
695 }
696
697 /* As a last resort, use branches to select the correct alternative. */
698 rtx_code_label *subword_label = gen_label_rtx ();
699 rtx_code_label *done_label = gen_label_rtx ();
700
701 NO_DEFER_POP;
702 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
703 0, 0, subword_label, -1);
704 OK_DEFER_POP;
705
706 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
707 outof_target, into_target,
708 unsignedp, methods))
709 return false;
710
711 emit_jump_insn (targetm.gen_jump (done_label));
712 emit_barrier ();
713 emit_label (subword_label);
714
715 if (!expand_subword_shift (op1_mode, binoptab,
716 outof_input, into_input, op1,
717 outof_target, into_target,
718 unsignedp, methods, shift_mask))
719 return false;
720
721 emit_label (done_label);
722 return true;
723 }
724 \f
725 /* Subroutine of expand_binop. Perform a double word multiplication of
726 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
727 as the target's word_mode. This function return NULL_RTX if anything
728 goes wrong, in which case it may have already emitted instructions
729 which need to be deleted.
730
731 If we want to multiply two two-word values and have normal and widening
732 multiplies of single-word values, we can do this with three smaller
733 multiplications.
734
735 The multiplication proceeds as follows:
736 _______________________
737 [__op0_high_|__op0_low__]
738 _______________________
739 * [__op1_high_|__op1_low__]
740 _______________________________________________
741 _______________________
742 (1) [__op0_low__*__op1_low__]
743 _______________________
744 (2a) [__op0_low__*__op1_high_]
745 _______________________
746 (2b) [__op0_high_*__op1_low__]
747 _______________________
748 (3) [__op0_high_*__op1_high_]
749
750
751 This gives a 4-word result. Since we are only interested in the
752 lower 2 words, partial result (3) and the upper words of (2a) and
753 (2b) don't need to be calculated. Hence (2a) and (2b) can be
754 calculated using non-widening multiplication.
755
756 (1), however, needs to be calculated with an unsigned widening
757 multiplication. If this operation is not directly supported we
758 try using a signed widening multiplication and adjust the result.
759 This adjustment works as follows:
760
761 If both operands are positive then no adjustment is needed.
762
763 If the operands have different signs, for example op0_low < 0 and
764 op1_low >= 0, the instruction treats the most significant bit of
765 op0_low as a sign bit instead of a bit with significance
766 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
767 with 2**BITS_PER_WORD - op0_low, and two's complements the
768 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
769 the result.
770
771 Similarly, if both operands are negative, we need to add
772 (op0_low + op1_low) * 2**BITS_PER_WORD.
773
774 We use a trick to adjust quickly. We logically shift op0_low right
775 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
776 op0_high (op1_high) before it is used to calculate 2b (2a). If no
777 logical shift exists, we do an arithmetic right shift and subtract
778 the 0 or -1. */
779
780 static rtx
781 expand_doubleword_mult (machine_mode mode, rtx op0, rtx op1, rtx target,
782 bool umulp, enum optab_methods methods)
783 {
784 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
785 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
786 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
787 rtx product, adjust, product_high, temp;
788
789 rtx op0_high = operand_subword_force (op0, high, mode);
790 rtx op0_low = operand_subword_force (op0, low, mode);
791 rtx op1_high = operand_subword_force (op1, high, mode);
792 rtx op1_low = operand_subword_force (op1, low, mode);
793
794 /* If we're using an unsigned multiply to directly compute the product
795 of the low-order words of the operands and perform any required
796 adjustments of the operands, we begin by trying two more multiplications
797 and then computing the appropriate sum.
798
799 We have checked above that the required addition is provided.
800 Full-word addition will normally always succeed, especially if
801 it is provided at all, so we don't worry about its failure. The
802 multiplication may well fail, however, so we do handle that. */
803
804 if (!umulp)
805 {
806 /* ??? This could be done with emit_store_flag where available. */
807 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
808 NULL_RTX, 1, methods);
809 if (temp)
810 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
811 NULL_RTX, 0, OPTAB_DIRECT);
812 else
813 {
814 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
815 NULL_RTX, 0, methods);
816 if (!temp)
817 return NULL_RTX;
818 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
819 NULL_RTX, 0, OPTAB_DIRECT);
820 }
821
822 if (!op0_high)
823 return NULL_RTX;
824 }
825
826 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
827 NULL_RTX, 0, OPTAB_DIRECT);
828 if (!adjust)
829 return NULL_RTX;
830
831 /* OP0_HIGH should now be dead. */
832
833 if (!umulp)
834 {
835 /* ??? This could be done with emit_store_flag where available. */
836 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
837 NULL_RTX, 1, methods);
838 if (temp)
839 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
840 NULL_RTX, 0, OPTAB_DIRECT);
841 else
842 {
843 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
844 NULL_RTX, 0, methods);
845 if (!temp)
846 return NULL_RTX;
847 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
848 NULL_RTX, 0, OPTAB_DIRECT);
849 }
850
851 if (!op1_high)
852 return NULL_RTX;
853 }
854
855 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
856 NULL_RTX, 0, OPTAB_DIRECT);
857 if (!temp)
858 return NULL_RTX;
859
860 /* OP1_HIGH should now be dead. */
861
862 adjust = expand_binop (word_mode, add_optab, adjust, temp,
863 NULL_RTX, 0, OPTAB_DIRECT);
864
865 if (target && !REG_P (target))
866 target = NULL_RTX;
867
868 if (umulp)
869 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
870 target, 1, OPTAB_DIRECT);
871 else
872 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
873 target, 1, OPTAB_DIRECT);
874
875 if (!product)
876 return NULL_RTX;
877
878 product_high = operand_subword (product, high, 1, mode);
879 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
880 NULL_RTX, 0, OPTAB_DIRECT);
881 emit_move_insn (product_high, adjust);
882 return product;
883 }
884 \f
885 /* Wrapper around expand_binop which takes an rtx code to specify
886 the operation to perform, not an optab pointer. All other
887 arguments are the same. */
888 rtx
889 expand_simple_binop (machine_mode mode, enum rtx_code code, rtx op0,
890 rtx op1, rtx target, int unsignedp,
891 enum optab_methods methods)
892 {
893 optab binop = code_to_optab (code);
894 gcc_assert (binop);
895
896 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
897 }
898
899 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
900 binop. Order them according to commutative_operand_precedence and, if
901 possible, try to put TARGET or a pseudo first. */
902 static bool
903 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
904 {
905 int op0_prec = commutative_operand_precedence (op0);
906 int op1_prec = commutative_operand_precedence (op1);
907
908 if (op0_prec < op1_prec)
909 return true;
910
911 if (op0_prec > op1_prec)
912 return false;
913
914 /* With equal precedence, both orders are ok, but it is better if the
915 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
916 if (target == 0 || REG_P (target))
917 return (REG_P (op1) && !REG_P (op0)) || target == op1;
918 else
919 return rtx_equal_p (op1, target);
920 }
921
922 /* Return true if BINOPTAB implements a shift operation. */
923
924 static bool
925 shift_optab_p (optab binoptab)
926 {
927 switch (optab_to_code (binoptab))
928 {
929 case ASHIFT:
930 case SS_ASHIFT:
931 case US_ASHIFT:
932 case ASHIFTRT:
933 case LSHIFTRT:
934 case ROTATE:
935 case ROTATERT:
936 return true;
937
938 default:
939 return false;
940 }
941 }
942
943 /* Return true if BINOPTAB implements a commutative binary operation. */
944
945 static bool
946 commutative_optab_p (optab binoptab)
947 {
948 return (GET_RTX_CLASS (optab_to_code (binoptab)) == RTX_COMM_ARITH
949 || binoptab == smul_widen_optab
950 || binoptab == umul_widen_optab
951 || binoptab == smul_highpart_optab
952 || binoptab == umul_highpart_optab);
953 }
954
955 /* X is to be used in mode MODE as operand OPN to BINOPTAB. If we're
956 optimizing, and if the operand is a constant that costs more than
957 1 instruction, force the constant into a register and return that
958 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
959
960 static rtx
961 avoid_expensive_constant (machine_mode mode, optab binoptab,
962 int opn, rtx x, bool unsignedp)
963 {
964 bool speed = optimize_insn_for_speed_p ();
965
966 if (mode != VOIDmode
967 && optimize
968 && CONSTANT_P (x)
969 && (rtx_cost (x, mode, optab_to_code (binoptab), opn, speed)
970 > set_src_cost (x, mode, speed)))
971 {
972 if (CONST_INT_P (x))
973 {
974 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
975 if (intval != INTVAL (x))
976 x = GEN_INT (intval);
977 }
978 else
979 x = convert_modes (mode, VOIDmode, x, unsignedp);
980 x = force_reg (mode, x);
981 }
982 return x;
983 }
984
985 /* Helper function for expand_binop: handle the case where there
986 is an insn that directly implements the indicated operation.
987 Returns null if this is not possible. */
988 static rtx
989 expand_binop_directly (machine_mode mode, optab binoptab,
990 rtx op0, rtx op1,
991 rtx target, int unsignedp, enum optab_methods methods,
992 rtx_insn *last)
993 {
994 machine_mode from_mode = widened_mode (mode, op0, op1);
995 enum insn_code icode = find_widening_optab_handler (binoptab, mode,
996 from_mode, 1);
997 machine_mode xmode0 = insn_data[(int) icode].operand[1].mode;
998 machine_mode xmode1 = insn_data[(int) icode].operand[2].mode;
999 machine_mode mode0, mode1, tmp_mode;
1000 struct expand_operand ops[3];
1001 bool commutative_p;
1002 rtx_insn *pat;
1003 rtx xop0 = op0, xop1 = op1;
1004
1005 /* If it is a commutative operator and the modes would match
1006 if we would swap the operands, we can save the conversions. */
1007 commutative_p = commutative_optab_p (binoptab);
1008 if (commutative_p
1009 && GET_MODE (xop0) != xmode0 && GET_MODE (xop1) != xmode1
1010 && GET_MODE (xop0) == xmode1 && GET_MODE (xop1) == xmode1)
1011 std::swap (xop0, xop1);
1012
1013 /* If we are optimizing, force expensive constants into a register. */
1014 xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp);
1015 if (!shift_optab_p (binoptab))
1016 xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp);
1017
1018 /* In case the insn wants input operands in modes different from
1019 those of the actual operands, convert the operands. It would
1020 seem that we don't need to convert CONST_INTs, but we do, so
1021 that they're properly zero-extended, sign-extended or truncated
1022 for their mode. */
1023
1024 mode0 = GET_MODE (xop0) != VOIDmode ? GET_MODE (xop0) : mode;
1025 if (xmode0 != VOIDmode && xmode0 != mode0)
1026 {
1027 xop0 = convert_modes (xmode0, mode0, xop0, unsignedp);
1028 mode0 = xmode0;
1029 }
1030
1031 mode1 = GET_MODE (xop1) != VOIDmode ? GET_MODE (xop1) : mode;
1032 if (xmode1 != VOIDmode && xmode1 != mode1)
1033 {
1034 xop1 = convert_modes (xmode1, mode1, xop1, unsignedp);
1035 mode1 = xmode1;
1036 }
1037
1038 /* If operation is commutative,
1039 try to make the first operand a register.
1040 Even better, try to make it the same as the target.
1041 Also try to make the last operand a constant. */
1042 if (commutative_p
1043 && swap_commutative_operands_with_target (target, xop0, xop1))
1044 std::swap (xop0, xop1);
1045
1046 /* Now, if insn's predicates don't allow our operands, put them into
1047 pseudo regs. */
1048
1049 if (binoptab == vec_pack_trunc_optab
1050 || binoptab == vec_pack_usat_optab
1051 || binoptab == vec_pack_ssat_optab
1052 || binoptab == vec_pack_ufix_trunc_optab
1053 || binoptab == vec_pack_sfix_trunc_optab)
1054 {
1055 /* The mode of the result is different then the mode of the
1056 arguments. */
1057 tmp_mode = insn_data[(int) icode].operand[0].mode;
1058 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1059 {
1060 delete_insns_since (last);
1061 return NULL_RTX;
1062 }
1063 }
1064 else
1065 tmp_mode = mode;
1066
1067 create_output_operand (&ops[0], target, tmp_mode);
1068 create_input_operand (&ops[1], xop0, mode0);
1069 create_input_operand (&ops[2], xop1, mode1);
1070 pat = maybe_gen_insn (icode, 3, ops);
1071 if (pat)
1072 {
1073 /* If PAT is composed of more than one insn, try to add an appropriate
1074 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1075 operand, call expand_binop again, this time without a target. */
1076 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1077 && ! add_equal_note (pat, ops[0].value,
1078 optab_to_code (binoptab),
1079 ops[1].value, ops[2].value))
1080 {
1081 delete_insns_since (last);
1082 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1083 unsignedp, methods);
1084 }
1085
1086 emit_insn (pat);
1087 return ops[0].value;
1088 }
1089 delete_insns_since (last);
1090 return NULL_RTX;
1091 }
1092
1093 /* Generate code to perform an operation specified by BINOPTAB
1094 on operands OP0 and OP1, with result having machine-mode MODE.
1095
1096 UNSIGNEDP is for the case where we have to widen the operands
1097 to perform the operation. It says to use zero-extension.
1098
1099 If TARGET is nonzero, the value
1100 is generated there, if it is convenient to do so.
1101 In all cases an rtx is returned for the locus of the value;
1102 this may or may not be TARGET. */
1103
1104 rtx
1105 expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
1106 rtx target, int unsignedp, enum optab_methods methods)
1107 {
1108 enum optab_methods next_methods
1109 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1110 ? OPTAB_WIDEN : methods);
1111 enum mode_class mclass;
1112 machine_mode wider_mode;
1113 rtx libfunc;
1114 rtx temp;
1115 rtx_insn *entry_last = get_last_insn ();
1116 rtx_insn *last;
1117
1118 mclass = GET_MODE_CLASS (mode);
1119
1120 /* If subtracting an integer constant, convert this into an addition of
1121 the negated constant. */
1122
1123 if (binoptab == sub_optab && CONST_INT_P (op1))
1124 {
1125 op1 = negate_rtx (mode, op1);
1126 binoptab = add_optab;
1127 }
1128
1129 /* Record where to delete back to if we backtrack. */
1130 last = get_last_insn ();
1131
1132 /* If we can do it with a three-operand insn, do so. */
1133
1134 if (methods != OPTAB_MUST_WIDEN
1135 && find_widening_optab_handler (binoptab, mode,
1136 widened_mode (mode, op0, op1), 1)
1137 != CODE_FOR_nothing)
1138 {
1139 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1140 unsignedp, methods, last);
1141 if (temp)
1142 return temp;
1143 }
1144
1145 /* If we were trying to rotate, and that didn't work, try rotating
1146 the other direction before falling back to shifts and bitwise-or. */
1147 if (((binoptab == rotl_optab
1148 && optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
1149 || (binoptab == rotr_optab
1150 && optab_handler (rotl_optab, mode) != CODE_FOR_nothing))
1151 && mclass == MODE_INT)
1152 {
1153 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1154 rtx newop1;
1155 unsigned int bits = GET_MODE_PRECISION (mode);
1156
1157 if (CONST_INT_P (op1))
1158 newop1 = GEN_INT (bits - INTVAL (op1));
1159 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1160 newop1 = negate_rtx (GET_MODE (op1), op1);
1161 else
1162 newop1 = expand_binop (GET_MODE (op1), sub_optab,
1163 gen_int_mode (bits, GET_MODE (op1)), op1,
1164 NULL_RTX, unsignedp, OPTAB_DIRECT);
1165
1166 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1167 target, unsignedp, methods, last);
1168 if (temp)
1169 return temp;
1170 }
1171
1172 /* If this is a multiply, see if we can do a widening operation that
1173 takes operands of this mode and makes a wider mode. */
1174
1175 if (binoptab == smul_optab
1176 && GET_MODE_2XWIDER_MODE (mode) != VOIDmode
1177 && (widening_optab_handler ((unsignedp ? umul_widen_optab
1178 : smul_widen_optab),
1179 GET_MODE_2XWIDER_MODE (mode), mode)
1180 != CODE_FOR_nothing))
1181 {
1182 temp = expand_binop (GET_MODE_2XWIDER_MODE (mode),
1183 unsignedp ? umul_widen_optab : smul_widen_optab,
1184 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1185
1186 if (temp != 0)
1187 {
1188 if (GET_MODE_CLASS (mode) == MODE_INT
1189 && TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (temp)))
1190 return gen_lowpart (mode, temp);
1191 else
1192 return convert_to_mode (mode, temp, unsignedp);
1193 }
1194 }
1195
1196 /* If this is a vector shift by a scalar, see if we can do a vector
1197 shift by a vector. If so, broadcast the scalar into a vector. */
1198 if (mclass == MODE_VECTOR_INT)
1199 {
1200 optab otheroptab = unknown_optab;
1201
1202 if (binoptab == ashl_optab)
1203 otheroptab = vashl_optab;
1204 else if (binoptab == ashr_optab)
1205 otheroptab = vashr_optab;
1206 else if (binoptab == lshr_optab)
1207 otheroptab = vlshr_optab;
1208 else if (binoptab == rotl_optab)
1209 otheroptab = vrotl_optab;
1210 else if (binoptab == rotr_optab)
1211 otheroptab = vrotr_optab;
1212
1213 if (otheroptab && optab_handler (otheroptab, mode) != CODE_FOR_nothing)
1214 {
1215 /* The scalar may have been extended to be too wide. Truncate
1216 it back to the proper size to fit in the broadcast vector. */
1217 machine_mode inner_mode = GET_MODE_INNER (mode);
1218 if (!CONST_INT_P (op1)
1219 && (GET_MODE_BITSIZE (inner_mode)
1220 < GET_MODE_BITSIZE (GET_MODE (op1))))
1221 op1 = force_reg (inner_mode,
1222 simplify_gen_unary (TRUNCATE, inner_mode, op1,
1223 GET_MODE (op1)));
1224 rtx vop1 = expand_vector_broadcast (mode, op1);
1225 if (vop1)
1226 {
1227 temp = expand_binop_directly (mode, otheroptab, op0, vop1,
1228 target, unsignedp, methods, last);
1229 if (temp)
1230 return temp;
1231 }
1232 }
1233 }
1234
1235 /* Look for a wider mode of the same class for which we think we
1236 can open-code the operation. Check for a widening multiply at the
1237 wider mode as well. */
1238
1239 if (CLASS_HAS_WIDER_MODES_P (mclass)
1240 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1241 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1242 wider_mode != VOIDmode;
1243 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1244 {
1245 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
1246 || (binoptab == smul_optab
1247 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1248 && (find_widening_optab_handler ((unsignedp
1249 ? umul_widen_optab
1250 : smul_widen_optab),
1251 GET_MODE_WIDER_MODE (wider_mode),
1252 mode, 0)
1253 != CODE_FOR_nothing)))
1254 {
1255 rtx xop0 = op0, xop1 = op1;
1256 int no_extend = 0;
1257
1258 /* For certain integer operations, we need not actually extend
1259 the narrow operands, as long as we will truncate
1260 the results to the same narrowness. */
1261
1262 if ((binoptab == ior_optab || binoptab == and_optab
1263 || binoptab == xor_optab
1264 || binoptab == add_optab || binoptab == sub_optab
1265 || binoptab == smul_optab || binoptab == ashl_optab)
1266 && mclass == MODE_INT)
1267 {
1268 no_extend = 1;
1269 xop0 = avoid_expensive_constant (mode, binoptab, 0,
1270 xop0, unsignedp);
1271 if (binoptab != ashl_optab)
1272 xop1 = avoid_expensive_constant (mode, binoptab, 1,
1273 xop1, unsignedp);
1274 }
1275
1276 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1277
1278 /* The second operand of a shift must always be extended. */
1279 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1280 no_extend && binoptab != ashl_optab);
1281
1282 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1283 unsignedp, OPTAB_DIRECT);
1284 if (temp)
1285 {
1286 if (mclass != MODE_INT
1287 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1288 {
1289 if (target == 0)
1290 target = gen_reg_rtx (mode);
1291 convert_move (target, temp, 0);
1292 return target;
1293 }
1294 else
1295 return gen_lowpart (mode, temp);
1296 }
1297 else
1298 delete_insns_since (last);
1299 }
1300 }
1301
1302 /* If operation is commutative,
1303 try to make the first operand a register.
1304 Even better, try to make it the same as the target.
1305 Also try to make the last operand a constant. */
1306 if (commutative_optab_p (binoptab)
1307 && swap_commutative_operands_with_target (target, op0, op1))
1308 std::swap (op0, op1);
1309
1310 /* These can be done a word at a time. */
1311 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1312 && mclass == MODE_INT
1313 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1314 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1315 {
1316 int i;
1317 rtx_insn *insns;
1318
1319 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1320 won't be accurate, so use a new target. */
1321 if (target == 0
1322 || target == op0
1323 || target == op1
1324 || !valid_multiword_target_p (target))
1325 target = gen_reg_rtx (mode);
1326
1327 start_sequence ();
1328
1329 /* Do the actual arithmetic. */
1330 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1331 {
1332 rtx target_piece = operand_subword (target, i, 1, mode);
1333 rtx x = expand_binop (word_mode, binoptab,
1334 operand_subword_force (op0, i, mode),
1335 operand_subword_force (op1, i, mode),
1336 target_piece, unsignedp, next_methods);
1337
1338 if (x == 0)
1339 break;
1340
1341 if (target_piece != x)
1342 emit_move_insn (target_piece, x);
1343 }
1344
1345 insns = get_insns ();
1346 end_sequence ();
1347
1348 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1349 {
1350 emit_insn (insns);
1351 return target;
1352 }
1353 }
1354
1355 /* Synthesize double word shifts from single word shifts. */
1356 if ((binoptab == lshr_optab || binoptab == ashl_optab
1357 || binoptab == ashr_optab)
1358 && mclass == MODE_INT
1359 && (CONST_INT_P (op1) || optimize_insn_for_speed_p ())
1360 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1361 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode)
1362 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing
1363 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1364 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1365 {
1366 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1367 machine_mode op1_mode;
1368
1369 double_shift_mask = targetm.shift_truncation_mask (mode);
1370 shift_mask = targetm.shift_truncation_mask (word_mode);
1371 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1372
1373 /* Apply the truncation to constant shifts. */
1374 if (double_shift_mask > 0 && CONST_INT_P (op1))
1375 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1376
1377 if (op1 == CONST0_RTX (op1_mode))
1378 return op0;
1379
1380 /* Make sure that this is a combination that expand_doubleword_shift
1381 can handle. See the comments there for details. */
1382 if (double_shift_mask == 0
1383 || (shift_mask == BITS_PER_WORD - 1
1384 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1385 {
1386 rtx_insn *insns;
1387 rtx into_target, outof_target;
1388 rtx into_input, outof_input;
1389 int left_shift, outof_word;
1390
1391 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1392 won't be accurate, so use a new target. */
1393 if (target == 0
1394 || target == op0
1395 || target == op1
1396 || !valid_multiword_target_p (target))
1397 target = gen_reg_rtx (mode);
1398
1399 start_sequence ();
1400
1401 /* OUTOF_* is the word we are shifting bits away from, and
1402 INTO_* is the word that we are shifting bits towards, thus
1403 they differ depending on the direction of the shift and
1404 WORDS_BIG_ENDIAN. */
1405
1406 left_shift = binoptab == ashl_optab;
1407 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1408
1409 outof_target = operand_subword (target, outof_word, 1, mode);
1410 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1411
1412 outof_input = operand_subword_force (op0, outof_word, mode);
1413 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1414
1415 if (expand_doubleword_shift (op1_mode, binoptab,
1416 outof_input, into_input, op1,
1417 outof_target, into_target,
1418 unsignedp, next_methods, shift_mask))
1419 {
1420 insns = get_insns ();
1421 end_sequence ();
1422
1423 emit_insn (insns);
1424 return target;
1425 }
1426 end_sequence ();
1427 }
1428 }
1429
1430 /* Synthesize double word rotates from single word shifts. */
1431 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1432 && mclass == MODE_INT
1433 && CONST_INT_P (op1)
1434 && GET_MODE_PRECISION (mode) == 2 * BITS_PER_WORD
1435 && optab_handler (ashl_optab, word_mode) != CODE_FOR_nothing
1436 && optab_handler (lshr_optab, word_mode) != CODE_FOR_nothing)
1437 {
1438 rtx_insn *insns;
1439 rtx into_target, outof_target;
1440 rtx into_input, outof_input;
1441 rtx inter;
1442 int shift_count, left_shift, outof_word;
1443
1444 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1445 won't be accurate, so use a new target. Do this also if target is not
1446 a REG, first because having a register instead may open optimization
1447 opportunities, and second because if target and op0 happen to be MEMs
1448 designating the same location, we would risk clobbering it too early
1449 in the code sequence we generate below. */
1450 if (target == 0
1451 || target == op0
1452 || target == op1
1453 || !REG_P (target)
1454 || !valid_multiword_target_p (target))
1455 target = gen_reg_rtx (mode);
1456
1457 start_sequence ();
1458
1459 shift_count = INTVAL (op1);
1460
1461 /* OUTOF_* is the word we are shifting bits away from, and
1462 INTO_* is the word that we are shifting bits towards, thus
1463 they differ depending on the direction of the shift and
1464 WORDS_BIG_ENDIAN. */
1465
1466 left_shift = (binoptab == rotl_optab);
1467 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1468
1469 outof_target = operand_subword (target, outof_word, 1, mode);
1470 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1471
1472 outof_input = operand_subword_force (op0, outof_word, mode);
1473 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1474
1475 if (shift_count == BITS_PER_WORD)
1476 {
1477 /* This is just a word swap. */
1478 emit_move_insn (outof_target, into_input);
1479 emit_move_insn (into_target, outof_input);
1480 inter = const0_rtx;
1481 }
1482 else
1483 {
1484 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1485 rtx first_shift_count, second_shift_count;
1486 optab reverse_unsigned_shift, unsigned_shift;
1487
1488 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1489 ? lshr_optab : ashl_optab);
1490
1491 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1492 ? ashl_optab : lshr_optab);
1493
1494 if (shift_count > BITS_PER_WORD)
1495 {
1496 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1497 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1498 }
1499 else
1500 {
1501 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1502 second_shift_count = GEN_INT (shift_count);
1503 }
1504
1505 into_temp1 = expand_binop (word_mode, unsigned_shift,
1506 outof_input, first_shift_count,
1507 NULL_RTX, unsignedp, next_methods);
1508 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1509 into_input, second_shift_count,
1510 NULL_RTX, unsignedp, next_methods);
1511
1512 if (into_temp1 != 0 && into_temp2 != 0)
1513 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1514 into_target, unsignedp, next_methods);
1515 else
1516 inter = 0;
1517
1518 if (inter != 0 && inter != into_target)
1519 emit_move_insn (into_target, inter);
1520
1521 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1522 into_input, first_shift_count,
1523 NULL_RTX, unsignedp, next_methods);
1524 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1525 outof_input, second_shift_count,
1526 NULL_RTX, unsignedp, next_methods);
1527
1528 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1529 inter = expand_binop (word_mode, ior_optab,
1530 outof_temp1, outof_temp2,
1531 outof_target, unsignedp, next_methods);
1532
1533 if (inter != 0 && inter != outof_target)
1534 emit_move_insn (outof_target, inter);
1535 }
1536
1537 insns = get_insns ();
1538 end_sequence ();
1539
1540 if (inter != 0)
1541 {
1542 emit_insn (insns);
1543 return target;
1544 }
1545 }
1546
1547 /* These can be done a word at a time by propagating carries. */
1548 if ((binoptab == add_optab || binoptab == sub_optab)
1549 && mclass == MODE_INT
1550 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1551 && optab_handler (binoptab, word_mode) != CODE_FOR_nothing)
1552 {
1553 unsigned int i;
1554 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1555 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1556 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1557 rtx xop0, xop1, xtarget;
1558
1559 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1560 value is one of those, use it. Otherwise, use 1 since it is the
1561 one easiest to get. */
1562 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1563 int normalizep = STORE_FLAG_VALUE;
1564 #else
1565 int normalizep = 1;
1566 #endif
1567
1568 /* Prepare the operands. */
1569 xop0 = force_reg (mode, op0);
1570 xop1 = force_reg (mode, op1);
1571
1572 xtarget = gen_reg_rtx (mode);
1573
1574 if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
1575 target = xtarget;
1576
1577 /* Indicate for flow that the entire target reg is being set. */
1578 if (REG_P (target))
1579 emit_clobber (xtarget);
1580
1581 /* Do the actual arithmetic. */
1582 for (i = 0; i < nwords; i++)
1583 {
1584 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1585 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1586 rtx op0_piece = operand_subword_force (xop0, index, mode);
1587 rtx op1_piece = operand_subword_force (xop1, index, mode);
1588 rtx x;
1589
1590 /* Main add/subtract of the input operands. */
1591 x = expand_binop (word_mode, binoptab,
1592 op0_piece, op1_piece,
1593 target_piece, unsignedp, next_methods);
1594 if (x == 0)
1595 break;
1596
1597 if (i + 1 < nwords)
1598 {
1599 /* Store carry from main add/subtract. */
1600 carry_out = gen_reg_rtx (word_mode);
1601 carry_out = emit_store_flag_force (carry_out,
1602 (binoptab == add_optab
1603 ? LT : GT),
1604 x, op0_piece,
1605 word_mode, 1, normalizep);
1606 }
1607
1608 if (i > 0)
1609 {
1610 rtx newx;
1611
1612 /* Add/subtract previous carry to main result. */
1613 newx = expand_binop (word_mode,
1614 normalizep == 1 ? binoptab : otheroptab,
1615 x, carry_in,
1616 NULL_RTX, 1, next_methods);
1617
1618 if (i + 1 < nwords)
1619 {
1620 /* Get out carry from adding/subtracting carry in. */
1621 rtx carry_tmp = gen_reg_rtx (word_mode);
1622 carry_tmp = emit_store_flag_force (carry_tmp,
1623 (binoptab == add_optab
1624 ? LT : GT),
1625 newx, x,
1626 word_mode, 1, normalizep);
1627
1628 /* Logical-ior the two poss. carry together. */
1629 carry_out = expand_binop (word_mode, ior_optab,
1630 carry_out, carry_tmp,
1631 carry_out, 0, next_methods);
1632 if (carry_out == 0)
1633 break;
1634 }
1635 emit_move_insn (target_piece, newx);
1636 }
1637 else
1638 {
1639 if (x != target_piece)
1640 emit_move_insn (target_piece, x);
1641 }
1642
1643 carry_in = carry_out;
1644 }
1645
1646 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1647 {
1648 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing
1649 || ! rtx_equal_p (target, xtarget))
1650 {
1651 rtx_insn *temp = emit_move_insn (target, xtarget);
1652
1653 set_dst_reg_note (temp, REG_EQUAL,
1654 gen_rtx_fmt_ee (optab_to_code (binoptab),
1655 mode, copy_rtx (xop0),
1656 copy_rtx (xop1)),
1657 target);
1658 }
1659 else
1660 target = xtarget;
1661
1662 return target;
1663 }
1664
1665 else
1666 delete_insns_since (last);
1667 }
1668
1669 /* Attempt to synthesize double word multiplies using a sequence of word
1670 mode multiplications. We first attempt to generate a sequence using a
1671 more efficient unsigned widening multiply, and if that fails we then
1672 try using a signed widening multiply. */
1673
1674 if (binoptab == smul_optab
1675 && mclass == MODE_INT
1676 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1677 && optab_handler (smul_optab, word_mode) != CODE_FOR_nothing
1678 && optab_handler (add_optab, word_mode) != CODE_FOR_nothing)
1679 {
1680 rtx product = NULL_RTX;
1681 if (widening_optab_handler (umul_widen_optab, mode, word_mode)
1682 != CODE_FOR_nothing)
1683 {
1684 product = expand_doubleword_mult (mode, op0, op1, target,
1685 true, methods);
1686 if (!product)
1687 delete_insns_since (last);
1688 }
1689
1690 if (product == NULL_RTX
1691 && widening_optab_handler (smul_widen_optab, mode, word_mode)
1692 != CODE_FOR_nothing)
1693 {
1694 product = expand_doubleword_mult (mode, op0, op1, target,
1695 false, methods);
1696 if (!product)
1697 delete_insns_since (last);
1698 }
1699
1700 if (product != NULL_RTX)
1701 {
1702 if (optab_handler (mov_optab, mode) != CODE_FOR_nothing)
1703 {
1704 temp = emit_move_insn (target ? target : product, product);
1705 set_dst_reg_note (temp,
1706 REG_EQUAL,
1707 gen_rtx_fmt_ee (MULT, mode,
1708 copy_rtx (op0),
1709 copy_rtx (op1)),
1710 target ? target : product);
1711 }
1712 return product;
1713 }
1714 }
1715
1716 /* It can't be open-coded in this mode.
1717 Use a library call if one is available and caller says that's ok. */
1718
1719 libfunc = optab_libfunc (binoptab, mode);
1720 if (libfunc
1721 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1722 {
1723 rtx_insn *insns;
1724 rtx op1x = op1;
1725 machine_mode op1_mode = mode;
1726 rtx value;
1727
1728 start_sequence ();
1729
1730 if (shift_optab_p (binoptab))
1731 {
1732 op1_mode = targetm.libgcc_shift_count_mode ();
1733 /* Specify unsigned here,
1734 since negative shift counts are meaningless. */
1735 op1x = convert_to_mode (op1_mode, op1, 1);
1736 }
1737
1738 if (GET_MODE (op0) != VOIDmode
1739 && GET_MODE (op0) != mode)
1740 op0 = convert_to_mode (mode, op0, unsignedp);
1741
1742 /* Pass 1 for NO_QUEUE so we don't lose any increments
1743 if the libcall is cse'd or moved. */
1744 value = emit_library_call_value (libfunc,
1745 NULL_RTX, LCT_CONST, mode, 2,
1746 op0, mode, op1x, op1_mode);
1747
1748 insns = get_insns ();
1749 end_sequence ();
1750
1751 bool trapv = trapv_binoptab_p (binoptab);
1752 target = gen_reg_rtx (mode);
1753 emit_libcall_block_1 (insns, target, value,
1754 trapv ? NULL_RTX
1755 : gen_rtx_fmt_ee (optab_to_code (binoptab),
1756 mode, op0, op1), trapv);
1757
1758 return target;
1759 }
1760
1761 delete_insns_since (last);
1762
1763 /* It can't be done in this mode. Can we do it in a wider mode? */
1764
1765 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1766 || methods == OPTAB_MUST_WIDEN))
1767 {
1768 /* Caller says, don't even try. */
1769 delete_insns_since (entry_last);
1770 return 0;
1771 }
1772
1773 /* Compute the value of METHODS to pass to recursive calls.
1774 Don't allow widening to be tried recursively. */
1775
1776 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1777
1778 /* Look for a wider mode of the same class for which it appears we can do
1779 the operation. */
1780
1781 if (CLASS_HAS_WIDER_MODES_P (mclass))
1782 {
1783 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1784 wider_mode != VOIDmode;
1785 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1786 {
1787 if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
1788 != CODE_FOR_nothing
1789 || (methods == OPTAB_LIB
1790 && optab_libfunc (binoptab, wider_mode)))
1791 {
1792 rtx xop0 = op0, xop1 = op1;
1793 int no_extend = 0;
1794
1795 /* For certain integer operations, we need not actually extend
1796 the narrow operands, as long as we will truncate
1797 the results to the same narrowness. */
1798
1799 if ((binoptab == ior_optab || binoptab == and_optab
1800 || binoptab == xor_optab
1801 || binoptab == add_optab || binoptab == sub_optab
1802 || binoptab == smul_optab || binoptab == ashl_optab)
1803 && mclass == MODE_INT)
1804 no_extend = 1;
1805
1806 xop0 = widen_operand (xop0, wider_mode, mode,
1807 unsignedp, no_extend);
1808
1809 /* The second operand of a shift must always be extended. */
1810 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1811 no_extend && binoptab != ashl_optab);
1812
1813 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1814 unsignedp, methods);
1815 if (temp)
1816 {
1817 if (mclass != MODE_INT
1818 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
1819 {
1820 if (target == 0)
1821 target = gen_reg_rtx (mode);
1822 convert_move (target, temp, 0);
1823 return target;
1824 }
1825 else
1826 return gen_lowpart (mode, temp);
1827 }
1828 else
1829 delete_insns_since (last);
1830 }
1831 }
1832 }
1833
1834 delete_insns_since (entry_last);
1835 return 0;
1836 }
1837 \f
1838 /* Expand a binary operator which has both signed and unsigned forms.
1839 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1840 signed operations.
1841
1842 If we widen unsigned operands, we may use a signed wider operation instead
1843 of an unsigned wider operation, since the result would be the same. */
1844
1845 rtx
1846 sign_expand_binop (machine_mode mode, optab uoptab, optab soptab,
1847 rtx op0, rtx op1, rtx target, int unsignedp,
1848 enum optab_methods methods)
1849 {
1850 rtx temp;
1851 optab direct_optab = unsignedp ? uoptab : soptab;
1852 bool save_enable;
1853
1854 /* Do it without widening, if possible. */
1855 temp = expand_binop (mode, direct_optab, op0, op1, target,
1856 unsignedp, OPTAB_DIRECT);
1857 if (temp || methods == OPTAB_DIRECT)
1858 return temp;
1859
1860 /* Try widening to a signed int. Disable any direct use of any
1861 signed insn in the current mode. */
1862 save_enable = swap_optab_enable (soptab, mode, false);
1863
1864 temp = expand_binop (mode, soptab, op0, op1, target,
1865 unsignedp, OPTAB_WIDEN);
1866
1867 /* For unsigned operands, try widening to an unsigned int. */
1868 if (!temp && unsignedp)
1869 temp = expand_binop (mode, uoptab, op0, op1, target,
1870 unsignedp, OPTAB_WIDEN);
1871 if (temp || methods == OPTAB_WIDEN)
1872 goto egress;
1873
1874 /* Use the right width libcall if that exists. */
1875 temp = expand_binop (mode, direct_optab, op0, op1, target,
1876 unsignedp, OPTAB_LIB);
1877 if (temp || methods == OPTAB_LIB)
1878 goto egress;
1879
1880 /* Must widen and use a libcall, use either signed or unsigned. */
1881 temp = expand_binop (mode, soptab, op0, op1, target,
1882 unsignedp, methods);
1883 if (!temp && unsignedp)
1884 temp = expand_binop (mode, uoptab, op0, op1, target,
1885 unsignedp, methods);
1886
1887 egress:
1888 /* Undo the fiddling above. */
1889 if (save_enable)
1890 swap_optab_enable (soptab, mode, true);
1891 return temp;
1892 }
1893 \f
1894 /* Generate code to perform an operation specified by UNOPPTAB
1895 on operand OP0, with two results to TARG0 and TARG1.
1896 We assume that the order of the operands for the instruction
1897 is TARG0, TARG1, OP0.
1898
1899 Either TARG0 or TARG1 may be zero, but what that means is that
1900 the result is not actually wanted. We will generate it into
1901 a dummy pseudo-reg and discard it. They may not both be zero.
1902
1903 Returns 1 if this operation can be performed; 0 if not. */
1904
1905 int
1906 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1907 int unsignedp)
1908 {
1909 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1910 enum mode_class mclass;
1911 machine_mode wider_mode;
1912 rtx_insn *entry_last = get_last_insn ();
1913 rtx_insn *last;
1914
1915 mclass = GET_MODE_CLASS (mode);
1916
1917 if (!targ0)
1918 targ0 = gen_reg_rtx (mode);
1919 if (!targ1)
1920 targ1 = gen_reg_rtx (mode);
1921
1922 /* Record where to go back to if we fail. */
1923 last = get_last_insn ();
1924
1925 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
1926 {
1927 struct expand_operand ops[3];
1928 enum insn_code icode = optab_handler (unoptab, mode);
1929
1930 create_fixed_operand (&ops[0], targ0);
1931 create_fixed_operand (&ops[1], targ1);
1932 create_convert_operand_from (&ops[2], op0, mode, unsignedp);
1933 if (maybe_expand_insn (icode, 3, ops))
1934 return 1;
1935 }
1936
1937 /* It can't be done in this mode. Can we do it in a wider mode? */
1938
1939 if (CLASS_HAS_WIDER_MODES_P (mclass))
1940 {
1941 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1942 wider_mode != VOIDmode;
1943 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1944 {
1945 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
1946 {
1947 rtx t0 = gen_reg_rtx (wider_mode);
1948 rtx t1 = gen_reg_rtx (wider_mode);
1949 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1950
1951 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
1952 {
1953 convert_move (targ0, t0, unsignedp);
1954 convert_move (targ1, t1, unsignedp);
1955 return 1;
1956 }
1957 else
1958 delete_insns_since (last);
1959 }
1960 }
1961 }
1962
1963 delete_insns_since (entry_last);
1964 return 0;
1965 }
1966 \f
1967 /* Generate code to perform an operation specified by BINOPTAB
1968 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1969 We assume that the order of the operands for the instruction
1970 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1971 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1972
1973 Either TARG0 or TARG1 may be zero, but what that means is that
1974 the result is not actually wanted. We will generate it into
1975 a dummy pseudo-reg and discard it. They may not both be zero.
1976
1977 Returns 1 if this operation can be performed; 0 if not. */
1978
1979 int
1980 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
1981 int unsignedp)
1982 {
1983 machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1984 enum mode_class mclass;
1985 machine_mode wider_mode;
1986 rtx_insn *entry_last = get_last_insn ();
1987 rtx_insn *last;
1988
1989 mclass = GET_MODE_CLASS (mode);
1990
1991 if (!targ0)
1992 targ0 = gen_reg_rtx (mode);
1993 if (!targ1)
1994 targ1 = gen_reg_rtx (mode);
1995
1996 /* Record where to go back to if we fail. */
1997 last = get_last_insn ();
1998
1999 if (optab_handler (binoptab, mode) != CODE_FOR_nothing)
2000 {
2001 struct expand_operand ops[4];
2002 enum insn_code icode = optab_handler (binoptab, mode);
2003 machine_mode mode0 = insn_data[icode].operand[1].mode;
2004 machine_mode mode1 = insn_data[icode].operand[2].mode;
2005 rtx xop0 = op0, xop1 = op1;
2006
2007 /* If we are optimizing, force expensive constants into a register. */
2008 xop0 = avoid_expensive_constant (mode0, binoptab, 0, xop0, unsignedp);
2009 xop1 = avoid_expensive_constant (mode1, binoptab, 1, xop1, unsignedp);
2010
2011 create_fixed_operand (&ops[0], targ0);
2012 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2013 create_convert_operand_from (&ops[2], op1, mode, unsignedp);
2014 create_fixed_operand (&ops[3], targ1);
2015 if (maybe_expand_insn (icode, 4, ops))
2016 return 1;
2017 delete_insns_since (last);
2018 }
2019
2020 /* It can't be done in this mode. Can we do it in a wider mode? */
2021
2022 if (CLASS_HAS_WIDER_MODES_P (mclass))
2023 {
2024 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2025 wider_mode != VOIDmode;
2026 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2027 {
2028 if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
2029 {
2030 rtx t0 = gen_reg_rtx (wider_mode);
2031 rtx t1 = gen_reg_rtx (wider_mode);
2032 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2033 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2034
2035 if (expand_twoval_binop (binoptab, cop0, cop1,
2036 t0, t1, unsignedp))
2037 {
2038 convert_move (targ0, t0, unsignedp);
2039 convert_move (targ1, t1, unsignedp);
2040 return 1;
2041 }
2042 else
2043 delete_insns_since (last);
2044 }
2045 }
2046 }
2047
2048 delete_insns_since (entry_last);
2049 return 0;
2050 }
2051
2052 /* Expand the two-valued library call indicated by BINOPTAB, but
2053 preserve only one of the values. If TARG0 is non-NULL, the first
2054 value is placed into TARG0; otherwise the second value is placed
2055 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2056 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2057 This routine assumes that the value returned by the library call is
2058 as if the return value was of an integral mode twice as wide as the
2059 mode of OP0. Returns 1 if the call was successful. */
2060
2061 bool
2062 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2063 rtx targ0, rtx targ1, enum rtx_code code)
2064 {
2065 machine_mode mode;
2066 machine_mode libval_mode;
2067 rtx libval;
2068 rtx_insn *insns;
2069 rtx libfunc;
2070
2071 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2072 gcc_assert (!targ0 != !targ1);
2073
2074 mode = GET_MODE (op0);
2075 libfunc = optab_libfunc (binoptab, mode);
2076 if (!libfunc)
2077 return false;
2078
2079 /* The value returned by the library function will have twice as
2080 many bits as the nominal MODE. */
2081 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2082 MODE_INT);
2083 start_sequence ();
2084 libval = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
2085 libval_mode, 2,
2086 op0, mode,
2087 op1, mode);
2088 /* Get the part of VAL containing the value that we want. */
2089 libval = simplify_gen_subreg (mode, libval, libval_mode,
2090 targ0 ? 0 : GET_MODE_SIZE (mode));
2091 insns = get_insns ();
2092 end_sequence ();
2093 /* Move the into the desired location. */
2094 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2095 gen_rtx_fmt_ee (code, mode, op0, op1));
2096
2097 return true;
2098 }
2099
2100 \f
2101 /* Wrapper around expand_unop which takes an rtx code to specify
2102 the operation to perform, not an optab pointer. All other
2103 arguments are the same. */
2104 rtx
2105 expand_simple_unop (machine_mode mode, enum rtx_code code, rtx op0,
2106 rtx target, int unsignedp)
2107 {
2108 optab unop = code_to_optab (code);
2109 gcc_assert (unop);
2110
2111 return expand_unop (mode, unop, op0, target, unsignedp);
2112 }
2113
2114 /* Try calculating
2115 (clz:narrow x)
2116 as
2117 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)).
2118
2119 A similar operation can be used for clrsb. UNOPTAB says which operation
2120 we are trying to expand. */
2121 static rtx
2122 widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab)
2123 {
2124 enum mode_class mclass = GET_MODE_CLASS (mode);
2125 if (CLASS_HAS_WIDER_MODES_P (mclass))
2126 {
2127 machine_mode wider_mode;
2128 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2129 wider_mode != VOIDmode;
2130 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2131 {
2132 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2133 {
2134 rtx xop0, temp;
2135 rtx_insn *last;
2136
2137 last = get_last_insn ();
2138
2139 if (target == 0)
2140 target = gen_reg_rtx (mode);
2141 xop0 = widen_operand (op0, wider_mode, mode,
2142 unoptab != clrsb_optab, false);
2143 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2144 unoptab != clrsb_optab);
2145 if (temp != 0)
2146 temp = expand_binop
2147 (wider_mode, sub_optab, temp,
2148 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2149 - GET_MODE_PRECISION (mode),
2150 wider_mode),
2151 target, true, OPTAB_DIRECT);
2152 if (temp == 0)
2153 delete_insns_since (last);
2154
2155 return temp;
2156 }
2157 }
2158 }
2159 return 0;
2160 }
2161
2162 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2163 quantities, choosing which based on whether the high word is nonzero. */
2164 static rtx
2165 expand_doubleword_clz (machine_mode mode, rtx op0, rtx target)
2166 {
2167 rtx xop0 = force_reg (mode, op0);
2168 rtx subhi = gen_highpart (word_mode, xop0);
2169 rtx sublo = gen_lowpart (word_mode, xop0);
2170 rtx_code_label *hi0_label = gen_label_rtx ();
2171 rtx_code_label *after_label = gen_label_rtx ();
2172 rtx_insn *seq;
2173 rtx temp, result;
2174
2175 /* If we were not given a target, use a word_mode register, not a
2176 'mode' register. The result will fit, and nobody is expecting
2177 anything bigger (the return type of __builtin_clz* is int). */
2178 if (!target)
2179 target = gen_reg_rtx (word_mode);
2180
2181 /* In any case, write to a word_mode scratch in both branches of the
2182 conditional, so we can ensure there is a single move insn setting
2183 'target' to tag a REG_EQUAL note on. */
2184 result = gen_reg_rtx (word_mode);
2185
2186 start_sequence ();
2187
2188 /* If the high word is not equal to zero,
2189 then clz of the full value is clz of the high word. */
2190 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2191 word_mode, true, hi0_label);
2192
2193 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2194 if (!temp)
2195 goto fail;
2196
2197 if (temp != result)
2198 convert_move (result, temp, true);
2199
2200 emit_jump_insn (targetm.gen_jump (after_label));
2201 emit_barrier ();
2202
2203 /* Else clz of the full value is clz of the low word plus the number
2204 of bits in the high word. */
2205 emit_label (hi0_label);
2206
2207 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2208 if (!temp)
2209 goto fail;
2210 temp = expand_binop (word_mode, add_optab, temp,
2211 gen_int_mode (GET_MODE_BITSIZE (word_mode), word_mode),
2212 result, true, OPTAB_DIRECT);
2213 if (!temp)
2214 goto fail;
2215 if (temp != result)
2216 convert_move (result, temp, true);
2217
2218 emit_label (after_label);
2219 convert_move (target, result, true);
2220
2221 seq = get_insns ();
2222 end_sequence ();
2223
2224 add_equal_note (seq, target, CLZ, xop0, 0);
2225 emit_insn (seq);
2226 return target;
2227
2228 fail:
2229 end_sequence ();
2230 return 0;
2231 }
2232
2233 /* Try calculating
2234 (bswap:narrow x)
2235 as
2236 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2237 static rtx
2238 widen_bswap (machine_mode mode, rtx op0, rtx target)
2239 {
2240 enum mode_class mclass = GET_MODE_CLASS (mode);
2241 machine_mode wider_mode;
2242 rtx x;
2243 rtx_insn *last;
2244
2245 if (!CLASS_HAS_WIDER_MODES_P (mclass))
2246 return NULL_RTX;
2247
2248 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2249 wider_mode != VOIDmode;
2250 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2251 if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
2252 goto found;
2253 return NULL_RTX;
2254
2255 found:
2256 last = get_last_insn ();
2257
2258 x = widen_operand (op0, wider_mode, mode, true, true);
2259 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2260
2261 gcc_assert (GET_MODE_PRECISION (wider_mode) == GET_MODE_BITSIZE (wider_mode)
2262 && GET_MODE_PRECISION (mode) == GET_MODE_BITSIZE (mode));
2263 if (x != 0)
2264 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2265 GET_MODE_BITSIZE (wider_mode)
2266 - GET_MODE_BITSIZE (mode),
2267 NULL_RTX, true);
2268
2269 if (x != 0)
2270 {
2271 if (target == 0)
2272 target = gen_reg_rtx (mode);
2273 emit_move_insn (target, gen_lowpart (mode, x));
2274 }
2275 else
2276 delete_insns_since (last);
2277
2278 return target;
2279 }
2280
2281 /* Try calculating bswap as two bswaps of two word-sized operands. */
2282
2283 static rtx
2284 expand_doubleword_bswap (machine_mode mode, rtx op, rtx target)
2285 {
2286 rtx t0, t1;
2287
2288 t1 = expand_unop (word_mode, bswap_optab,
2289 operand_subword_force (op, 0, mode), NULL_RTX, true);
2290 t0 = expand_unop (word_mode, bswap_optab,
2291 operand_subword_force (op, 1, mode), NULL_RTX, true);
2292
2293 if (target == 0 || !valid_multiword_target_p (target))
2294 target = gen_reg_rtx (mode);
2295 if (REG_P (target))
2296 emit_clobber (target);
2297 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2298 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2299
2300 return target;
2301 }
2302
2303 /* Try calculating (parity x) as (and (popcount x) 1), where
2304 popcount can also be done in a wider mode. */
2305 static rtx
2306 expand_parity (machine_mode mode, rtx op0, rtx target)
2307 {
2308 enum mode_class mclass = GET_MODE_CLASS (mode);
2309 if (CLASS_HAS_WIDER_MODES_P (mclass))
2310 {
2311 machine_mode wider_mode;
2312 for (wider_mode = mode; wider_mode != VOIDmode;
2313 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2314 {
2315 if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
2316 {
2317 rtx xop0, temp;
2318 rtx_insn *last;
2319
2320 last = get_last_insn ();
2321
2322 if (target == 0)
2323 target = gen_reg_rtx (mode);
2324 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2325 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2326 true);
2327 if (temp != 0)
2328 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2329 target, true, OPTAB_DIRECT);
2330 if (temp == 0)
2331 delete_insns_since (last);
2332
2333 return temp;
2334 }
2335 }
2336 }
2337 return 0;
2338 }
2339
2340 /* Try calculating ctz(x) as K - clz(x & -x) ,
2341 where K is GET_MODE_PRECISION(mode) - 1.
2342
2343 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2344 don't have to worry about what the hardware does in that case. (If
2345 the clz instruction produces the usual value at 0, which is K, the
2346 result of this code sequence will be -1; expand_ffs, below, relies
2347 on this. It might be nice to have it be K instead, for consistency
2348 with the (very few) processors that provide a ctz with a defined
2349 value, but that would take one more instruction, and it would be
2350 less convenient for expand_ffs anyway. */
2351
2352 static rtx
2353 expand_ctz (machine_mode mode, rtx op0, rtx target)
2354 {
2355 rtx_insn *seq;
2356 rtx temp;
2357
2358 if (optab_handler (clz_optab, mode) == CODE_FOR_nothing)
2359 return 0;
2360
2361 start_sequence ();
2362
2363 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2364 if (temp)
2365 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2366 true, OPTAB_DIRECT);
2367 if (temp)
2368 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2369 if (temp)
2370 temp = expand_binop (mode, sub_optab,
2371 gen_int_mode (GET_MODE_PRECISION (mode) - 1, mode),
2372 temp, target,
2373 true, OPTAB_DIRECT);
2374 if (temp == 0)
2375 {
2376 end_sequence ();
2377 return 0;
2378 }
2379
2380 seq = get_insns ();
2381 end_sequence ();
2382
2383 add_equal_note (seq, temp, CTZ, op0, 0);
2384 emit_insn (seq);
2385 return temp;
2386 }
2387
2388
2389 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2390 else with the sequence used by expand_clz.
2391
2392 The ffs builtin promises to return zero for a zero value and ctz/clz
2393 may have an undefined value in that case. If they do not give us a
2394 convenient value, we have to generate a test and branch. */
2395 static rtx
2396 expand_ffs (machine_mode mode, rtx op0, rtx target)
2397 {
2398 HOST_WIDE_INT val = 0;
2399 bool defined_at_zero = false;
2400 rtx temp;
2401 rtx_insn *seq;
2402
2403 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing)
2404 {
2405 start_sequence ();
2406
2407 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2408 if (!temp)
2409 goto fail;
2410
2411 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2412 }
2413 else if (optab_handler (clz_optab, mode) != CODE_FOR_nothing)
2414 {
2415 start_sequence ();
2416 temp = expand_ctz (mode, op0, 0);
2417 if (!temp)
2418 goto fail;
2419
2420 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2421 {
2422 defined_at_zero = true;
2423 val = (GET_MODE_PRECISION (mode) - 1) - val;
2424 }
2425 }
2426 else
2427 return 0;
2428
2429 if (defined_at_zero && val == -1)
2430 /* No correction needed at zero. */;
2431 else
2432 {
2433 /* We don't try to do anything clever with the situation found
2434 on some processors (eg Alpha) where ctz(0:mode) ==
2435 bitsize(mode). If someone can think of a way to send N to -1
2436 and leave alone all values in the range 0..N-1 (where N is a
2437 power of two), cheaper than this test-and-branch, please add it.
2438
2439 The test-and-branch is done after the operation itself, in case
2440 the operation sets condition codes that can be recycled for this.
2441 (This is true on i386, for instance.) */
2442
2443 rtx_code_label *nonzero_label = gen_label_rtx ();
2444 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2445 mode, true, nonzero_label);
2446
2447 convert_move (temp, GEN_INT (-1), false);
2448 emit_label (nonzero_label);
2449 }
2450
2451 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2452 to produce a value in the range 0..bitsize. */
2453 temp = expand_binop (mode, add_optab, temp, gen_int_mode (1, mode),
2454 target, false, OPTAB_DIRECT);
2455 if (!temp)
2456 goto fail;
2457
2458 seq = get_insns ();
2459 end_sequence ();
2460
2461 add_equal_note (seq, temp, FFS, op0, 0);
2462 emit_insn (seq);
2463 return temp;
2464
2465 fail:
2466 end_sequence ();
2467 return 0;
2468 }
2469
2470 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2471 conditions, VAL may already be a SUBREG against which we cannot generate
2472 a further SUBREG. In this case, we expect forcing the value into a
2473 register will work around the situation. */
2474
2475 static rtx
2476 lowpart_subreg_maybe_copy (machine_mode omode, rtx val,
2477 machine_mode imode)
2478 {
2479 rtx ret;
2480 ret = lowpart_subreg (omode, val, imode);
2481 if (ret == NULL)
2482 {
2483 val = force_reg (imode, val);
2484 ret = lowpart_subreg (omode, val, imode);
2485 gcc_assert (ret != NULL);
2486 }
2487 return ret;
2488 }
2489
2490 /* Expand a floating point absolute value or negation operation via a
2491 logical operation on the sign bit. */
2492
2493 static rtx
2494 expand_absneg_bit (enum rtx_code code, machine_mode mode,
2495 rtx op0, rtx target)
2496 {
2497 const struct real_format *fmt;
2498 int bitpos, word, nwords, i;
2499 machine_mode imode;
2500 rtx temp;
2501 rtx_insn *insns;
2502
2503 /* The format has to have a simple sign bit. */
2504 fmt = REAL_MODE_FORMAT (mode);
2505 if (fmt == NULL)
2506 return NULL_RTX;
2507
2508 bitpos = fmt->signbit_rw;
2509 if (bitpos < 0)
2510 return NULL_RTX;
2511
2512 /* Don't create negative zeros if the format doesn't support them. */
2513 if (code == NEG && !fmt->has_signed_zero)
2514 return NULL_RTX;
2515
2516 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2517 {
2518 imode = int_mode_for_mode (mode);
2519 if (imode == BLKmode)
2520 return NULL_RTX;
2521 word = 0;
2522 nwords = 1;
2523 }
2524 else
2525 {
2526 imode = word_mode;
2527
2528 if (FLOAT_WORDS_BIG_ENDIAN)
2529 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2530 else
2531 word = bitpos / BITS_PER_WORD;
2532 bitpos = bitpos % BITS_PER_WORD;
2533 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2534 }
2535
2536 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
2537 if (code == ABS)
2538 mask = ~mask;
2539
2540 if (target == 0
2541 || target == op0
2542 || (nwords > 1 && !valid_multiword_target_p (target)))
2543 target = gen_reg_rtx (mode);
2544
2545 if (nwords > 1)
2546 {
2547 start_sequence ();
2548
2549 for (i = 0; i < nwords; ++i)
2550 {
2551 rtx targ_piece = operand_subword (target, i, 1, mode);
2552 rtx op0_piece = operand_subword_force (op0, i, mode);
2553
2554 if (i == word)
2555 {
2556 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2557 op0_piece,
2558 immed_wide_int_const (mask, imode),
2559 targ_piece, 1, OPTAB_LIB_WIDEN);
2560 if (temp != targ_piece)
2561 emit_move_insn (targ_piece, temp);
2562 }
2563 else
2564 emit_move_insn (targ_piece, op0_piece);
2565 }
2566
2567 insns = get_insns ();
2568 end_sequence ();
2569
2570 emit_insn (insns);
2571 }
2572 else
2573 {
2574 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2575 gen_lowpart (imode, op0),
2576 immed_wide_int_const (mask, imode),
2577 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2578 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2579
2580 set_dst_reg_note (get_last_insn (), REG_EQUAL,
2581 gen_rtx_fmt_e (code, mode, copy_rtx (op0)),
2582 target);
2583 }
2584
2585 return target;
2586 }
2587
2588 /* As expand_unop, but will fail rather than attempt the operation in a
2589 different mode or with a libcall. */
2590 static rtx
2591 expand_unop_direct (machine_mode mode, optab unoptab, rtx op0, rtx target,
2592 int unsignedp)
2593 {
2594 if (optab_handler (unoptab, mode) != CODE_FOR_nothing)
2595 {
2596 struct expand_operand ops[2];
2597 enum insn_code icode = optab_handler (unoptab, mode);
2598 rtx_insn *last = get_last_insn ();
2599 rtx_insn *pat;
2600
2601 create_output_operand (&ops[0], target, mode);
2602 create_convert_operand_from (&ops[1], op0, mode, unsignedp);
2603 pat = maybe_gen_insn (icode, 2, ops);
2604 if (pat)
2605 {
2606 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2607 && ! add_equal_note (pat, ops[0].value,
2608 optab_to_code (unoptab),
2609 ops[1].value, NULL_RTX))
2610 {
2611 delete_insns_since (last);
2612 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2613 }
2614
2615 emit_insn (pat);
2616
2617 return ops[0].value;
2618 }
2619 }
2620 return 0;
2621 }
2622
2623 /* Generate code to perform an operation specified by UNOPTAB
2624 on operand OP0, with result having machine-mode MODE.
2625
2626 UNSIGNEDP is for the case where we have to widen the operands
2627 to perform the operation. It says to use zero-extension.
2628
2629 If TARGET is nonzero, the value
2630 is generated there, if it is convenient to do so.
2631 In all cases an rtx is returned for the locus of the value;
2632 this may or may not be TARGET. */
2633
2634 rtx
2635 expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
2636 int unsignedp)
2637 {
2638 enum mode_class mclass = GET_MODE_CLASS (mode);
2639 machine_mode wider_mode;
2640 rtx temp;
2641 rtx libfunc;
2642
2643 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2644 if (temp)
2645 return temp;
2646
2647 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2648
2649 /* Widening (or narrowing) clz needs special treatment. */
2650 if (unoptab == clz_optab)
2651 {
2652 temp = widen_leading (mode, op0, target, unoptab);
2653 if (temp)
2654 return temp;
2655
2656 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2657 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2658 {
2659 temp = expand_doubleword_clz (mode, op0, target);
2660 if (temp)
2661 return temp;
2662 }
2663
2664 goto try_libcall;
2665 }
2666
2667 if (unoptab == clrsb_optab)
2668 {
2669 temp = widen_leading (mode, op0, target, unoptab);
2670 if (temp)
2671 return temp;
2672 goto try_libcall;
2673 }
2674
2675 /* Widening (or narrowing) bswap needs special treatment. */
2676 if (unoptab == bswap_optab)
2677 {
2678 /* HImode is special because in this mode BSWAP is equivalent to ROTATE
2679 or ROTATERT. First try these directly; if this fails, then try the
2680 obvious pair of shifts with allowed widening, as this will probably
2681 be always more efficient than the other fallback methods. */
2682 if (mode == HImode)
2683 {
2684 rtx_insn *last;
2685 rtx temp1, temp2;
2686
2687 if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
2688 {
2689 temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
2690 unsignedp, OPTAB_DIRECT);
2691 if (temp)
2692 return temp;
2693 }
2694
2695 if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
2696 {
2697 temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
2698 unsignedp, OPTAB_DIRECT);
2699 if (temp)
2700 return temp;
2701 }
2702
2703 last = get_last_insn ();
2704
2705 temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
2706 unsignedp, OPTAB_WIDEN);
2707 temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
2708 unsignedp, OPTAB_WIDEN);
2709 if (temp1 && temp2)
2710 {
2711 temp = expand_binop (mode, ior_optab, temp1, temp2, target,
2712 unsignedp, OPTAB_WIDEN);
2713 if (temp)
2714 return temp;
2715 }
2716
2717 delete_insns_since (last);
2718 }
2719
2720 temp = widen_bswap (mode, op0, target);
2721 if (temp)
2722 return temp;
2723
2724 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2725 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2726 {
2727 temp = expand_doubleword_bswap (mode, op0, target);
2728 if (temp)
2729 return temp;
2730 }
2731
2732 goto try_libcall;
2733 }
2734
2735 if (CLASS_HAS_WIDER_MODES_P (mclass))
2736 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2737 wider_mode != VOIDmode;
2738 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2739 {
2740 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
2741 {
2742 rtx xop0 = op0;
2743 rtx_insn *last = get_last_insn ();
2744
2745 /* For certain operations, we need not actually extend
2746 the narrow operand, as long as we will truncate the
2747 results to the same narrowness. */
2748
2749 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2750 (unoptab == neg_optab
2751 || unoptab == one_cmpl_optab)
2752 && mclass == MODE_INT);
2753
2754 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2755 unsignedp);
2756
2757 if (temp)
2758 {
2759 if (mclass != MODE_INT
2760 || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode))
2761 {
2762 if (target == 0)
2763 target = gen_reg_rtx (mode);
2764 convert_move (target, temp, 0);
2765 return target;
2766 }
2767 else
2768 return gen_lowpart (mode, temp);
2769 }
2770 else
2771 delete_insns_since (last);
2772 }
2773 }
2774
2775 /* These can be done a word at a time. */
2776 if (unoptab == one_cmpl_optab
2777 && mclass == MODE_INT
2778 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2779 && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
2780 {
2781 int i;
2782 rtx_insn *insns;
2783
2784 if (target == 0 || target == op0 || !valid_multiword_target_p (target))
2785 target = gen_reg_rtx (mode);
2786
2787 start_sequence ();
2788
2789 /* Do the actual arithmetic. */
2790 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2791 {
2792 rtx target_piece = operand_subword (target, i, 1, mode);
2793 rtx x = expand_unop (word_mode, unoptab,
2794 operand_subword_force (op0, i, mode),
2795 target_piece, unsignedp);
2796
2797 if (target_piece != x)
2798 emit_move_insn (target_piece, x);
2799 }
2800
2801 insns = get_insns ();
2802 end_sequence ();
2803
2804 emit_insn (insns);
2805 return target;
2806 }
2807
2808 if (optab_to_code (unoptab) == NEG)
2809 {
2810 /* Try negating floating point values by flipping the sign bit. */
2811 if (SCALAR_FLOAT_MODE_P (mode))
2812 {
2813 temp = expand_absneg_bit (NEG, mode, op0, target);
2814 if (temp)
2815 return temp;
2816 }
2817
2818 /* If there is no negation pattern, and we have no negative zero,
2819 try subtracting from zero. */
2820 if (!HONOR_SIGNED_ZEROS (mode))
2821 {
2822 temp = expand_binop (mode, (unoptab == negv_optab
2823 ? subv_optab : sub_optab),
2824 CONST0_RTX (mode), op0, target,
2825 unsignedp, OPTAB_DIRECT);
2826 if (temp)
2827 return temp;
2828 }
2829 }
2830
2831 /* Try calculating parity (x) as popcount (x) % 2. */
2832 if (unoptab == parity_optab)
2833 {
2834 temp = expand_parity (mode, op0, target);
2835 if (temp)
2836 return temp;
2837 }
2838
2839 /* Try implementing ffs (x) in terms of clz (x). */
2840 if (unoptab == ffs_optab)
2841 {
2842 temp = expand_ffs (mode, op0, target);
2843 if (temp)
2844 return temp;
2845 }
2846
2847 /* Try implementing ctz (x) in terms of clz (x). */
2848 if (unoptab == ctz_optab)
2849 {
2850 temp = expand_ctz (mode, op0, target);
2851 if (temp)
2852 return temp;
2853 }
2854
2855 try_libcall:
2856 /* Now try a library call in this mode. */
2857 libfunc = optab_libfunc (unoptab, mode);
2858 if (libfunc)
2859 {
2860 rtx_insn *insns;
2861 rtx value;
2862 rtx eq_value;
2863 machine_mode outmode = mode;
2864
2865 /* All of these functions return small values. Thus we choose to
2866 have them return something that isn't a double-word. */
2867 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2868 || unoptab == clrsb_optab || unoptab == popcount_optab
2869 || unoptab == parity_optab)
2870 outmode
2871 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node),
2872 optab_libfunc (unoptab, mode)));
2873
2874 start_sequence ();
2875
2876 /* Pass 1 for NO_QUEUE so we don't lose any increments
2877 if the libcall is cse'd or moved. */
2878 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
2879 1, op0, mode);
2880 insns = get_insns ();
2881 end_sequence ();
2882
2883 target = gen_reg_rtx (outmode);
2884 bool trapv = trapv_unoptab_p (unoptab);
2885 if (trapv)
2886 eq_value = NULL_RTX;
2887 else
2888 {
2889 eq_value = gen_rtx_fmt_e (optab_to_code (unoptab), mode, op0);
2890 if (GET_MODE_SIZE (outmode) < GET_MODE_SIZE (mode))
2891 eq_value = simplify_gen_unary (TRUNCATE, outmode, eq_value, mode);
2892 else if (GET_MODE_SIZE (outmode) > GET_MODE_SIZE (mode))
2893 eq_value = simplify_gen_unary (ZERO_EXTEND,
2894 outmode, eq_value, mode);
2895 }
2896 emit_libcall_block_1 (insns, target, value, eq_value, trapv);
2897
2898 return target;
2899 }
2900
2901 /* It can't be done in this mode. Can we do it in a wider mode? */
2902
2903 if (CLASS_HAS_WIDER_MODES_P (mclass))
2904 {
2905 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2906 wider_mode != VOIDmode;
2907 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2908 {
2909 if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
2910 || optab_libfunc (unoptab, wider_mode))
2911 {
2912 rtx xop0 = op0;
2913 rtx_insn *last = get_last_insn ();
2914
2915 /* For certain operations, we need not actually extend
2916 the narrow operand, as long as we will truncate the
2917 results to the same narrowness. */
2918 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2919 (unoptab == neg_optab
2920 || unoptab == one_cmpl_optab
2921 || unoptab == bswap_optab)
2922 && mclass == MODE_INT);
2923
2924 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2925 unsignedp);
2926
2927 /* If we are generating clz using wider mode, adjust the
2928 result. Similarly for clrsb. */
2929 if ((unoptab == clz_optab || unoptab == clrsb_optab)
2930 && temp != 0)
2931 temp = expand_binop
2932 (wider_mode, sub_optab, temp,
2933 gen_int_mode (GET_MODE_PRECISION (wider_mode)
2934 - GET_MODE_PRECISION (mode),
2935 wider_mode),
2936 target, true, OPTAB_DIRECT);
2937
2938 /* Likewise for bswap. */
2939 if (unoptab == bswap_optab && temp != 0)
2940 {
2941 gcc_assert (GET_MODE_PRECISION (wider_mode)
2942 == GET_MODE_BITSIZE (wider_mode)
2943 && GET_MODE_PRECISION (mode)
2944 == GET_MODE_BITSIZE (mode));
2945
2946 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
2947 GET_MODE_BITSIZE (wider_mode)
2948 - GET_MODE_BITSIZE (mode),
2949 NULL_RTX, true);
2950 }
2951
2952 if (temp)
2953 {
2954 if (mclass != MODE_INT)
2955 {
2956 if (target == 0)
2957 target = gen_reg_rtx (mode);
2958 convert_move (target, temp, 0);
2959 return target;
2960 }
2961 else
2962 return gen_lowpart (mode, temp);
2963 }
2964 else
2965 delete_insns_since (last);
2966 }
2967 }
2968 }
2969
2970 /* One final attempt at implementing negation via subtraction,
2971 this time allowing widening of the operand. */
2972 if (optab_to_code (unoptab) == NEG && !HONOR_SIGNED_ZEROS (mode))
2973 {
2974 rtx temp;
2975 temp = expand_binop (mode,
2976 unoptab == negv_optab ? subv_optab : sub_optab,
2977 CONST0_RTX (mode), op0,
2978 target, unsignedp, OPTAB_LIB_WIDEN);
2979 if (temp)
2980 return temp;
2981 }
2982
2983 return 0;
2984 }
2985 \f
2986 /* Emit code to compute the absolute value of OP0, with result to
2987 TARGET if convenient. (TARGET may be 0.) The return value says
2988 where the result actually is to be found.
2989
2990 MODE is the mode of the operand; the mode of the result is
2991 different but can be deduced from MODE.
2992
2993 */
2994
2995 rtx
2996 expand_abs_nojump (machine_mode mode, rtx op0, rtx target,
2997 int result_unsignedp)
2998 {
2999 rtx temp;
3000
3001 if (GET_MODE_CLASS (mode) != MODE_INT
3002 || ! flag_trapv)
3003 result_unsignedp = 1;
3004
3005 /* First try to do it with a special abs instruction. */
3006 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3007 op0, target, 0);
3008 if (temp != 0)
3009 return temp;
3010
3011 /* For floating point modes, try clearing the sign bit. */
3012 if (SCALAR_FLOAT_MODE_P (mode))
3013 {
3014 temp = expand_absneg_bit (ABS, mode, op0, target);
3015 if (temp)
3016 return temp;
3017 }
3018
3019 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3020 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing
3021 && !HONOR_SIGNED_ZEROS (mode))
3022 {
3023 rtx_insn *last = get_last_insn ();
3024
3025 temp = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3026 op0, NULL_RTX, 0);
3027 if (temp != 0)
3028 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3029 OPTAB_WIDEN);
3030
3031 if (temp != 0)
3032 return temp;
3033
3034 delete_insns_since (last);
3035 }
3036
3037 /* If this machine has expensive jumps, we can do integer absolute
3038 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3039 where W is the width of MODE. */
3040
3041 if (GET_MODE_CLASS (mode) == MODE_INT
3042 && BRANCH_COST (optimize_insn_for_speed_p (),
3043 false) >= 2)
3044 {
3045 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3046 GET_MODE_PRECISION (mode) - 1,
3047 NULL_RTX, 0);
3048
3049 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3050 OPTAB_LIB_WIDEN);
3051 if (temp != 0)
3052 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3053 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3054
3055 if (temp != 0)
3056 return temp;
3057 }
3058
3059 return NULL_RTX;
3060 }
3061
3062 rtx
3063 expand_abs (machine_mode mode, rtx op0, rtx target,
3064 int result_unsignedp, int safe)
3065 {
3066 rtx temp;
3067 rtx_code_label *op1;
3068
3069 if (GET_MODE_CLASS (mode) != MODE_INT
3070 || ! flag_trapv)
3071 result_unsignedp = 1;
3072
3073 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3074 if (temp != 0)
3075 return temp;
3076
3077 /* If that does not win, use conditional jump and negate. */
3078
3079 /* It is safe to use the target if it is the same
3080 as the source if this is also a pseudo register */
3081 if (op0 == target && REG_P (op0)
3082 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3083 safe = 1;
3084
3085 op1 = gen_label_rtx ();
3086 if (target == 0 || ! safe
3087 || GET_MODE (target) != mode
3088 || (MEM_P (target) && MEM_VOLATILE_P (target))
3089 || (REG_P (target)
3090 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3091 target = gen_reg_rtx (mode);
3092
3093 emit_move_insn (target, op0);
3094 NO_DEFER_POP;
3095
3096 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3097 NULL_RTX, NULL, op1, -1);
3098
3099 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3100 target, target, 0);
3101 if (op0 != target)
3102 emit_move_insn (target, op0);
3103 emit_label (op1);
3104 OK_DEFER_POP;
3105 return target;
3106 }
3107
3108 /* Emit code to compute the one's complement absolute value of OP0
3109 (if (OP0 < 0) OP0 = ~OP0), with result to TARGET if convenient.
3110 (TARGET may be NULL_RTX.) The return value says where the result
3111 actually is to be found.
3112
3113 MODE is the mode of the operand; the mode of the result is
3114 different but can be deduced from MODE. */
3115
3116 rtx
3117 expand_one_cmpl_abs_nojump (machine_mode mode, rtx op0, rtx target)
3118 {
3119 rtx temp;
3120
3121 /* Not applicable for floating point modes. */
3122 if (FLOAT_MODE_P (mode))
3123 return NULL_RTX;
3124
3125 /* If we have a MAX insn, we can do this as MAX (x, ~x). */
3126 if (optab_handler (smax_optab, mode) != CODE_FOR_nothing)
3127 {
3128 rtx_insn *last = get_last_insn ();
3129
3130 temp = expand_unop (mode, one_cmpl_optab, op0, NULL_RTX, 0);
3131 if (temp != 0)
3132 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3133 OPTAB_WIDEN);
3134
3135 if (temp != 0)
3136 return temp;
3137
3138 delete_insns_since (last);
3139 }
3140
3141 /* If this machine has expensive jumps, we can do one's complement
3142 absolute value of X as (((signed) x >> (W-1)) ^ x). */
3143
3144 if (GET_MODE_CLASS (mode) == MODE_INT
3145 && BRANCH_COST (optimize_insn_for_speed_p (),
3146 false) >= 2)
3147 {
3148 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3149 GET_MODE_PRECISION (mode) - 1,
3150 NULL_RTX, 0);
3151
3152 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3153 OPTAB_LIB_WIDEN);
3154
3155 if (temp != 0)
3156 return temp;
3157 }
3158
3159 return NULL_RTX;
3160 }
3161
3162 /* A subroutine of expand_copysign, perform the copysign operation using the
3163 abs and neg primitives advertised to exist on the target. The assumption
3164 is that we have a split register file, and leaving op0 in fp registers,
3165 and not playing with subregs so much, will help the register allocator. */
3166
3167 static rtx
3168 expand_copysign_absneg (machine_mode mode, rtx op0, rtx op1, rtx target,
3169 int bitpos, bool op0_is_abs)
3170 {
3171 machine_mode imode;
3172 enum insn_code icode;
3173 rtx sign;
3174 rtx_code_label *label;
3175
3176 if (target == op1)
3177 target = NULL_RTX;
3178
3179 /* Check if the back end provides an insn that handles signbit for the
3180 argument's mode. */
3181 icode = optab_handler (signbit_optab, mode);
3182 if (icode != CODE_FOR_nothing)
3183 {
3184 imode = insn_data[(int) icode].operand[0].mode;
3185 sign = gen_reg_rtx (imode);
3186 emit_unop_insn (icode, sign, op1, UNKNOWN);
3187 }
3188 else
3189 {
3190 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3191 {
3192 imode = int_mode_for_mode (mode);
3193 if (imode == BLKmode)
3194 return NULL_RTX;
3195 op1 = gen_lowpart (imode, op1);
3196 }
3197 else
3198 {
3199 int word;
3200
3201 imode = word_mode;
3202 if (FLOAT_WORDS_BIG_ENDIAN)
3203 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3204 else
3205 word = bitpos / BITS_PER_WORD;
3206 bitpos = bitpos % BITS_PER_WORD;
3207 op1 = operand_subword_force (op1, word, mode);
3208 }
3209
3210 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3211 sign = expand_binop (imode, and_optab, op1,
3212 immed_wide_int_const (mask, imode),
3213 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3214 }
3215
3216 if (!op0_is_abs)
3217 {
3218 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3219 if (op0 == NULL)
3220 return NULL_RTX;
3221 target = op0;
3222 }
3223 else
3224 {
3225 if (target == NULL_RTX)
3226 target = copy_to_reg (op0);
3227 else
3228 emit_move_insn (target, op0);
3229 }
3230
3231 label = gen_label_rtx ();
3232 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3233
3234 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3235 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3236 else
3237 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3238 if (op0 != target)
3239 emit_move_insn (target, op0);
3240
3241 emit_label (label);
3242
3243 return target;
3244 }
3245
3246
3247 /* A subroutine of expand_copysign, perform the entire copysign operation
3248 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3249 is true if op0 is known to have its sign bit clear. */
3250
3251 static rtx
3252 expand_copysign_bit (machine_mode mode, rtx op0, rtx op1, rtx target,
3253 int bitpos, bool op0_is_abs)
3254 {
3255 machine_mode imode;
3256 int word, nwords, i;
3257 rtx temp;
3258 rtx_insn *insns;
3259
3260 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3261 {
3262 imode = int_mode_for_mode (mode);
3263 if (imode == BLKmode)
3264 return NULL_RTX;
3265 word = 0;
3266 nwords = 1;
3267 }
3268 else
3269 {
3270 imode = word_mode;
3271
3272 if (FLOAT_WORDS_BIG_ENDIAN)
3273 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3274 else
3275 word = bitpos / BITS_PER_WORD;
3276 bitpos = bitpos % BITS_PER_WORD;
3277 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3278 }
3279
3280 wide_int mask = wi::set_bit_in_zero (bitpos, GET_MODE_PRECISION (imode));
3281
3282 if (target == 0
3283 || target == op0
3284 || target == op1
3285 || (nwords > 1 && !valid_multiword_target_p (target)))
3286 target = gen_reg_rtx (mode);
3287
3288 if (nwords > 1)
3289 {
3290 start_sequence ();
3291
3292 for (i = 0; i < nwords; ++i)
3293 {
3294 rtx targ_piece = operand_subword (target, i, 1, mode);
3295 rtx op0_piece = operand_subword_force (op0, i, mode);
3296
3297 if (i == word)
3298 {
3299 if (!op0_is_abs)
3300 op0_piece
3301 = expand_binop (imode, and_optab, op0_piece,
3302 immed_wide_int_const (~mask, imode),
3303 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3304 op1 = expand_binop (imode, and_optab,
3305 operand_subword_force (op1, i, mode),
3306 immed_wide_int_const (mask, imode),
3307 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3308
3309 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3310 targ_piece, 1, OPTAB_LIB_WIDEN);
3311 if (temp != targ_piece)
3312 emit_move_insn (targ_piece, temp);
3313 }
3314 else
3315 emit_move_insn (targ_piece, op0_piece);
3316 }
3317
3318 insns = get_insns ();
3319 end_sequence ();
3320
3321 emit_insn (insns);
3322 }
3323 else
3324 {
3325 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3326 immed_wide_int_const (mask, imode),
3327 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3328
3329 op0 = gen_lowpart (imode, op0);
3330 if (!op0_is_abs)
3331 op0 = expand_binop (imode, and_optab, op0,
3332 immed_wide_int_const (~mask, imode),
3333 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3334
3335 temp = expand_binop (imode, ior_optab, op0, op1,
3336 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3337 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3338 }
3339
3340 return target;
3341 }
3342
3343 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3344 scalar floating point mode. Return NULL if we do not know how to
3345 expand the operation inline. */
3346
3347 rtx
3348 expand_copysign (rtx op0, rtx op1, rtx target)
3349 {
3350 machine_mode mode = GET_MODE (op0);
3351 const struct real_format *fmt;
3352 bool op0_is_abs;
3353 rtx temp;
3354
3355 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3356 gcc_assert (GET_MODE (op1) == mode);
3357
3358 /* First try to do it with a special instruction. */
3359 temp = expand_binop (mode, copysign_optab, op0, op1,
3360 target, 0, OPTAB_DIRECT);
3361 if (temp)
3362 return temp;
3363
3364 fmt = REAL_MODE_FORMAT (mode);
3365 if (fmt == NULL || !fmt->has_signed_zero)
3366 return NULL_RTX;
3367
3368 op0_is_abs = false;
3369 if (CONST_DOUBLE_AS_FLOAT_P (op0))
3370 {
3371 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3372 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3373 op0_is_abs = true;
3374 }
3375
3376 if (fmt->signbit_ro >= 0
3377 && (CONST_DOUBLE_AS_FLOAT_P (op0)
3378 || (optab_handler (neg_optab, mode) != CODE_FOR_nothing
3379 && optab_handler (abs_optab, mode) != CODE_FOR_nothing)))
3380 {
3381 temp = expand_copysign_absneg (mode, op0, op1, target,
3382 fmt->signbit_ro, op0_is_abs);
3383 if (temp)
3384 return temp;
3385 }
3386
3387 if (fmt->signbit_rw < 0)
3388 return NULL_RTX;
3389 return expand_copysign_bit (mode, op0, op1, target,
3390 fmt->signbit_rw, op0_is_abs);
3391 }
3392 \f
3393 /* Generate an instruction whose insn-code is INSN_CODE,
3394 with two operands: an output TARGET and an input OP0.
3395 TARGET *must* be nonzero, and the output is always stored there.
3396 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3397 the value that is stored into TARGET.
3398
3399 Return false if expansion failed. */
3400
3401 bool
3402 maybe_emit_unop_insn (enum insn_code icode, rtx target, rtx op0,
3403 enum rtx_code code)
3404 {
3405 struct expand_operand ops[2];
3406 rtx_insn *pat;
3407
3408 create_output_operand (&ops[0], target, GET_MODE (target));
3409 create_input_operand (&ops[1], op0, GET_MODE (op0));
3410 pat = maybe_gen_insn (icode, 2, ops);
3411 if (!pat)
3412 return false;
3413
3414 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
3415 && code != UNKNOWN)
3416 add_equal_note (pat, ops[0].value, code, ops[1].value, NULL_RTX);
3417
3418 emit_insn (pat);
3419
3420 if (ops[0].value != target)
3421 emit_move_insn (target, ops[0].value);
3422 return true;
3423 }
3424 /* Generate an instruction whose insn-code is INSN_CODE,
3425 with two operands: an output TARGET and an input OP0.
3426 TARGET *must* be nonzero, and the output is always stored there.
3427 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3428 the value that is stored into TARGET. */
3429
3430 void
3431 emit_unop_insn (enum insn_code icode, rtx target, rtx op0, enum rtx_code code)
3432 {
3433 bool ok = maybe_emit_unop_insn (icode, target, op0, code);
3434 gcc_assert (ok);
3435 }
3436 \f
3437 struct no_conflict_data
3438 {
3439 rtx target;
3440 rtx_insn *first, *insn;
3441 bool must_stay;
3442 };
3443
3444 /* Called via note_stores by emit_libcall_block. Set P->must_stay if
3445 the currently examined clobber / store has to stay in the list of
3446 insns that constitute the actual libcall block. */
3447 static void
3448 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3449 {
3450 struct no_conflict_data *p= (struct no_conflict_data *) p0;
3451
3452 /* If this inns directly contributes to setting the target, it must stay. */
3453 if (reg_overlap_mentioned_p (p->target, dest))
3454 p->must_stay = true;
3455 /* If we haven't committed to keeping any other insns in the list yet,
3456 there is nothing more to check. */
3457 else if (p->insn == p->first)
3458 return;
3459 /* If this insn sets / clobbers a register that feeds one of the insns
3460 already in the list, this insn has to stay too. */
3461 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3462 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3463 || reg_used_between_p (dest, p->first, p->insn)
3464 /* Likewise if this insn depends on a register set by a previous
3465 insn in the list, or if it sets a result (presumably a hard
3466 register) that is set or clobbered by a previous insn.
3467 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3468 SET_DEST perform the former check on the address, and the latter
3469 check on the MEM. */
3470 || (GET_CODE (set) == SET
3471 && (modified_in_p (SET_SRC (set), p->first)
3472 || modified_in_p (SET_DEST (set), p->first)
3473 || modified_between_p (SET_SRC (set), p->first, p->insn)
3474 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3475 p->must_stay = true;
3476 }
3477
3478 \f
3479 /* Emit code to make a call to a constant function or a library call.
3480
3481 INSNS is a list containing all insns emitted in the call.
3482 These insns leave the result in RESULT. Our block is to copy RESULT
3483 to TARGET, which is logically equivalent to EQUIV.
3484
3485 We first emit any insns that set a pseudo on the assumption that these are
3486 loading constants into registers; doing so allows them to be safely cse'ed
3487 between blocks. Then we emit all the other insns in the block, followed by
3488 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3489 note with an operand of EQUIV. */
3490
3491 static void
3492 emit_libcall_block_1 (rtx_insn *insns, rtx target, rtx result, rtx equiv,
3493 bool equiv_may_trap)
3494 {
3495 rtx final_dest = target;
3496 rtx_insn *next, *last, *insn;
3497
3498 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3499 into a MEM later. Protect the libcall block from this change. */
3500 if (! REG_P (target) || REG_USERVAR_P (target))
3501 target = gen_reg_rtx (GET_MODE (target));
3502
3503 /* If we're using non-call exceptions, a libcall corresponding to an
3504 operation that may trap may also trap. */
3505 /* ??? See the comment in front of make_reg_eh_region_note. */
3506 if (cfun->can_throw_non_call_exceptions
3507 && (equiv_may_trap || may_trap_p (equiv)))
3508 {
3509 for (insn = insns; insn; insn = NEXT_INSN (insn))
3510 if (CALL_P (insn))
3511 {
3512 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3513 if (note)
3514 {
3515 int lp_nr = INTVAL (XEXP (note, 0));
3516 if (lp_nr == 0 || lp_nr == INT_MIN)
3517 remove_note (insn, note);
3518 }
3519 }
3520 }
3521 else
3522 {
3523 /* Look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3524 reg note to indicate that this call cannot throw or execute a nonlocal
3525 goto (unless there is already a REG_EH_REGION note, in which case
3526 we update it). */
3527 for (insn = insns; insn; insn = NEXT_INSN (insn))
3528 if (CALL_P (insn))
3529 make_reg_eh_region_note_nothrow_nononlocal (insn);
3530 }
3531
3532 /* First emit all insns that set pseudos. Remove them from the list as
3533 we go. Avoid insns that set pseudos which were referenced in previous
3534 insns. These can be generated by move_by_pieces, for example,
3535 to update an address. Similarly, avoid insns that reference things
3536 set in previous insns. */
3537
3538 for (insn = insns; insn; insn = next)
3539 {
3540 rtx set = single_set (insn);
3541
3542 next = NEXT_INSN (insn);
3543
3544 if (set != 0 && REG_P (SET_DEST (set))
3545 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3546 {
3547 struct no_conflict_data data;
3548
3549 data.target = const0_rtx;
3550 data.first = insns;
3551 data.insn = insn;
3552 data.must_stay = 0;
3553 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3554 if (! data.must_stay)
3555 {
3556 if (PREV_INSN (insn))
3557 SET_NEXT_INSN (PREV_INSN (insn)) = next;
3558 else
3559 insns = next;
3560
3561 if (next)
3562 SET_PREV_INSN (next) = PREV_INSN (insn);
3563
3564 add_insn (insn);
3565 }
3566 }
3567
3568 /* Some ports use a loop to copy large arguments onto the stack.
3569 Don't move anything outside such a loop. */
3570 if (LABEL_P (insn))
3571 break;
3572 }
3573
3574 /* Write the remaining insns followed by the final copy. */
3575 for (insn = insns; insn; insn = next)
3576 {
3577 next = NEXT_INSN (insn);
3578
3579 add_insn (insn);
3580 }
3581
3582 last = emit_move_insn (target, result);
3583 if (equiv)
3584 set_dst_reg_note (last, REG_EQUAL, copy_rtx (equiv), target);
3585
3586 if (final_dest != target)
3587 emit_move_insn (final_dest, target);
3588 }
3589
3590 void
3591 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3592 {
3593 emit_libcall_block_1 (safe_as_a <rtx_insn *> (insns),
3594 target, result, equiv, false);
3595 }
3596 \f
3597 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3598 PURPOSE describes how this comparison will be used. CODE is the rtx
3599 comparison code we will be using.
3600
3601 ??? Actually, CODE is slightly weaker than that. A target is still
3602 required to implement all of the normal bcc operations, but not
3603 required to implement all (or any) of the unordered bcc operations. */
3604
3605 int
3606 can_compare_p (enum rtx_code code, machine_mode mode,
3607 enum can_compare_purpose purpose)
3608 {
3609 rtx test;
3610 test = gen_rtx_fmt_ee (code, mode, const0_rtx, const0_rtx);
3611 do
3612 {
3613 enum insn_code icode;
3614
3615 if (purpose == ccp_jump
3616 && (icode = optab_handler (cbranch_optab, mode)) != CODE_FOR_nothing
3617 && insn_operand_matches (icode, 0, test))
3618 return 1;
3619 if (purpose == ccp_store_flag
3620 && (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
3621 && insn_operand_matches (icode, 1, test))
3622 return 1;
3623 if (purpose == ccp_cmov
3624 && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
3625 return 1;
3626
3627 mode = GET_MODE_WIDER_MODE (mode);
3628 PUT_MODE (test, mode);
3629 }
3630 while (mode != VOIDmode);
3631
3632 return 0;
3633 }
3634
3635 /* This function is called when we are going to emit a compare instruction that
3636 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3637
3638 *PMODE is the mode of the inputs (in case they are const_int).
3639 *PUNSIGNEDP nonzero says that the operands are unsigned;
3640 this matters if they need to be widened (as given by METHODS).
3641
3642 If they have mode BLKmode, then SIZE specifies the size of both operands.
3643
3644 This function performs all the setup necessary so that the caller only has
3645 to emit a single comparison insn. This setup can involve doing a BLKmode
3646 comparison or emitting a library call to perform the comparison if no insn
3647 is available to handle it.
3648 The values which are passed in through pointers can be modified; the caller
3649 should perform the comparison on the modified values. Constant
3650 comparisons must have already been folded. */
3651
3652 static void
3653 prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3654 int unsignedp, enum optab_methods methods,
3655 rtx *ptest, machine_mode *pmode)
3656 {
3657 machine_mode mode = *pmode;
3658 rtx libfunc, test;
3659 machine_mode cmp_mode;
3660 enum mode_class mclass;
3661
3662 /* The other methods are not needed. */
3663 gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
3664 || methods == OPTAB_LIB_WIDEN);
3665
3666 /* If we are optimizing, force expensive constants into a register. */
3667 if (CONSTANT_P (x) && optimize
3668 && (rtx_cost (x, mode, COMPARE, 0, optimize_insn_for_speed_p ())
3669 > COSTS_N_INSNS (1)))
3670 x = force_reg (mode, x);
3671
3672 if (CONSTANT_P (y) && optimize
3673 && (rtx_cost (y, mode, COMPARE, 1, optimize_insn_for_speed_p ())
3674 > COSTS_N_INSNS (1)))
3675 y = force_reg (mode, y);
3676
3677 #if HAVE_cc0
3678 /* Make sure if we have a canonical comparison. The RTL
3679 documentation states that canonical comparisons are required only
3680 for targets which have cc0. */
3681 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3682 #endif
3683
3684 /* Don't let both operands fail to indicate the mode. */
3685 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3686 x = force_reg (mode, x);
3687 if (mode == VOIDmode)
3688 mode = GET_MODE (x) != VOIDmode ? GET_MODE (x) : GET_MODE (y);
3689
3690 /* Handle all BLKmode compares. */
3691
3692 if (mode == BLKmode)
3693 {
3694 machine_mode result_mode;
3695 enum insn_code cmp_code;
3696 tree length_type;
3697 rtx libfunc;
3698 rtx result;
3699 rtx opalign
3700 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3701
3702 gcc_assert (size);
3703
3704 /* Try to use a memory block compare insn - either cmpstr
3705 or cmpmem will do. */
3706 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3707 cmp_mode != VOIDmode;
3708 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3709 {
3710 cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
3711 if (cmp_code == CODE_FOR_nothing)
3712 cmp_code = direct_optab_handler (cmpstr_optab, cmp_mode);
3713 if (cmp_code == CODE_FOR_nothing)
3714 cmp_code = direct_optab_handler (cmpstrn_optab, cmp_mode);
3715 if (cmp_code == CODE_FOR_nothing)
3716 continue;
3717
3718 /* Must make sure the size fits the insn's mode. */
3719 if ((CONST_INT_P (size)
3720 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3721 || (GET_MODE_BITSIZE (GET_MODE (size))
3722 > GET_MODE_BITSIZE (cmp_mode)))
3723 continue;
3724
3725 result_mode = insn_data[cmp_code].operand[0].mode;
3726 result = gen_reg_rtx (result_mode);
3727 size = convert_to_mode (cmp_mode, size, 1);
3728 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3729
3730 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, result, const0_rtx);
3731 *pmode = result_mode;
3732 return;
3733 }
3734
3735 if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
3736 goto fail;
3737
3738 /* Otherwise call a library function, memcmp. */
3739 libfunc = memcmp_libfunc;
3740 length_type = sizetype;
3741 result_mode = TYPE_MODE (integer_type_node);
3742 cmp_mode = TYPE_MODE (length_type);
3743 size = convert_to_mode (TYPE_MODE (length_type), size,
3744 TYPE_UNSIGNED (length_type));
3745
3746 result = emit_library_call_value (libfunc, 0, LCT_PURE,
3747 result_mode, 3,
3748 XEXP (x, 0), Pmode,
3749 XEXP (y, 0), Pmode,
3750 size, cmp_mode);
3751 x = result;
3752 y = const0_rtx;
3753 mode = result_mode;
3754 methods = OPTAB_LIB_WIDEN;
3755 unsignedp = false;
3756 }
3757
3758 /* Don't allow operands to the compare to trap, as that can put the
3759 compare and branch in different basic blocks. */
3760 if (cfun->can_throw_non_call_exceptions)
3761 {
3762 if (may_trap_p (x))
3763 x = force_reg (mode, x);
3764 if (may_trap_p (y))
3765 y = force_reg (mode, y);
3766 }
3767
3768 if (GET_MODE_CLASS (mode) == MODE_CC)
3769 {
3770 enum insn_code icode = optab_handler (cbranch_optab, CCmode);
3771 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3772 gcc_assert (icode != CODE_FOR_nothing
3773 && insn_operand_matches (icode, 0, test));
3774 *ptest = test;
3775 return;
3776 }
3777
3778 mclass = GET_MODE_CLASS (mode);
3779 test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
3780 cmp_mode = mode;
3781 do
3782 {
3783 enum insn_code icode;
3784 icode = optab_handler (cbranch_optab, cmp_mode);
3785 if (icode != CODE_FOR_nothing
3786 && insn_operand_matches (icode, 0, test))
3787 {
3788 rtx_insn *last = get_last_insn ();
3789 rtx op0 = prepare_operand (icode, x, 1, mode, cmp_mode, unsignedp);
3790 rtx op1 = prepare_operand (icode, y, 2, mode, cmp_mode, unsignedp);
3791 if (op0 && op1
3792 && insn_operand_matches (icode, 1, op0)
3793 && insn_operand_matches (icode, 2, op1))
3794 {
3795 XEXP (test, 0) = op0;
3796 XEXP (test, 1) = op1;
3797 *ptest = test;
3798 *pmode = cmp_mode;
3799 return;
3800 }
3801 delete_insns_since (last);
3802 }
3803
3804 if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
3805 break;
3806 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
3807 }
3808 while (cmp_mode != VOIDmode);
3809
3810 if (methods != OPTAB_LIB_WIDEN)
3811 goto fail;
3812
3813 if (!SCALAR_FLOAT_MODE_P (mode))
3814 {
3815 rtx result;
3816 machine_mode ret_mode;
3817
3818 /* Handle a libcall just for the mode we are using. */
3819 libfunc = optab_libfunc (cmp_optab, mode);
3820 gcc_assert (libfunc);
3821
3822 /* If we want unsigned, and this mode has a distinct unsigned
3823 comparison routine, use that. */
3824 if (unsignedp)
3825 {
3826 rtx ulibfunc = optab_libfunc (ucmp_optab, mode);
3827 if (ulibfunc)
3828 libfunc = ulibfunc;
3829 }
3830
3831 ret_mode = targetm.libgcc_cmp_return_mode ();
3832 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3833 ret_mode, 2, x, mode, y, mode);
3834
3835 /* There are two kinds of comparison routines. Biased routines
3836 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3837 of gcc expect that the comparison operation is equivalent
3838 to the modified comparison. For signed comparisons compare the
3839 result against 1 in the biased case, and zero in the unbiased
3840 case. For unsigned comparisons always compare against 1 after
3841 biasing the unbiased result by adding 1. This gives us a way to
3842 represent LTU.
3843 The comparisons in the fixed-point helper library are always
3844 biased. */
3845 x = result;
3846 y = const1_rtx;
3847
3848 if (!TARGET_LIB_INT_CMP_BIASED && !ALL_FIXED_POINT_MODE_P (mode))
3849 {
3850 if (unsignedp)
3851 x = plus_constant (ret_mode, result, 1);
3852 else
3853 y = const0_rtx;
3854 }
3855
3856 *pmode = ret_mode;
3857 prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods,
3858 ptest, pmode);
3859 }
3860 else
3861 prepare_float_lib_cmp (x, y, comparison, ptest, pmode);
3862
3863 return;
3864
3865 fail:
3866 *ptest = NULL_RTX;
3867 }
3868
3869 /* Before emitting an insn with code ICODE, make sure that X, which is going
3870 to be used for operand OPNUM of the insn, is converted from mode MODE to
3871 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3872 that it is accepted by the operand predicate. Return the new value. */
3873
3874 rtx
3875 prepare_operand (enum insn_code icode, rtx x, int opnum, machine_mode mode,
3876 machine_mode wider_mode, int unsignedp)
3877 {
3878 if (mode != wider_mode)
3879 x = convert_modes (wider_mode, mode, x, unsignedp);
3880
3881 if (!insn_operand_matches (icode, opnum, x))
3882 {
3883 machine_mode op_mode = insn_data[(int) icode].operand[opnum].mode;
3884 if (reload_completed)
3885 return NULL_RTX;
3886 if (GET_MODE (x) != op_mode && GET_MODE (x) != VOIDmode)
3887 return NULL_RTX;
3888 x = copy_to_mode_reg (op_mode, x);
3889 }
3890
3891 return x;
3892 }
3893
3894 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3895 we can do the branch. */
3896
3897 static void
3898 emit_cmp_and_jump_insn_1 (rtx test, machine_mode mode, rtx label, int prob)
3899 {
3900 machine_mode optab_mode;
3901 enum mode_class mclass;
3902 enum insn_code icode;
3903 rtx_insn *insn;
3904
3905 mclass = GET_MODE_CLASS (mode);
3906 optab_mode = (mclass == MODE_CC) ? CCmode : mode;
3907 icode = optab_handler (cbranch_optab, optab_mode);
3908
3909 gcc_assert (icode != CODE_FOR_nothing);
3910 gcc_assert (insn_operand_matches (icode, 0, test));
3911 insn = emit_jump_insn (GEN_FCN (icode) (test, XEXP (test, 0),
3912 XEXP (test, 1), label));
3913 if (prob != -1
3914 && profile_status_for_fn (cfun) != PROFILE_ABSENT
3915 && insn
3916 && JUMP_P (insn)
3917 && any_condjump_p (insn)
3918 && !find_reg_note (insn, REG_BR_PROB, 0))
3919 add_int_reg_note (insn, REG_BR_PROB, prob);
3920 }
3921
3922 /* Generate code to compare X with Y so that the condition codes are
3923 set and to jump to LABEL if the condition is true. If X is a
3924 constant and Y is not a constant, then the comparison is swapped to
3925 ensure that the comparison RTL has the canonical form.
3926
3927 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3928 need to be widened. UNSIGNEDP is also used to select the proper
3929 branch condition code.
3930
3931 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3932
3933 MODE is the mode of the inputs (in case they are const_int).
3934
3935 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
3936 It will be potentially converted into an unsigned variant based on
3937 UNSIGNEDP to select a proper jump instruction.
3938
3939 PROB is the probability of jumping to LABEL. */
3940
3941 void
3942 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3943 machine_mode mode, int unsignedp, rtx label,
3944 int prob)
3945 {
3946 rtx op0 = x, op1 = y;
3947 rtx test;
3948
3949 /* Swap operands and condition to ensure canonical RTL. */
3950 if (swap_commutative_operands_p (x, y)
3951 && can_compare_p (swap_condition (comparison), mode, ccp_jump))
3952 {
3953 op0 = y, op1 = x;
3954 comparison = swap_condition (comparison);
3955 }
3956
3957 /* If OP0 is still a constant, then both X and Y must be constants
3958 or the opposite comparison is not supported. Force X into a register
3959 to create canonical RTL. */
3960 if (CONSTANT_P (op0))
3961 op0 = force_reg (mode, op0);
3962
3963 if (unsignedp)
3964 comparison = unsigned_condition (comparison);
3965
3966 prepare_cmp_insn (op0, op1, comparison, size, unsignedp, OPTAB_LIB_WIDEN,
3967 &test, &mode);
3968 emit_cmp_and_jump_insn_1 (test, mode, label, prob);
3969 }
3970
3971 \f
3972 /* Emit a library call comparison between floating point X and Y.
3973 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3974
3975 static void
3976 prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
3977 rtx *ptest, machine_mode *pmode)
3978 {
3979 enum rtx_code swapped = swap_condition (comparison);
3980 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3981 machine_mode orig_mode = GET_MODE (x);
3982 machine_mode mode, cmp_mode;
3983 rtx true_rtx, false_rtx;
3984 rtx value, target, equiv;
3985 rtx_insn *insns;
3986 rtx libfunc = 0;
3987 bool reversed_p = false;
3988 cmp_mode = targetm.libgcc_cmp_return_mode ();
3989
3990 for (mode = orig_mode;
3991 mode != VOIDmode;
3992 mode = GET_MODE_WIDER_MODE (mode))
3993 {
3994 if (code_to_optab (comparison)
3995 && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
3996 break;
3997
3998 if (code_to_optab (swapped)
3999 && (libfunc = optab_libfunc (code_to_optab (swapped), mode)))
4000 {
4001 std::swap (x, y);
4002 comparison = swapped;
4003 break;
4004 }
4005
4006 if (code_to_optab (reversed)
4007 && (libfunc = optab_libfunc (code_to_optab (reversed), mode)))
4008 {
4009 comparison = reversed;
4010 reversed_p = true;
4011 break;
4012 }
4013 }
4014
4015 gcc_assert (mode != VOIDmode);
4016
4017 if (mode != orig_mode)
4018 {
4019 x = convert_to_mode (mode, x, 0);
4020 y = convert_to_mode (mode, y, 0);
4021 }
4022
4023 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4024 the RTL. The allows the RTL optimizers to delete the libcall if the
4025 condition can be determined at compile-time. */
4026 if (comparison == UNORDERED
4027 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4028 {
4029 true_rtx = const_true_rtx;
4030 false_rtx = const0_rtx;
4031 }
4032 else
4033 {
4034 switch (comparison)
4035 {
4036 case EQ:
4037 true_rtx = const0_rtx;
4038 false_rtx = const_true_rtx;
4039 break;
4040
4041 case NE:
4042 true_rtx = const_true_rtx;
4043 false_rtx = const0_rtx;
4044 break;
4045
4046 case GT:
4047 true_rtx = const1_rtx;
4048 false_rtx = const0_rtx;
4049 break;
4050
4051 case GE:
4052 true_rtx = const0_rtx;
4053 false_rtx = constm1_rtx;
4054 break;
4055
4056 case LT:
4057 true_rtx = constm1_rtx;
4058 false_rtx = const0_rtx;
4059 break;
4060
4061 case LE:
4062 true_rtx = const0_rtx;
4063 false_rtx = const1_rtx;
4064 break;
4065
4066 default:
4067 gcc_unreachable ();
4068 }
4069 }
4070
4071 if (comparison == UNORDERED)
4072 {
4073 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4074 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4075 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4076 temp, const_true_rtx, equiv);
4077 }
4078 else
4079 {
4080 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4081 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4082 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4083 equiv, true_rtx, false_rtx);
4084 }
4085
4086 start_sequence ();
4087 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4088 cmp_mode, 2, x, mode, y, mode);
4089 insns = get_insns ();
4090 end_sequence ();
4091
4092 target = gen_reg_rtx (cmp_mode);
4093 emit_libcall_block (insns, target, value, equiv);
4094
4095 if (comparison == UNORDERED
4096 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
4097 || reversed_p)
4098 *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
4099 else
4100 *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
4101
4102 *pmode = cmp_mode;
4103 }
4104 \f
4105 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4106
4107 void
4108 emit_indirect_jump (rtx loc)
4109 {
4110 if (!targetm.have_indirect_jump ())
4111 sorry ("indirect jumps are not available on this target");
4112 else
4113 {
4114 struct expand_operand ops[1];
4115 create_address_operand (&ops[0], loc);
4116 expand_jump_insn (targetm.code_for_indirect_jump, 1, ops);
4117 emit_barrier ();
4118 }
4119 }
4120 \f
4121
4122 /* Emit a conditional move instruction if the machine supports one for that
4123 condition and machine mode.
4124
4125 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4126 the mode to use should they be constants. If it is VOIDmode, they cannot
4127 both be constants.
4128
4129 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4130 should be stored there. MODE is the mode to use should they be constants.
4131 If it is VOIDmode, they cannot both be constants.
4132
4133 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4134 is not supported. */
4135
4136 rtx
4137 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4138 machine_mode cmode, rtx op2, rtx op3,
4139 machine_mode mode, int unsignedp)
4140 {
4141 rtx comparison;
4142 rtx_insn *last;
4143 enum insn_code icode;
4144 enum rtx_code reversed;
4145
4146 /* If one operand is constant, make it the second one. Only do this
4147 if the other operand is not constant as well. */
4148
4149 if (swap_commutative_operands_p (op0, op1))
4150 {
4151 std::swap (op0, op1);
4152 code = swap_condition (code);
4153 }
4154
4155 /* get_condition will prefer to generate LT and GT even if the old
4156 comparison was against zero, so undo that canonicalization here since
4157 comparisons against zero are cheaper. */
4158 if (code == LT && op1 == const1_rtx)
4159 code = LE, op1 = const0_rtx;
4160 else if (code == GT && op1 == constm1_rtx)
4161 code = GE, op1 = const0_rtx;
4162
4163 if (cmode == VOIDmode)
4164 cmode = GET_MODE (op0);
4165
4166 if (swap_commutative_operands_p (op2, op3)
4167 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4168 != UNKNOWN))
4169 {
4170 std::swap (op2, op3);
4171 code = reversed;
4172 }
4173
4174 if (mode == VOIDmode)
4175 mode = GET_MODE (op2);
4176
4177 icode = direct_optab_handler (movcc_optab, mode);
4178
4179 if (icode == CODE_FOR_nothing)
4180 return 0;
4181
4182 if (!target)
4183 target = gen_reg_rtx (mode);
4184
4185 code = unsignedp ? unsigned_condition (code) : code;
4186 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4187
4188 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4189 return NULL and let the caller figure out how best to deal with this
4190 situation. */
4191 if (!COMPARISON_P (comparison))
4192 return NULL_RTX;
4193
4194 saved_pending_stack_adjust save;
4195 save_pending_stack_adjust (&save);
4196 last = get_last_insn ();
4197 do_pending_stack_adjust ();
4198 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4199 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4200 &comparison, &cmode);
4201 if (comparison)
4202 {
4203 struct expand_operand ops[4];
4204
4205 create_output_operand (&ops[0], target, mode);
4206 create_fixed_operand (&ops[1], comparison);
4207 create_input_operand (&ops[2], op2, mode);
4208 create_input_operand (&ops[3], op3, mode);
4209 if (maybe_expand_insn (icode, 4, ops))
4210 {
4211 if (ops[0].value != target)
4212 convert_move (target, ops[0].value, false);
4213 return target;
4214 }
4215 }
4216 delete_insns_since (last);
4217 restore_pending_stack_adjust (&save);
4218 return NULL_RTX;
4219 }
4220
4221 /* Emit a conditional addition instruction if the machine supports one for that
4222 condition and machine mode.
4223
4224 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4225 the mode to use should they be constants. If it is VOIDmode, they cannot
4226 both be constants.
4227
4228 OP2 should be stored in TARGET if the comparison is false, otherwise OP2+OP3
4229 should be stored there. MODE is the mode to use should they be constants.
4230 If it is VOIDmode, they cannot both be constants.
4231
4232 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4233 is not supported. */
4234
4235 rtx
4236 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4237 machine_mode cmode, rtx op2, rtx op3,
4238 machine_mode mode, int unsignedp)
4239 {
4240 rtx comparison;
4241 rtx_insn *last;
4242 enum insn_code icode;
4243
4244 /* If one operand is constant, make it the second one. Only do this
4245 if the other operand is not constant as well. */
4246
4247 if (swap_commutative_operands_p (op0, op1))
4248 {
4249 std::swap (op0, op1);
4250 code = swap_condition (code);
4251 }
4252
4253 /* get_condition will prefer to generate LT and GT even if the old
4254 comparison was against zero, so undo that canonicalization here since
4255 comparisons against zero are cheaper. */
4256 if (code == LT && op1 == const1_rtx)
4257 code = LE, op1 = const0_rtx;
4258 else if (code == GT && op1 == constm1_rtx)
4259 code = GE, op1 = const0_rtx;
4260
4261 if (cmode == VOIDmode)
4262 cmode = GET_MODE (op0);
4263
4264 if (mode == VOIDmode)
4265 mode = GET_MODE (op2);
4266
4267 icode = optab_handler (addcc_optab, mode);
4268
4269 if (icode == CODE_FOR_nothing)
4270 return 0;
4271
4272 if (!target)
4273 target = gen_reg_rtx (mode);
4274
4275 code = unsignedp ? unsigned_condition (code) : code;
4276 comparison = simplify_gen_relational (code, VOIDmode, cmode, op0, op1);
4277
4278 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4279 return NULL and let the caller figure out how best to deal with this
4280 situation. */
4281 if (!COMPARISON_P (comparison))
4282 return NULL_RTX;
4283
4284 do_pending_stack_adjust ();
4285 last = get_last_insn ();
4286 prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1),
4287 GET_CODE (comparison), NULL_RTX, unsignedp, OPTAB_WIDEN,
4288 &comparison, &cmode);
4289 if (comparison)
4290 {
4291 struct expand_operand ops[4];
4292
4293 create_output_operand (&ops[0], target, mode);
4294 create_fixed_operand (&ops[1], comparison);
4295 create_input_operand (&ops[2], op2, mode);
4296 create_input_operand (&ops[3], op3, mode);
4297 if (maybe_expand_insn (icode, 4, ops))
4298 {
4299 if (ops[0].value != target)
4300 convert_move (target, ops[0].value, false);
4301 return target;
4302 }
4303 }
4304 delete_insns_since (last);
4305 return NULL_RTX;
4306 }
4307 \f
4308 /* These functions attempt to generate an insn body, rather than
4309 emitting the insn, but if the gen function already emits them, we
4310 make no attempt to turn them back into naked patterns. */
4311
4312 /* Generate and return an insn body to add Y to X. */
4313
4314 rtx_insn *
4315 gen_add2_insn (rtx x, rtx y)
4316 {
4317 enum insn_code icode = optab_handler (add_optab, GET_MODE (x));
4318
4319 gcc_assert (insn_operand_matches (icode, 0, x));
4320 gcc_assert (insn_operand_matches (icode, 1, x));
4321 gcc_assert (insn_operand_matches (icode, 2, y));
4322
4323 return GEN_FCN (icode) (x, x, y);
4324 }
4325
4326 /* Generate and return an insn body to add r1 and c,
4327 storing the result in r0. */
4328
4329 rtx_insn *
4330 gen_add3_insn (rtx r0, rtx r1, rtx c)
4331 {
4332 enum insn_code icode = optab_handler (add_optab, GET_MODE (r0));
4333
4334 if (icode == CODE_FOR_nothing
4335 || !insn_operand_matches (icode, 0, r0)
4336 || !insn_operand_matches (icode, 1, r1)
4337 || !insn_operand_matches (icode, 2, c))
4338 return NULL;
4339
4340 return GEN_FCN (icode) (r0, r1, c);
4341 }
4342
4343 int
4344 have_add2_insn (rtx x, rtx y)
4345 {
4346 enum insn_code icode;
4347
4348 gcc_assert (GET_MODE (x) != VOIDmode);
4349
4350 icode = optab_handler (add_optab, GET_MODE (x));
4351
4352 if (icode == CODE_FOR_nothing)
4353 return 0;
4354
4355 if (!insn_operand_matches (icode, 0, x)
4356 || !insn_operand_matches (icode, 1, x)
4357 || !insn_operand_matches (icode, 2, y))
4358 return 0;
4359
4360 return 1;
4361 }
4362
4363 /* Generate and return an insn body to add Y to X. */
4364
4365 rtx_insn *
4366 gen_addptr3_insn (rtx x, rtx y, rtx z)
4367 {
4368 enum insn_code icode = optab_handler (addptr3_optab, GET_MODE (x));
4369
4370 gcc_assert (insn_operand_matches (icode, 0, x));
4371 gcc_assert (insn_operand_matches (icode, 1, y));
4372 gcc_assert (insn_operand_matches (icode, 2, z));
4373
4374 return GEN_FCN (icode) (x, y, z);
4375 }
4376
4377 /* Return true if the target implements an addptr pattern and X, Y,
4378 and Z are valid for the pattern predicates. */
4379
4380 int
4381 have_addptr3_insn (rtx x, rtx y, rtx z)
4382 {
4383 enum insn_code icode;
4384
4385 gcc_assert (GET_MODE (x) != VOIDmode);
4386
4387 icode = optab_handler (addptr3_optab, GET_MODE (x));
4388
4389 if (icode == CODE_FOR_nothing)
4390 return 0;
4391
4392 if (!insn_operand_matches (icode, 0, x)
4393 || !insn_operand_matches (icode, 1, y)
4394 || !insn_operand_matches (icode, 2, z))
4395 return 0;
4396
4397 return 1;
4398 }
4399
4400 /* Generate and return an insn body to subtract Y from X. */
4401
4402 rtx_insn *
4403 gen_sub2_insn (rtx x, rtx y)
4404 {
4405 enum insn_code icode = optab_handler (sub_optab, GET_MODE (x));
4406
4407 gcc_assert (insn_operand_matches (icode, 0, x));
4408 gcc_assert (insn_operand_matches (icode, 1, x));
4409 gcc_assert (insn_operand_matches (icode, 2, y));
4410
4411 return GEN_FCN (icode) (x, x, y);
4412 }
4413
4414 /* Generate and return an insn body to subtract r1 and c,
4415 storing the result in r0. */
4416
4417 rtx_insn *
4418 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4419 {
4420 enum insn_code icode = optab_handler (sub_optab, GET_MODE (r0));
4421
4422 if (icode == CODE_FOR_nothing
4423 || !insn_operand_matches (icode, 0, r0)
4424 || !insn_operand_matches (icode, 1, r1)
4425 || !insn_operand_matches (icode, 2, c))
4426 return NULL;
4427
4428 return GEN_FCN (icode) (r0, r1, c);
4429 }
4430
4431 int
4432 have_sub2_insn (rtx x, rtx y)
4433 {
4434 enum insn_code icode;
4435
4436 gcc_assert (GET_MODE (x) != VOIDmode);
4437
4438 icode = optab_handler (sub_optab, GET_MODE (x));
4439
4440 if (icode == CODE_FOR_nothing)
4441 return 0;
4442
4443 if (!insn_operand_matches (icode, 0, x)
4444 || !insn_operand_matches (icode, 1, x)
4445 || !insn_operand_matches (icode, 2, y))
4446 return 0;
4447
4448 return 1;
4449 }
4450 \f
4451 /* Generate the body of an insn to extend Y (with mode MFROM)
4452 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4453
4454 rtx_insn *
4455 gen_extend_insn (rtx x, rtx y, machine_mode mto,
4456 machine_mode mfrom, int unsignedp)
4457 {
4458 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4459 return GEN_FCN (icode) (x, y);
4460 }
4461 \f
4462 /* Generate code to convert FROM to floating point
4463 and store in TO. FROM must be fixed point and not VOIDmode.
4464 UNSIGNEDP nonzero means regard FROM as unsigned.
4465 Normally this is done by correcting the final value
4466 if it is negative. */
4467
4468 void
4469 expand_float (rtx to, rtx from, int unsignedp)
4470 {
4471 enum insn_code icode;
4472 rtx target = to;
4473 machine_mode fmode, imode;
4474 bool can_do_signed = false;
4475
4476 /* Crash now, because we won't be able to decide which mode to use. */
4477 gcc_assert (GET_MODE (from) != VOIDmode);
4478
4479 /* Look for an insn to do the conversion. Do it in the specified
4480 modes if possible; otherwise convert either input, output or both to
4481 wider mode. If the integer mode is wider than the mode of FROM,
4482 we can do the conversion signed even if the input is unsigned. */
4483
4484 for (fmode = GET_MODE (to); fmode != VOIDmode;
4485 fmode = GET_MODE_WIDER_MODE (fmode))
4486 for (imode = GET_MODE (from); imode != VOIDmode;
4487 imode = GET_MODE_WIDER_MODE (imode))
4488 {
4489 int doing_unsigned = unsignedp;
4490
4491 if (fmode != GET_MODE (to)
4492 && significand_size (fmode) < GET_MODE_PRECISION (GET_MODE (from)))
4493 continue;
4494
4495 icode = can_float_p (fmode, imode, unsignedp);
4496 if (icode == CODE_FOR_nothing && unsignedp)
4497 {
4498 enum insn_code scode = can_float_p (fmode, imode, 0);
4499 if (scode != CODE_FOR_nothing)
4500 can_do_signed = true;
4501 if (imode != GET_MODE (from))
4502 icode = scode, doing_unsigned = 0;
4503 }
4504
4505 if (icode != CODE_FOR_nothing)
4506 {
4507 if (imode != GET_MODE (from))
4508 from = convert_to_mode (imode, from, unsignedp);
4509
4510 if (fmode != GET_MODE (to))
4511 target = gen_reg_rtx (fmode);
4512
4513 emit_unop_insn (icode, target, from,
4514 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4515
4516 if (target != to)
4517 convert_move (to, target, 0);
4518 return;
4519 }
4520 }
4521
4522 /* Unsigned integer, and no way to convert directly. Convert as signed,
4523 then unconditionally adjust the result. */
4524 if (unsignedp && can_do_signed)
4525 {
4526 rtx_code_label *label = gen_label_rtx ();
4527 rtx temp;
4528 REAL_VALUE_TYPE offset;
4529
4530 /* Look for a usable floating mode FMODE wider than the source and at
4531 least as wide as the target. Using FMODE will avoid rounding woes
4532 with unsigned values greater than the signed maximum value. */
4533
4534 for (fmode = GET_MODE (to); fmode != VOIDmode;
4535 fmode = GET_MODE_WIDER_MODE (fmode))
4536 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4537 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4538 break;
4539
4540 if (fmode == VOIDmode)
4541 {
4542 /* There is no such mode. Pretend the target is wide enough. */
4543 fmode = GET_MODE (to);
4544
4545 /* Avoid double-rounding when TO is narrower than FROM. */
4546 if ((significand_size (fmode) + 1)
4547 < GET_MODE_PRECISION (GET_MODE (from)))
4548 {
4549 rtx temp1;
4550 rtx_code_label *neglabel = gen_label_rtx ();
4551
4552 /* Don't use TARGET if it isn't a register, is a hard register,
4553 or is the wrong mode. */
4554 if (!REG_P (target)
4555 || REGNO (target) < FIRST_PSEUDO_REGISTER
4556 || GET_MODE (target) != fmode)
4557 target = gen_reg_rtx (fmode);
4558
4559 imode = GET_MODE (from);
4560 do_pending_stack_adjust ();
4561
4562 /* Test whether the sign bit is set. */
4563 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4564 0, neglabel);
4565
4566 /* The sign bit is not set. Convert as signed. */
4567 expand_float (target, from, 0);
4568 emit_jump_insn (targetm.gen_jump (label));
4569 emit_barrier ();
4570
4571 /* The sign bit is set.
4572 Convert to a usable (positive signed) value by shifting right
4573 one bit, while remembering if a nonzero bit was shifted
4574 out; i.e., compute (from & 1) | (from >> 1). */
4575
4576 emit_label (neglabel);
4577 temp = expand_binop (imode, and_optab, from, const1_rtx,
4578 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4579 temp1 = expand_shift (RSHIFT_EXPR, imode, from, 1, NULL_RTX, 1);
4580 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4581 OPTAB_LIB_WIDEN);
4582 expand_float (target, temp, 0);
4583
4584 /* Multiply by 2 to undo the shift above. */
4585 temp = expand_binop (fmode, add_optab, target, target,
4586 target, 0, OPTAB_LIB_WIDEN);
4587 if (temp != target)
4588 emit_move_insn (target, temp);
4589
4590 do_pending_stack_adjust ();
4591 emit_label (label);
4592 goto done;
4593 }
4594 }
4595
4596 /* If we are about to do some arithmetic to correct for an
4597 unsigned operand, do it in a pseudo-register. */
4598
4599 if (GET_MODE (to) != fmode
4600 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4601 target = gen_reg_rtx (fmode);
4602
4603 /* Convert as signed integer to floating. */
4604 expand_float (target, from, 0);
4605
4606 /* If FROM is negative (and therefore TO is negative),
4607 correct its value by 2**bitwidth. */
4608
4609 do_pending_stack_adjust ();
4610 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4611 0, label);
4612
4613
4614 real_2expN (&offset, GET_MODE_PRECISION (GET_MODE (from)), fmode);
4615 temp = expand_binop (fmode, add_optab, target,
4616 const_double_from_real_value (offset, fmode),
4617 target, 0, OPTAB_LIB_WIDEN);
4618 if (temp != target)
4619 emit_move_insn (target, temp);
4620
4621 do_pending_stack_adjust ();
4622 emit_label (label);
4623 goto done;
4624 }
4625
4626 /* No hardware instruction available; call a library routine. */
4627 {
4628 rtx libfunc;
4629 rtx_insn *insns;
4630 rtx value;
4631 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4632
4633 if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_PRECISION (SImode))
4634 from = convert_to_mode (SImode, from, unsignedp);
4635
4636 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4637 gcc_assert (libfunc);
4638
4639 start_sequence ();
4640
4641 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4642 GET_MODE (to), 1, from,
4643 GET_MODE (from));
4644 insns = get_insns ();
4645 end_sequence ();
4646
4647 emit_libcall_block (insns, target, value,
4648 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
4649 GET_MODE (to), from));
4650 }
4651
4652 done:
4653
4654 /* Copy result to requested destination
4655 if we have been computing in a temp location. */
4656
4657 if (target != to)
4658 {
4659 if (GET_MODE (target) == GET_MODE (to))
4660 emit_move_insn (to, target);
4661 else
4662 convert_move (to, target, 0);
4663 }
4664 }
4665 \f
4666 /* Generate code to convert FROM to fixed point and store in TO. FROM
4667 must be floating point. */
4668
4669 void
4670 expand_fix (rtx to, rtx from, int unsignedp)
4671 {
4672 enum insn_code icode;
4673 rtx target = to;
4674 machine_mode fmode, imode;
4675 bool must_trunc = false;
4676
4677 /* We first try to find a pair of modes, one real and one integer, at
4678 least as wide as FROM and TO, respectively, in which we can open-code
4679 this conversion. If the integer mode is wider than the mode of TO,
4680 we can do the conversion either signed or unsigned. */
4681
4682 for (fmode = GET_MODE (from); fmode != VOIDmode;
4683 fmode = GET_MODE_WIDER_MODE (fmode))
4684 for (imode = GET_MODE (to); imode != VOIDmode;
4685 imode = GET_MODE_WIDER_MODE (imode))
4686 {
4687 int doing_unsigned = unsignedp;
4688
4689 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4690 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4691 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4692
4693 if (icode != CODE_FOR_nothing)
4694 {
4695 rtx_insn *last = get_last_insn ();
4696 if (fmode != GET_MODE (from))
4697 from = convert_to_mode (fmode, from, 0);
4698
4699 if (must_trunc)
4700 {
4701 rtx temp = gen_reg_rtx (GET_MODE (from));
4702 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4703 temp, 0);
4704 }
4705
4706 if (imode != GET_MODE (to))
4707 target = gen_reg_rtx (imode);
4708
4709 if (maybe_emit_unop_insn (icode, target, from,
4710 doing_unsigned ? UNSIGNED_FIX : FIX))
4711 {
4712 if (target != to)
4713 convert_move (to, target, unsignedp);
4714 return;
4715 }
4716 delete_insns_since (last);
4717 }
4718 }
4719
4720 /* For an unsigned conversion, there is one more way to do it.
4721 If we have a signed conversion, we generate code that compares
4722 the real value to the largest representable positive number. If if
4723 is smaller, the conversion is done normally. Otherwise, subtract
4724 one plus the highest signed number, convert, and add it back.
4725
4726 We only need to check all real modes, since we know we didn't find
4727 anything with a wider integer mode.
4728
4729 This code used to extend FP value into mode wider than the destination.
4730 This is needed for decimal float modes which cannot accurately
4731 represent one plus the highest signed number of the same size, but
4732 not for binary modes. Consider, for instance conversion from SFmode
4733 into DImode.
4734
4735 The hot path through the code is dealing with inputs smaller than 2^63
4736 and doing just the conversion, so there is no bits to lose.
4737
4738 In the other path we know the value is positive in the range 2^63..2^64-1
4739 inclusive. (as for other input overflow happens and result is undefined)
4740 So we know that the most important bit set in mantissa corresponds to
4741 2^63. The subtraction of 2^63 should not generate any rounding as it
4742 simply clears out that bit. The rest is trivial. */
4743
4744 if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4745 for (fmode = GET_MODE (from); fmode != VOIDmode;
4746 fmode = GET_MODE_WIDER_MODE (fmode))
4747 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
4748 && (!DECIMAL_FLOAT_MODE_P (fmode)
4749 || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
4750 {
4751 int bitsize;
4752 REAL_VALUE_TYPE offset;
4753 rtx limit;
4754 rtx_code_label *lab1, *lab2;
4755 rtx_insn *insn;
4756
4757 bitsize = GET_MODE_PRECISION (GET_MODE (to));
4758 real_2expN (&offset, bitsize - 1, fmode);
4759 limit = const_double_from_real_value (offset, fmode);
4760 lab1 = gen_label_rtx ();
4761 lab2 = gen_label_rtx ();
4762
4763 if (fmode != GET_MODE (from))
4764 from = convert_to_mode (fmode, from, 0);
4765
4766 /* See if we need to do the subtraction. */
4767 do_pending_stack_adjust ();
4768 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4769 0, lab1);
4770
4771 /* If not, do the signed "fix" and branch around fixup code. */
4772 expand_fix (to, from, 0);
4773 emit_jump_insn (targetm.gen_jump (lab2));
4774 emit_barrier ();
4775
4776 /* Otherwise, subtract 2**(N-1), convert to signed number,
4777 then add 2**(N-1). Do the addition using XOR since this
4778 will often generate better code. */
4779 emit_label (lab1);
4780 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4781 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4782 expand_fix (to, target, 0);
4783 target = expand_binop (GET_MODE (to), xor_optab, to,
4784 gen_int_mode
4785 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4786 GET_MODE (to)),
4787 to, 1, OPTAB_LIB_WIDEN);
4788
4789 if (target != to)
4790 emit_move_insn (to, target);
4791
4792 emit_label (lab2);
4793
4794 if (optab_handler (mov_optab, GET_MODE (to)) != CODE_FOR_nothing)
4795 {
4796 /* Make a place for a REG_NOTE and add it. */
4797 insn = emit_move_insn (to, to);
4798 set_dst_reg_note (insn, REG_EQUAL,
4799 gen_rtx_fmt_e (UNSIGNED_FIX, GET_MODE (to),
4800 copy_rtx (from)),
4801 to);
4802 }
4803
4804 return;
4805 }
4806
4807 /* We can't do it with an insn, so use a library call. But first ensure
4808 that the mode of TO is at least as wide as SImode, since those are the
4809 only library calls we know about. */
4810
4811 if (GET_MODE_PRECISION (GET_MODE (to)) < GET_MODE_PRECISION (SImode))
4812 {
4813 target = gen_reg_rtx (SImode);
4814
4815 expand_fix (target, from, unsignedp);
4816 }
4817 else
4818 {
4819 rtx_insn *insns;
4820 rtx value;
4821 rtx libfunc;
4822
4823 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4824 libfunc = convert_optab_libfunc (tab, GET_MODE (to), GET_MODE (from));
4825 gcc_assert (libfunc);
4826
4827 start_sequence ();
4828
4829 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4830 GET_MODE (to), 1, from,
4831 GET_MODE (from));
4832 insns = get_insns ();
4833 end_sequence ();
4834
4835 emit_libcall_block (insns, target, value,
4836 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4837 GET_MODE (to), from));
4838 }
4839
4840 if (target != to)
4841 {
4842 if (GET_MODE (to) == GET_MODE (target))
4843 emit_move_insn (to, target);
4844 else
4845 convert_move (to, target, 0);
4846 }
4847 }
4848
4849 /* Generate code to convert FROM or TO a fixed-point.
4850 If UINTP is true, either TO or FROM is an unsigned integer.
4851 If SATP is true, we need to saturate the result. */
4852
4853 void
4854 expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
4855 {
4856 machine_mode to_mode = GET_MODE (to);
4857 machine_mode from_mode = GET_MODE (from);
4858 convert_optab tab;
4859 enum rtx_code this_code;
4860 enum insn_code code;
4861 rtx_insn *insns;
4862 rtx value;
4863 rtx libfunc;
4864
4865 if (to_mode == from_mode)
4866 {
4867 emit_move_insn (to, from);
4868 return;
4869 }
4870
4871 if (uintp)
4872 {
4873 tab = satp ? satfractuns_optab : fractuns_optab;
4874 this_code = satp ? UNSIGNED_SAT_FRACT : UNSIGNED_FRACT_CONVERT;
4875 }
4876 else
4877 {
4878 tab = satp ? satfract_optab : fract_optab;
4879 this_code = satp ? SAT_FRACT : FRACT_CONVERT;
4880 }
4881 code = convert_optab_handler (tab, to_mode, from_mode);
4882 if (code != CODE_FOR_nothing)
4883 {
4884 emit_unop_insn (code, to, from, this_code);
4885 return;
4886 }
4887
4888 libfunc = convert_optab_libfunc (tab, to_mode, from_mode);
4889 gcc_assert (libfunc);
4890
4891 start_sequence ();
4892 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
4893 1, from, from_mode);
4894 insns = get_insns ();
4895 end_sequence ();
4896
4897 emit_libcall_block (insns, to, value,
4898 gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
4899 }
4900
4901 /* Generate code to convert FROM to fixed point and store in TO. FROM
4902 must be floating point, TO must be signed. Use the conversion optab
4903 TAB to do the conversion. */
4904
4905 bool
4906 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
4907 {
4908 enum insn_code icode;
4909 rtx target = to;
4910 machine_mode fmode, imode;
4911
4912 /* We first try to find a pair of modes, one real and one integer, at
4913 least as wide as FROM and TO, respectively, in which we can open-code
4914 this conversion. If the integer mode is wider than the mode of TO,
4915 we can do the conversion either signed or unsigned. */
4916
4917 for (fmode = GET_MODE (from); fmode != VOIDmode;
4918 fmode = GET_MODE_WIDER_MODE (fmode))
4919 for (imode = GET_MODE (to); imode != VOIDmode;
4920 imode = GET_MODE_WIDER_MODE (imode))
4921 {
4922 icode = convert_optab_handler (tab, imode, fmode);
4923 if (icode != CODE_FOR_nothing)
4924 {
4925 rtx_insn *last = get_last_insn ();
4926 if (fmode != GET_MODE (from))
4927 from = convert_to_mode (fmode, from, 0);
4928
4929 if (imode != GET_MODE (to))
4930 target = gen_reg_rtx (imode);
4931
4932 if (!maybe_emit_unop_insn (icode, target, from, UNKNOWN))
4933 {
4934 delete_insns_since (last);
4935 continue;
4936 }
4937 if (target != to)
4938 convert_move (to, target, 0);
4939 return true;
4940 }
4941 }
4942
4943 return false;
4944 }
4945 \f
4946 /* Report whether we have an instruction to perform the operation
4947 specified by CODE on operands of mode MODE. */
4948 int
4949 have_insn_for (enum rtx_code code, machine_mode mode)
4950 {
4951 return (code_to_optab (code)
4952 && (optab_handler (code_to_optab (code), mode)
4953 != CODE_FOR_nothing));
4954 }
4955
4956 /* Print information about the current contents of the optabs on
4957 STDERR. */
4958
4959 DEBUG_FUNCTION void
4960 debug_optab_libfuncs (void)
4961 {
4962 int i, j, k;
4963
4964 /* Dump the arithmetic optabs. */
4965 for (i = FIRST_NORM_OPTAB; i <= LAST_NORMLIB_OPTAB; ++i)
4966 for (j = 0; j < NUM_MACHINE_MODES; ++j)
4967 {
4968 rtx l = optab_libfunc ((optab) i, (machine_mode) j);
4969 if (l)
4970 {
4971 gcc_assert (GET_CODE (l) == SYMBOL_REF);
4972 fprintf (stderr, "%s\t%s:\t%s\n",
4973 GET_RTX_NAME (optab_to_code ((optab) i)),
4974 GET_MODE_NAME (j),
4975 XSTR (l, 0));
4976 }
4977 }
4978
4979 /* Dump the conversion optabs. */
4980 for (i = FIRST_CONV_OPTAB; i <= LAST_CONVLIB_OPTAB; ++i)
4981 for (j = 0; j < NUM_MACHINE_MODES; ++j)
4982 for (k = 0; k < NUM_MACHINE_MODES; ++k)
4983 {
4984 rtx l = convert_optab_libfunc ((optab) i, (machine_mode) j,
4985 (machine_mode) k);
4986 if (l)
4987 {
4988 gcc_assert (GET_CODE (l) == SYMBOL_REF);
4989 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
4990 GET_RTX_NAME (optab_to_code ((optab) i)),
4991 GET_MODE_NAME (j),
4992 GET_MODE_NAME (k),
4993 XSTR (l, 0));
4994 }
4995 }
4996 }
4997
4998 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4999 CODE. Return 0 on failure. */
5000
5001 rtx_insn *
5002 gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
5003 {
5004 machine_mode mode = GET_MODE (op1);
5005 enum insn_code icode;
5006 rtx_insn *insn;
5007 rtx trap_rtx;
5008
5009 if (mode == VOIDmode)
5010 return 0;
5011
5012 icode = optab_handler (ctrap_optab, mode);
5013 if (icode == CODE_FOR_nothing)
5014 return 0;
5015
5016 /* Some targets only accept a zero trap code. */
5017 if (!insn_operand_matches (icode, 3, tcode))
5018 return 0;
5019
5020 do_pending_stack_adjust ();
5021 start_sequence ();
5022 prepare_cmp_insn (op1, op2, code, NULL_RTX, false, OPTAB_DIRECT,
5023 &trap_rtx, &mode);
5024 if (!trap_rtx)
5025 insn = NULL;
5026 else
5027 insn = GEN_FCN (icode) (trap_rtx, XEXP (trap_rtx, 0), XEXP (trap_rtx, 1),
5028 tcode);
5029
5030 /* If that failed, then give up. */
5031 if (insn == 0)
5032 {
5033 end_sequence ();
5034 return 0;
5035 }
5036
5037 emit_insn (insn);
5038 insn = get_insns ();
5039 end_sequence ();
5040 return insn;
5041 }
5042
5043 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5044 or unsigned operation code. */
5045
5046 enum rtx_code
5047 get_rtx_code (enum tree_code tcode, bool unsignedp)
5048 {
5049 enum rtx_code code;
5050 switch (tcode)
5051 {
5052 case EQ_EXPR:
5053 code = EQ;
5054 break;
5055 case NE_EXPR:
5056 code = NE;
5057 break;
5058 case LT_EXPR:
5059 code = unsignedp ? LTU : LT;
5060 break;
5061 case LE_EXPR:
5062 code = unsignedp ? LEU : LE;
5063 break;
5064 case GT_EXPR:
5065 code = unsignedp ? GTU : GT;
5066 break;
5067 case GE_EXPR:
5068 code = unsignedp ? GEU : GE;
5069 break;
5070
5071 case UNORDERED_EXPR:
5072 code = UNORDERED;
5073 break;
5074 case ORDERED_EXPR:
5075 code = ORDERED;
5076 break;
5077 case UNLT_EXPR:
5078 code = UNLT;
5079 break;
5080 case UNLE_EXPR:
5081 code = UNLE;
5082 break;
5083 case UNGT_EXPR:
5084 code = UNGT;
5085 break;
5086 case UNGE_EXPR:
5087 code = UNGE;
5088 break;
5089 case UNEQ_EXPR:
5090 code = UNEQ;
5091 break;
5092 case LTGT_EXPR:
5093 code = LTGT;
5094 break;
5095
5096 case BIT_AND_EXPR:
5097 code = AND;
5098 break;
5099
5100 case BIT_IOR_EXPR:
5101 code = IOR;
5102 break;
5103
5104 default:
5105 gcc_unreachable ();
5106 }
5107 return code;
5108 }
5109
5110 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5111 unsigned operators. Do not generate compare instruction. */
5112
5113 static rtx
5114 vector_compare_rtx (enum tree_code tcode, tree t_op0, tree t_op1,
5115 bool unsignedp, enum insn_code icode)
5116 {
5117 struct expand_operand ops[2];
5118 rtx rtx_op0, rtx_op1;
5119 machine_mode m0, m1;
5120 enum rtx_code rcode = get_rtx_code (tcode, unsignedp);
5121
5122 gcc_assert (TREE_CODE_CLASS (tcode) == tcc_comparison);
5123
5124 /* Expand operands. For vector types with scalar modes, e.g. where int64x1_t
5125 has mode DImode, this can produce a constant RTX of mode VOIDmode; in such
5126 cases, use the original mode. */
5127 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
5128 EXPAND_STACK_PARM);
5129 m0 = GET_MODE (rtx_op0);
5130 if (m0 == VOIDmode)
5131 m0 = TYPE_MODE (TREE_TYPE (t_op0));
5132
5133 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
5134 EXPAND_STACK_PARM);
5135 m1 = GET_MODE (rtx_op1);
5136 if (m1 == VOIDmode)
5137 m1 = TYPE_MODE (TREE_TYPE (t_op1));
5138
5139 create_input_operand (&ops[0], rtx_op0, m0);
5140 create_input_operand (&ops[1], rtx_op1, m1);
5141 if (!maybe_legitimize_operands (icode, 4, 2, ops))
5142 gcc_unreachable ();
5143 return gen_rtx_fmt_ee (rcode, VOIDmode, ops[0].value, ops[1].value);
5144 }
5145
5146 /* Checks if vec_perm mask SEL is a constant equivalent to a shift of the first
5147 vec_perm operand, assuming the second operand is a constant vector of zeroes.
5148 Return the shift distance in bits if so, or NULL_RTX if the vec_perm is not a
5149 shift. */
5150 static rtx
5151 shift_amt_for_vec_perm_mask (rtx sel)
5152 {
5153 unsigned int i, first, nelt = GET_MODE_NUNITS (GET_MODE (sel));
5154 unsigned int bitsize = GET_MODE_UNIT_BITSIZE (GET_MODE (sel));
5155
5156 if (GET_CODE (sel) != CONST_VECTOR)
5157 return NULL_RTX;
5158
5159 first = INTVAL (CONST_VECTOR_ELT (sel, 0));
5160 if (first >= 2*nelt)
5161 return NULL_RTX;
5162 for (i = 1; i < nelt; i++)
5163 {
5164 int idx = INTVAL (CONST_VECTOR_ELT (sel, i));
5165 unsigned int expected = (i + first) & (2 * nelt - 1);
5166 /* Indices into the second vector are all equivalent. */
5167 if (idx < 0 || (MIN (nelt, (unsigned) idx) != MIN (nelt, expected)))
5168 return NULL_RTX;
5169 }
5170
5171 return GEN_INT (first * bitsize);
5172 }
5173
5174 /* A subroutine of expand_vec_perm for expanding one vec_perm insn. */
5175
5176 static rtx
5177 expand_vec_perm_1 (enum insn_code icode, rtx target,
5178 rtx v0, rtx v1, rtx sel)
5179 {
5180 machine_mode tmode = GET_MODE (target);
5181 machine_mode smode = GET_MODE (sel);
5182 struct expand_operand ops[4];
5183
5184 create_output_operand (&ops[0], target, tmode);
5185 create_input_operand (&ops[3], sel, smode);
5186
5187 /* Make an effort to preserve v0 == v1. The target expander is able to
5188 rely on this to determine if we're permuting a single input operand. */
5189 if (rtx_equal_p (v0, v1))
5190 {
5191 if (!insn_operand_matches (icode, 1, v0))
5192 v0 = force_reg (tmode, v0);
5193 gcc_checking_assert (insn_operand_matches (icode, 1, v0));
5194 gcc_checking_assert (insn_operand_matches (icode, 2, v0));
5195
5196 create_fixed_operand (&ops[1], v0);
5197 create_fixed_operand (&ops[2], v0);
5198 }
5199 else
5200 {
5201 create_input_operand (&ops[1], v0, tmode);
5202 /* See if this can be handled with a vec_shr. We only do this if the
5203 second vector is all zeroes. */
5204 enum insn_code shift_code = optab_handler (vec_shr_optab, GET_MODE (v0));
5205 if (v1 == CONST0_RTX (GET_MODE (v1)) && shift_code)
5206 if (rtx shift_amt = shift_amt_for_vec_perm_mask (sel))
5207 {
5208 create_convert_operand_from_type (&ops[2], shift_amt,
5209 sizetype_tab[(int) stk_sizetype]);
5210 if (maybe_expand_insn (shift_code, 3, ops))
5211 return ops[0].value;
5212 }
5213 create_input_operand (&ops[2], v1, tmode);
5214 }
5215
5216 if (maybe_expand_insn (icode, 4, ops))
5217 return ops[0].value;
5218 return NULL_RTX;
5219 }
5220
5221 /* Generate instructions for vec_perm optab given its mode
5222 and three operands. */
5223
5224 rtx
5225 expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
5226 {
5227 enum insn_code icode;
5228 machine_mode qimode;
5229 unsigned int i, w, e, u;
5230 rtx tmp, sel_qi = NULL;
5231 rtvec vec;
5232
5233 if (!target || GET_MODE (target) != mode)
5234 target = gen_reg_rtx (mode);
5235
5236 w = GET_MODE_SIZE (mode);
5237 e = GET_MODE_NUNITS (mode);
5238 u = GET_MODE_UNIT_SIZE (mode);
5239
5240 /* Set QIMODE to a different vector mode with byte elements.
5241 If no such mode, or if MODE already has byte elements, use VOIDmode. */
5242 qimode = VOIDmode;
5243 if (GET_MODE_INNER (mode) != QImode)
5244 {
5245 qimode = mode_for_vector (QImode, w);
5246 if (!VECTOR_MODE_P (qimode))
5247 qimode = VOIDmode;
5248 }
5249
5250 /* If the input is a constant, expand it specially. */
5251 gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
5252 if (GET_CODE (sel) == CONST_VECTOR)
5253 {
5254 icode = direct_optab_handler (vec_perm_const_optab, mode);
5255 if (icode != CODE_FOR_nothing)
5256 {
5257 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5258 if (tmp)
5259 return tmp;
5260 }
5261
5262 /* Fall back to a constant byte-based permutation. */
5263 if (qimode != VOIDmode)
5264 {
5265 vec = rtvec_alloc (w);
5266 for (i = 0; i < e; ++i)
5267 {
5268 unsigned int j, this_e;
5269
5270 this_e = INTVAL (CONST_VECTOR_ELT (sel, i));
5271 this_e &= 2 * e - 1;
5272 this_e *= u;
5273
5274 for (j = 0; j < u; ++j)
5275 RTVEC_ELT (vec, i * u + j) = GEN_INT (this_e + j);
5276 }
5277 sel_qi = gen_rtx_CONST_VECTOR (qimode, vec);
5278
5279 icode = direct_optab_handler (vec_perm_const_optab, qimode);
5280 if (icode != CODE_FOR_nothing)
5281 {
5282 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5283 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5284 gen_lowpart (qimode, v1), sel_qi);
5285 if (tmp)
5286 return gen_lowpart (mode, tmp);
5287 }
5288 }
5289 }
5290
5291 /* Otherwise expand as a fully variable permuation. */
5292 icode = direct_optab_handler (vec_perm_optab, mode);
5293 if (icode != CODE_FOR_nothing)
5294 {
5295 tmp = expand_vec_perm_1 (icode, target, v0, v1, sel);
5296 if (tmp)
5297 return tmp;
5298 }
5299
5300 /* As a special case to aid several targets, lower the element-based
5301 permutation to a byte-based permutation and try again. */
5302 if (qimode == VOIDmode)
5303 return NULL_RTX;
5304 icode = direct_optab_handler (vec_perm_optab, qimode);
5305 if (icode == CODE_FOR_nothing)
5306 return NULL_RTX;
5307
5308 if (sel_qi == NULL)
5309 {
5310 /* Multiply each element by its byte size. */
5311 machine_mode selmode = GET_MODE (sel);
5312 if (u == 2)
5313 sel = expand_simple_binop (selmode, PLUS, sel, sel,
5314 NULL, 0, OPTAB_DIRECT);
5315 else
5316 sel = expand_simple_binop (selmode, ASHIFT, sel,
5317 GEN_INT (exact_log2 (u)),
5318 NULL, 0, OPTAB_DIRECT);
5319 gcc_assert (sel != NULL);
5320
5321 /* Broadcast the low byte each element into each of its bytes. */
5322 vec = rtvec_alloc (w);
5323 for (i = 0; i < w; ++i)
5324 {
5325 int this_e = i / u * u;
5326 if (BYTES_BIG_ENDIAN)
5327 this_e += u - 1;
5328 RTVEC_ELT (vec, i) = GEN_INT (this_e);
5329 }
5330 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5331 sel = gen_lowpart (qimode, sel);
5332 sel = expand_vec_perm (qimode, sel, sel, tmp, NULL);
5333 gcc_assert (sel != NULL);
5334
5335 /* Add the byte offset to each byte element. */
5336 /* Note that the definition of the indicies here is memory ordering,
5337 so there should be no difference between big and little endian. */
5338 vec = rtvec_alloc (w);
5339 for (i = 0; i < w; ++i)
5340 RTVEC_ELT (vec, i) = GEN_INT (i % u);
5341 tmp = gen_rtx_CONST_VECTOR (qimode, vec);
5342 sel_qi = expand_simple_binop (qimode, PLUS, sel, tmp,
5343 sel, 0, OPTAB_DIRECT);
5344 gcc_assert (sel_qi != NULL);
5345 }
5346
5347 tmp = mode != qimode ? gen_reg_rtx (qimode) : target;
5348 tmp = expand_vec_perm_1 (icode, tmp, gen_lowpart (qimode, v0),
5349 gen_lowpart (qimode, v1), sel_qi);
5350 if (tmp)
5351 tmp = gen_lowpart (mode, tmp);
5352 return tmp;
5353 }
5354
5355 /* Generate insns for a VEC_COND_EXPR, given its TYPE and its
5356 three operands. */
5357
5358 rtx
5359 expand_vec_cond_expr (tree vec_cond_type, tree op0, tree op1, tree op2,
5360 rtx target)
5361 {
5362 struct expand_operand ops[6];
5363 enum insn_code icode;
5364 rtx comparison, rtx_op1, rtx_op2;
5365 machine_mode mode = TYPE_MODE (vec_cond_type);
5366 machine_mode cmp_op_mode;
5367 bool unsignedp;
5368 tree op0a, op0b;
5369 enum tree_code tcode;
5370
5371 if (COMPARISON_CLASS_P (op0))
5372 {
5373 op0a = TREE_OPERAND (op0, 0);
5374 op0b = TREE_OPERAND (op0, 1);
5375 tcode = TREE_CODE (op0);
5376 unsignedp = TYPE_UNSIGNED (TREE_TYPE (op0a));
5377 }
5378 else
5379 {
5380 /* Fake op0 < 0. */
5381 gcc_assert (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (op0)));
5382 op0a = op0;
5383 op0b = build_zero_cst (TREE_TYPE (op0));
5384 tcode = LT_EXPR;
5385 unsignedp = false;
5386 }
5387 cmp_op_mode = TYPE_MODE (TREE_TYPE (op0a));
5388
5389
5390 gcc_assert (GET_MODE_SIZE (mode) == GET_MODE_SIZE (cmp_op_mode)
5391 && GET_MODE_NUNITS (mode) == GET_MODE_NUNITS (cmp_op_mode));
5392
5393 icode = get_vcond_icode (mode, cmp_op_mode, unsignedp);
5394 if (icode == CODE_FOR_nothing)
5395 return 0;
5396
5397 comparison = vector_compare_rtx (tcode, op0a, op0b, unsignedp, icode);
5398 rtx_op1 = expand_normal (op1);
5399 rtx_op2 = expand_normal (op2);
5400
5401 create_output_operand (&ops[0], target, mode);
5402 create_input_operand (&ops[1], rtx_op1, mode);
5403 create_input_operand (&ops[2], rtx_op2, mode);
5404 create_fixed_operand (&ops[3], comparison);
5405 create_fixed_operand (&ops[4], XEXP (comparison, 0));
5406 create_fixed_operand (&ops[5], XEXP (comparison, 1));
5407 expand_insn (icode, 6, ops);
5408 return ops[0].value;
5409 }
5410
5411 /* Expand a highpart multiply. */
5412
5413 rtx
5414 expand_mult_highpart (machine_mode mode, rtx op0, rtx op1,
5415 rtx target, bool uns_p)
5416 {
5417 struct expand_operand eops[3];
5418 enum insn_code icode;
5419 int method, i, nunits;
5420 machine_mode wmode;
5421 rtx m1, m2, perm;
5422 optab tab1, tab2;
5423 rtvec v;
5424
5425 method = can_mult_highpart_p (mode, uns_p);
5426 switch (method)
5427 {
5428 case 0:
5429 return NULL_RTX;
5430 case 1:
5431 tab1 = uns_p ? umul_highpart_optab : smul_highpart_optab;
5432 return expand_binop (mode, tab1, op0, op1, target, uns_p,
5433 OPTAB_LIB_WIDEN);
5434 case 2:
5435 tab1 = uns_p ? vec_widen_umult_even_optab : vec_widen_smult_even_optab;
5436 tab2 = uns_p ? vec_widen_umult_odd_optab : vec_widen_smult_odd_optab;
5437 break;
5438 case 3:
5439 tab1 = uns_p ? vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
5440 tab2 = uns_p ? vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
5441 if (BYTES_BIG_ENDIAN)
5442 std::swap (tab1, tab2);
5443 break;
5444 default:
5445 gcc_unreachable ();
5446 }
5447
5448 icode = optab_handler (tab1, mode);
5449 nunits = GET_MODE_NUNITS (mode);
5450 wmode = insn_data[icode].operand[0].mode;
5451 gcc_checking_assert (2 * GET_MODE_NUNITS (wmode) == nunits);
5452 gcc_checking_assert (GET_MODE_SIZE (wmode) == GET_MODE_SIZE (mode));
5453
5454 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5455 create_input_operand (&eops[1], op0, mode);
5456 create_input_operand (&eops[2], op1, mode);
5457 expand_insn (icode, 3, eops);
5458 m1 = gen_lowpart (mode, eops[0].value);
5459
5460 create_output_operand (&eops[0], gen_reg_rtx (wmode), wmode);
5461 create_input_operand (&eops[1], op0, mode);
5462 create_input_operand (&eops[2], op1, mode);
5463 expand_insn (optab_handler (tab2, mode), 3, eops);
5464 m2 = gen_lowpart (mode, eops[0].value);
5465
5466 v = rtvec_alloc (nunits);
5467 if (method == 2)
5468 {
5469 for (i = 0; i < nunits; ++i)
5470 RTVEC_ELT (v, i) = GEN_INT (!BYTES_BIG_ENDIAN + (i & ~1)
5471 + ((i & 1) ? nunits : 0));
5472 }
5473 else
5474 {
5475 for (i = 0; i < nunits; ++i)
5476 RTVEC_ELT (v, i) = GEN_INT (2 * i + (BYTES_BIG_ENDIAN ? 0 : 1));
5477 }
5478 perm = gen_rtx_CONST_VECTOR (mode, v);
5479
5480 return expand_vec_perm (mode, m1, m2, perm, target);
5481 }
5482 \f
5483 /* Helper function to find the MODE_CC set in a sync_compare_and_swap
5484 pattern. */
5485
5486 static void
5487 find_cc_set (rtx x, const_rtx pat, void *data)
5488 {
5489 if (REG_P (x) && GET_MODE_CLASS (GET_MODE (x)) == MODE_CC
5490 && GET_CODE (pat) == SET)
5491 {
5492 rtx *p_cc_reg = (rtx *) data;
5493 gcc_assert (!*p_cc_reg);
5494 *p_cc_reg = x;
5495 }
5496 }
5497
5498 /* This is a helper function for the other atomic operations. This function
5499 emits a loop that contains SEQ that iterates until a compare-and-swap
5500 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5501 a set of instructions that takes a value from OLD_REG as an input and
5502 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5503 set to the current contents of MEM. After SEQ, a compare-and-swap will
5504 attempt to update MEM with NEW_REG. The function returns true when the
5505 loop was generated successfully. */
5506
5507 static bool
5508 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5509 {
5510 machine_mode mode = GET_MODE (mem);
5511 rtx_code_label *label;
5512 rtx cmp_reg, success, oldval;
5513
5514 /* The loop we want to generate looks like
5515
5516 cmp_reg = mem;
5517 label:
5518 old_reg = cmp_reg;
5519 seq;
5520 (success, cmp_reg) = compare-and-swap(mem, old_reg, new_reg)
5521 if (success)
5522 goto label;
5523
5524 Note that we only do the plain load from memory once. Subsequent
5525 iterations use the value loaded by the compare-and-swap pattern. */
5526
5527 label = gen_label_rtx ();
5528 cmp_reg = gen_reg_rtx (mode);
5529
5530 emit_move_insn (cmp_reg, mem);
5531 emit_label (label);
5532 emit_move_insn (old_reg, cmp_reg);
5533 if (seq)
5534 emit_insn (seq);
5535
5536 success = NULL_RTX;
5537 oldval = cmp_reg;
5538 if (!expand_atomic_compare_and_swap (&success, &oldval, mem, old_reg,
5539 new_reg, false, MEMMODEL_SYNC_SEQ_CST,
5540 MEMMODEL_RELAXED))
5541 return false;
5542
5543 if (oldval != cmp_reg)
5544 emit_move_insn (cmp_reg, oldval);
5545
5546 /* Mark this jump predicted not taken. */
5547 emit_cmp_and_jump_insns (success, const0_rtx, EQ, const0_rtx,
5548 GET_MODE (success), 1, label, 0);
5549 return true;
5550 }
5551
5552
5553 /* This function tries to emit an atomic_exchange intruction. VAL is written
5554 to *MEM using memory model MODEL. The previous contents of *MEM are returned,
5555 using TARGET if possible. */
5556
5557 static rtx
5558 maybe_emit_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5559 {
5560 machine_mode mode = GET_MODE (mem);
5561 enum insn_code icode;
5562
5563 /* If the target supports the exchange directly, great. */
5564 icode = direct_optab_handler (atomic_exchange_optab, mode);
5565 if (icode != CODE_FOR_nothing)
5566 {
5567 struct expand_operand ops[4];
5568
5569 create_output_operand (&ops[0], target, mode);
5570 create_fixed_operand (&ops[1], mem);
5571 create_input_operand (&ops[2], val, mode);
5572 create_integer_operand (&ops[3], model);
5573 if (maybe_expand_insn (icode, 4, ops))
5574 return ops[0].value;
5575 }
5576
5577 return NULL_RTX;
5578 }
5579
5580 /* This function tries to implement an atomic exchange operation using
5581 __sync_lock_test_and_set. VAL is written to *MEM using memory model MODEL.
5582 The previous contents of *MEM are returned, using TARGET if possible.
5583 Since this instructionn is an acquire barrier only, stronger memory
5584 models may require additional barriers to be emitted. */
5585
5586 static rtx
5587 maybe_emit_sync_lock_test_and_set (rtx target, rtx mem, rtx val,
5588 enum memmodel model)
5589 {
5590 machine_mode mode = GET_MODE (mem);
5591 enum insn_code icode;
5592 rtx_insn *last_insn = get_last_insn ();
5593
5594 icode = optab_handler (sync_lock_test_and_set_optab, mode);
5595
5596 /* Legacy sync_lock_test_and_set is an acquire barrier. If the pattern
5597 exists, and the memory model is stronger than acquire, add a release
5598 barrier before the instruction. */
5599
5600 if (is_mm_seq_cst (model) || is_mm_release (model) || is_mm_acq_rel (model))
5601 expand_mem_thread_fence (model);
5602
5603 if (icode != CODE_FOR_nothing)
5604 {
5605 struct expand_operand ops[3];
5606 create_output_operand (&ops[0], target, mode);
5607 create_fixed_operand (&ops[1], mem);
5608 create_input_operand (&ops[2], val, mode);
5609 if (maybe_expand_insn (icode, 3, ops))
5610 return ops[0].value;
5611 }
5612
5613 /* If an external test-and-set libcall is provided, use that instead of
5614 any external compare-and-swap that we might get from the compare-and-
5615 swap-loop expansion later. */
5616 if (!can_compare_and_swap_p (mode, false))
5617 {
5618 rtx libfunc = optab_libfunc (sync_lock_test_and_set_optab, mode);
5619 if (libfunc != NULL)
5620 {
5621 rtx addr;
5622
5623 addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5624 return emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5625 mode, 2, addr, ptr_mode,
5626 val, mode);
5627 }
5628 }
5629
5630 /* If the test_and_set can't be emitted, eliminate any barrier that might
5631 have been emitted. */
5632 delete_insns_since (last_insn);
5633 return NULL_RTX;
5634 }
5635
5636 /* This function tries to implement an atomic exchange operation using a
5637 compare_and_swap loop. VAL is written to *MEM. The previous contents of
5638 *MEM are returned, using TARGET if possible. No memory model is required
5639 since a compare_and_swap loop is seq-cst. */
5640
5641 static rtx
5642 maybe_emit_compare_and_swap_exchange_loop (rtx target, rtx mem, rtx val)
5643 {
5644 machine_mode mode = GET_MODE (mem);
5645
5646 if (can_compare_and_swap_p (mode, true))
5647 {
5648 if (!target || !register_operand (target, mode))
5649 target = gen_reg_rtx (mode);
5650 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
5651 return target;
5652 }
5653
5654 return NULL_RTX;
5655 }
5656
5657 /* This function tries to implement an atomic test-and-set operation
5658 using the atomic_test_and_set instruction pattern. A boolean value
5659 is returned from the operation, using TARGET if possible. */
5660
5661 static rtx
5662 maybe_emit_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5663 {
5664 machine_mode pat_bool_mode;
5665 struct expand_operand ops[3];
5666
5667 if (!targetm.have_atomic_test_and_set ())
5668 return NULL_RTX;
5669
5670 /* While we always get QImode from __atomic_test_and_set, we get
5671 other memory modes from __sync_lock_test_and_set. Note that we
5672 use no endian adjustment here. This matches the 4.6 behavior
5673 in the Sparc backend. */
5674 enum insn_code icode = targetm.code_for_atomic_test_and_set;
5675 gcc_checking_assert (insn_data[icode].operand[1].mode == QImode);
5676 if (GET_MODE (mem) != QImode)
5677 mem = adjust_address_nv (mem, QImode, 0);
5678
5679 pat_bool_mode = insn_data[icode].operand[0].mode;
5680 create_output_operand (&ops[0], target, pat_bool_mode);
5681 create_fixed_operand (&ops[1], mem);
5682 create_integer_operand (&ops[2], model);
5683
5684 if (maybe_expand_insn (icode, 3, ops))
5685 return ops[0].value;
5686 return NULL_RTX;
5687 }
5688
5689 /* This function expands the legacy _sync_lock test_and_set operation which is
5690 generally an atomic exchange. Some limited targets only allow the
5691 constant 1 to be stored. This is an ACQUIRE operation.
5692
5693 TARGET is an optional place to stick the return value.
5694 MEM is where VAL is stored. */
5695
5696 rtx
5697 expand_sync_lock_test_and_set (rtx target, rtx mem, rtx val)
5698 {
5699 rtx ret;
5700
5701 /* Try an atomic_exchange first. */
5702 ret = maybe_emit_atomic_exchange (target, mem, val, MEMMODEL_SYNC_ACQUIRE);
5703 if (ret)
5704 return ret;
5705
5706 ret = maybe_emit_sync_lock_test_and_set (target, mem, val,
5707 MEMMODEL_SYNC_ACQUIRE);
5708 if (ret)
5709 return ret;
5710
5711 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
5712 if (ret)
5713 return ret;
5714
5715 /* If there are no other options, try atomic_test_and_set if the value
5716 being stored is 1. */
5717 if (val == const1_rtx)
5718 ret = maybe_emit_atomic_test_and_set (target, mem, MEMMODEL_SYNC_ACQUIRE);
5719
5720 return ret;
5721 }
5722
5723 /* This function expands the atomic test_and_set operation:
5724 atomically store a boolean TRUE into MEM and return the previous value.
5725
5726 MEMMODEL is the memory model variant to use.
5727 TARGET is an optional place to stick the return value. */
5728
5729 rtx
5730 expand_atomic_test_and_set (rtx target, rtx mem, enum memmodel model)
5731 {
5732 machine_mode mode = GET_MODE (mem);
5733 rtx ret, trueval, subtarget;
5734
5735 ret = maybe_emit_atomic_test_and_set (target, mem, model);
5736 if (ret)
5737 return ret;
5738
5739 /* Be binary compatible with non-default settings of trueval, and different
5740 cpu revisions. E.g. one revision may have atomic-test-and-set, but
5741 another only has atomic-exchange. */
5742 if (targetm.atomic_test_and_set_trueval == 1)
5743 {
5744 trueval = const1_rtx;
5745 subtarget = target ? target : gen_reg_rtx (mode);
5746 }
5747 else
5748 {
5749 trueval = gen_int_mode (targetm.atomic_test_and_set_trueval, mode);
5750 subtarget = gen_reg_rtx (mode);
5751 }
5752
5753 /* Try the atomic-exchange optab... */
5754 ret = maybe_emit_atomic_exchange (subtarget, mem, trueval, model);
5755
5756 /* ... then an atomic-compare-and-swap loop ... */
5757 if (!ret)
5758 ret = maybe_emit_compare_and_swap_exchange_loop (subtarget, mem, trueval);
5759
5760 /* ... before trying the vaguely defined legacy lock_test_and_set. */
5761 if (!ret)
5762 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, trueval, model);
5763
5764 /* Recall that the legacy lock_test_and_set optab was allowed to do magic
5765 things with the value 1. Thus we try again without trueval. */
5766 if (!ret && targetm.atomic_test_and_set_trueval != 1)
5767 ret = maybe_emit_sync_lock_test_and_set (subtarget, mem, const1_rtx, model);
5768
5769 /* Failing all else, assume a single threaded environment and simply
5770 perform the operation. */
5771 if (!ret)
5772 {
5773 /* If the result is ignored skip the move to target. */
5774 if (subtarget != const0_rtx)
5775 emit_move_insn (subtarget, mem);
5776
5777 emit_move_insn (mem, trueval);
5778 ret = subtarget;
5779 }
5780
5781 /* Recall that have to return a boolean value; rectify if trueval
5782 is not exactly one. */
5783 if (targetm.atomic_test_and_set_trueval != 1)
5784 ret = emit_store_flag_force (target, NE, ret, const0_rtx, mode, 0, 1);
5785
5786 return ret;
5787 }
5788
5789 /* This function expands the atomic exchange operation:
5790 atomically store VAL in MEM and return the previous value in MEM.
5791
5792 MEMMODEL is the memory model variant to use.
5793 TARGET is an optional place to stick the return value. */
5794
5795 rtx
5796 expand_atomic_exchange (rtx target, rtx mem, rtx val, enum memmodel model)
5797 {
5798 rtx ret;
5799
5800 ret = maybe_emit_atomic_exchange (target, mem, val, model);
5801
5802 /* Next try a compare-and-swap loop for the exchange. */
5803 if (!ret)
5804 ret = maybe_emit_compare_and_swap_exchange_loop (target, mem, val);
5805
5806 return ret;
5807 }
5808
5809 /* This function expands the atomic compare exchange operation:
5810
5811 *PTARGET_BOOL is an optional place to store the boolean success/failure.
5812 *PTARGET_OVAL is an optional place to store the old value from memory.
5813 Both target parameters may be NULL to indicate that we do not care about
5814 that return value. Both target parameters are updated on success to
5815 the actual location of the corresponding result.
5816
5817 MEMMODEL is the memory model variant to use.
5818
5819 The return value of the function is true for success. */
5820
5821 bool
5822 expand_atomic_compare_and_swap (rtx *ptarget_bool, rtx *ptarget_oval,
5823 rtx mem, rtx expected, rtx desired,
5824 bool is_weak, enum memmodel succ_model,
5825 enum memmodel fail_model)
5826 {
5827 machine_mode mode = GET_MODE (mem);
5828 struct expand_operand ops[8];
5829 enum insn_code icode;
5830 rtx target_oval, target_bool = NULL_RTX;
5831 rtx libfunc;
5832
5833 /* Load expected into a register for the compare and swap. */
5834 if (MEM_P (expected))
5835 expected = copy_to_reg (expected);
5836
5837 /* Make sure we always have some place to put the return oldval.
5838 Further, make sure that place is distinct from the input expected,
5839 just in case we need that path down below. */
5840 if (ptarget_oval == NULL
5841 || (target_oval = *ptarget_oval) == NULL
5842 || reg_overlap_mentioned_p (expected, target_oval))
5843 target_oval = gen_reg_rtx (mode);
5844
5845 icode = direct_optab_handler (atomic_compare_and_swap_optab, mode);
5846 if (icode != CODE_FOR_nothing)
5847 {
5848 machine_mode bool_mode = insn_data[icode].operand[0].mode;
5849
5850 /* Make sure we always have a place for the bool operand. */
5851 if (ptarget_bool == NULL
5852 || (target_bool = *ptarget_bool) == NULL
5853 || GET_MODE (target_bool) != bool_mode)
5854 target_bool = gen_reg_rtx (bool_mode);
5855
5856 /* Emit the compare_and_swap. */
5857 create_output_operand (&ops[0], target_bool, bool_mode);
5858 create_output_operand (&ops[1], target_oval, mode);
5859 create_fixed_operand (&ops[2], mem);
5860 create_input_operand (&ops[3], expected, mode);
5861 create_input_operand (&ops[4], desired, mode);
5862 create_integer_operand (&ops[5], is_weak);
5863 create_integer_operand (&ops[6], succ_model);
5864 create_integer_operand (&ops[7], fail_model);
5865 if (maybe_expand_insn (icode, 8, ops))
5866 {
5867 /* Return success/failure. */
5868 target_bool = ops[0].value;
5869 target_oval = ops[1].value;
5870 goto success;
5871 }
5872 }
5873
5874 /* Otherwise fall back to the original __sync_val_compare_and_swap
5875 which is always seq-cst. */
5876 icode = optab_handler (sync_compare_and_swap_optab, mode);
5877 if (icode != CODE_FOR_nothing)
5878 {
5879 rtx cc_reg;
5880
5881 create_output_operand (&ops[0], target_oval, mode);
5882 create_fixed_operand (&ops[1], mem);
5883 create_input_operand (&ops[2], expected, mode);
5884 create_input_operand (&ops[3], desired, mode);
5885 if (!maybe_expand_insn (icode, 4, ops))
5886 return false;
5887
5888 target_oval = ops[0].value;
5889
5890 /* If the caller isn't interested in the boolean return value,
5891 skip the computation of it. */
5892 if (ptarget_bool == NULL)
5893 goto success;
5894
5895 /* Otherwise, work out if the compare-and-swap succeeded. */
5896 cc_reg = NULL_RTX;
5897 if (have_insn_for (COMPARE, CCmode))
5898 note_stores (PATTERN (get_last_insn ()), find_cc_set, &cc_reg);
5899 if (cc_reg)
5900 {
5901 target_bool = emit_store_flag_force (target_bool, EQ, cc_reg,
5902 const0_rtx, VOIDmode, 0, 1);
5903 goto success;
5904 }
5905 goto success_bool_from_val;
5906 }
5907
5908 /* Also check for library support for __sync_val_compare_and_swap. */
5909 libfunc = optab_libfunc (sync_compare_and_swap_optab, mode);
5910 if (libfunc != NULL)
5911 {
5912 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
5913 rtx target = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
5914 mode, 3, addr, ptr_mode,
5915 expected, mode, desired, mode);
5916 emit_move_insn (target_oval, target);
5917
5918 /* Compute the boolean return value only if requested. */
5919 if (ptarget_bool)
5920 goto success_bool_from_val;
5921 else
5922 goto success;
5923 }
5924
5925 /* Failure. */
5926 return false;
5927
5928 success_bool_from_val:
5929 target_bool = emit_store_flag_force (target_bool, EQ, target_oval,
5930 expected, VOIDmode, 1, 1);
5931 success:
5932 /* Make sure that the oval output winds up where the caller asked. */
5933 if (ptarget_oval)
5934 *ptarget_oval = target_oval;
5935 if (ptarget_bool)
5936 *ptarget_bool = target_bool;
5937 return true;
5938 }
5939
5940 /* Generate asm volatile("" : : : "memory") as the memory barrier. */
5941
5942 static void
5943 expand_asm_memory_barrier (void)
5944 {
5945 rtx asm_op, clob;
5946
5947 asm_op = gen_rtx_ASM_OPERANDS (VOIDmode, empty_string, empty_string, 0,
5948 rtvec_alloc (0), rtvec_alloc (0),
5949 rtvec_alloc (0), UNKNOWN_LOCATION);
5950 MEM_VOLATILE_P (asm_op) = 1;
5951
5952 clob = gen_rtx_SCRATCH (VOIDmode);
5953 clob = gen_rtx_MEM (BLKmode, clob);
5954 clob = gen_rtx_CLOBBER (VOIDmode, clob);
5955
5956 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, asm_op, clob)));
5957 }
5958
5959 /* This routine will either emit the mem_thread_fence pattern or issue a
5960 sync_synchronize to generate a fence for memory model MEMMODEL. */
5961
5962 void
5963 expand_mem_thread_fence (enum memmodel model)
5964 {
5965 if (targetm.have_mem_thread_fence ())
5966 emit_insn (targetm.gen_mem_thread_fence (GEN_INT (model)));
5967 else if (!is_mm_relaxed (model))
5968 {
5969 if (targetm.have_memory_barrier ())
5970 emit_insn (targetm.gen_memory_barrier ());
5971 else if (synchronize_libfunc != NULL_RTX)
5972 emit_library_call (synchronize_libfunc, LCT_NORMAL, VOIDmode, 0);
5973 else
5974 expand_asm_memory_barrier ();
5975 }
5976 }
5977
5978 /* This routine will either emit the mem_signal_fence pattern or issue a
5979 sync_synchronize to generate a fence for memory model MEMMODEL. */
5980
5981 void
5982 expand_mem_signal_fence (enum memmodel model)
5983 {
5984 if (targetm.have_mem_signal_fence ())
5985 emit_insn (targetm.gen_mem_signal_fence (GEN_INT (model)));
5986 else if (!is_mm_relaxed (model))
5987 {
5988 /* By default targets are coherent between a thread and the signal
5989 handler running on the same thread. Thus this really becomes a
5990 compiler barrier, in that stores must not be sunk past
5991 (or raised above) a given point. */
5992 expand_asm_memory_barrier ();
5993 }
5994 }
5995
5996 /* This function expands the atomic load operation:
5997 return the atomically loaded value in MEM.
5998
5999 MEMMODEL is the memory model variant to use.
6000 TARGET is an option place to stick the return value. */
6001
6002 rtx
6003 expand_atomic_load (rtx target, rtx mem, enum memmodel model)
6004 {
6005 machine_mode mode = GET_MODE (mem);
6006 enum insn_code icode;
6007
6008 /* If the target supports the load directly, great. */
6009 icode = direct_optab_handler (atomic_load_optab, mode);
6010 if (icode != CODE_FOR_nothing)
6011 {
6012 struct expand_operand ops[3];
6013
6014 create_output_operand (&ops[0], target, mode);
6015 create_fixed_operand (&ops[1], mem);
6016 create_integer_operand (&ops[2], model);
6017 if (maybe_expand_insn (icode, 3, ops))
6018 return ops[0].value;
6019 }
6020
6021 /* If the size of the object is greater than word size on this target,
6022 then we assume that a load will not be atomic. */
6023 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6024 {
6025 /* Issue val = compare_and_swap (mem, 0, 0).
6026 This may cause the occasional harmless store of 0 when the value is
6027 already 0, but it seems to be OK according to the standards guys. */
6028 if (expand_atomic_compare_and_swap (NULL, &target, mem, const0_rtx,
6029 const0_rtx, false, model, model))
6030 return target;
6031 else
6032 /* Otherwise there is no atomic load, leave the library call. */
6033 return NULL_RTX;
6034 }
6035
6036 /* Otherwise assume loads are atomic, and emit the proper barriers. */
6037 if (!target || target == const0_rtx)
6038 target = gen_reg_rtx (mode);
6039
6040 /* For SEQ_CST, emit a barrier before the load. */
6041 if (is_mm_seq_cst (model))
6042 expand_mem_thread_fence (model);
6043
6044 emit_move_insn (target, mem);
6045
6046 /* Emit the appropriate barrier after the load. */
6047 expand_mem_thread_fence (model);
6048
6049 return target;
6050 }
6051
6052 /* This function expands the atomic store operation:
6053 Atomically store VAL in MEM.
6054 MEMMODEL is the memory model variant to use.
6055 USE_RELEASE is true if __sync_lock_release can be used as a fall back.
6056 function returns const0_rtx if a pattern was emitted. */
6057
6058 rtx
6059 expand_atomic_store (rtx mem, rtx val, enum memmodel model, bool use_release)
6060 {
6061 machine_mode mode = GET_MODE (mem);
6062 enum insn_code icode;
6063 struct expand_operand ops[3];
6064
6065 /* If the target supports the store directly, great. */
6066 icode = direct_optab_handler (atomic_store_optab, mode);
6067 if (icode != CODE_FOR_nothing)
6068 {
6069 create_fixed_operand (&ops[0], mem);
6070 create_input_operand (&ops[1], val, mode);
6071 create_integer_operand (&ops[2], model);
6072 if (maybe_expand_insn (icode, 3, ops))
6073 return const0_rtx;
6074 }
6075
6076 /* If using __sync_lock_release is a viable alternative, try it. */
6077 if (use_release)
6078 {
6079 icode = direct_optab_handler (sync_lock_release_optab, mode);
6080 if (icode != CODE_FOR_nothing)
6081 {
6082 create_fixed_operand (&ops[0], mem);
6083 create_input_operand (&ops[1], const0_rtx, mode);
6084 if (maybe_expand_insn (icode, 2, ops))
6085 {
6086 /* lock_release is only a release barrier. */
6087 if (is_mm_seq_cst (model))
6088 expand_mem_thread_fence (model);
6089 return const0_rtx;
6090 }
6091 }
6092 }
6093
6094 /* If the size of the object is greater than word size on this target,
6095 a default store will not be atomic, Try a mem_exchange and throw away
6096 the result. If that doesn't work, don't do anything. */
6097 if (GET_MODE_PRECISION (mode) > BITS_PER_WORD)
6098 {
6099 rtx target = maybe_emit_atomic_exchange (NULL_RTX, mem, val, model);
6100 if (!target)
6101 target = maybe_emit_compare_and_swap_exchange_loop (NULL_RTX, mem, val);
6102 if (target)
6103 return const0_rtx;
6104 else
6105 return NULL_RTX;
6106 }
6107
6108 /* Otherwise assume stores are atomic, and emit the proper barriers. */
6109 expand_mem_thread_fence (model);
6110
6111 emit_move_insn (mem, val);
6112
6113 /* For SEQ_CST, also emit a barrier after the store. */
6114 if (is_mm_seq_cst (model))
6115 expand_mem_thread_fence (model);
6116
6117 return const0_rtx;
6118 }
6119
6120
6121 /* Structure containing the pointers and values required to process the
6122 various forms of the atomic_fetch_op and atomic_op_fetch builtins. */
6123
6124 struct atomic_op_functions
6125 {
6126 direct_optab mem_fetch_before;
6127 direct_optab mem_fetch_after;
6128 direct_optab mem_no_result;
6129 optab fetch_before;
6130 optab fetch_after;
6131 direct_optab no_result;
6132 enum rtx_code reverse_code;
6133 };
6134
6135
6136 /* Fill in structure pointed to by OP with the various optab entries for an
6137 operation of type CODE. */
6138
6139 static void
6140 get_atomic_op_for_code (struct atomic_op_functions *op, enum rtx_code code)
6141 {
6142 gcc_assert (op!= NULL);
6143
6144 /* If SWITCHABLE_TARGET is defined, then subtargets can be switched
6145 in the source code during compilation, and the optab entries are not
6146 computable until runtime. Fill in the values at runtime. */
6147 switch (code)
6148 {
6149 case PLUS:
6150 op->mem_fetch_before = atomic_fetch_add_optab;
6151 op->mem_fetch_after = atomic_add_fetch_optab;
6152 op->mem_no_result = atomic_add_optab;
6153 op->fetch_before = sync_old_add_optab;
6154 op->fetch_after = sync_new_add_optab;
6155 op->no_result = sync_add_optab;
6156 op->reverse_code = MINUS;
6157 break;
6158 case MINUS:
6159 op->mem_fetch_before = atomic_fetch_sub_optab;
6160 op->mem_fetch_after = atomic_sub_fetch_optab;
6161 op->mem_no_result = atomic_sub_optab;
6162 op->fetch_before = sync_old_sub_optab;
6163 op->fetch_after = sync_new_sub_optab;
6164 op->no_result = sync_sub_optab;
6165 op->reverse_code = PLUS;
6166 break;
6167 case XOR:
6168 op->mem_fetch_before = atomic_fetch_xor_optab;
6169 op->mem_fetch_after = atomic_xor_fetch_optab;
6170 op->mem_no_result = atomic_xor_optab;
6171 op->fetch_before = sync_old_xor_optab;
6172 op->fetch_after = sync_new_xor_optab;
6173 op->no_result = sync_xor_optab;
6174 op->reverse_code = XOR;
6175 break;
6176 case AND:
6177 op->mem_fetch_before = atomic_fetch_and_optab;
6178 op->mem_fetch_after = atomic_and_fetch_optab;
6179 op->mem_no_result = atomic_and_optab;
6180 op->fetch_before = sync_old_and_optab;
6181 op->fetch_after = sync_new_and_optab;
6182 op->no_result = sync_and_optab;
6183 op->reverse_code = UNKNOWN;
6184 break;
6185 case IOR:
6186 op->mem_fetch_before = atomic_fetch_or_optab;
6187 op->mem_fetch_after = atomic_or_fetch_optab;
6188 op->mem_no_result = atomic_or_optab;
6189 op->fetch_before = sync_old_ior_optab;
6190 op->fetch_after = sync_new_ior_optab;
6191 op->no_result = sync_ior_optab;
6192 op->reverse_code = UNKNOWN;
6193 break;
6194 case NOT:
6195 op->mem_fetch_before = atomic_fetch_nand_optab;
6196 op->mem_fetch_after = atomic_nand_fetch_optab;
6197 op->mem_no_result = atomic_nand_optab;
6198 op->fetch_before = sync_old_nand_optab;
6199 op->fetch_after = sync_new_nand_optab;
6200 op->no_result = sync_nand_optab;
6201 op->reverse_code = UNKNOWN;
6202 break;
6203 default:
6204 gcc_unreachable ();
6205 }
6206 }
6207
6208 /* See if there is a more optimal way to implement the operation "*MEM CODE VAL"
6209 using memory order MODEL. If AFTER is true the operation needs to return
6210 the value of *MEM after the operation, otherwise the previous value.
6211 TARGET is an optional place to place the result. The result is unused if
6212 it is const0_rtx.
6213 Return the result if there is a better sequence, otherwise NULL_RTX. */
6214
6215 static rtx
6216 maybe_optimize_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6217 enum memmodel model, bool after)
6218 {
6219 /* If the value is prefetched, or not used, it may be possible to replace
6220 the sequence with a native exchange operation. */
6221 if (!after || target == const0_rtx)
6222 {
6223 /* fetch_and (&x, 0, m) can be replaced with exchange (&x, 0, m). */
6224 if (code == AND && val == const0_rtx)
6225 {
6226 if (target == const0_rtx)
6227 target = gen_reg_rtx (GET_MODE (mem));
6228 return maybe_emit_atomic_exchange (target, mem, val, model);
6229 }
6230
6231 /* fetch_or (&x, -1, m) can be replaced with exchange (&x, -1, m). */
6232 if (code == IOR && val == constm1_rtx)
6233 {
6234 if (target == const0_rtx)
6235 target = gen_reg_rtx (GET_MODE (mem));
6236 return maybe_emit_atomic_exchange (target, mem, val, model);
6237 }
6238 }
6239
6240 return NULL_RTX;
6241 }
6242
6243 /* Try to emit an instruction for a specific operation varaition.
6244 OPTAB contains the OP functions.
6245 TARGET is an optional place to return the result. const0_rtx means unused.
6246 MEM is the memory location to operate on.
6247 VAL is the value to use in the operation.
6248 USE_MEMMODEL is TRUE if the variation with a memory model should be tried.
6249 MODEL is the memory model, if used.
6250 AFTER is true if the returned result is the value after the operation. */
6251
6252 static rtx
6253 maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
6254 rtx val, bool use_memmodel, enum memmodel model, bool after)
6255 {
6256 machine_mode mode = GET_MODE (mem);
6257 struct expand_operand ops[4];
6258 enum insn_code icode;
6259 int op_counter = 0;
6260 int num_ops;
6261
6262 /* Check to see if there is a result returned. */
6263 if (target == const0_rtx)
6264 {
6265 if (use_memmodel)
6266 {
6267 icode = direct_optab_handler (optab->mem_no_result, mode);
6268 create_integer_operand (&ops[2], model);
6269 num_ops = 3;
6270 }
6271 else
6272 {
6273 icode = direct_optab_handler (optab->no_result, mode);
6274 num_ops = 2;
6275 }
6276 }
6277 /* Otherwise, we need to generate a result. */
6278 else
6279 {
6280 if (use_memmodel)
6281 {
6282 icode = direct_optab_handler (after ? optab->mem_fetch_after
6283 : optab->mem_fetch_before, mode);
6284 create_integer_operand (&ops[3], model);
6285 num_ops = 4;
6286 }
6287 else
6288 {
6289 icode = optab_handler (after ? optab->fetch_after
6290 : optab->fetch_before, mode);
6291 num_ops = 3;
6292 }
6293 create_output_operand (&ops[op_counter++], target, mode);
6294 }
6295 if (icode == CODE_FOR_nothing)
6296 return NULL_RTX;
6297
6298 create_fixed_operand (&ops[op_counter++], mem);
6299 /* VAL may have been promoted to a wider mode. Shrink it if so. */
6300 create_convert_operand_to (&ops[op_counter++], val, mode, true);
6301
6302 if (maybe_expand_insn (icode, num_ops, ops))
6303 return (target == const0_rtx ? const0_rtx : ops[0].value);
6304
6305 return NULL_RTX;
6306 }
6307
6308
6309 /* This function expands an atomic fetch_OP or OP_fetch operation:
6310 TARGET is an option place to stick the return value. const0_rtx indicates
6311 the result is unused.
6312 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6313 CODE is the operation being performed (OP)
6314 MEMMODEL is the memory model variant to use.
6315 AFTER is true to return the result of the operation (OP_fetch).
6316 AFTER is false to return the value before the operation (fetch_OP).
6317
6318 This function will *only* generate instructions if there is a direct
6319 optab. No compare and swap loops or libcalls will be generated. */
6320
6321 static rtx
6322 expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
6323 enum rtx_code code, enum memmodel model,
6324 bool after)
6325 {
6326 machine_mode mode = GET_MODE (mem);
6327 struct atomic_op_functions optab;
6328 rtx result;
6329 bool unused_result = (target == const0_rtx);
6330
6331 get_atomic_op_for_code (&optab, code);
6332
6333 /* Check to see if there are any better instructions. */
6334 result = maybe_optimize_fetch_op (target, mem, val, code, model, after);
6335 if (result)
6336 return result;
6337
6338 /* Check for the case where the result isn't used and try those patterns. */
6339 if (unused_result)
6340 {
6341 /* Try the memory model variant first. */
6342 result = maybe_emit_op (&optab, target, mem, val, true, model, true);
6343 if (result)
6344 return result;
6345
6346 /* Next try the old style withuot a memory model. */
6347 result = maybe_emit_op (&optab, target, mem, val, false, model, true);
6348 if (result)
6349 return result;
6350
6351 /* There is no no-result pattern, so try patterns with a result. */
6352 target = NULL_RTX;
6353 }
6354
6355 /* Try the __atomic version. */
6356 result = maybe_emit_op (&optab, target, mem, val, true, model, after);
6357 if (result)
6358 return result;
6359
6360 /* Try the older __sync version. */
6361 result = maybe_emit_op (&optab, target, mem, val, false, model, after);
6362 if (result)
6363 return result;
6364
6365 /* If the fetch value can be calculated from the other variation of fetch,
6366 try that operation. */
6367 if (after || unused_result || optab.reverse_code != UNKNOWN)
6368 {
6369 /* Try the __atomic version, then the older __sync version. */
6370 result = maybe_emit_op (&optab, target, mem, val, true, model, !after);
6371 if (!result)
6372 result = maybe_emit_op (&optab, target, mem, val, false, model, !after);
6373
6374 if (result)
6375 {
6376 /* If the result isn't used, no need to do compensation code. */
6377 if (unused_result)
6378 return result;
6379
6380 /* Issue compensation code. Fetch_after == fetch_before OP val.
6381 Fetch_before == after REVERSE_OP val. */
6382 if (!after)
6383 code = optab.reverse_code;
6384 if (code == NOT)
6385 {
6386 result = expand_simple_binop (mode, AND, result, val, NULL_RTX,
6387 true, OPTAB_LIB_WIDEN);
6388 result = expand_simple_unop (mode, NOT, result, target, true);
6389 }
6390 else
6391 result = expand_simple_binop (mode, code, result, val, target,
6392 true, OPTAB_LIB_WIDEN);
6393 return result;
6394 }
6395 }
6396
6397 /* No direct opcode can be generated. */
6398 return NULL_RTX;
6399 }
6400
6401
6402
6403 /* This function expands an atomic fetch_OP or OP_fetch operation:
6404 TARGET is an option place to stick the return value. const0_rtx indicates
6405 the result is unused.
6406 atomically fetch MEM, perform the operation with VAL and return it to MEM.
6407 CODE is the operation being performed (OP)
6408 MEMMODEL is the memory model variant to use.
6409 AFTER is true to return the result of the operation (OP_fetch).
6410 AFTER is false to return the value before the operation (fetch_OP). */
6411 rtx
6412 expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
6413 enum memmodel model, bool after)
6414 {
6415 machine_mode mode = GET_MODE (mem);
6416 rtx result;
6417 bool unused_result = (target == const0_rtx);
6418
6419 result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
6420 after);
6421
6422 if (result)
6423 return result;
6424
6425 /* Add/sub can be implemented by doing the reverse operation with -(val). */
6426 if (code == PLUS || code == MINUS)
6427 {
6428 rtx tmp;
6429 enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
6430
6431 start_sequence ();
6432 tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
6433 result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
6434 model, after);
6435 if (result)
6436 {
6437 /* PLUS worked so emit the insns and return. */
6438 tmp = get_insns ();
6439 end_sequence ();
6440 emit_insn (tmp);
6441 return result;
6442 }
6443
6444 /* PLUS did not work, so throw away the negation code and continue. */
6445 end_sequence ();
6446 }
6447
6448 /* Try the __sync libcalls only if we can't do compare-and-swap inline. */
6449 if (!can_compare_and_swap_p (mode, false))
6450 {
6451 rtx libfunc;
6452 bool fixup = false;
6453 enum rtx_code orig_code = code;
6454 struct atomic_op_functions optab;
6455
6456 get_atomic_op_for_code (&optab, code);
6457 libfunc = optab_libfunc (after ? optab.fetch_after
6458 : optab.fetch_before, mode);
6459 if (libfunc == NULL
6460 && (after || unused_result || optab.reverse_code != UNKNOWN))
6461 {
6462 fixup = true;
6463 if (!after)
6464 code = optab.reverse_code;
6465 libfunc = optab_libfunc (after ? optab.fetch_before
6466 : optab.fetch_after, mode);
6467 }
6468 if (libfunc != NULL)
6469 {
6470 rtx addr = convert_memory_address (ptr_mode, XEXP (mem, 0));
6471 result = emit_library_call_value (libfunc, NULL, LCT_NORMAL, mode,
6472 2, addr, ptr_mode, val, mode);
6473
6474 if (!unused_result && fixup)
6475 result = expand_simple_binop (mode, code, result, val, target,
6476 true, OPTAB_LIB_WIDEN);
6477 return result;
6478 }
6479
6480 /* We need the original code for any further attempts. */
6481 code = orig_code;
6482 }
6483
6484 /* If nothing else has succeeded, default to a compare and swap loop. */
6485 if (can_compare_and_swap_p (mode, true))
6486 {
6487 rtx_insn *insn;
6488 rtx t0 = gen_reg_rtx (mode), t1;
6489
6490 start_sequence ();
6491
6492 /* If the result is used, get a register for it. */
6493 if (!unused_result)
6494 {
6495 if (!target || !register_operand (target, mode))
6496 target = gen_reg_rtx (mode);
6497 /* If fetch_before, copy the value now. */
6498 if (!after)
6499 emit_move_insn (target, t0);
6500 }
6501 else
6502 target = const0_rtx;
6503
6504 t1 = t0;
6505 if (code == NOT)
6506 {
6507 t1 = expand_simple_binop (mode, AND, t1, val, NULL_RTX,
6508 true, OPTAB_LIB_WIDEN);
6509 t1 = expand_simple_unop (mode, code, t1, NULL_RTX, true);
6510 }
6511 else
6512 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX, true,
6513 OPTAB_LIB_WIDEN);
6514
6515 /* For after, copy the value now. */
6516 if (!unused_result && after)
6517 emit_move_insn (target, t1);
6518 insn = get_insns ();
6519 end_sequence ();
6520
6521 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6522 return target;
6523 }
6524
6525 return NULL_RTX;
6526 }
6527 \f
6528 /* Return true if OPERAND is suitable for operand number OPNO of
6529 instruction ICODE. */
6530
6531 bool
6532 insn_operand_matches (enum insn_code icode, unsigned int opno, rtx operand)
6533 {
6534 return (!insn_data[(int) icode].operand[opno].predicate
6535 || (insn_data[(int) icode].operand[opno].predicate
6536 (operand, insn_data[(int) icode].operand[opno].mode)));
6537 }
6538 \f
6539 /* TARGET is a target of a multiword operation that we are going to
6540 implement as a series of word-mode operations. Return true if
6541 TARGET is suitable for this purpose. */
6542
6543 bool
6544 valid_multiword_target_p (rtx target)
6545 {
6546 machine_mode mode;
6547 int i;
6548
6549 mode = GET_MODE (target);
6550 for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
6551 if (!validate_subreg (word_mode, mode, target, i))
6552 return false;
6553 return true;
6554 }
6555
6556 /* Like maybe_legitimize_operand, but do not change the code of the
6557 current rtx value. */
6558
6559 static bool
6560 maybe_legitimize_operand_same_code (enum insn_code icode, unsigned int opno,
6561 struct expand_operand *op)
6562 {
6563 /* See if the operand matches in its current form. */
6564 if (insn_operand_matches (icode, opno, op->value))
6565 return true;
6566
6567 /* If the operand is a memory whose address has no side effects,
6568 try forcing the address into a non-virtual pseudo register.
6569 The check for side effects is important because copy_to_mode_reg
6570 cannot handle things like auto-modified addresses. */
6571 if (insn_data[(int) icode].operand[opno].allows_mem && MEM_P (op->value))
6572 {
6573 rtx addr, mem;
6574
6575 mem = op->value;
6576 addr = XEXP (mem, 0);
6577 if (!(REG_P (addr) && REGNO (addr) > LAST_VIRTUAL_REGISTER)
6578 && !side_effects_p (addr))
6579 {
6580 rtx_insn *last;
6581 machine_mode mode;
6582
6583 last = get_last_insn ();
6584 mode = get_address_mode (mem);
6585 mem = replace_equiv_address (mem, copy_to_mode_reg (mode, addr));
6586 if (insn_operand_matches (icode, opno, mem))
6587 {
6588 op->value = mem;
6589 return true;
6590 }
6591 delete_insns_since (last);
6592 }
6593 }
6594
6595 return false;
6596 }
6597
6598 /* Try to make OP match operand OPNO of instruction ICODE. Return true
6599 on success, storing the new operand value back in OP. */
6600
6601 static bool
6602 maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
6603 struct expand_operand *op)
6604 {
6605 machine_mode mode, imode;
6606 bool old_volatile_ok, result;
6607
6608 mode = op->mode;
6609 switch (op->type)
6610 {
6611 case EXPAND_FIXED:
6612 old_volatile_ok = volatile_ok;
6613 volatile_ok = true;
6614 result = maybe_legitimize_operand_same_code (icode, opno, op);
6615 volatile_ok = old_volatile_ok;
6616 return result;
6617
6618 case EXPAND_OUTPUT:
6619 gcc_assert (mode != VOIDmode);
6620 if (op->value
6621 && op->value != const0_rtx
6622 && GET_MODE (op->value) == mode
6623 && maybe_legitimize_operand_same_code (icode, opno, op))
6624 return true;
6625
6626 op->value = gen_reg_rtx (mode);
6627 break;
6628
6629 case EXPAND_INPUT:
6630 input:
6631 gcc_assert (mode != VOIDmode);
6632 gcc_assert (GET_MODE (op->value) == VOIDmode
6633 || GET_MODE (op->value) == mode);
6634 if (maybe_legitimize_operand_same_code (icode, opno, op))
6635 return true;
6636
6637 op->value = copy_to_mode_reg (mode, op->value);
6638 break;
6639
6640 case EXPAND_CONVERT_TO:
6641 gcc_assert (mode != VOIDmode);
6642 op->value = convert_to_mode (mode, op->value, op->unsigned_p);
6643 goto input;
6644
6645 case EXPAND_CONVERT_FROM:
6646 if (GET_MODE (op->value) != VOIDmode)
6647 mode = GET_MODE (op->value);
6648 else
6649 /* The caller must tell us what mode this value has. */
6650 gcc_assert (mode != VOIDmode);
6651
6652 imode = insn_data[(int) icode].operand[opno].mode;
6653 if (imode != VOIDmode && imode != mode)
6654 {
6655 op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
6656 mode = imode;
6657 }
6658 goto input;
6659
6660 case EXPAND_ADDRESS:
6661 gcc_assert (mode != VOIDmode);
6662 op->value = convert_memory_address (mode, op->value);
6663 goto input;
6664
6665 case EXPAND_INTEGER:
6666 mode = insn_data[(int) icode].operand[opno].mode;
6667 if (mode != VOIDmode && const_int_operand (op->value, mode))
6668 goto input;
6669 break;
6670 }
6671 return insn_operand_matches (icode, opno, op->value);
6672 }
6673
6674 /* Make OP describe an input operand that should have the same value
6675 as VALUE, after any mode conversion that the target might request.
6676 TYPE is the type of VALUE. */
6677
6678 void
6679 create_convert_operand_from_type (struct expand_operand *op,
6680 rtx value, tree type)
6681 {
6682 create_convert_operand_from (op, value, TYPE_MODE (type),
6683 TYPE_UNSIGNED (type));
6684 }
6685
6686 /* Try to make operands [OPS, OPS + NOPS) match operands [OPNO, OPNO + NOPS)
6687 of instruction ICODE. Return true on success, leaving the new operand
6688 values in the OPS themselves. Emit no code on failure. */
6689
6690 bool
6691 maybe_legitimize_operands (enum insn_code icode, unsigned int opno,
6692 unsigned int nops, struct expand_operand *ops)
6693 {
6694 rtx_insn *last;
6695 unsigned int i;
6696
6697 last = get_last_insn ();
6698 for (i = 0; i < nops; i++)
6699 if (!maybe_legitimize_operand (icode, opno + i, &ops[i]))
6700 {
6701 delete_insns_since (last);
6702 return false;
6703 }
6704 return true;
6705 }
6706
6707 /* Try to generate instruction ICODE, using operands [OPS, OPS + NOPS)
6708 as its operands. Return the instruction pattern on success,
6709 and emit any necessary set-up code. Return null and emit no
6710 code on failure. */
6711
6712 rtx_insn *
6713 maybe_gen_insn (enum insn_code icode, unsigned int nops,
6714 struct expand_operand *ops)
6715 {
6716 gcc_assert (nops == (unsigned int) insn_data[(int) icode].n_generator_args);
6717 if (!maybe_legitimize_operands (icode, 0, nops, ops))
6718 return NULL;
6719
6720 switch (nops)
6721 {
6722 case 1:
6723 return GEN_FCN (icode) (ops[0].value);
6724 case 2:
6725 return GEN_FCN (icode) (ops[0].value, ops[1].value);
6726 case 3:
6727 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value);
6728 case 4:
6729 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6730 ops[3].value);
6731 case 5:
6732 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6733 ops[3].value, ops[4].value);
6734 case 6:
6735 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6736 ops[3].value, ops[4].value, ops[5].value);
6737 case 7:
6738 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6739 ops[3].value, ops[4].value, ops[5].value,
6740 ops[6].value);
6741 case 8:
6742 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6743 ops[3].value, ops[4].value, ops[5].value,
6744 ops[6].value, ops[7].value);
6745 case 9:
6746 return GEN_FCN (icode) (ops[0].value, ops[1].value, ops[2].value,
6747 ops[3].value, ops[4].value, ops[5].value,
6748 ops[6].value, ops[7].value, ops[8].value);
6749 }
6750 gcc_unreachable ();
6751 }
6752
6753 /* Try to emit instruction ICODE, using operands [OPS, OPS + NOPS)
6754 as its operands. Return true on success and emit no code on failure. */
6755
6756 bool
6757 maybe_expand_insn (enum insn_code icode, unsigned int nops,
6758 struct expand_operand *ops)
6759 {
6760 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6761 if (pat)
6762 {
6763 emit_insn (pat);
6764 return true;
6765 }
6766 return false;
6767 }
6768
6769 /* Like maybe_expand_insn, but for jumps. */
6770
6771 bool
6772 maybe_expand_jump_insn (enum insn_code icode, unsigned int nops,
6773 struct expand_operand *ops)
6774 {
6775 rtx_insn *pat = maybe_gen_insn (icode, nops, ops);
6776 if (pat)
6777 {
6778 emit_jump_insn (pat);
6779 return true;
6780 }
6781 return false;
6782 }
6783
6784 /* Emit instruction ICODE, using operands [OPS, OPS + NOPS)
6785 as its operands. */
6786
6787 void
6788 expand_insn (enum insn_code icode, unsigned int nops,
6789 struct expand_operand *ops)
6790 {
6791 if (!maybe_expand_insn (icode, nops, ops))
6792 gcc_unreachable ();
6793 }
6794
6795 /* Like expand_insn, but for jumps. */
6796
6797 void
6798 expand_jump_insn (enum insn_code icode, unsigned int nops,
6799 struct expand_operand *ops)
6800 {
6801 if (!maybe_expand_jump_insn (icode, nops, ops))
6802 gcc_unreachable ();
6803 }