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