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