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