PR c++/14032
[official-gcc.git] / gcc / optabs.c
blobf28393dec6df9c2b7ff29f4ee17c57d5668354e6
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "toplev.h"
29 /* Include insn-config.h before expr.h so that HAVE_conditional_move
30 is properly defined. */
31 #include "insn-config.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "tm_p.h"
35 #include "flags.h"
36 #include "function.h"
37 #include "except.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "libfuncs.h"
41 #include "recog.h"
42 #include "reload.h"
43 #include "ggc.h"
44 #include "real.h"
45 #include "basic-block.h"
46 #include "target.h"
48 /* Each optab contains info on how this target machine
49 can perform a particular operation
50 for all sizes and kinds of operands.
52 The operation to be performed is often specified
53 by passing one of these optabs as an argument.
55 See expr.h for documentation of these optabs. */
57 optab optab_table[OTI_MAX];
59 rtx libfunc_table[LTI_MAX];
61 /* Tables of patterns for converting one mode to another. */
62 convert_optab convert_optab_table[COI_MAX];
64 /* Contains the optab used for each rtx code. */
65 optab code_to_optab[NUM_RTX_CODE + 1];
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68 gives the gen_function to make a branch to test that condition. */
70 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73 gives the insn code to make a store-condition insn
74 to test that condition. */
76 enum insn_code setcc_gen_code[NUM_RTX_CODE];
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
81 setcc_gen_code to cut down on the number of named patterns. Consider a day
82 when a lot more rtx codes are conditional (eg: for the ARM). */
84 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
85 #endif
87 /* Indexed by the machine mode, gives the insn code for vector conditional
88 operation. */
90 enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
91 enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
93 /* The insn generating function can not take an rtx_code argument.
94 TRAP_RTX is used as an rtx argument. Its code is replaced with
95 the code to be used in the trap insn and all other fields are ignored. */
96 static GTY(()) rtx trap_rtx;
98 static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
99 enum machine_mode *, int *);
100 static rtx expand_unop_direct (enum machine_mode, optab, rtx, rtx, int);
102 /* Current libcall id. It doesn't matter what these are, as long
103 as they are unique to each libcall that is emitted. */
104 static HOST_WIDE_INT libcall_id = 0;
106 #ifndef HAVE_conditional_trap
107 #define HAVE_conditional_trap 0
108 #define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
109 #endif
111 /* Prefixes for the current version of decimal floating point (BID vs. DPD) */
112 #if ENABLE_DECIMAL_BID_FORMAT
113 #define DECIMAL_PREFIX "bid_"
114 #else
115 #define DECIMAL_PREFIX "dpd_"
116 #endif
119 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
120 the result of operation CODE applied to OP0 (and OP1 if it is a binary
121 operation).
123 If the last insn does not set TARGET, don't do anything, but return 1.
125 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
126 don't add the REG_EQUAL note but return 0. Our caller can then try
127 again, ensuring that TARGET is not one of the operands. */
129 static int
130 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
132 rtx last_insn, insn, set;
133 rtx note;
135 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
137 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
138 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
139 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
140 && GET_RTX_CLASS (code) != RTX_COMPARE
141 && GET_RTX_CLASS (code) != RTX_UNARY)
142 return 1;
144 if (GET_CODE (target) == ZERO_EXTRACT)
145 return 1;
147 for (last_insn = insns;
148 NEXT_INSN (last_insn) != NULL_RTX;
149 last_insn = NEXT_INSN (last_insn))
152 set = single_set (last_insn);
153 if (set == NULL_RTX)
154 return 1;
156 if (! rtx_equal_p (SET_DEST (set), target)
157 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
158 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
159 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
160 return 1;
162 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
163 besides the last insn. */
164 if (reg_overlap_mentioned_p (target, op0)
165 || (op1 && reg_overlap_mentioned_p (target, op1)))
167 insn = PREV_INSN (last_insn);
168 while (insn != NULL_RTX)
170 if (reg_set_p (target, insn))
171 return 0;
173 insn = PREV_INSN (insn);
177 if (GET_RTX_CLASS (code) == RTX_UNARY)
178 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
179 else
180 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
182 set_unique_reg_note (last_insn, REG_EQUAL, note);
184 return 1;
187 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
188 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
189 not actually do a sign-extend or zero-extend, but can leave the
190 higher-order bits of the result rtx undefined, for example, in the case
191 of logical operations, but not right shifts. */
193 static rtx
194 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
195 int unsignedp, int no_extend)
197 rtx result;
199 /* If we don't have to extend and this is a constant, return it. */
200 if (no_extend && GET_MODE (op) == VOIDmode)
201 return op;
203 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
204 extend since it will be more efficient to do so unless the signedness of
205 a promoted object differs from our extension. */
206 if (! no_extend
207 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
208 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
209 return convert_modes (mode, oldmode, op, unsignedp);
211 /* If MODE is no wider than a single word, we return a paradoxical
212 SUBREG. */
213 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
214 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
216 /* Otherwise, get an object of MODE, clobber it, and set the low-order
217 part to OP. */
219 result = gen_reg_rtx (mode);
220 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
221 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
222 return result;
225 /* Return the optab used for computing the operation given by
226 the tree code, CODE. This function is not always usable (for
227 example, it cannot give complete results for multiplication
228 or division) but probably ought to be relied on more widely
229 throughout the expander. */
230 optab
231 optab_for_tree_code (enum tree_code code, const_tree type)
233 bool trapv;
234 switch (code)
236 case BIT_AND_EXPR:
237 return and_optab;
239 case BIT_IOR_EXPR:
240 return ior_optab;
242 case BIT_NOT_EXPR:
243 return one_cmpl_optab;
245 case BIT_XOR_EXPR:
246 return xor_optab;
248 case TRUNC_MOD_EXPR:
249 case CEIL_MOD_EXPR:
250 case FLOOR_MOD_EXPR:
251 case ROUND_MOD_EXPR:
252 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
254 case RDIV_EXPR:
255 case TRUNC_DIV_EXPR:
256 case CEIL_DIV_EXPR:
257 case FLOOR_DIV_EXPR:
258 case ROUND_DIV_EXPR:
259 case EXACT_DIV_EXPR:
260 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
262 case LSHIFT_EXPR:
263 return ashl_optab;
265 case RSHIFT_EXPR:
266 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
268 case LROTATE_EXPR:
269 return rotl_optab;
271 case RROTATE_EXPR:
272 return rotr_optab;
274 case MAX_EXPR:
275 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
277 case MIN_EXPR:
278 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
280 case REALIGN_LOAD_EXPR:
281 return vec_realign_load_optab;
283 case WIDEN_SUM_EXPR:
284 return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
286 case DOT_PROD_EXPR:
287 return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
289 case REDUC_MAX_EXPR:
290 return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
292 case REDUC_MIN_EXPR:
293 return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
295 case REDUC_PLUS_EXPR:
296 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
298 case VEC_LSHIFT_EXPR:
299 return vec_shl_optab;
301 case VEC_RSHIFT_EXPR:
302 return vec_shr_optab;
304 case VEC_WIDEN_MULT_HI_EXPR:
305 return TYPE_UNSIGNED (type) ?
306 vec_widen_umult_hi_optab : vec_widen_smult_hi_optab;
308 case VEC_WIDEN_MULT_LO_EXPR:
309 return TYPE_UNSIGNED (type) ?
310 vec_widen_umult_lo_optab : vec_widen_smult_lo_optab;
312 case VEC_UNPACK_HI_EXPR:
313 return TYPE_UNSIGNED (type) ?
314 vec_unpacku_hi_optab : vec_unpacks_hi_optab;
316 case VEC_UNPACK_LO_EXPR:
317 return TYPE_UNSIGNED (type) ?
318 vec_unpacku_lo_optab : vec_unpacks_lo_optab;
320 case VEC_UNPACK_FLOAT_HI_EXPR:
321 /* The signedness is determined from input operand. */
322 return TYPE_UNSIGNED (type) ?
323 vec_unpacku_float_hi_optab : vec_unpacks_float_hi_optab;
325 case VEC_UNPACK_FLOAT_LO_EXPR:
326 /* The signedness is determined from input operand. */
327 return TYPE_UNSIGNED (type) ?
328 vec_unpacku_float_lo_optab : vec_unpacks_float_lo_optab;
330 case VEC_PACK_TRUNC_EXPR:
331 return vec_pack_trunc_optab;
333 case VEC_PACK_SAT_EXPR:
334 return TYPE_UNSIGNED (type) ? vec_pack_usat_optab : vec_pack_ssat_optab;
336 case VEC_PACK_FIX_TRUNC_EXPR:
337 /* The signedness is determined from output operand. */
338 return TYPE_UNSIGNED (type) ?
339 vec_pack_ufix_trunc_optab : vec_pack_sfix_trunc_optab;
341 default:
342 break;
345 trapv = INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type);
346 switch (code)
348 case POINTER_PLUS_EXPR:
349 case PLUS_EXPR:
350 return trapv ? addv_optab : add_optab;
352 case MINUS_EXPR:
353 return trapv ? subv_optab : sub_optab;
355 case MULT_EXPR:
356 return trapv ? smulv_optab : smul_optab;
358 case NEGATE_EXPR:
359 return trapv ? negv_optab : neg_optab;
361 case ABS_EXPR:
362 return trapv ? absv_optab : abs_optab;
364 case VEC_EXTRACT_EVEN_EXPR:
365 return vec_extract_even_optab;
367 case VEC_EXTRACT_ODD_EXPR:
368 return vec_extract_odd_optab;
370 case VEC_INTERLEAVE_HIGH_EXPR:
371 return vec_interleave_high_optab;
373 case VEC_INTERLEAVE_LOW_EXPR:
374 return vec_interleave_low_optab;
376 default:
377 return NULL;
382 /* Expand vector widening operations.
384 There are two different classes of operations handled here:
385 1) Operations whose result is wider than all the arguments to the operation.
386 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
387 In this case OP0 and optionally OP1 would be initialized,
388 but WIDE_OP wouldn't (not relevant for this case).
389 2) Operations whose result is of the same size as the last argument to the
390 operation, but wider than all the other arguments to the operation.
391 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
392 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
394 E.g, when called to expand the following operations, this is how
395 the arguments will be initialized:
396 nops OP0 OP1 WIDE_OP
397 widening-sum 2 oprnd0 - oprnd1
398 widening-dot-product 3 oprnd0 oprnd1 oprnd2
399 widening-mult 2 oprnd0 oprnd1 -
400 type-promotion (vec-unpack) 1 oprnd0 - - */
403 expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target,
404 int unsignedp)
406 tree oprnd0, oprnd1, oprnd2;
407 enum machine_mode wmode = 0, tmode0, tmode1 = 0;
408 optab widen_pattern_optab;
409 int icode;
410 enum machine_mode xmode0, xmode1 = 0, wxmode = 0;
411 rtx temp;
412 rtx pat;
413 rtx xop0, xop1, wxop;
414 int nops = TREE_OPERAND_LENGTH (exp);
416 oprnd0 = TREE_OPERAND (exp, 0);
417 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
418 widen_pattern_optab =
419 optab_for_tree_code (TREE_CODE (exp), TREE_TYPE (oprnd0));
420 icode = (int) optab_handler (widen_pattern_optab, tmode0)->insn_code;
421 gcc_assert (icode != CODE_FOR_nothing);
422 xmode0 = insn_data[icode].operand[1].mode;
424 if (nops >= 2)
426 oprnd1 = TREE_OPERAND (exp, 1);
427 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
428 xmode1 = insn_data[icode].operand[2].mode;
431 /* The last operand is of a wider mode than the rest of the operands. */
432 if (nops == 2)
434 wmode = tmode1;
435 wxmode = xmode1;
437 else if (nops == 3)
439 gcc_assert (tmode1 == tmode0);
440 gcc_assert (op1);
441 oprnd2 = TREE_OPERAND (exp, 2);
442 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
443 wxmode = insn_data[icode].operand[3].mode;
446 if (!wide_op)
447 wmode = wxmode = insn_data[icode].operand[0].mode;
449 if (!target
450 || ! (*insn_data[icode].operand[0].predicate) (target, wmode))
451 temp = gen_reg_rtx (wmode);
452 else
453 temp = target;
455 xop0 = op0;
456 xop1 = op1;
457 wxop = wide_op;
459 /* In case the insn wants input operands in modes different from
460 those of the actual operands, convert the operands. It would
461 seem that we don't need to convert CONST_INTs, but we do, so
462 that they're properly zero-extended, sign-extended or truncated
463 for their mode. */
465 if (GET_MODE (op0) != xmode0 && xmode0 != VOIDmode)
466 xop0 = convert_modes (xmode0,
467 GET_MODE (op0) != VOIDmode
468 ? GET_MODE (op0)
469 : tmode0,
470 xop0, unsignedp);
472 if (op1)
473 if (GET_MODE (op1) != xmode1 && xmode1 != VOIDmode)
474 xop1 = convert_modes (xmode1,
475 GET_MODE (op1) != VOIDmode
476 ? GET_MODE (op1)
477 : tmode1,
478 xop1, unsignedp);
480 if (wide_op)
481 if (GET_MODE (wide_op) != wxmode && wxmode != VOIDmode)
482 wxop = convert_modes (wxmode,
483 GET_MODE (wide_op) != VOIDmode
484 ? GET_MODE (wide_op)
485 : wmode,
486 wxop, unsignedp);
488 /* Now, if insn's predicates don't allow our operands, put them into
489 pseudo regs. */
491 if (! (*insn_data[icode].operand[1].predicate) (xop0, xmode0)
492 && xmode0 != VOIDmode)
493 xop0 = copy_to_mode_reg (xmode0, xop0);
495 if (op1)
497 if (! (*insn_data[icode].operand[2].predicate) (xop1, xmode1)
498 && xmode1 != VOIDmode)
499 xop1 = copy_to_mode_reg (xmode1, xop1);
501 if (wide_op)
503 if (! (*insn_data[icode].operand[3].predicate) (wxop, wxmode)
504 && wxmode != VOIDmode)
505 wxop = copy_to_mode_reg (wxmode, wxop);
507 pat = GEN_FCN (icode) (temp, xop0, xop1, wxop);
509 else
510 pat = GEN_FCN (icode) (temp, xop0, xop1);
512 else
514 if (wide_op)
516 if (! (*insn_data[icode].operand[2].predicate) (wxop, wxmode)
517 && wxmode != VOIDmode)
518 wxop = copy_to_mode_reg (wxmode, wxop);
520 pat = GEN_FCN (icode) (temp, xop0, wxop);
522 else
523 pat = GEN_FCN (icode) (temp, xop0);
526 emit_insn (pat);
527 return temp;
530 /* Generate code to perform an operation specified by TERNARY_OPTAB
531 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
533 UNSIGNEDP is for the case where we have to widen the operands
534 to perform the operation. It says to use zero-extension.
536 If TARGET is nonzero, the value
537 is generated there, if it is convenient to do so.
538 In all cases an rtx is returned for the locus of the value;
539 this may or may not be TARGET. */
542 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
543 rtx op1, rtx op2, rtx target, int unsignedp)
545 int icode = (int) optab_handler (ternary_optab, mode)->insn_code;
546 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
547 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
548 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
549 rtx temp;
550 rtx pat;
551 rtx xop0 = op0, xop1 = op1, xop2 = op2;
553 gcc_assert (optab_handler (ternary_optab, mode)->insn_code
554 != CODE_FOR_nothing);
556 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
557 temp = gen_reg_rtx (mode);
558 else
559 temp = target;
561 /* In case the insn wants input operands in modes different from
562 those of the actual operands, convert the operands. It would
563 seem that we don't need to convert CONST_INTs, but we do, so
564 that they're properly zero-extended, sign-extended or truncated
565 for their mode. */
567 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
568 xop0 = convert_modes (mode0,
569 GET_MODE (op0) != VOIDmode
570 ? GET_MODE (op0)
571 : mode,
572 xop0, unsignedp);
574 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
575 xop1 = convert_modes (mode1,
576 GET_MODE (op1) != VOIDmode
577 ? GET_MODE (op1)
578 : mode,
579 xop1, unsignedp);
581 if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
582 xop2 = convert_modes (mode2,
583 GET_MODE (op2) != VOIDmode
584 ? GET_MODE (op2)
585 : mode,
586 xop2, unsignedp);
588 /* Now, if insn's predicates don't allow our operands, put them into
589 pseudo regs. */
591 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
592 && mode0 != VOIDmode)
593 xop0 = copy_to_mode_reg (mode0, xop0);
595 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
596 && mode1 != VOIDmode)
597 xop1 = copy_to_mode_reg (mode1, xop1);
599 if (!insn_data[icode].operand[3].predicate (xop2, mode2)
600 && mode2 != VOIDmode)
601 xop2 = copy_to_mode_reg (mode2, xop2);
603 pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
605 emit_insn (pat);
606 return temp;
610 /* Like expand_binop, but return a constant rtx if the result can be
611 calculated at compile time. The arguments and return value are
612 otherwise the same as for expand_binop. */
614 static rtx
615 simplify_expand_binop (enum machine_mode mode, optab binoptab,
616 rtx op0, rtx op1, rtx target, int unsignedp,
617 enum optab_methods methods)
619 if (CONSTANT_P (op0) && CONSTANT_P (op1))
621 rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
623 if (x)
624 return x;
627 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
630 /* Like simplify_expand_binop, but always put the result in TARGET.
631 Return true if the expansion succeeded. */
633 bool
634 force_expand_binop (enum machine_mode mode, optab binoptab,
635 rtx op0, rtx op1, rtx target, int unsignedp,
636 enum optab_methods methods)
638 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
639 target, unsignedp, methods);
640 if (x == 0)
641 return false;
642 if (x != target)
643 emit_move_insn (target, x);
644 return true;
647 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
650 expand_vec_shift_expr (tree vec_shift_expr, rtx target)
652 enum insn_code icode;
653 rtx rtx_op1, rtx_op2;
654 enum machine_mode mode1;
655 enum machine_mode mode2;
656 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr));
657 tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0);
658 tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1);
659 optab shift_optab;
660 rtx pat;
662 switch (TREE_CODE (vec_shift_expr))
664 case VEC_RSHIFT_EXPR:
665 shift_optab = vec_shr_optab;
666 break;
667 case VEC_LSHIFT_EXPR:
668 shift_optab = vec_shl_optab;
669 break;
670 default:
671 gcc_unreachable ();
674 icode = (int) optab_handler (shift_optab, mode)->insn_code;
675 gcc_assert (icode != CODE_FOR_nothing);
677 mode1 = insn_data[icode].operand[1].mode;
678 mode2 = insn_data[icode].operand[2].mode;
680 rtx_op1 = expand_normal (vec_oprnd);
681 if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
682 && mode1 != VOIDmode)
683 rtx_op1 = force_reg (mode1, rtx_op1);
685 rtx_op2 = expand_normal (shift_oprnd);
686 if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
687 && mode2 != VOIDmode)
688 rtx_op2 = force_reg (mode2, rtx_op2);
690 if (!target
691 || ! (*insn_data[icode].operand[0].predicate) (target, mode))
692 target = gen_reg_rtx (mode);
694 /* Emit instruction */
695 pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
696 gcc_assert (pat);
697 emit_insn (pat);
699 return target;
702 /* This subroutine of expand_doubleword_shift handles the cases in which
703 the effective shift value is >= BITS_PER_WORD. The arguments and return
704 value are the same as for the parent routine, except that SUPERWORD_OP1
705 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
706 INTO_TARGET may be null if the caller has decided to calculate it. */
708 static bool
709 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
710 rtx outof_target, rtx into_target,
711 int unsignedp, enum optab_methods methods)
713 if (into_target != 0)
714 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
715 into_target, unsignedp, methods))
716 return false;
718 if (outof_target != 0)
720 /* For a signed right shift, we must fill OUTOF_TARGET with copies
721 of the sign bit, otherwise we must fill it with zeros. */
722 if (binoptab != ashr_optab)
723 emit_move_insn (outof_target, CONST0_RTX (word_mode));
724 else
725 if (!force_expand_binop (word_mode, binoptab,
726 outof_input, GEN_INT (BITS_PER_WORD - 1),
727 outof_target, unsignedp, methods))
728 return false;
730 return true;
733 /* This subroutine of expand_doubleword_shift handles the cases in which
734 the effective shift value is < BITS_PER_WORD. The arguments and return
735 value are the same as for the parent routine. */
737 static bool
738 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
739 rtx outof_input, rtx into_input, rtx op1,
740 rtx outof_target, rtx into_target,
741 int unsignedp, enum optab_methods methods,
742 unsigned HOST_WIDE_INT shift_mask)
744 optab reverse_unsigned_shift, unsigned_shift;
745 rtx tmp, carries;
747 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
748 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
750 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
751 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
752 the opposite direction to BINOPTAB. */
753 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
755 carries = outof_input;
756 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
757 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
758 0, true, methods);
760 else
762 /* We must avoid shifting by BITS_PER_WORD bits since that is either
763 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
764 has unknown behavior. Do a single shift first, then shift by the
765 remainder. It's OK to use ~OP1 as the remainder if shift counts
766 are truncated to the mode size. */
767 carries = expand_binop (word_mode, reverse_unsigned_shift,
768 outof_input, const1_rtx, 0, unsignedp, methods);
769 if (shift_mask == BITS_PER_WORD - 1)
771 tmp = immed_double_const (-1, -1, op1_mode);
772 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
773 0, true, methods);
775 else
777 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
778 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
779 0, true, methods);
782 if (tmp == 0 || carries == 0)
783 return false;
784 carries = expand_binop (word_mode, reverse_unsigned_shift,
785 carries, tmp, 0, unsignedp, methods);
786 if (carries == 0)
787 return false;
789 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
790 so the result can go directly into INTO_TARGET if convenient. */
791 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
792 into_target, unsignedp, methods);
793 if (tmp == 0)
794 return false;
796 /* Now OR in the bits carried over from OUTOF_INPUT. */
797 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
798 into_target, unsignedp, methods))
799 return false;
801 /* Use a standard word_mode shift for the out-of half. */
802 if (outof_target != 0)
803 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
804 outof_target, unsignedp, methods))
805 return false;
807 return true;
811 #ifdef HAVE_conditional_move
812 /* Try implementing expand_doubleword_shift using conditional moves.
813 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
814 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
815 are the shift counts to use in the former and latter case. All other
816 arguments are the same as the parent routine. */
818 static bool
819 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
820 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
821 rtx outof_input, rtx into_input,
822 rtx subword_op1, rtx superword_op1,
823 rtx outof_target, rtx into_target,
824 int unsignedp, enum optab_methods methods,
825 unsigned HOST_WIDE_INT shift_mask)
827 rtx outof_superword, into_superword;
829 /* Put the superword version of the output into OUTOF_SUPERWORD and
830 INTO_SUPERWORD. */
831 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
832 if (outof_target != 0 && subword_op1 == superword_op1)
834 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
835 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
836 into_superword = outof_target;
837 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
838 outof_superword, 0, unsignedp, methods))
839 return false;
841 else
843 into_superword = gen_reg_rtx (word_mode);
844 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
845 outof_superword, into_superword,
846 unsignedp, methods))
847 return false;
850 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
851 if (!expand_subword_shift (op1_mode, binoptab,
852 outof_input, into_input, subword_op1,
853 outof_target, into_target,
854 unsignedp, methods, shift_mask))
855 return false;
857 /* Select between them. Do the INTO half first because INTO_SUPERWORD
858 might be the current value of OUTOF_TARGET. */
859 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
860 into_target, into_superword, word_mode, false))
861 return false;
863 if (outof_target != 0)
864 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
865 outof_target, outof_superword,
866 word_mode, false))
867 return false;
869 return true;
871 #endif
873 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
874 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
875 input operand; the shift moves bits in the direction OUTOF_INPUT->
876 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
877 of the target. OP1 is the shift count and OP1_MODE is its mode.
878 If OP1 is constant, it will have been truncated as appropriate
879 and is known to be nonzero.
881 If SHIFT_MASK is zero, the result of word shifts is undefined when the
882 shift count is outside the range [0, BITS_PER_WORD). This routine must
883 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
885 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
886 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
887 fill with zeros or sign bits as appropriate.
889 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
890 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
891 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
892 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
893 are undefined.
895 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
896 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
897 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
898 function wants to calculate it itself.
900 Return true if the shift could be successfully synthesized. */
902 static bool
903 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
904 rtx outof_input, rtx into_input, rtx op1,
905 rtx outof_target, rtx into_target,
906 int unsignedp, enum optab_methods methods,
907 unsigned HOST_WIDE_INT shift_mask)
909 rtx superword_op1, tmp, cmp1, cmp2;
910 rtx subword_label, done_label;
911 enum rtx_code cmp_code;
913 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
914 fill the result with sign or zero bits as appropriate. If so, the value
915 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
916 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
917 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
919 This isn't worthwhile for constant shifts since the optimizers will
920 cope better with in-range shift counts. */
921 if (shift_mask >= BITS_PER_WORD
922 && outof_target != 0
923 && !CONSTANT_P (op1))
925 if (!expand_doubleword_shift (op1_mode, binoptab,
926 outof_input, into_input, op1,
927 0, into_target,
928 unsignedp, methods, shift_mask))
929 return false;
930 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
931 outof_target, unsignedp, methods))
932 return false;
933 return true;
936 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
937 is true when the effective shift value is less than BITS_PER_WORD.
938 Set SUPERWORD_OP1 to the shift count that should be used to shift
939 OUTOF_INPUT into INTO_TARGET when the condition is false. */
940 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
941 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
943 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
944 is a subword shift count. */
945 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
946 0, true, methods);
947 cmp2 = CONST0_RTX (op1_mode);
948 cmp_code = EQ;
949 superword_op1 = op1;
951 else
953 /* Set CMP1 to OP1 - BITS_PER_WORD. */
954 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
955 0, true, methods);
956 cmp2 = CONST0_RTX (op1_mode);
957 cmp_code = LT;
958 superword_op1 = cmp1;
960 if (cmp1 == 0)
961 return false;
963 /* If we can compute the condition at compile time, pick the
964 appropriate subroutine. */
965 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
966 if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
968 if (tmp == const0_rtx)
969 return expand_superword_shift (binoptab, outof_input, superword_op1,
970 outof_target, into_target,
971 unsignedp, methods);
972 else
973 return expand_subword_shift (op1_mode, binoptab,
974 outof_input, into_input, op1,
975 outof_target, into_target,
976 unsignedp, methods, shift_mask);
979 #ifdef HAVE_conditional_move
980 /* Try using conditional moves to generate straight-line code. */
982 rtx start = get_last_insn ();
983 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
984 cmp_code, cmp1, cmp2,
985 outof_input, into_input,
986 op1, superword_op1,
987 outof_target, into_target,
988 unsignedp, methods, shift_mask))
989 return true;
990 delete_insns_since (start);
992 #endif
994 /* As a last resort, use branches to select the correct alternative. */
995 subword_label = gen_label_rtx ();
996 done_label = gen_label_rtx ();
998 NO_DEFER_POP;
999 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
1000 0, 0, subword_label);
1001 OK_DEFER_POP;
1003 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
1004 outof_target, into_target,
1005 unsignedp, methods))
1006 return false;
1008 emit_jump_insn (gen_jump (done_label));
1009 emit_barrier ();
1010 emit_label (subword_label);
1012 if (!expand_subword_shift (op1_mode, binoptab,
1013 outof_input, into_input, op1,
1014 outof_target, into_target,
1015 unsignedp, methods, shift_mask))
1016 return false;
1018 emit_label (done_label);
1019 return true;
1022 /* Subroutine of expand_binop. Perform a double word multiplication of
1023 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
1024 as the target's word_mode. This function return NULL_RTX if anything
1025 goes wrong, in which case it may have already emitted instructions
1026 which need to be deleted.
1028 If we want to multiply two two-word values and have normal and widening
1029 multiplies of single-word values, we can do this with three smaller
1030 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1031 because we are not operating on one word at a time.
1033 The multiplication proceeds as follows:
1034 _______________________
1035 [__op0_high_|__op0_low__]
1036 _______________________
1037 * [__op1_high_|__op1_low__]
1038 _______________________________________________
1039 _______________________
1040 (1) [__op0_low__*__op1_low__]
1041 _______________________
1042 (2a) [__op0_low__*__op1_high_]
1043 _______________________
1044 (2b) [__op0_high_*__op1_low__]
1045 _______________________
1046 (3) [__op0_high_*__op1_high_]
1049 This gives a 4-word result. Since we are only interested in the
1050 lower 2 words, partial result (3) and the upper words of (2a) and
1051 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1052 calculated using non-widening multiplication.
1054 (1), however, needs to be calculated with an unsigned widening
1055 multiplication. If this operation is not directly supported we
1056 try using a signed widening multiplication and adjust the result.
1057 This adjustment works as follows:
1059 If both operands are positive then no adjustment is needed.
1061 If the operands have different signs, for example op0_low < 0 and
1062 op1_low >= 0, the instruction treats the most significant bit of
1063 op0_low as a sign bit instead of a bit with significance
1064 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1065 with 2**BITS_PER_WORD - op0_low, and two's complements the
1066 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1067 the result.
1069 Similarly, if both operands are negative, we need to add
1070 (op0_low + op1_low) * 2**BITS_PER_WORD.
1072 We use a trick to adjust quickly. We logically shift op0_low right
1073 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1074 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1075 logical shift exists, we do an arithmetic right shift and subtract
1076 the 0 or -1. */
1078 static rtx
1079 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1080 bool umulp, enum optab_methods methods)
1082 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1083 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1084 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1085 rtx product, adjust, product_high, temp;
1087 rtx op0_high = operand_subword_force (op0, high, mode);
1088 rtx op0_low = operand_subword_force (op0, low, mode);
1089 rtx op1_high = operand_subword_force (op1, high, mode);
1090 rtx op1_low = operand_subword_force (op1, low, mode);
1092 /* If we're using an unsigned multiply to directly compute the product
1093 of the low-order words of the operands and perform any required
1094 adjustments of the operands, we begin by trying two more multiplications
1095 and then computing the appropriate sum.
1097 We have checked above that the required addition is provided.
1098 Full-word addition will normally always succeed, especially if
1099 it is provided at all, so we don't worry about its failure. The
1100 multiplication may well fail, however, so we do handle that. */
1102 if (!umulp)
1104 /* ??? This could be done with emit_store_flag where available. */
1105 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1106 NULL_RTX, 1, methods);
1107 if (temp)
1108 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1109 NULL_RTX, 0, OPTAB_DIRECT);
1110 else
1112 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1113 NULL_RTX, 0, methods);
1114 if (!temp)
1115 return NULL_RTX;
1116 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1117 NULL_RTX, 0, OPTAB_DIRECT);
1120 if (!op0_high)
1121 return NULL_RTX;
1124 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1125 NULL_RTX, 0, OPTAB_DIRECT);
1126 if (!adjust)
1127 return NULL_RTX;
1129 /* OP0_HIGH should now be dead. */
1131 if (!umulp)
1133 /* ??? This could be done with emit_store_flag where available. */
1134 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1135 NULL_RTX, 1, methods);
1136 if (temp)
1137 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1138 NULL_RTX, 0, OPTAB_DIRECT);
1139 else
1141 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1142 NULL_RTX, 0, methods);
1143 if (!temp)
1144 return NULL_RTX;
1145 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1146 NULL_RTX, 0, OPTAB_DIRECT);
1149 if (!op1_high)
1150 return NULL_RTX;
1153 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1154 NULL_RTX, 0, OPTAB_DIRECT);
1155 if (!temp)
1156 return NULL_RTX;
1158 /* OP1_HIGH should now be dead. */
1160 adjust = expand_binop (word_mode, add_optab, adjust, temp,
1161 adjust, 0, OPTAB_DIRECT);
1163 if (target && !REG_P (target))
1164 target = NULL_RTX;
1166 if (umulp)
1167 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1168 target, 1, OPTAB_DIRECT);
1169 else
1170 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1171 target, 1, OPTAB_DIRECT);
1173 if (!product)
1174 return NULL_RTX;
1176 product_high = operand_subword (product, high, 1, mode);
1177 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1178 REG_P (product_high) ? product_high : adjust,
1179 0, OPTAB_DIRECT);
1180 emit_move_insn (product_high, adjust);
1181 return product;
1184 /* Wrapper around expand_binop which takes an rtx code to specify
1185 the operation to perform, not an optab pointer. All other
1186 arguments are the same. */
1188 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1189 rtx op1, rtx target, int unsignedp,
1190 enum optab_methods methods)
1192 optab binop = code_to_optab[(int) code];
1193 gcc_assert (binop);
1195 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1198 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1199 binop. Order them according to commutative_operand_precedence and, if
1200 possible, try to put TARGET or a pseudo first. */
1201 static bool
1202 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1204 int op0_prec = commutative_operand_precedence (op0);
1205 int op1_prec = commutative_operand_precedence (op1);
1207 if (op0_prec < op1_prec)
1208 return true;
1210 if (op0_prec > op1_prec)
1211 return false;
1213 /* With equal precedence, both orders are ok, but it is better if the
1214 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1215 if (target == 0 || REG_P (target))
1216 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1217 else
1218 return rtx_equal_p (op1, target);
1221 /* Return true if BINOPTAB implements a shift operation. */
1223 static bool
1224 shift_optab_p (optab binoptab)
1226 switch (binoptab->code)
1228 case ASHIFT:
1229 case ASHIFTRT:
1230 case LSHIFTRT:
1231 case ROTATE:
1232 case ROTATERT:
1233 return true;
1235 default:
1236 return false;
1240 /* Return true if BINOPTAB implements a commutative binary operation. */
1242 static bool
1243 commutative_optab_p (optab binoptab)
1245 return (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1246 || binoptab == smul_widen_optab
1247 || binoptab == umul_widen_optab
1248 || binoptab == smul_highpart_optab
1249 || binoptab == umul_highpart_optab);
1252 /* X is to be used in mode MODE as an operand to BINOPTAB. If we're
1253 optimizing, and if the operand is a constant that costs more than
1254 1 instruction, force the constant into a register and return that
1255 register. Return X otherwise. UNSIGNEDP says whether X is unsigned. */
1257 static rtx
1258 avoid_expensive_constant (enum machine_mode mode, optab binoptab,
1259 rtx x, bool unsignedp)
1261 if (optimize
1262 && CONSTANT_P (x)
1263 && rtx_cost (x, binoptab->code) > COSTS_N_INSNS (1))
1265 if (GET_CODE (x) == CONST_INT)
1267 HOST_WIDE_INT intval = trunc_int_for_mode (INTVAL (x), mode);
1268 if (intval != INTVAL (x))
1269 x = GEN_INT (intval);
1271 else
1272 x = convert_modes (mode, VOIDmode, x, unsignedp);
1273 x = force_reg (mode, x);
1275 return x;
1278 /* Helper function for expand_binop: handle the case where there
1279 is an insn that directly implements the indicated operation.
1280 Returns null if this is not possible. */
1281 static rtx
1282 expand_binop_directly (enum machine_mode mode, optab binoptab,
1283 rtx op0, rtx op1,
1284 rtx target, int unsignedp, enum optab_methods methods,
1285 rtx last)
1287 int icode = (int) optab_handler (binoptab, mode)->insn_code;
1288 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1289 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1290 enum machine_mode tmp_mode;
1291 bool commutative_p;
1292 rtx pat;
1293 rtx xop0 = op0, xop1 = op1;
1294 rtx temp;
1295 rtx swap;
1297 if (target)
1298 temp = target;
1299 else
1300 temp = gen_reg_rtx (mode);
1302 /* If it is a commutative operator and the modes would match
1303 if we would swap the operands, we can save the conversions. */
1304 commutative_p = commutative_optab_p (binoptab);
1305 if (commutative_p
1306 && GET_MODE (xop0) != mode0 && GET_MODE (xop1) != mode1
1307 && GET_MODE (xop0) == mode1 && GET_MODE (xop1) == mode1)
1309 swap = xop0;
1310 xop0 = xop1;
1311 xop1 = swap;
1314 /* If we are optimizing, force expensive constants into a register. */
1315 xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
1316 if (!shift_optab_p (binoptab))
1317 xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
1319 /* In case the insn wants input operands in modes different from
1320 those of the actual operands, convert the operands. It would
1321 seem that we don't need to convert CONST_INTs, but we do, so
1322 that they're properly zero-extended, sign-extended or truncated
1323 for their mode. */
1325 if (GET_MODE (xop0) != mode0 && mode0 != VOIDmode)
1326 xop0 = convert_modes (mode0,
1327 GET_MODE (xop0) != VOIDmode
1328 ? GET_MODE (xop0)
1329 : mode,
1330 xop0, unsignedp);
1332 if (GET_MODE (xop1) != mode1 && mode1 != VOIDmode)
1333 xop1 = convert_modes (mode1,
1334 GET_MODE (xop1) != VOIDmode
1335 ? GET_MODE (xop1)
1336 : mode,
1337 xop1, unsignedp);
1339 /* If operation is commutative,
1340 try to make the first operand a register.
1341 Even better, try to make it the same as the target.
1342 Also try to make the last operand a constant. */
1343 if (commutative_p
1344 && swap_commutative_operands_with_target (target, xop0, xop1))
1346 swap = xop1;
1347 xop1 = xop0;
1348 xop0 = swap;
1351 /* Now, if insn's predicates don't allow our operands, put them into
1352 pseudo regs. */
1354 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1355 && mode0 != VOIDmode)
1356 xop0 = copy_to_mode_reg (mode0, xop0);
1358 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1359 && mode1 != VOIDmode)
1360 xop1 = copy_to_mode_reg (mode1, xop1);
1362 if (binoptab == vec_pack_trunc_optab
1363 || binoptab == vec_pack_usat_optab
1364 || binoptab == vec_pack_ssat_optab
1365 || binoptab == vec_pack_ufix_trunc_optab
1366 || binoptab == vec_pack_sfix_trunc_optab)
1368 /* The mode of the result is different then the mode of the
1369 arguments. */
1370 tmp_mode = insn_data[icode].operand[0].mode;
1371 if (GET_MODE_NUNITS (tmp_mode) != 2 * GET_MODE_NUNITS (mode))
1372 return 0;
1374 else
1375 tmp_mode = mode;
1377 if (!insn_data[icode].operand[0].predicate (temp, tmp_mode))
1378 temp = gen_reg_rtx (tmp_mode);
1380 pat = GEN_FCN (icode) (temp, xop0, xop1);
1381 if (pat)
1383 /* If PAT is composed of more than one insn, try to add an appropriate
1384 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1385 operand, call expand_binop again, this time without a target. */
1386 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1387 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1389 delete_insns_since (last);
1390 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1391 unsignedp, methods);
1394 emit_insn (pat);
1395 return temp;
1398 delete_insns_since (last);
1399 return NULL_RTX;
1402 /* Generate code to perform an operation specified by BINOPTAB
1403 on operands OP0 and OP1, with result having machine-mode MODE.
1405 UNSIGNEDP is for the case where we have to widen the operands
1406 to perform the operation. It says to use zero-extension.
1408 If TARGET is nonzero, the value
1409 is generated there, if it is convenient to do so.
1410 In all cases an rtx is returned for the locus of the value;
1411 this may or may not be TARGET. */
1414 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1415 rtx target, int unsignedp, enum optab_methods methods)
1417 enum optab_methods next_methods
1418 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1419 ? OPTAB_WIDEN : methods);
1420 enum mode_class class;
1421 enum machine_mode wider_mode;
1422 rtx temp;
1423 rtx entry_last = get_last_insn ();
1424 rtx last;
1426 class = GET_MODE_CLASS (mode);
1428 /* If subtracting an integer constant, convert this into an addition of
1429 the negated constant. */
1431 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
1433 op1 = negate_rtx (mode, op1);
1434 binoptab = add_optab;
1437 /* Record where to delete back to if we backtrack. */
1438 last = get_last_insn ();
1440 /* If we can do it with a three-operand insn, do so. */
1442 if (methods != OPTAB_MUST_WIDEN
1443 && optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
1445 temp = expand_binop_directly (mode, binoptab, op0, op1, target,
1446 unsignedp, methods, last);
1447 if (temp)
1448 return temp;
1451 /* If we were trying to rotate, and that didn't work, try rotating
1452 the other direction before falling back to shifts and bitwise-or. */
1453 if (((binoptab == rotl_optab
1454 && optab_handler (rotr_optab, mode)->insn_code != CODE_FOR_nothing)
1455 || (binoptab == rotr_optab
1456 && optab_handler (rotl_optab, mode)->insn_code != CODE_FOR_nothing))
1457 && class == MODE_INT)
1459 optab otheroptab = (binoptab == rotl_optab ? rotr_optab : rotl_optab);
1460 rtx newop1;
1461 unsigned int bits = GET_MODE_BITSIZE (mode);
1463 if (GET_CODE (op1) == CONST_INT)
1464 newop1 = GEN_INT (bits - INTVAL (op1));
1465 else if (targetm.shift_truncation_mask (mode) == bits - 1)
1466 newop1 = negate_rtx (mode, op1);
1467 else
1468 newop1 = expand_binop (mode, sub_optab,
1469 GEN_INT (bits), op1,
1470 NULL_RTX, unsignedp, OPTAB_DIRECT);
1472 temp = expand_binop_directly (mode, otheroptab, op0, newop1,
1473 target, unsignedp, methods, last);
1474 if (temp)
1475 return temp;
1478 /* If this is a multiply, see if we can do a widening operation that
1479 takes operands of this mode and makes a wider mode. */
1481 if (binoptab == smul_optab
1482 && GET_MODE_WIDER_MODE (mode) != VOIDmode
1483 && ((optab_handler ((unsignedp ? umul_widen_optab : smul_widen_optab),
1484 GET_MODE_WIDER_MODE (mode))->insn_code)
1485 != CODE_FOR_nothing))
1487 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1488 unsignedp ? umul_widen_optab : smul_widen_optab,
1489 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1491 if (temp != 0)
1493 if (GET_MODE_CLASS (mode) == MODE_INT
1494 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1495 GET_MODE_BITSIZE (GET_MODE (temp))))
1496 return gen_lowpart (mode, temp);
1497 else
1498 return convert_to_mode (mode, temp, unsignedp);
1502 /* Look for a wider mode of the same class for which we think we
1503 can open-code the operation. Check for a widening multiply at the
1504 wider mode as well. */
1506 if (CLASS_HAS_WIDER_MODES_P (class)
1507 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1508 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1509 wider_mode != VOIDmode;
1510 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1512 if (optab_handler (binoptab, wider_mode)->insn_code != CODE_FOR_nothing
1513 || (binoptab == smul_optab
1514 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1515 && ((optab_handler ((unsignedp ? umul_widen_optab
1516 : smul_widen_optab),
1517 GET_MODE_WIDER_MODE (wider_mode))->insn_code)
1518 != CODE_FOR_nothing)))
1520 rtx xop0 = op0, xop1 = op1;
1521 int no_extend = 0;
1523 /* For certain integer operations, we need not actually extend
1524 the narrow operands, as long as we will truncate
1525 the results to the same narrowness. */
1527 if ((binoptab == ior_optab || binoptab == and_optab
1528 || binoptab == xor_optab
1529 || binoptab == add_optab || binoptab == sub_optab
1530 || binoptab == smul_optab || binoptab == ashl_optab)
1531 && class == MODE_INT)
1533 no_extend = 1;
1534 xop0 = avoid_expensive_constant (mode, binoptab,
1535 xop0, unsignedp);
1536 if (binoptab != ashl_optab)
1537 xop1 = avoid_expensive_constant (mode, binoptab,
1538 xop1, unsignedp);
1541 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1543 /* The second operand of a shift must always be extended. */
1544 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1545 no_extend && binoptab != ashl_optab);
1547 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1548 unsignedp, OPTAB_DIRECT);
1549 if (temp)
1551 if (class != MODE_INT
1552 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1553 GET_MODE_BITSIZE (wider_mode)))
1555 if (target == 0)
1556 target = gen_reg_rtx (mode);
1557 convert_move (target, temp, 0);
1558 return target;
1560 else
1561 return gen_lowpart (mode, temp);
1563 else
1564 delete_insns_since (last);
1568 /* If operation is commutative,
1569 try to make the first operand a register.
1570 Even better, try to make it the same as the target.
1571 Also try to make the last operand a constant. */
1572 if (commutative_optab_p (binoptab)
1573 && swap_commutative_operands_with_target (target, op0, op1))
1575 temp = op1;
1576 op1 = op0;
1577 op0 = temp;
1580 /* These can be done a word at a time. */
1581 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1582 && class == MODE_INT
1583 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1584 && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1586 int i;
1587 rtx insns;
1588 rtx equiv_value;
1590 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1591 won't be accurate, so use a new target. */
1592 if (target == 0 || target == op0 || target == op1)
1593 target = gen_reg_rtx (mode);
1595 start_sequence ();
1597 /* Do the actual arithmetic. */
1598 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1600 rtx target_piece = operand_subword (target, i, 1, mode);
1601 rtx x = expand_binop (word_mode, binoptab,
1602 operand_subword_force (op0, i, mode),
1603 operand_subword_force (op1, i, mode),
1604 target_piece, unsignedp, next_methods);
1606 if (x == 0)
1607 break;
1609 if (target_piece != x)
1610 emit_move_insn (target_piece, x);
1613 insns = get_insns ();
1614 end_sequence ();
1616 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1618 if (binoptab->code != UNKNOWN)
1619 equiv_value
1620 = gen_rtx_fmt_ee (binoptab->code, mode,
1621 copy_rtx (op0), copy_rtx (op1));
1622 else
1623 equiv_value = 0;
1625 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1626 return target;
1630 /* Synthesize double word shifts from single word shifts. */
1631 if ((binoptab == lshr_optab || binoptab == ashl_optab
1632 || binoptab == ashr_optab)
1633 && class == MODE_INT
1634 && (GET_CODE (op1) == CONST_INT || !optimize_size)
1635 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1636 && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing
1637 && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1638 && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1640 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1641 enum machine_mode op1_mode;
1643 double_shift_mask = targetm.shift_truncation_mask (mode);
1644 shift_mask = targetm.shift_truncation_mask (word_mode);
1645 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1647 /* Apply the truncation to constant shifts. */
1648 if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1649 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1651 if (op1 == CONST0_RTX (op1_mode))
1652 return op0;
1654 /* Make sure that this is a combination that expand_doubleword_shift
1655 can handle. See the comments there for details. */
1656 if (double_shift_mask == 0
1657 || (shift_mask == BITS_PER_WORD - 1
1658 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1660 rtx insns, equiv_value;
1661 rtx into_target, outof_target;
1662 rtx into_input, outof_input;
1663 int left_shift, outof_word;
1665 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1666 won't be accurate, so use a new target. */
1667 if (target == 0 || target == op0 || target == op1)
1668 target = gen_reg_rtx (mode);
1670 start_sequence ();
1672 /* OUTOF_* is the word we are shifting bits away from, and
1673 INTO_* is the word that we are shifting bits towards, thus
1674 they differ depending on the direction of the shift and
1675 WORDS_BIG_ENDIAN. */
1677 left_shift = binoptab == ashl_optab;
1678 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1680 outof_target = operand_subword (target, outof_word, 1, mode);
1681 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1683 outof_input = operand_subword_force (op0, outof_word, mode);
1684 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1686 if (expand_doubleword_shift (op1_mode, binoptab,
1687 outof_input, into_input, op1,
1688 outof_target, into_target,
1689 unsignedp, next_methods, shift_mask))
1691 insns = get_insns ();
1692 end_sequence ();
1694 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1695 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1696 return target;
1698 end_sequence ();
1702 /* Synthesize double word rotates from single word shifts. */
1703 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1704 && class == MODE_INT
1705 && GET_CODE (op1) == CONST_INT
1706 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1707 && optab_handler (ashl_optab, word_mode)->insn_code != CODE_FOR_nothing
1708 && optab_handler (lshr_optab, word_mode)->insn_code != CODE_FOR_nothing)
1710 rtx insns;
1711 rtx into_target, outof_target;
1712 rtx into_input, outof_input;
1713 rtx inter;
1714 int shift_count, left_shift, outof_word;
1716 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1717 won't be accurate, so use a new target. Do this also if target is not
1718 a REG, first because having a register instead may open optimization
1719 opportunities, and second because if target and op0 happen to be MEMs
1720 designating the same location, we would risk clobbering it too early
1721 in the code sequence we generate below. */
1722 if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1723 target = gen_reg_rtx (mode);
1725 start_sequence ();
1727 shift_count = INTVAL (op1);
1729 /* OUTOF_* is the word we are shifting bits away from, and
1730 INTO_* is the word that we are shifting bits towards, thus
1731 they differ depending on the direction of the shift and
1732 WORDS_BIG_ENDIAN. */
1734 left_shift = (binoptab == rotl_optab);
1735 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1737 outof_target = operand_subword (target, outof_word, 1, mode);
1738 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1740 outof_input = operand_subword_force (op0, outof_word, mode);
1741 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1743 if (shift_count == BITS_PER_WORD)
1745 /* This is just a word swap. */
1746 emit_move_insn (outof_target, into_input);
1747 emit_move_insn (into_target, outof_input);
1748 inter = const0_rtx;
1750 else
1752 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1753 rtx first_shift_count, second_shift_count;
1754 optab reverse_unsigned_shift, unsigned_shift;
1756 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1757 ? lshr_optab : ashl_optab);
1759 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1760 ? ashl_optab : lshr_optab);
1762 if (shift_count > BITS_PER_WORD)
1764 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1765 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1767 else
1769 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1770 second_shift_count = GEN_INT (shift_count);
1773 into_temp1 = expand_binop (word_mode, unsigned_shift,
1774 outof_input, first_shift_count,
1775 NULL_RTX, unsignedp, next_methods);
1776 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1777 into_input, second_shift_count,
1778 NULL_RTX, unsignedp, next_methods);
1780 if (into_temp1 != 0 && into_temp2 != 0)
1781 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1782 into_target, unsignedp, next_methods);
1783 else
1784 inter = 0;
1786 if (inter != 0 && inter != into_target)
1787 emit_move_insn (into_target, inter);
1789 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1790 into_input, first_shift_count,
1791 NULL_RTX, unsignedp, next_methods);
1792 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1793 outof_input, second_shift_count,
1794 NULL_RTX, unsignedp, next_methods);
1796 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1797 inter = expand_binop (word_mode, ior_optab,
1798 outof_temp1, outof_temp2,
1799 outof_target, unsignedp, next_methods);
1801 if (inter != 0 && inter != outof_target)
1802 emit_move_insn (outof_target, inter);
1805 insns = get_insns ();
1806 end_sequence ();
1808 if (inter != 0)
1810 /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1811 block to help the register allocator a bit. But a multi-word
1812 rotate will need all the input bits when setting the output
1813 bits, so there clearly is a conflict between the input and
1814 output registers. So we can't use a no-conflict block here. */
1815 emit_insn (insns);
1816 return target;
1820 /* These can be done a word at a time by propagating carries. */
1821 if ((binoptab == add_optab || binoptab == sub_optab)
1822 && class == MODE_INT
1823 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1824 && optab_handler (binoptab, word_mode)->insn_code != CODE_FOR_nothing)
1826 unsigned int i;
1827 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1828 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1829 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1830 rtx xop0, xop1, xtarget;
1832 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1833 value is one of those, use it. Otherwise, use 1 since it is the
1834 one easiest to get. */
1835 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1836 int normalizep = STORE_FLAG_VALUE;
1837 #else
1838 int normalizep = 1;
1839 #endif
1841 /* Prepare the operands. */
1842 xop0 = force_reg (mode, op0);
1843 xop1 = force_reg (mode, op1);
1845 xtarget = gen_reg_rtx (mode);
1847 if (target == 0 || !REG_P (target))
1848 target = xtarget;
1850 /* Indicate for flow that the entire target reg is being set. */
1851 if (REG_P (target))
1852 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1854 /* Do the actual arithmetic. */
1855 for (i = 0; i < nwords; i++)
1857 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1858 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1859 rtx op0_piece = operand_subword_force (xop0, index, mode);
1860 rtx op1_piece = operand_subword_force (xop1, index, mode);
1861 rtx x;
1863 /* Main add/subtract of the input operands. */
1864 x = expand_binop (word_mode, binoptab,
1865 op0_piece, op1_piece,
1866 target_piece, unsignedp, next_methods);
1867 if (x == 0)
1868 break;
1870 if (i + 1 < nwords)
1872 /* Store carry from main add/subtract. */
1873 carry_out = gen_reg_rtx (word_mode);
1874 carry_out = emit_store_flag_force (carry_out,
1875 (binoptab == add_optab
1876 ? LT : GT),
1877 x, op0_piece,
1878 word_mode, 1, normalizep);
1881 if (i > 0)
1883 rtx newx;
1885 /* Add/subtract previous carry to main result. */
1886 newx = expand_binop (word_mode,
1887 normalizep == 1 ? binoptab : otheroptab,
1888 x, carry_in,
1889 NULL_RTX, 1, next_methods);
1891 if (i + 1 < nwords)
1893 /* Get out carry from adding/subtracting carry in. */
1894 rtx carry_tmp = gen_reg_rtx (word_mode);
1895 carry_tmp = emit_store_flag_force (carry_tmp,
1896 (binoptab == add_optab
1897 ? LT : GT),
1898 newx, x,
1899 word_mode, 1, normalizep);
1901 /* Logical-ior the two poss. carry together. */
1902 carry_out = expand_binop (word_mode, ior_optab,
1903 carry_out, carry_tmp,
1904 carry_out, 0, next_methods);
1905 if (carry_out == 0)
1906 break;
1908 emit_move_insn (target_piece, newx);
1910 else
1912 if (x != target_piece)
1913 emit_move_insn (target_piece, x);
1916 carry_in = carry_out;
1919 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1921 if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing
1922 || ! rtx_equal_p (target, xtarget))
1924 rtx temp = emit_move_insn (target, xtarget);
1926 set_unique_reg_note (temp,
1927 REG_EQUAL,
1928 gen_rtx_fmt_ee (binoptab->code, mode,
1929 copy_rtx (xop0),
1930 copy_rtx (xop1)));
1932 else
1933 target = xtarget;
1935 return target;
1938 else
1939 delete_insns_since (last);
1942 /* Attempt to synthesize double word multiplies using a sequence of word
1943 mode multiplications. We first attempt to generate a sequence using a
1944 more efficient unsigned widening multiply, and if that fails we then
1945 try using a signed widening multiply. */
1947 if (binoptab == smul_optab
1948 && class == MODE_INT
1949 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1950 && optab_handler (smul_optab, word_mode)->insn_code != CODE_FOR_nothing
1951 && optab_handler (add_optab, word_mode)->insn_code != CODE_FOR_nothing)
1953 rtx product = NULL_RTX;
1955 if (optab_handler (umul_widen_optab, mode)->insn_code
1956 != CODE_FOR_nothing)
1958 product = expand_doubleword_mult (mode, op0, op1, target,
1959 true, methods);
1960 if (!product)
1961 delete_insns_since (last);
1964 if (product == NULL_RTX
1965 && optab_handler (smul_widen_optab, mode)->insn_code
1966 != CODE_FOR_nothing)
1968 product = expand_doubleword_mult (mode, op0, op1, target,
1969 false, methods);
1970 if (!product)
1971 delete_insns_since (last);
1974 if (product != NULL_RTX)
1976 if (optab_handler (mov_optab, mode)->insn_code != CODE_FOR_nothing)
1978 temp = emit_move_insn (target ? target : product, product);
1979 set_unique_reg_note (temp,
1980 REG_EQUAL,
1981 gen_rtx_fmt_ee (MULT, mode,
1982 copy_rtx (op0),
1983 copy_rtx (op1)));
1985 return product;
1989 /* It can't be open-coded in this mode.
1990 Use a library call if one is available and caller says that's ok. */
1992 if (optab_handler (binoptab, mode)->libfunc
1993 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1995 rtx insns;
1996 rtx op1x = op1;
1997 enum machine_mode op1_mode = mode;
1998 rtx value;
2000 start_sequence ();
2002 if (shift_optab_p (binoptab))
2004 op1_mode = targetm.libgcc_shift_count_mode ();
2005 /* Specify unsigned here,
2006 since negative shift counts are meaningless. */
2007 op1x = convert_to_mode (op1_mode, op1, 1);
2010 if (GET_MODE (op0) != VOIDmode
2011 && GET_MODE (op0) != mode)
2012 op0 = convert_to_mode (mode, op0, unsignedp);
2014 /* Pass 1 for NO_QUEUE so we don't lose any increments
2015 if the libcall is cse'd or moved. */
2016 value = emit_library_call_value (optab_handler (binoptab, mode)->libfunc,
2017 NULL_RTX, LCT_CONST, mode, 2,
2018 op0, mode, op1x, op1_mode);
2020 insns = get_insns ();
2021 end_sequence ();
2023 target = gen_reg_rtx (mode);
2024 emit_libcall_block (insns, target, value,
2025 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
2027 return target;
2030 delete_insns_since (last);
2032 /* It can't be done in this mode. Can we do it in a wider mode? */
2034 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
2035 || methods == OPTAB_MUST_WIDEN))
2037 /* Caller says, don't even try. */
2038 delete_insns_since (entry_last);
2039 return 0;
2042 /* Compute the value of METHODS to pass to recursive calls.
2043 Don't allow widening to be tried recursively. */
2045 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
2047 /* Look for a wider mode of the same class for which it appears we can do
2048 the operation. */
2050 if (CLASS_HAS_WIDER_MODES_P (class))
2052 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2053 wider_mode != VOIDmode;
2054 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2056 if ((optab_handler (binoptab, wider_mode)->insn_code
2057 != CODE_FOR_nothing)
2058 || (methods == OPTAB_LIB
2059 && optab_handler (binoptab, wider_mode)->libfunc))
2061 rtx xop0 = op0, xop1 = op1;
2062 int no_extend = 0;
2064 /* For certain integer operations, we need not actually extend
2065 the narrow operands, as long as we will truncate
2066 the results to the same narrowness. */
2068 if ((binoptab == ior_optab || binoptab == and_optab
2069 || binoptab == xor_optab
2070 || binoptab == add_optab || binoptab == sub_optab
2071 || binoptab == smul_optab || binoptab == ashl_optab)
2072 && class == MODE_INT)
2073 no_extend = 1;
2075 xop0 = widen_operand (xop0, wider_mode, mode,
2076 unsignedp, no_extend);
2078 /* The second operand of a shift must always be extended. */
2079 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
2080 no_extend && binoptab != ashl_optab);
2082 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
2083 unsignedp, methods);
2084 if (temp)
2086 if (class != MODE_INT
2087 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2088 GET_MODE_BITSIZE (wider_mode)))
2090 if (target == 0)
2091 target = gen_reg_rtx (mode);
2092 convert_move (target, temp, 0);
2093 return target;
2095 else
2096 return gen_lowpart (mode, temp);
2098 else
2099 delete_insns_since (last);
2104 delete_insns_since (entry_last);
2105 return 0;
2108 /* Expand a binary operator which has both signed and unsigned forms.
2109 UOPTAB is the optab for unsigned operations, and SOPTAB is for
2110 signed operations.
2112 If we widen unsigned operands, we may use a signed wider operation instead
2113 of an unsigned wider operation, since the result would be the same. */
2116 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
2117 rtx op0, rtx op1, rtx target, int unsignedp,
2118 enum optab_methods methods)
2120 rtx temp;
2121 optab direct_optab = unsignedp ? uoptab : soptab;
2122 struct optab wide_soptab;
2124 /* Do it without widening, if possible. */
2125 temp = expand_binop (mode, direct_optab, op0, op1, target,
2126 unsignedp, OPTAB_DIRECT);
2127 if (temp || methods == OPTAB_DIRECT)
2128 return temp;
2130 /* Try widening to a signed int. Make a fake signed optab that
2131 hides any signed insn for direct use. */
2132 wide_soptab = *soptab;
2133 optab_handler (&wide_soptab, mode)->insn_code = CODE_FOR_nothing;
2134 optab_handler (&wide_soptab, mode)->libfunc = 0;
2136 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2137 unsignedp, OPTAB_WIDEN);
2139 /* For unsigned operands, try widening to an unsigned int. */
2140 if (temp == 0 && unsignedp)
2141 temp = expand_binop (mode, uoptab, op0, op1, target,
2142 unsignedp, OPTAB_WIDEN);
2143 if (temp || methods == OPTAB_WIDEN)
2144 return temp;
2146 /* Use the right width lib call if that exists. */
2147 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2148 if (temp || methods == OPTAB_LIB)
2149 return temp;
2151 /* Must widen and use a lib call, use either signed or unsigned. */
2152 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2153 unsignedp, methods);
2154 if (temp != 0)
2155 return temp;
2156 if (unsignedp)
2157 return expand_binop (mode, uoptab, op0, op1, target,
2158 unsignedp, methods);
2159 return 0;
2162 /* Generate code to perform an operation specified by UNOPPTAB
2163 on operand OP0, with two results to TARG0 and TARG1.
2164 We assume that the order of the operands for the instruction
2165 is TARG0, TARG1, OP0.
2167 Either TARG0 or TARG1 may be zero, but what that means is that
2168 the result is not actually wanted. We will generate it into
2169 a dummy pseudo-reg and discard it. They may not both be zero.
2171 Returns 1 if this operation can be performed; 0 if not. */
2174 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2175 int unsignedp)
2177 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2178 enum mode_class class;
2179 enum machine_mode wider_mode;
2180 rtx entry_last = get_last_insn ();
2181 rtx last;
2183 class = GET_MODE_CLASS (mode);
2185 if (!targ0)
2186 targ0 = gen_reg_rtx (mode);
2187 if (!targ1)
2188 targ1 = gen_reg_rtx (mode);
2190 /* Record where to go back to if we fail. */
2191 last = get_last_insn ();
2193 if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
2195 int icode = (int) optab_handler (unoptab, mode)->insn_code;
2196 enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2197 rtx pat;
2198 rtx xop0 = op0;
2200 if (GET_MODE (xop0) != VOIDmode
2201 && GET_MODE (xop0) != mode0)
2202 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2204 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2205 if (!insn_data[icode].operand[2].predicate (xop0, mode0))
2206 xop0 = copy_to_mode_reg (mode0, xop0);
2208 /* We could handle this, but we should always be called with a pseudo
2209 for our targets and all insns should take them as outputs. */
2210 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2211 gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
2213 pat = GEN_FCN (icode) (targ0, targ1, xop0);
2214 if (pat)
2216 emit_insn (pat);
2217 return 1;
2219 else
2220 delete_insns_since (last);
2223 /* It can't be done in this mode. Can we do it in a wider mode? */
2225 if (CLASS_HAS_WIDER_MODES_P (class))
2227 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2228 wider_mode != VOIDmode;
2229 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2231 if (optab_handler (unoptab, wider_mode)->insn_code
2232 != CODE_FOR_nothing)
2234 rtx t0 = gen_reg_rtx (wider_mode);
2235 rtx t1 = gen_reg_rtx (wider_mode);
2236 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2238 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2240 convert_move (targ0, t0, unsignedp);
2241 convert_move (targ1, t1, unsignedp);
2242 return 1;
2244 else
2245 delete_insns_since (last);
2250 delete_insns_since (entry_last);
2251 return 0;
2254 /* Generate code to perform an operation specified by BINOPTAB
2255 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2256 We assume that the order of the operands for the instruction
2257 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2258 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2260 Either TARG0 or TARG1 may be zero, but what that means is that
2261 the result is not actually wanted. We will generate it into
2262 a dummy pseudo-reg and discard it. They may not both be zero.
2264 Returns 1 if this operation can be performed; 0 if not. */
2267 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2268 int unsignedp)
2270 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2271 enum mode_class class;
2272 enum machine_mode wider_mode;
2273 rtx entry_last = get_last_insn ();
2274 rtx last;
2276 class = GET_MODE_CLASS (mode);
2278 if (!targ0)
2279 targ0 = gen_reg_rtx (mode);
2280 if (!targ1)
2281 targ1 = gen_reg_rtx (mode);
2283 /* Record where to go back to if we fail. */
2284 last = get_last_insn ();
2286 if (optab_handler (binoptab, mode)->insn_code != CODE_FOR_nothing)
2288 int icode = (int) optab_handler (binoptab, mode)->insn_code;
2289 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2290 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2291 rtx pat;
2292 rtx xop0 = op0, xop1 = op1;
2294 /* If we are optimizing, force expensive constants into a register. */
2295 xop0 = avoid_expensive_constant (mode0, binoptab, xop0, unsignedp);
2296 xop1 = avoid_expensive_constant (mode1, binoptab, xop1, unsignedp);
2298 /* In case the insn wants input operands in modes different from
2299 those of the actual operands, convert the operands. It would
2300 seem that we don't need to convert CONST_INTs, but we do, so
2301 that they're properly zero-extended, sign-extended or truncated
2302 for their mode. */
2304 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2305 xop0 = convert_modes (mode0,
2306 GET_MODE (op0) != VOIDmode
2307 ? GET_MODE (op0)
2308 : mode,
2309 xop0, unsignedp);
2311 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2312 xop1 = convert_modes (mode1,
2313 GET_MODE (op1) != VOIDmode
2314 ? GET_MODE (op1)
2315 : mode,
2316 xop1, unsignedp);
2318 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2319 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2320 xop0 = copy_to_mode_reg (mode0, xop0);
2322 if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2323 xop1 = copy_to_mode_reg (mode1, xop1);
2325 /* We could handle this, but we should always be called with a pseudo
2326 for our targets and all insns should take them as outputs. */
2327 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2328 gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2330 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2331 if (pat)
2333 emit_insn (pat);
2334 return 1;
2336 else
2337 delete_insns_since (last);
2340 /* It can't be done in this mode. Can we do it in a wider mode? */
2342 if (CLASS_HAS_WIDER_MODES_P (class))
2344 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2345 wider_mode != VOIDmode;
2346 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2348 if (optab_handler (binoptab, wider_mode)->insn_code
2349 != CODE_FOR_nothing)
2351 rtx t0 = gen_reg_rtx (wider_mode);
2352 rtx t1 = gen_reg_rtx (wider_mode);
2353 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2354 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2356 if (expand_twoval_binop (binoptab, cop0, cop1,
2357 t0, t1, unsignedp))
2359 convert_move (targ0, t0, unsignedp);
2360 convert_move (targ1, t1, unsignedp);
2361 return 1;
2363 else
2364 delete_insns_since (last);
2369 delete_insns_since (entry_last);
2370 return 0;
2373 /* Expand the two-valued library call indicated by BINOPTAB, but
2374 preserve only one of the values. If TARG0 is non-NULL, the first
2375 value is placed into TARG0; otherwise the second value is placed
2376 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2377 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2378 This routine assumes that the value returned by the library call is
2379 as if the return value was of an integral mode twice as wide as the
2380 mode of OP0. Returns 1 if the call was successful. */
2382 bool
2383 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2384 rtx targ0, rtx targ1, enum rtx_code code)
2386 enum machine_mode mode;
2387 enum machine_mode libval_mode;
2388 rtx libval;
2389 rtx insns;
2391 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2392 gcc_assert (!targ0 != !targ1);
2394 mode = GET_MODE (op0);
2395 if (!optab_handler (binoptab, mode)->libfunc)
2396 return false;
2398 /* The value returned by the library function will have twice as
2399 many bits as the nominal MODE. */
2400 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2401 MODE_INT);
2402 start_sequence ();
2403 libval = emit_library_call_value (optab_handler (binoptab, mode)->libfunc,
2404 NULL_RTX, LCT_CONST,
2405 libval_mode, 2,
2406 op0, mode,
2407 op1, mode);
2408 /* Get the part of VAL containing the value that we want. */
2409 libval = simplify_gen_subreg (mode, libval, libval_mode,
2410 targ0 ? 0 : GET_MODE_SIZE (mode));
2411 insns = get_insns ();
2412 end_sequence ();
2413 /* Move the into the desired location. */
2414 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2415 gen_rtx_fmt_ee (code, mode, op0, op1));
2417 return true;
2421 /* Wrapper around expand_unop which takes an rtx code to specify
2422 the operation to perform, not an optab pointer. All other
2423 arguments are the same. */
2425 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2426 rtx target, int unsignedp)
2428 optab unop = code_to_optab[(int) code];
2429 gcc_assert (unop);
2431 return expand_unop (mode, unop, op0, target, unsignedp);
2434 /* Try calculating
2435 (clz:narrow x)
2437 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2438 static rtx
2439 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2441 enum mode_class class = GET_MODE_CLASS (mode);
2442 if (CLASS_HAS_WIDER_MODES_P (class))
2444 enum machine_mode wider_mode;
2445 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2446 wider_mode != VOIDmode;
2447 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2449 if (optab_handler (clz_optab, wider_mode)->insn_code
2450 != CODE_FOR_nothing)
2452 rtx xop0, temp, last;
2454 last = get_last_insn ();
2456 if (target == 0)
2457 target = gen_reg_rtx (mode);
2458 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2459 temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2460 if (temp != 0)
2461 temp = expand_binop (wider_mode, sub_optab, temp,
2462 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2463 - GET_MODE_BITSIZE (mode)),
2464 target, true, OPTAB_DIRECT);
2465 if (temp == 0)
2466 delete_insns_since (last);
2468 return temp;
2472 return 0;
2475 /* Try calculating clz of a double-word quantity as two clz's of word-sized
2476 quantities, choosing which based on whether the high word is nonzero. */
2477 static rtx
2478 expand_doubleword_clz (enum machine_mode mode, rtx op0, rtx target)
2480 rtx xop0 = force_reg (mode, op0);
2481 rtx subhi = gen_highpart (word_mode, xop0);
2482 rtx sublo = gen_lowpart (word_mode, xop0);
2483 rtx hi0_label = gen_label_rtx ();
2484 rtx after_label = gen_label_rtx ();
2485 rtx seq, temp, result;
2487 /* If we were not given a target, use a word_mode register, not a
2488 'mode' register. The result will fit, and nobody is expecting
2489 anything bigger (the return type of __builtin_clz* is int). */
2490 if (!target)
2491 target = gen_reg_rtx (word_mode);
2493 /* In any case, write to a word_mode scratch in both branches of the
2494 conditional, so we can ensure there is a single move insn setting
2495 'target' to tag a REG_EQUAL note on. */
2496 result = gen_reg_rtx (word_mode);
2498 start_sequence ();
2500 /* If the high word is not equal to zero,
2501 then clz of the full value is clz of the high word. */
2502 emit_cmp_and_jump_insns (subhi, CONST0_RTX (word_mode), EQ, 0,
2503 word_mode, true, hi0_label);
2505 temp = expand_unop_direct (word_mode, clz_optab, subhi, result, true);
2506 if (!temp)
2507 goto fail;
2509 if (temp != result)
2510 convert_move (result, temp, true);
2512 emit_jump_insn (gen_jump (after_label));
2513 emit_barrier ();
2515 /* Else clz of the full value is clz of the low word plus the number
2516 of bits in the high word. */
2517 emit_label (hi0_label);
2519 temp = expand_unop_direct (word_mode, clz_optab, sublo, 0, true);
2520 if (!temp)
2521 goto fail;
2522 temp = expand_binop (word_mode, add_optab, temp,
2523 GEN_INT (GET_MODE_BITSIZE (word_mode)),
2524 result, true, OPTAB_DIRECT);
2525 if (!temp)
2526 goto fail;
2527 if (temp != result)
2528 convert_move (result, temp, true);
2530 emit_label (after_label);
2531 convert_move (target, result, true);
2533 seq = get_insns ();
2534 end_sequence ();
2536 add_equal_note (seq, target, CLZ, xop0, 0);
2537 emit_insn (seq);
2538 return target;
2540 fail:
2541 end_sequence ();
2542 return 0;
2545 /* Try calculating
2546 (bswap:narrow x)
2548 (lshiftrt:wide (bswap:wide x) ((width wide) - (width narrow))). */
2549 static rtx
2550 widen_bswap (enum machine_mode mode, rtx op0, rtx target)
2552 enum mode_class class = GET_MODE_CLASS (mode);
2553 enum machine_mode wider_mode;
2554 rtx x, last;
2556 if (!CLASS_HAS_WIDER_MODES_P (class))
2557 return NULL_RTX;
2559 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2560 wider_mode != VOIDmode;
2561 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2562 if (optab_handler (bswap_optab, wider_mode)->insn_code != CODE_FOR_nothing)
2563 goto found;
2564 return NULL_RTX;
2566 found:
2567 last = get_last_insn ();
2569 x = widen_operand (op0, wider_mode, mode, true, true);
2570 x = expand_unop (wider_mode, bswap_optab, x, NULL_RTX, true);
2572 if (x != 0)
2573 x = expand_shift (RSHIFT_EXPR, wider_mode, x,
2574 size_int (GET_MODE_BITSIZE (wider_mode)
2575 - GET_MODE_BITSIZE (mode)),
2576 NULL_RTX, true);
2578 if (x != 0)
2580 if (target == 0)
2581 target = gen_reg_rtx (mode);
2582 emit_move_insn (target, gen_lowpart (mode, x));
2584 else
2585 delete_insns_since (last);
2587 return target;
2590 /* Try calculating bswap as two bswaps of two word-sized operands. */
2592 static rtx
2593 expand_doubleword_bswap (enum machine_mode mode, rtx op, rtx target)
2595 rtx t0, t1;
2597 t1 = expand_unop (word_mode, bswap_optab,
2598 operand_subword_force (op, 0, mode), NULL_RTX, true);
2599 t0 = expand_unop (word_mode, bswap_optab,
2600 operand_subword_force (op, 1, mode), NULL_RTX, true);
2602 if (target == 0)
2603 target = gen_reg_rtx (mode);
2604 if (REG_P (target))
2605 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2606 emit_move_insn (operand_subword (target, 0, 1, mode), t0);
2607 emit_move_insn (operand_subword (target, 1, 1, mode), t1);
2609 return target;
2612 /* Try calculating (parity x) as (and (popcount x) 1), where
2613 popcount can also be done in a wider mode. */
2614 static rtx
2615 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2617 enum mode_class class = GET_MODE_CLASS (mode);
2618 if (CLASS_HAS_WIDER_MODES_P (class))
2620 enum machine_mode wider_mode;
2621 for (wider_mode = mode; wider_mode != VOIDmode;
2622 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2624 if (optab_handler (popcount_optab, wider_mode)->insn_code
2625 != CODE_FOR_nothing)
2627 rtx xop0, temp, last;
2629 last = get_last_insn ();
2631 if (target == 0)
2632 target = gen_reg_rtx (mode);
2633 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2634 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2635 true);
2636 if (temp != 0)
2637 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2638 target, true, OPTAB_DIRECT);
2639 if (temp == 0)
2640 delete_insns_since (last);
2642 return temp;
2646 return 0;
2649 /* Try calculating ctz(x) as K - clz(x & -x) ,
2650 where K is GET_MODE_BITSIZE(mode) - 1.
2652 Both __builtin_ctz and __builtin_clz are undefined at zero, so we
2653 don't have to worry about what the hardware does in that case. (If
2654 the clz instruction produces the usual value at 0, which is K, the
2655 result of this code sequence will be -1; expand_ffs, below, relies
2656 on this. It might be nice to have it be K instead, for consistency
2657 with the (very few) processors that provide a ctz with a defined
2658 value, but that would take one more instruction, and it would be
2659 less convenient for expand_ffs anyway. */
2661 static rtx
2662 expand_ctz (enum machine_mode mode, rtx op0, rtx target)
2664 rtx seq, temp;
2666 if (optab_handler (clz_optab, mode)->insn_code == CODE_FOR_nothing)
2667 return 0;
2669 start_sequence ();
2671 temp = expand_unop_direct (mode, neg_optab, op0, NULL_RTX, true);
2672 if (temp)
2673 temp = expand_binop (mode, and_optab, op0, temp, NULL_RTX,
2674 true, OPTAB_DIRECT);
2675 if (temp)
2676 temp = expand_unop_direct (mode, clz_optab, temp, NULL_RTX, true);
2677 if (temp)
2678 temp = expand_binop (mode, sub_optab, GEN_INT (GET_MODE_BITSIZE (mode) - 1),
2679 temp, target,
2680 true, OPTAB_DIRECT);
2681 if (temp == 0)
2683 end_sequence ();
2684 return 0;
2687 seq = get_insns ();
2688 end_sequence ();
2690 add_equal_note (seq, temp, CTZ, op0, 0);
2691 emit_insn (seq);
2692 return temp;
2696 /* Try calculating ffs(x) using ctz(x) if we have that instruction, or
2697 else with the sequence used by expand_clz.
2699 The ffs builtin promises to return zero for a zero value and ctz/clz
2700 may have an undefined value in that case. If they do not give us a
2701 convenient value, we have to generate a test and branch. */
2702 static rtx
2703 expand_ffs (enum machine_mode mode, rtx op0, rtx target)
2705 HOST_WIDE_INT val = 0;
2706 bool defined_at_zero = false;
2707 rtx temp, seq;
2709 if (optab_handler (ctz_optab, mode)->insn_code != CODE_FOR_nothing)
2711 start_sequence ();
2713 temp = expand_unop_direct (mode, ctz_optab, op0, 0, true);
2714 if (!temp)
2715 goto fail;
2717 defined_at_zero = (CTZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2);
2719 else if (optab_handler (clz_optab, mode)->insn_code != CODE_FOR_nothing)
2721 start_sequence ();
2722 temp = expand_ctz (mode, op0, 0);
2723 if (!temp)
2724 goto fail;
2726 if (CLZ_DEFINED_VALUE_AT_ZERO (mode, val) == 2)
2728 defined_at_zero = true;
2729 val = (GET_MODE_BITSIZE (mode) - 1) - val;
2732 else
2733 return 0;
2735 if (defined_at_zero && val == -1)
2736 /* No correction needed at zero. */;
2737 else
2739 /* We don't try to do anything clever with the situation found
2740 on some processors (eg Alpha) where ctz(0:mode) ==
2741 bitsize(mode). If someone can think of a way to send N to -1
2742 and leave alone all values in the range 0..N-1 (where N is a
2743 power of two), cheaper than this test-and-branch, please add it.
2745 The test-and-branch is done after the operation itself, in case
2746 the operation sets condition codes that can be recycled for this.
2747 (This is true on i386, for instance.) */
2749 rtx nonzero_label = gen_label_rtx ();
2750 emit_cmp_and_jump_insns (op0, CONST0_RTX (mode), NE, 0,
2751 mode, true, nonzero_label);
2753 convert_move (temp, GEN_INT (-1), false);
2754 emit_label (nonzero_label);
2757 /* temp now has a value in the range -1..bitsize-1. ffs is supposed
2758 to produce a value in the range 0..bitsize. */
2759 temp = expand_binop (mode, add_optab, temp, GEN_INT (1),
2760 target, false, OPTAB_DIRECT);
2761 if (!temp)
2762 goto fail;
2764 seq = get_insns ();
2765 end_sequence ();
2767 add_equal_note (seq, temp, FFS, op0, 0);
2768 emit_insn (seq);
2769 return temp;
2771 fail:
2772 end_sequence ();
2773 return 0;
2776 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2777 conditions, VAL may already be a SUBREG against which we cannot generate
2778 a further SUBREG. In this case, we expect forcing the value into a
2779 register will work around the situation. */
2781 static rtx
2782 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2783 enum machine_mode imode)
2785 rtx ret;
2786 ret = lowpart_subreg (omode, val, imode);
2787 if (ret == NULL)
2789 val = force_reg (imode, val);
2790 ret = lowpart_subreg (omode, val, imode);
2791 gcc_assert (ret != NULL);
2793 return ret;
2796 /* Expand a floating point absolute value or negation operation via a
2797 logical operation on the sign bit. */
2799 static rtx
2800 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2801 rtx op0, rtx target)
2803 const struct real_format *fmt;
2804 int bitpos, word, nwords, i;
2805 enum machine_mode imode;
2806 HOST_WIDE_INT hi, lo;
2807 rtx temp, insns;
2809 /* The format has to have a simple sign bit. */
2810 fmt = REAL_MODE_FORMAT (mode);
2811 if (fmt == NULL)
2812 return NULL_RTX;
2814 bitpos = fmt->signbit_rw;
2815 if (bitpos < 0)
2816 return NULL_RTX;
2818 /* Don't create negative zeros if the format doesn't support them. */
2819 if (code == NEG && !fmt->has_signed_zero)
2820 return NULL_RTX;
2822 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2824 imode = int_mode_for_mode (mode);
2825 if (imode == BLKmode)
2826 return NULL_RTX;
2827 word = 0;
2828 nwords = 1;
2830 else
2832 imode = word_mode;
2834 if (FLOAT_WORDS_BIG_ENDIAN)
2835 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2836 else
2837 word = bitpos / BITS_PER_WORD;
2838 bitpos = bitpos % BITS_PER_WORD;
2839 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2842 if (bitpos < HOST_BITS_PER_WIDE_INT)
2844 hi = 0;
2845 lo = (HOST_WIDE_INT) 1 << bitpos;
2847 else
2849 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2850 lo = 0;
2852 if (code == ABS)
2853 lo = ~lo, hi = ~hi;
2855 if (target == 0 || target == op0)
2856 target = gen_reg_rtx (mode);
2858 if (nwords > 1)
2860 start_sequence ();
2862 for (i = 0; i < nwords; ++i)
2864 rtx targ_piece = operand_subword (target, i, 1, mode);
2865 rtx op0_piece = operand_subword_force (op0, i, mode);
2867 if (i == word)
2869 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2870 op0_piece,
2871 immed_double_const (lo, hi, imode),
2872 targ_piece, 1, OPTAB_LIB_WIDEN);
2873 if (temp != targ_piece)
2874 emit_move_insn (targ_piece, temp);
2876 else
2877 emit_move_insn (targ_piece, op0_piece);
2880 insns = get_insns ();
2881 end_sequence ();
2883 temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2884 emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2886 else
2888 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2889 gen_lowpart (imode, op0),
2890 immed_double_const (lo, hi, imode),
2891 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2892 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2894 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2895 gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2898 return target;
2901 /* As expand_unop, but will fail rather than attempt the operation in a
2902 different mode or with a libcall. */
2903 static rtx
2904 expand_unop_direct (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2905 int unsignedp)
2907 if (optab_handler (unoptab, mode)->insn_code != CODE_FOR_nothing)
2909 int icode = (int) optab_handler (unoptab, mode)->insn_code;
2910 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2911 rtx xop0 = op0;
2912 rtx last = get_last_insn ();
2913 rtx pat, temp;
2915 if (target)
2916 temp = target;
2917 else
2918 temp = gen_reg_rtx (mode);
2920 if (GET_MODE (xop0) != VOIDmode
2921 && GET_MODE (xop0) != mode0)
2922 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2924 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2926 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2927 xop0 = copy_to_mode_reg (mode0, xop0);
2929 if (!insn_data[icode].operand[0].predicate (temp, mode))
2930 temp = gen_reg_rtx (mode);
2932 pat = GEN_FCN (icode) (temp, xop0);
2933 if (pat)
2935 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2936 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2938 delete_insns_since (last);
2939 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2942 emit_insn (pat);
2944 return temp;
2946 else
2947 delete_insns_since (last);
2949 return 0;
2952 /* Generate code to perform an operation specified by UNOPTAB
2953 on operand OP0, with result having machine-mode MODE.
2955 UNSIGNEDP is for the case where we have to widen the operands
2956 to perform the operation. It says to use zero-extension.
2958 If TARGET is nonzero, the value
2959 is generated there, if it is convenient to do so.
2960 In all cases an rtx is returned for the locus of the value;
2961 this may or may not be TARGET. */
2964 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2965 int unsignedp)
2967 enum mode_class class = GET_MODE_CLASS (mode);
2968 enum machine_mode wider_mode;
2969 rtx temp;
2971 temp = expand_unop_direct (mode, unoptab, op0, target, unsignedp);
2972 if (temp)
2973 return temp;
2975 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2977 /* Widening (or narrowing) clz needs special treatment. */
2978 if (unoptab == clz_optab)
2980 temp = widen_clz (mode, op0, target);
2981 if (temp)
2982 return temp;
2984 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
2985 && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
2987 temp = expand_doubleword_clz (mode, op0, target);
2988 if (temp)
2989 return temp;
2992 goto try_libcall;
2995 /* Widening (or narrowing) bswap needs special treatment. */
2996 if (unoptab == bswap_optab)
2998 temp = widen_bswap (mode, op0, target);
2999 if (temp)
3000 return temp;
3002 if (GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
3003 && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3005 temp = expand_doubleword_bswap (mode, op0, target);
3006 if (temp)
3007 return temp;
3010 goto try_libcall;
3013 if (CLASS_HAS_WIDER_MODES_P (class))
3014 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3015 wider_mode != VOIDmode;
3016 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3018 if (optab_handler (unoptab, wider_mode)->insn_code != CODE_FOR_nothing)
3020 rtx xop0 = op0;
3021 rtx last = get_last_insn ();
3023 /* For certain operations, we need not actually extend
3024 the narrow operand, as long as we will truncate the
3025 results to the same narrowness. */
3027 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3028 (unoptab == neg_optab
3029 || unoptab == one_cmpl_optab)
3030 && class == MODE_INT);
3032 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3033 unsignedp);
3035 if (temp)
3037 if (class != MODE_INT
3038 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
3039 GET_MODE_BITSIZE (wider_mode)))
3041 if (target == 0)
3042 target = gen_reg_rtx (mode);
3043 convert_move (target, temp, 0);
3044 return target;
3046 else
3047 return gen_lowpart (mode, temp);
3049 else
3050 delete_insns_since (last);
3054 /* These can be done a word at a time. */
3055 if (unoptab == one_cmpl_optab
3056 && class == MODE_INT
3057 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
3058 && optab_handler (unoptab, word_mode)->insn_code != CODE_FOR_nothing)
3060 int i;
3061 rtx insns;
3063 if (target == 0 || target == op0)
3064 target = gen_reg_rtx (mode);
3066 start_sequence ();
3068 /* Do the actual arithmetic. */
3069 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
3071 rtx target_piece = operand_subword (target, i, 1, mode);
3072 rtx x = expand_unop (word_mode, unoptab,
3073 operand_subword_force (op0, i, mode),
3074 target_piece, unsignedp);
3076 if (target_piece != x)
3077 emit_move_insn (target_piece, x);
3080 insns = get_insns ();
3081 end_sequence ();
3083 emit_no_conflict_block (insns, target, op0, NULL_RTX,
3084 gen_rtx_fmt_e (unoptab->code, mode,
3085 copy_rtx (op0)));
3086 return target;
3089 if (unoptab->code == NEG)
3091 /* Try negating floating point values by flipping the sign bit. */
3092 if (SCALAR_FLOAT_MODE_P (mode))
3094 temp = expand_absneg_bit (NEG, mode, op0, target);
3095 if (temp)
3096 return temp;
3099 /* If there is no negation pattern, and we have no negative zero,
3100 try subtracting from zero. */
3101 if (!HONOR_SIGNED_ZEROS (mode))
3103 temp = expand_binop (mode, (unoptab == negv_optab
3104 ? subv_optab : sub_optab),
3105 CONST0_RTX (mode), op0, target,
3106 unsignedp, OPTAB_DIRECT);
3107 if (temp)
3108 return temp;
3112 /* Try calculating parity (x) as popcount (x) % 2. */
3113 if (unoptab == parity_optab)
3115 temp = expand_parity (mode, op0, target);
3116 if (temp)
3117 return temp;
3120 /* Try implementing ffs (x) in terms of clz (x). */
3121 if (unoptab == ffs_optab)
3123 temp = expand_ffs (mode, op0, target);
3124 if (temp)
3125 return temp;
3128 /* Try implementing ctz (x) in terms of clz (x). */
3129 if (unoptab == ctz_optab)
3131 temp = expand_ctz (mode, op0, target);
3132 if (temp)
3133 return temp;
3136 try_libcall:
3137 /* Now try a library call in this mode. */
3138 if (optab_handler (unoptab, mode)->libfunc)
3140 rtx insns;
3141 rtx value;
3142 enum machine_mode outmode = mode;
3144 /* All of these functions return small values. Thus we choose to
3145 have them return something that isn't a double-word. */
3146 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
3147 || unoptab == popcount_optab || unoptab == parity_optab)
3148 outmode
3149 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
3151 start_sequence ();
3153 /* Pass 1 for NO_QUEUE so we don't lose any increments
3154 if the libcall is cse'd or moved. */
3155 value = emit_library_call_value (optab_handler (unoptab, mode)->libfunc,
3156 NULL_RTX, LCT_CONST, outmode,
3157 1, op0, mode);
3158 insns = get_insns ();
3159 end_sequence ();
3161 target = gen_reg_rtx (outmode);
3162 emit_libcall_block (insns, target, value,
3163 gen_rtx_fmt_e (unoptab->code, outmode, op0));
3165 return target;
3168 /* It can't be done in this mode. Can we do it in a wider mode? */
3170 if (CLASS_HAS_WIDER_MODES_P (class))
3172 for (wider_mode = GET_MODE_WIDER_MODE (mode);
3173 wider_mode != VOIDmode;
3174 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3176 if ((optab_handler (unoptab, wider_mode)->insn_code
3177 != CODE_FOR_nothing)
3178 || optab_handler (unoptab, wider_mode)->libfunc)
3180 rtx xop0 = op0;
3181 rtx last = get_last_insn ();
3183 /* For certain operations, we need not actually extend
3184 the narrow operand, as long as we will truncate the
3185 results to the same narrowness. */
3187 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
3188 (unoptab == neg_optab
3189 || unoptab == one_cmpl_optab)
3190 && class == MODE_INT);
3192 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
3193 unsignedp);
3195 /* If we are generating clz using wider mode, adjust the
3196 result. */
3197 if (unoptab == clz_optab && temp != 0)
3198 temp = expand_binop (wider_mode, sub_optab, temp,
3199 GEN_INT (GET_MODE_BITSIZE (wider_mode)
3200 - GET_MODE_BITSIZE (mode)),
3201 target, true, OPTAB_DIRECT);
3203 if (temp)
3205 if (class != MODE_INT)
3207 if (target == 0)
3208 target = gen_reg_rtx (mode);
3209 convert_move (target, temp, 0);
3210 return target;
3212 else
3213 return gen_lowpart (mode, temp);
3215 else
3216 delete_insns_since (last);
3221 /* One final attempt at implementing negation via subtraction,
3222 this time allowing widening of the operand. */
3223 if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
3225 rtx temp;
3226 temp = expand_binop (mode,
3227 unoptab == negv_optab ? subv_optab : sub_optab,
3228 CONST0_RTX (mode), op0,
3229 target, unsignedp, OPTAB_LIB_WIDEN);
3230 if (temp)
3231 return temp;
3234 return 0;
3237 /* Emit code to compute the absolute value of OP0, with result to
3238 TARGET if convenient. (TARGET may be 0.) The return value says
3239 where the result actually is to be found.
3241 MODE is the mode of the operand; the mode of the result is
3242 different but can be deduced from MODE.
3247 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
3248 int result_unsignedp)
3250 rtx temp;
3252 if (! flag_trapv)
3253 result_unsignedp = 1;
3255 /* First try to do it with a special abs instruction. */
3256 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
3257 op0, target, 0);
3258 if (temp != 0)
3259 return temp;
3261 /* For floating point modes, try clearing the sign bit. */
3262 if (SCALAR_FLOAT_MODE_P (mode))
3264 temp = expand_absneg_bit (ABS, mode, op0, target);
3265 if (temp)
3266 return temp;
3269 /* If we have a MAX insn, we can do this as MAX (x, -x). */
3270 if (optab_handler (smax_optab, mode)->insn_code != CODE_FOR_nothing
3271 && !HONOR_SIGNED_ZEROS (mode))
3273 rtx last = get_last_insn ();
3275 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
3276 if (temp != 0)
3277 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
3278 OPTAB_WIDEN);
3280 if (temp != 0)
3281 return temp;
3283 delete_insns_since (last);
3286 /* If this machine has expensive jumps, we can do integer absolute
3287 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
3288 where W is the width of MODE. */
3290 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
3292 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
3293 size_int (GET_MODE_BITSIZE (mode) - 1),
3294 NULL_RTX, 0);
3296 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
3297 OPTAB_LIB_WIDEN);
3298 if (temp != 0)
3299 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
3300 temp, extended, target, 0, OPTAB_LIB_WIDEN);
3302 if (temp != 0)
3303 return temp;
3306 return NULL_RTX;
3310 expand_abs (enum machine_mode mode, rtx op0, rtx target,
3311 int result_unsignedp, int safe)
3313 rtx temp, op1;
3315 if (! flag_trapv)
3316 result_unsignedp = 1;
3318 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
3319 if (temp != 0)
3320 return temp;
3322 /* If that does not win, use conditional jump and negate. */
3324 /* It is safe to use the target if it is the same
3325 as the source if this is also a pseudo register */
3326 if (op0 == target && REG_P (op0)
3327 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
3328 safe = 1;
3330 op1 = gen_label_rtx ();
3331 if (target == 0 || ! safe
3332 || GET_MODE (target) != mode
3333 || (MEM_P (target) && MEM_VOLATILE_P (target))
3334 || (REG_P (target)
3335 && REGNO (target) < FIRST_PSEUDO_REGISTER))
3336 target = gen_reg_rtx (mode);
3338 emit_move_insn (target, op0);
3339 NO_DEFER_POP;
3341 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
3342 NULL_RTX, NULL_RTX, op1);
3344 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
3345 target, target, 0);
3346 if (op0 != target)
3347 emit_move_insn (target, op0);
3348 emit_label (op1);
3349 OK_DEFER_POP;
3350 return target;
3353 /* A subroutine of expand_copysign, perform the copysign operation using the
3354 abs and neg primitives advertised to exist on the target. The assumption
3355 is that we have a split register file, and leaving op0 in fp registers,
3356 and not playing with subregs so much, will help the register allocator. */
3358 static rtx
3359 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3360 int bitpos, bool op0_is_abs)
3362 enum machine_mode imode;
3363 int icode;
3364 rtx sign, label;
3366 if (target == op1)
3367 target = NULL_RTX;
3369 /* Check if the back end provides an insn that handles signbit for the
3370 argument's mode. */
3371 icode = (int) signbit_optab->handlers [(int) mode].insn_code;
3372 if (icode != CODE_FOR_nothing)
3374 imode = insn_data[icode].operand[0].mode;
3375 sign = gen_reg_rtx (imode);
3376 emit_unop_insn (icode, sign, op1, UNKNOWN);
3378 else
3380 HOST_WIDE_INT hi, lo;
3382 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3384 imode = int_mode_for_mode (mode);
3385 if (imode == BLKmode)
3386 return NULL_RTX;
3387 op1 = gen_lowpart (imode, op1);
3389 else
3391 int word;
3393 imode = word_mode;
3394 if (FLOAT_WORDS_BIG_ENDIAN)
3395 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3396 else
3397 word = bitpos / BITS_PER_WORD;
3398 bitpos = bitpos % BITS_PER_WORD;
3399 op1 = operand_subword_force (op1, word, mode);
3402 if (bitpos < HOST_BITS_PER_WIDE_INT)
3404 hi = 0;
3405 lo = (HOST_WIDE_INT) 1 << bitpos;
3407 else
3409 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3410 lo = 0;
3413 sign = gen_reg_rtx (imode);
3414 sign = expand_binop (imode, and_optab, op1,
3415 immed_double_const (lo, hi, imode),
3416 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3419 if (!op0_is_abs)
3421 op0 = expand_unop (mode, abs_optab, op0, target, 0);
3422 if (op0 == NULL)
3423 return NULL_RTX;
3424 target = op0;
3426 else
3428 if (target == NULL_RTX)
3429 target = copy_to_reg (op0);
3430 else
3431 emit_move_insn (target, op0);
3434 label = gen_label_rtx ();
3435 emit_cmp_and_jump_insns (sign, const0_rtx, EQ, NULL_RTX, imode, 1, label);
3437 if (GET_CODE (op0) == CONST_DOUBLE)
3438 op0 = simplify_unary_operation (NEG, mode, op0, mode);
3439 else
3440 op0 = expand_unop (mode, neg_optab, op0, target, 0);
3441 if (op0 != target)
3442 emit_move_insn (target, op0);
3444 emit_label (label);
3446 return target;
3450 /* A subroutine of expand_copysign, perform the entire copysign operation
3451 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3452 is true if op0 is known to have its sign bit clear. */
3454 static rtx
3455 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3456 int bitpos, bool op0_is_abs)
3458 enum machine_mode imode;
3459 HOST_WIDE_INT hi, lo;
3460 int word, nwords, i;
3461 rtx temp, insns;
3463 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3465 imode = int_mode_for_mode (mode);
3466 if (imode == BLKmode)
3467 return NULL_RTX;
3468 word = 0;
3469 nwords = 1;
3471 else
3473 imode = word_mode;
3475 if (FLOAT_WORDS_BIG_ENDIAN)
3476 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3477 else
3478 word = bitpos / BITS_PER_WORD;
3479 bitpos = bitpos % BITS_PER_WORD;
3480 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3483 if (bitpos < HOST_BITS_PER_WIDE_INT)
3485 hi = 0;
3486 lo = (HOST_WIDE_INT) 1 << bitpos;
3488 else
3490 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3491 lo = 0;
3494 if (target == 0 || target == op0 || target == op1)
3495 target = gen_reg_rtx (mode);
3497 if (nwords > 1)
3499 start_sequence ();
3501 for (i = 0; i < nwords; ++i)
3503 rtx targ_piece = operand_subword (target, i, 1, mode);
3504 rtx op0_piece = operand_subword_force (op0, i, mode);
3506 if (i == word)
3508 if (!op0_is_abs)
3509 op0_piece = expand_binop (imode, and_optab, op0_piece,
3510 immed_double_const (~lo, ~hi, imode),
3511 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3513 op1 = expand_binop (imode, and_optab,
3514 operand_subword_force (op1, i, mode),
3515 immed_double_const (lo, hi, imode),
3516 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3518 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3519 targ_piece, 1, OPTAB_LIB_WIDEN);
3520 if (temp != targ_piece)
3521 emit_move_insn (targ_piece, temp);
3523 else
3524 emit_move_insn (targ_piece, op0_piece);
3527 insns = get_insns ();
3528 end_sequence ();
3530 emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
3532 else
3534 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3535 immed_double_const (lo, hi, imode),
3536 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3538 op0 = gen_lowpart (imode, op0);
3539 if (!op0_is_abs)
3540 op0 = expand_binop (imode, and_optab, op0,
3541 immed_double_const (~lo, ~hi, imode),
3542 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3544 temp = expand_binop (imode, ior_optab, op0, op1,
3545 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3546 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3549 return target;
3552 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3553 scalar floating point mode. Return NULL if we do not know how to
3554 expand the operation inline. */
3557 expand_copysign (rtx op0, rtx op1, rtx target)
3559 enum machine_mode mode = GET_MODE (op0);
3560 const struct real_format *fmt;
3561 bool op0_is_abs;
3562 rtx temp;
3564 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3565 gcc_assert (GET_MODE (op1) == mode);
3567 /* First try to do it with a special instruction. */
3568 temp = expand_binop (mode, copysign_optab, op0, op1,
3569 target, 0, OPTAB_DIRECT);
3570 if (temp)
3571 return temp;
3573 fmt = REAL_MODE_FORMAT (mode);
3574 if (fmt == NULL || !fmt->has_signed_zero)
3575 return NULL_RTX;
3577 op0_is_abs = false;
3578 if (GET_CODE (op0) == CONST_DOUBLE)
3580 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3581 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3582 op0_is_abs = true;
3585 if (fmt->signbit_ro >= 0
3586 && (GET_CODE (op0) == CONST_DOUBLE
3587 || (optab_handler (neg_optab, mode)->insn_code != CODE_FOR_nothing
3588 && optab_handler (abs_optab, mode)->insn_code != CODE_FOR_nothing)))
3590 temp = expand_copysign_absneg (mode, op0, op1, target,
3591 fmt->signbit_ro, op0_is_abs);
3592 if (temp)
3593 return temp;
3596 if (fmt->signbit_rw < 0)
3597 return NULL_RTX;
3598 return expand_copysign_bit (mode, op0, op1, target,
3599 fmt->signbit_rw, op0_is_abs);
3602 /* Generate an instruction whose insn-code is INSN_CODE,
3603 with two operands: an output TARGET and an input OP0.
3604 TARGET *must* be nonzero, and the output is always stored there.
3605 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3606 the value that is stored into TARGET. */
3608 void
3609 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3611 rtx temp;
3612 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3613 rtx pat;
3615 temp = target;
3617 /* Now, if insn does not accept our operands, put them into pseudos. */
3619 if (!insn_data[icode].operand[1].predicate (op0, mode0))
3620 op0 = copy_to_mode_reg (mode0, op0);
3622 if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3623 temp = gen_reg_rtx (GET_MODE (temp));
3625 pat = GEN_FCN (icode) (temp, op0);
3627 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3628 add_equal_note (pat, temp, code, op0, NULL_RTX);
3630 emit_insn (pat);
3632 if (temp != target)
3633 emit_move_insn (target, temp);
3636 struct no_conflict_data
3638 rtx target, first, insn;
3639 bool must_stay;
3642 /* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3643 Set P->must_stay if the currently examined clobber / store has to stay
3644 in the list of insns that constitute the actual no_conflict block /
3645 libcall block. */
3646 static void
3647 no_conflict_move_test (rtx dest, const_rtx set, void *p0)
3649 struct no_conflict_data *p= p0;
3651 /* If this inns directly contributes to setting the target, it must stay. */
3652 if (reg_overlap_mentioned_p (p->target, dest))
3653 p->must_stay = true;
3654 /* If we haven't committed to keeping any other insns in the list yet,
3655 there is nothing more to check. */
3656 else if (p->insn == p->first)
3657 return;
3658 /* If this insn sets / clobbers a register that feeds one of the insns
3659 already in the list, this insn has to stay too. */
3660 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3661 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3662 || reg_used_between_p (dest, p->first, p->insn)
3663 /* Likewise if this insn depends on a register set by a previous
3664 insn in the list, or if it sets a result (presumably a hard
3665 register) that is set or clobbered by a previous insn.
3666 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3667 SET_DEST perform the former check on the address, and the latter
3668 check on the MEM. */
3669 || (GET_CODE (set) == SET
3670 && (modified_in_p (SET_SRC (set), p->first)
3671 || modified_in_p (SET_DEST (set), p->first)
3672 || modified_between_p (SET_SRC (set), p->first, p->insn)
3673 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3674 p->must_stay = true;
3677 /* Encapsulate the block starting at FIRST and ending with LAST, which is
3678 logically equivalent to EQUIV, so it gets manipulated as a unit if it
3679 is possible to do so. */
3681 void
3682 maybe_encapsulate_block (rtx first, rtx last, rtx equiv)
3684 if (!flag_non_call_exceptions || !may_trap_p (equiv))
3686 /* We can't attach the REG_LIBCALL and REG_RETVAL notes when the
3687 encapsulated region would not be in one basic block, i.e. when
3688 there is a control_flow_insn_p insn between FIRST and LAST. */
3689 bool attach_libcall_retval_notes = true;
3690 rtx insn, next = NEXT_INSN (last);
3692 for (insn = first; insn != next; insn = NEXT_INSN (insn))
3693 if (control_flow_insn_p (insn))
3695 attach_libcall_retval_notes = false;
3696 break;
3699 if (attach_libcall_retval_notes)
3701 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3702 REG_NOTES (first));
3703 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3704 REG_NOTES (last));
3705 next = NEXT_INSN (last);
3706 for (insn = first; insn != next; insn = NEXT_INSN (insn))
3707 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_LIBCALL_ID,
3708 GEN_INT (libcall_id),
3709 REG_NOTES (insn));
3710 libcall_id++;
3715 /* Emit code to perform a series of operations on a multi-word quantity, one
3716 word at a time.
3718 Such a block is preceded by a CLOBBER of the output, consists of multiple
3719 insns, each setting one word of the output, and followed by a SET copying
3720 the output to itself.
3722 Each of the insns setting words of the output receives a REG_NO_CONFLICT
3723 note indicating that it doesn't conflict with the (also multi-word)
3724 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3725 notes.
3727 INSNS is a block of code generated to perform the operation, not including
3728 the CLOBBER and final copy. All insns that compute intermediate values
3729 are first emitted, followed by the block as described above.
3731 TARGET, OP0, and OP1 are the output and inputs of the operations,
3732 respectively. OP1 may be zero for a unary operation.
3734 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3735 on the last insn.
3737 If TARGET is not a register, INSNS is simply emitted with no special
3738 processing. Likewise if anything in INSNS is not an INSN or if
3739 there is a libcall block inside INSNS.
3741 The final insn emitted is returned. */
3744 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3746 rtx prev, next, first, last, insn;
3748 if (!REG_P (target) || reload_in_progress)
3749 return emit_insn (insns);
3750 else
3751 for (insn = insns; insn; insn = NEXT_INSN (insn))
3752 if (!NONJUMP_INSN_P (insn)
3753 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3754 return emit_insn (insns);
3756 /* First emit all insns that do not store into words of the output and remove
3757 these from the list. */
3758 for (insn = insns; insn; insn = next)
3760 rtx note;
3761 struct no_conflict_data data;
3763 next = NEXT_INSN (insn);
3765 /* Some ports (cris) create a libcall regions at their own. We must
3766 avoid any potential nesting of LIBCALLs. */
3767 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3768 remove_note (insn, note);
3769 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3770 remove_note (insn, note);
3771 if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL)) != NULL)
3772 remove_note (insn, note);
3774 data.target = target;
3775 data.first = insns;
3776 data.insn = insn;
3777 data.must_stay = 0;
3778 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3779 if (! data.must_stay)
3781 if (PREV_INSN (insn))
3782 NEXT_INSN (PREV_INSN (insn)) = next;
3783 else
3784 insns = next;
3786 if (next)
3787 PREV_INSN (next) = PREV_INSN (insn);
3789 add_insn (insn);
3793 prev = get_last_insn ();
3795 /* Now write the CLOBBER of the output, followed by the setting of each
3796 of the words, followed by the final copy. */
3797 if (target != op0 && target != op1)
3798 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3800 for (insn = insns; insn; insn = next)
3802 next = NEXT_INSN (insn);
3803 add_insn (insn);
3805 if (op1 && REG_P (op1))
3806 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3807 REG_NOTES (insn));
3809 if (op0 && REG_P (op0))
3810 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3811 REG_NOTES (insn));
3814 if (optab_handler (mov_optab, GET_MODE (target))->insn_code
3815 != CODE_FOR_nothing)
3817 last = emit_move_insn (target, target);
3818 if (equiv)
3819 set_unique_reg_note (last, REG_EQUAL, equiv);
3821 else
3823 last = get_last_insn ();
3825 /* Remove any existing REG_EQUAL note from "last", or else it will
3826 be mistaken for a note referring to the full contents of the
3827 alleged libcall value when found together with the REG_RETVAL
3828 note added below. An existing note can come from an insn
3829 expansion at "last". */
3830 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3833 if (prev == 0)
3834 first = get_insns ();
3835 else
3836 first = NEXT_INSN (prev);
3838 maybe_encapsulate_block (first, last, equiv);
3840 return last;
3843 /* Emit code to make a call to a constant function or a library call.
3845 INSNS is a list containing all insns emitted in the call.
3846 These insns leave the result in RESULT. Our block is to copy RESULT
3847 to TARGET, which is logically equivalent to EQUIV.
3849 We first emit any insns that set a pseudo on the assumption that these are
3850 loading constants into registers; doing so allows them to be safely cse'ed
3851 between blocks. Then we emit all the other insns in the block, followed by
3852 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3853 note with an operand of EQUIV.
3855 Moving assignments to pseudos outside of the block is done to improve
3856 the generated code, but is not required to generate correct code,
3857 hence being unable to move an assignment is not grounds for not making
3858 a libcall block. There are two reasons why it is safe to leave these
3859 insns inside the block: First, we know that these pseudos cannot be
3860 used in generated RTL outside the block since they are created for
3861 temporary purposes within the block. Second, CSE will not record the
3862 values of anything set inside a libcall block, so we know they must
3863 be dead at the end of the block.
3865 Except for the first group of insns (the ones setting pseudos), the
3866 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3867 void
3868 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3870 rtx final_dest = target;
3871 rtx prev, next, first, last, insn;
3873 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3874 into a MEM later. Protect the libcall block from this change. */
3875 if (! REG_P (target) || REG_USERVAR_P (target))
3876 target = gen_reg_rtx (GET_MODE (target));
3878 /* If we're using non-call exceptions, a libcall corresponding to an
3879 operation that may trap may also trap. */
3880 if (flag_non_call_exceptions && may_trap_p (equiv))
3882 for (insn = insns; insn; insn = NEXT_INSN (insn))
3883 if (CALL_P (insn))
3885 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3887 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3888 remove_note (insn, note);
3891 else
3892 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3893 reg note to indicate that this call cannot throw or execute a nonlocal
3894 goto (unless there is already a REG_EH_REGION note, in which case
3895 we update it). */
3896 for (insn = insns; insn; insn = NEXT_INSN (insn))
3897 if (CALL_P (insn))
3899 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3901 if (note != 0)
3902 XEXP (note, 0) = constm1_rtx;
3903 else
3904 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3905 REG_NOTES (insn));
3908 /* First emit all insns that set pseudos. Remove them from the list as
3909 we go. Avoid insns that set pseudos which were referenced in previous
3910 insns. These can be generated by move_by_pieces, for example,
3911 to update an address. Similarly, avoid insns that reference things
3912 set in previous insns. */
3914 for (insn = insns; insn; insn = next)
3916 rtx set = single_set (insn);
3917 rtx note;
3919 /* Some ports (cris) create a libcall regions at their own. We must
3920 avoid any potential nesting of LIBCALLs. */
3921 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3922 remove_note (insn, note);
3923 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3924 remove_note (insn, note);
3925 if ((note = find_reg_note (insn, REG_LIBCALL_ID, NULL)) != NULL)
3926 remove_note (insn, note);
3928 next = NEXT_INSN (insn);
3930 if (set != 0 && REG_P (SET_DEST (set))
3931 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3933 struct no_conflict_data data;
3935 data.target = const0_rtx;
3936 data.first = insns;
3937 data.insn = insn;
3938 data.must_stay = 0;
3939 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3940 if (! data.must_stay)
3942 if (PREV_INSN (insn))
3943 NEXT_INSN (PREV_INSN (insn)) = next;
3944 else
3945 insns = next;
3947 if (next)
3948 PREV_INSN (next) = PREV_INSN (insn);
3950 add_insn (insn);
3954 /* Some ports use a loop to copy large arguments onto the stack.
3955 Don't move anything outside such a loop. */
3956 if (LABEL_P (insn))
3957 break;
3960 prev = get_last_insn ();
3962 /* Write the remaining insns followed by the final copy. */
3964 for (insn = insns; insn; insn = next)
3966 next = NEXT_INSN (insn);
3968 add_insn (insn);
3971 last = emit_move_insn (target, result);
3972 if (optab_handler (mov_optab, GET_MODE (target))->insn_code
3973 != CODE_FOR_nothing)
3974 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3975 else
3977 /* Remove any existing REG_EQUAL note from "last", or else it will
3978 be mistaken for a note referring to the full contents of the
3979 libcall value when found together with the REG_RETVAL note added
3980 below. An existing note can come from an insn expansion at
3981 "last". */
3982 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3985 if (final_dest != target)
3986 emit_move_insn (final_dest, target);
3988 if (prev == 0)
3989 first = get_insns ();
3990 else
3991 first = NEXT_INSN (prev);
3993 maybe_encapsulate_block (first, last, equiv);
3996 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3997 PURPOSE describes how this comparison will be used. CODE is the rtx
3998 comparison code we will be using.
4000 ??? Actually, CODE is slightly weaker than that. A target is still
4001 required to implement all of the normal bcc operations, but not
4002 required to implement all (or any) of the unordered bcc operations. */
4005 can_compare_p (enum rtx_code code, enum machine_mode mode,
4006 enum can_compare_purpose purpose)
4010 if (optab_handler (cmp_optab, mode)->insn_code != CODE_FOR_nothing)
4012 if (purpose == ccp_jump)
4013 return bcc_gen_fctn[(int) code] != NULL;
4014 else if (purpose == ccp_store_flag)
4015 return setcc_gen_code[(int) code] != CODE_FOR_nothing;
4016 else
4017 /* There's only one cmov entry point, and it's allowed to fail. */
4018 return 1;
4020 if (purpose == ccp_jump
4021 && optab_handler (cbranch_optab, mode)->insn_code != CODE_FOR_nothing)
4022 return 1;
4023 if (purpose == ccp_cmov
4024 && optab_handler (cmov_optab, mode)->insn_code != CODE_FOR_nothing)
4025 return 1;
4026 if (purpose == ccp_store_flag
4027 && optab_handler (cstore_optab, mode)->insn_code != CODE_FOR_nothing)
4028 return 1;
4029 mode = GET_MODE_WIDER_MODE (mode);
4031 while (mode != VOIDmode);
4033 return 0;
4036 /* This function is called when we are going to emit a compare instruction that
4037 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
4039 *PMODE is the mode of the inputs (in case they are const_int).
4040 *PUNSIGNEDP nonzero says that the operands are unsigned;
4041 this matters if they need to be widened.
4043 If they have mode BLKmode, then SIZE specifies the size of both operands.
4045 This function performs all the setup necessary so that the caller only has
4046 to emit a single comparison insn. This setup can involve doing a BLKmode
4047 comparison or emitting a library call to perform the comparison if no insn
4048 is available to handle it.
4049 The values which are passed in through pointers can be modified; the caller
4050 should perform the comparison on the modified values. Constant
4051 comparisons must have already been folded. */
4053 static void
4054 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
4055 enum machine_mode *pmode, int *punsignedp,
4056 enum can_compare_purpose purpose)
4058 enum machine_mode mode = *pmode;
4059 rtx x = *px, y = *py;
4060 int unsignedp = *punsignedp;
4062 /* If we are inside an appropriately-short loop and we are optimizing,
4063 force expensive constants into a register. */
4064 if (CONSTANT_P (x) && optimize
4065 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
4066 x = force_reg (mode, x);
4068 if (CONSTANT_P (y) && optimize
4069 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
4070 y = force_reg (mode, y);
4072 #ifdef HAVE_cc0
4073 /* Make sure if we have a canonical comparison. The RTL
4074 documentation states that canonical comparisons are required only
4075 for targets which have cc0. */
4076 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
4077 #endif
4079 /* Don't let both operands fail to indicate the mode. */
4080 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
4081 x = force_reg (mode, x);
4083 /* Handle all BLKmode compares. */
4085 if (mode == BLKmode)
4087 enum machine_mode cmp_mode, result_mode;
4088 enum insn_code cmp_code;
4089 tree length_type;
4090 rtx libfunc;
4091 rtx result;
4092 rtx opalign
4093 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
4095 gcc_assert (size);
4097 /* Try to use a memory block compare insn - either cmpstr
4098 or cmpmem will do. */
4099 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
4100 cmp_mode != VOIDmode;
4101 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
4103 cmp_code = cmpmem_optab[cmp_mode];
4104 if (cmp_code == CODE_FOR_nothing)
4105 cmp_code = cmpstr_optab[cmp_mode];
4106 if (cmp_code == CODE_FOR_nothing)
4107 cmp_code = cmpstrn_optab[cmp_mode];
4108 if (cmp_code == CODE_FOR_nothing)
4109 continue;
4111 /* Must make sure the size fits the insn's mode. */
4112 if ((GET_CODE (size) == CONST_INT
4113 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
4114 || (GET_MODE_BITSIZE (GET_MODE (size))
4115 > GET_MODE_BITSIZE (cmp_mode)))
4116 continue;
4118 result_mode = insn_data[cmp_code].operand[0].mode;
4119 result = gen_reg_rtx (result_mode);
4120 size = convert_to_mode (cmp_mode, size, 1);
4121 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
4123 *px = result;
4124 *py = const0_rtx;
4125 *pmode = result_mode;
4126 return;
4129 /* Otherwise call a library function, memcmp. */
4130 libfunc = memcmp_libfunc;
4131 length_type = sizetype;
4132 result_mode = TYPE_MODE (integer_type_node);
4133 cmp_mode = TYPE_MODE (length_type);
4134 size = convert_to_mode (TYPE_MODE (length_type), size,
4135 TYPE_UNSIGNED (length_type));
4137 result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
4138 result_mode, 3,
4139 XEXP (x, 0), Pmode,
4140 XEXP (y, 0), Pmode,
4141 size, cmp_mode);
4142 *px = result;
4143 *py = const0_rtx;
4144 *pmode = result_mode;
4145 return;
4148 /* Don't allow operands to the compare to trap, as that can put the
4149 compare and branch in different basic blocks. */
4150 if (flag_non_call_exceptions)
4152 if (may_trap_p (x))
4153 x = force_reg (mode, x);
4154 if (may_trap_p (y))
4155 y = force_reg (mode, y);
4158 *px = x;
4159 *py = y;
4160 if (can_compare_p (*pcomparison, mode, purpose))
4161 return;
4163 /* Handle a lib call just for the mode we are using. */
4165 if (optab_handler (cmp_optab, mode)->libfunc && !SCALAR_FLOAT_MODE_P (mode))
4167 rtx libfunc = optab_handler (cmp_optab, mode)->libfunc;
4168 rtx result;
4170 /* If we want unsigned, and this mode has a distinct unsigned
4171 comparison routine, use that. */
4172 if (unsignedp && optab_handler (ucmp_optab, mode)->libfunc)
4173 libfunc = optab_handler (ucmp_optab, mode)->libfunc;
4175 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
4176 targetm.libgcc_cmp_return_mode (),
4177 2, x, mode, y, mode);
4179 /* There are two kinds of comparison routines. Biased routines
4180 return 0/1/2, and unbiased routines return -1/0/1. Other parts
4181 of gcc expect that the comparison operation is equivalent
4182 to the modified comparison. For signed comparisons compare the
4183 result against 1 in the biased case, and zero in the unbiased
4184 case. For unsigned comparisons always compare against 1 after
4185 biasing the unbiased result by adding 1. This gives us a way to
4186 represent LTU. */
4187 *px = result;
4188 *pmode = word_mode;
4189 *py = const1_rtx;
4191 if (!TARGET_LIB_INT_CMP_BIASED)
4193 if (*punsignedp)
4194 *px = plus_constant (result, 1);
4195 else
4196 *py = const0_rtx;
4198 return;
4201 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
4202 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
4205 /* Before emitting an insn with code ICODE, make sure that X, which is going
4206 to be used for operand OPNUM of the insn, is converted from mode MODE to
4207 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
4208 that it is accepted by the operand predicate. Return the new value. */
4210 static rtx
4211 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
4212 enum machine_mode wider_mode, int unsignedp)
4214 if (mode != wider_mode)
4215 x = convert_modes (wider_mode, mode, x, unsignedp);
4217 if (!insn_data[icode].operand[opnum].predicate
4218 (x, insn_data[icode].operand[opnum].mode))
4220 if (reload_completed)
4221 return NULL_RTX;
4222 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
4225 return x;
4228 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
4229 we can do the comparison.
4230 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
4231 be NULL_RTX which indicates that only a comparison is to be generated. */
4233 static void
4234 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
4235 enum rtx_code comparison, int unsignedp, rtx label)
4237 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
4238 enum mode_class class = GET_MODE_CLASS (mode);
4239 enum machine_mode wider_mode = mode;
4241 /* Try combined insns first. */
4244 enum insn_code icode;
4245 PUT_MODE (test, wider_mode);
4247 if (label)
4249 icode = optab_handler (cbranch_optab, wider_mode)->insn_code;
4251 if (icode != CODE_FOR_nothing
4252 && insn_data[icode].operand[0].predicate (test, wider_mode))
4254 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
4255 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
4256 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
4257 return;
4261 /* Handle some compares against zero. */
4262 icode = (int) optab_handler (tst_optab, wider_mode)->insn_code;
4263 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
4265 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4266 emit_insn (GEN_FCN (icode) (x));
4267 if (label)
4268 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4269 return;
4272 /* Handle compares for which there is a directly suitable insn. */
4274 icode = (int) optab_handler (cmp_optab, wider_mode)->insn_code;
4275 if (icode != CODE_FOR_nothing)
4277 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
4278 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
4279 emit_insn (GEN_FCN (icode) (x, y));
4280 if (label)
4281 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
4282 return;
4285 if (!CLASS_HAS_WIDER_MODES_P (class))
4286 break;
4288 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
4290 while (wider_mode != VOIDmode);
4292 gcc_unreachable ();
4295 /* Generate code to compare X with Y so that the condition codes are
4296 set and to jump to LABEL if the condition is true. If X is a
4297 constant and Y is not a constant, then the comparison is swapped to
4298 ensure that the comparison RTL has the canonical form.
4300 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
4301 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
4302 the proper branch condition code.
4304 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
4306 MODE is the mode of the inputs (in case they are const_int).
4308 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
4309 be passed unchanged to emit_cmp_insn, then potentially converted into an
4310 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
4312 void
4313 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
4314 enum machine_mode mode, int unsignedp, rtx label)
4316 rtx op0 = x, op1 = y;
4318 /* Swap operands and condition to ensure canonical RTL. */
4319 if (swap_commutative_operands_p (x, y))
4321 /* If we're not emitting a branch, callers are required to pass
4322 operands in an order conforming to canonical RTL. We relax this
4323 for commutative comparisons so callers using EQ don't need to do
4324 swapping by hand. */
4325 gcc_assert (label || (comparison == swap_condition (comparison)));
4327 op0 = y, op1 = x;
4328 comparison = swap_condition (comparison);
4331 #ifdef HAVE_cc0
4332 /* If OP0 is still a constant, then both X and Y must be constants.
4333 Force X into a register to create canonical RTL. */
4334 if (CONSTANT_P (op0))
4335 op0 = force_reg (mode, op0);
4336 #endif
4338 if (unsignedp)
4339 comparison = unsigned_condition (comparison);
4341 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
4342 ccp_jump);
4343 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
4346 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
4348 void
4349 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
4350 enum machine_mode mode, int unsignedp)
4352 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
4355 /* Emit a library call comparison between floating point X and Y.
4356 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
4358 static void
4359 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
4360 enum machine_mode *pmode, int *punsignedp)
4362 enum rtx_code comparison = *pcomparison;
4363 enum rtx_code swapped = swap_condition (comparison);
4364 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
4365 rtx x = *px;
4366 rtx y = *py;
4367 enum machine_mode orig_mode = GET_MODE (x);
4368 enum machine_mode mode, cmp_mode;
4369 rtx value, target, insns, equiv;
4370 rtx libfunc = 0;
4371 bool reversed_p = false;
4372 cmp_mode = targetm.libgcc_cmp_return_mode ();
4374 for (mode = orig_mode;
4375 mode != VOIDmode;
4376 mode = GET_MODE_WIDER_MODE (mode))
4378 if ((libfunc = optab_handler (code_to_optab[comparison], mode)->libfunc))
4379 break;
4381 if ((libfunc = optab_handler (code_to_optab[swapped], mode)->libfunc))
4383 rtx tmp;
4384 tmp = x; x = y; y = tmp;
4385 comparison = swapped;
4386 break;
4389 if ((libfunc = optab_handler (code_to_optab[reversed], mode)->libfunc)
4390 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
4392 comparison = reversed;
4393 reversed_p = true;
4394 break;
4398 gcc_assert (mode != VOIDmode);
4400 if (mode != orig_mode)
4402 x = convert_to_mode (mode, x, 0);
4403 y = convert_to_mode (mode, y, 0);
4406 /* Attach a REG_EQUAL note describing the semantics of the libcall to
4407 the RTL. The allows the RTL optimizers to delete the libcall if the
4408 condition can be determined at compile-time. */
4409 if (comparison == UNORDERED)
4411 rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
4412 equiv = simplify_gen_relational (NE, cmp_mode, mode, y, y);
4413 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4414 temp, const_true_rtx, equiv);
4416 else
4418 equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
4419 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4421 rtx true_rtx, false_rtx;
4423 switch (comparison)
4425 case EQ:
4426 true_rtx = const0_rtx;
4427 false_rtx = const_true_rtx;
4428 break;
4430 case NE:
4431 true_rtx = const_true_rtx;
4432 false_rtx = const0_rtx;
4433 break;
4435 case GT:
4436 true_rtx = const1_rtx;
4437 false_rtx = const0_rtx;
4438 break;
4440 case GE:
4441 true_rtx = const0_rtx;
4442 false_rtx = constm1_rtx;
4443 break;
4445 case LT:
4446 true_rtx = constm1_rtx;
4447 false_rtx = const0_rtx;
4448 break;
4450 case LE:
4451 true_rtx = const0_rtx;
4452 false_rtx = const1_rtx;
4453 break;
4455 default:
4456 gcc_unreachable ();
4458 equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
4459 equiv, true_rtx, false_rtx);
4463 start_sequence ();
4464 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4465 cmp_mode, 2, x, mode, y, mode);
4466 insns = get_insns ();
4467 end_sequence ();
4469 target = gen_reg_rtx (cmp_mode);
4470 emit_libcall_block (insns, target, value, equiv);
4472 if (comparison == UNORDERED
4473 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4474 comparison = reversed_p ? EQ : NE;
4476 *px = target;
4477 *py = const0_rtx;
4478 *pmode = cmp_mode;
4479 *pcomparison = comparison;
4480 *punsignedp = 0;
4483 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4485 void
4486 emit_indirect_jump (rtx loc)
4488 if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4489 (loc, Pmode))
4490 loc = copy_to_mode_reg (Pmode, loc);
4492 emit_jump_insn (gen_indirect_jump (loc));
4493 emit_barrier ();
4496 #ifdef HAVE_conditional_move
4498 /* Emit a conditional move instruction if the machine supports one for that
4499 condition and machine mode.
4501 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4502 the mode to use should they be constants. If it is VOIDmode, they cannot
4503 both be constants.
4505 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4506 should be stored there. MODE is the mode to use should they be constants.
4507 If it is VOIDmode, they cannot both be constants.
4509 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4510 is not supported. */
4513 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4514 enum machine_mode cmode, rtx op2, rtx op3,
4515 enum machine_mode mode, int unsignedp)
4517 rtx tem, subtarget, comparison, insn;
4518 enum insn_code icode;
4519 enum rtx_code reversed;
4521 /* If one operand is constant, make it the second one. Only do this
4522 if the other operand is not constant as well. */
4524 if (swap_commutative_operands_p (op0, op1))
4526 tem = op0;
4527 op0 = op1;
4528 op1 = tem;
4529 code = swap_condition (code);
4532 /* get_condition will prefer to generate LT and GT even if the old
4533 comparison was against zero, so undo that canonicalization here since
4534 comparisons against zero are cheaper. */
4535 if (code == LT && op1 == const1_rtx)
4536 code = LE, op1 = const0_rtx;
4537 else if (code == GT && op1 == constm1_rtx)
4538 code = GE, op1 = const0_rtx;
4540 if (cmode == VOIDmode)
4541 cmode = GET_MODE (op0);
4543 if (swap_commutative_operands_p (op2, op3)
4544 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4545 != UNKNOWN))
4547 tem = op2;
4548 op2 = op3;
4549 op3 = tem;
4550 code = reversed;
4553 if (mode == VOIDmode)
4554 mode = GET_MODE (op2);
4556 icode = movcc_gen_code[mode];
4558 if (icode == CODE_FOR_nothing)
4559 return 0;
4561 if (!target)
4562 target = gen_reg_rtx (mode);
4564 subtarget = target;
4566 /* If the insn doesn't accept these operands, put them in pseudos. */
4568 if (!insn_data[icode].operand[0].predicate
4569 (subtarget, insn_data[icode].operand[0].mode))
4570 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4572 if (!insn_data[icode].operand[2].predicate
4573 (op2, insn_data[icode].operand[2].mode))
4574 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4576 if (!insn_data[icode].operand[3].predicate
4577 (op3, insn_data[icode].operand[3].mode))
4578 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4580 /* Everything should now be in the suitable form, so emit the compare insn
4581 and then the conditional move. */
4583 comparison
4584 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4586 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4587 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4588 return NULL and let the caller figure out how best to deal with this
4589 situation. */
4590 if (GET_CODE (comparison) != code)
4591 return NULL_RTX;
4593 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4595 /* If that failed, then give up. */
4596 if (insn == 0)
4597 return 0;
4599 emit_insn (insn);
4601 if (subtarget != target)
4602 convert_move (target, subtarget, 0);
4604 return target;
4607 /* Return nonzero if a conditional move of mode MODE is supported.
4609 This function is for combine so it can tell whether an insn that looks
4610 like a conditional move is actually supported by the hardware. If we
4611 guess wrong we lose a bit on optimization, but that's it. */
4612 /* ??? sparc64 supports conditionally moving integers values based on fp
4613 comparisons, and vice versa. How do we handle them? */
4616 can_conditionally_move_p (enum machine_mode mode)
4618 if (movcc_gen_code[mode] != CODE_FOR_nothing)
4619 return 1;
4621 return 0;
4624 #endif /* HAVE_conditional_move */
4626 /* Emit a conditional addition instruction if the machine supports one for that
4627 condition and machine mode.
4629 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4630 the mode to use should they be constants. If it is VOIDmode, they cannot
4631 both be constants.
4633 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4634 should be stored there. MODE is the mode to use should they be constants.
4635 If it is VOIDmode, they cannot both be constants.
4637 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4638 is not supported. */
4641 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4642 enum machine_mode cmode, rtx op2, rtx op3,
4643 enum machine_mode mode, int unsignedp)
4645 rtx tem, subtarget, comparison, insn;
4646 enum insn_code icode;
4647 enum rtx_code reversed;
4649 /* If one operand is constant, make it the second one. Only do this
4650 if the other operand is not constant as well. */
4652 if (swap_commutative_operands_p (op0, op1))
4654 tem = op0;
4655 op0 = op1;
4656 op1 = tem;
4657 code = swap_condition (code);
4660 /* get_condition will prefer to generate LT and GT even if the old
4661 comparison was against zero, so undo that canonicalization here since
4662 comparisons against zero are cheaper. */
4663 if (code == LT && op1 == const1_rtx)
4664 code = LE, op1 = const0_rtx;
4665 else if (code == GT && op1 == constm1_rtx)
4666 code = GE, op1 = const0_rtx;
4668 if (cmode == VOIDmode)
4669 cmode = GET_MODE (op0);
4671 if (swap_commutative_operands_p (op2, op3)
4672 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4673 != UNKNOWN))
4675 tem = op2;
4676 op2 = op3;
4677 op3 = tem;
4678 code = reversed;
4681 if (mode == VOIDmode)
4682 mode = GET_MODE (op2);
4684 icode = optab_handler (addcc_optab, mode)->insn_code;
4686 if (icode == CODE_FOR_nothing)
4687 return 0;
4689 if (!target)
4690 target = gen_reg_rtx (mode);
4692 /* If the insn doesn't accept these operands, put them in pseudos. */
4694 if (!insn_data[icode].operand[0].predicate
4695 (target, insn_data[icode].operand[0].mode))
4696 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4697 else
4698 subtarget = target;
4700 if (!insn_data[icode].operand[2].predicate
4701 (op2, insn_data[icode].operand[2].mode))
4702 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4704 if (!insn_data[icode].operand[3].predicate
4705 (op3, insn_data[icode].operand[3].mode))
4706 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4708 /* Everything should now be in the suitable form, so emit the compare insn
4709 and then the conditional move. */
4711 comparison
4712 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4714 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4715 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4716 return NULL and let the caller figure out how best to deal with this
4717 situation. */
4718 if (GET_CODE (comparison) != code)
4719 return NULL_RTX;
4721 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4723 /* If that failed, then give up. */
4724 if (insn == 0)
4725 return 0;
4727 emit_insn (insn);
4729 if (subtarget != target)
4730 convert_move (target, subtarget, 0);
4732 return target;
4735 /* These functions attempt to generate an insn body, rather than
4736 emitting the insn, but if the gen function already emits them, we
4737 make no attempt to turn them back into naked patterns. */
4739 /* Generate and return an insn body to add Y to X. */
4742 gen_add2_insn (rtx x, rtx y)
4744 int icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4746 gcc_assert (insn_data[icode].operand[0].predicate
4747 (x, insn_data[icode].operand[0].mode));
4748 gcc_assert (insn_data[icode].operand[1].predicate
4749 (x, insn_data[icode].operand[1].mode));
4750 gcc_assert (insn_data[icode].operand[2].predicate
4751 (y, insn_data[icode].operand[2].mode));
4753 return GEN_FCN (icode) (x, x, y);
4756 /* Generate and return an insn body to add r1 and c,
4757 storing the result in r0. */
4759 gen_add3_insn (rtx r0, rtx r1, rtx c)
4761 int icode = (int) optab_handler (add_optab, GET_MODE (r0))->insn_code;
4763 if (icode == CODE_FOR_nothing
4764 || !(insn_data[icode].operand[0].predicate
4765 (r0, insn_data[icode].operand[0].mode))
4766 || !(insn_data[icode].operand[1].predicate
4767 (r1, insn_data[icode].operand[1].mode))
4768 || !(insn_data[icode].operand[2].predicate
4769 (c, insn_data[icode].operand[2].mode)))
4770 return NULL_RTX;
4772 return GEN_FCN (icode) (r0, r1, c);
4776 have_add2_insn (rtx x, rtx y)
4778 int icode;
4780 gcc_assert (GET_MODE (x) != VOIDmode);
4782 icode = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
4784 if (icode == CODE_FOR_nothing)
4785 return 0;
4787 if (!(insn_data[icode].operand[0].predicate
4788 (x, insn_data[icode].operand[0].mode))
4789 || !(insn_data[icode].operand[1].predicate
4790 (x, insn_data[icode].operand[1].mode))
4791 || !(insn_data[icode].operand[2].predicate
4792 (y, insn_data[icode].operand[2].mode)))
4793 return 0;
4795 return 1;
4798 /* Generate and return an insn body to subtract Y from X. */
4801 gen_sub2_insn (rtx x, rtx y)
4803 int icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4805 gcc_assert (insn_data[icode].operand[0].predicate
4806 (x, insn_data[icode].operand[0].mode));
4807 gcc_assert (insn_data[icode].operand[1].predicate
4808 (x, insn_data[icode].operand[1].mode));
4809 gcc_assert (insn_data[icode].operand[2].predicate
4810 (y, insn_data[icode].operand[2].mode));
4812 return GEN_FCN (icode) (x, x, y);
4815 /* Generate and return an insn body to subtract r1 and c,
4816 storing the result in r0. */
4818 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4820 int icode = (int) optab_handler (sub_optab, GET_MODE (r0))->insn_code;
4822 if (icode == CODE_FOR_nothing
4823 || !(insn_data[icode].operand[0].predicate
4824 (r0, insn_data[icode].operand[0].mode))
4825 || !(insn_data[icode].operand[1].predicate
4826 (r1, insn_data[icode].operand[1].mode))
4827 || !(insn_data[icode].operand[2].predicate
4828 (c, insn_data[icode].operand[2].mode)))
4829 return NULL_RTX;
4831 return GEN_FCN (icode) (r0, r1, c);
4835 have_sub2_insn (rtx x, rtx y)
4837 int icode;
4839 gcc_assert (GET_MODE (x) != VOIDmode);
4841 icode = (int) optab_handler (sub_optab, GET_MODE (x))->insn_code;
4843 if (icode == CODE_FOR_nothing)
4844 return 0;
4846 if (!(insn_data[icode].operand[0].predicate
4847 (x, insn_data[icode].operand[0].mode))
4848 || !(insn_data[icode].operand[1].predicate
4849 (x, insn_data[icode].operand[1].mode))
4850 || !(insn_data[icode].operand[2].predicate
4851 (y, insn_data[icode].operand[2].mode)))
4852 return 0;
4854 return 1;
4857 /* Generate the body of an instruction to copy Y into X.
4858 It may be a list of insns, if one insn isn't enough. */
4861 gen_move_insn (rtx x, rtx y)
4863 rtx seq;
4865 start_sequence ();
4866 emit_move_insn_1 (x, y);
4867 seq = get_insns ();
4868 end_sequence ();
4869 return seq;
4872 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4873 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4874 no such operation exists, CODE_FOR_nothing will be returned. */
4876 enum insn_code
4877 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4878 int unsignedp)
4880 convert_optab tab;
4881 #ifdef HAVE_ptr_extend
4882 if (unsignedp < 0)
4883 return CODE_FOR_ptr_extend;
4884 #endif
4886 tab = unsignedp ? zext_optab : sext_optab;
4887 return convert_optab_handler (tab, to_mode, from_mode)->insn_code;
4890 /* Generate the body of an insn to extend Y (with mode MFROM)
4891 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4894 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4895 enum machine_mode mfrom, int unsignedp)
4897 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4898 return GEN_FCN (icode) (x, y);
4901 /* can_fix_p and can_float_p say whether the target machine
4902 can directly convert a given fixed point type to
4903 a given floating point type, or vice versa.
4904 The returned value is the CODE_FOR_... value to use,
4905 or CODE_FOR_nothing if these modes cannot be directly converted.
4907 *TRUNCP_PTR is set to 1 if it is necessary to output
4908 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4910 static enum insn_code
4911 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4912 int unsignedp, int *truncp_ptr)
4914 convert_optab tab;
4915 enum insn_code icode;
4917 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4918 icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
4919 if (icode != CODE_FOR_nothing)
4921 *truncp_ptr = 0;
4922 return icode;
4925 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4926 for this to work. We need to rework the fix* and ftrunc* patterns
4927 and documentation. */
4928 tab = unsignedp ? ufix_optab : sfix_optab;
4929 icode = convert_optab_handler (tab, fixmode, fltmode)->insn_code;
4930 if (icode != CODE_FOR_nothing
4931 && optab_handler (ftrunc_optab, fltmode)->insn_code != CODE_FOR_nothing)
4933 *truncp_ptr = 1;
4934 return icode;
4937 *truncp_ptr = 0;
4938 return CODE_FOR_nothing;
4941 static enum insn_code
4942 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4943 int unsignedp)
4945 convert_optab tab;
4947 tab = unsignedp ? ufloat_optab : sfloat_optab;
4948 return convert_optab_handler (tab, fltmode, fixmode)->insn_code;
4951 /* Generate code to convert FROM to floating point
4952 and store in TO. FROM must be fixed point and not VOIDmode.
4953 UNSIGNEDP nonzero means regard FROM as unsigned.
4954 Normally this is done by correcting the final value
4955 if it is negative. */
4957 void
4958 expand_float (rtx to, rtx from, int unsignedp)
4960 enum insn_code icode;
4961 rtx target = to;
4962 enum machine_mode fmode, imode;
4963 bool can_do_signed = false;
4965 /* Crash now, because we won't be able to decide which mode to use. */
4966 gcc_assert (GET_MODE (from) != VOIDmode);
4968 /* Look for an insn to do the conversion. Do it in the specified
4969 modes if possible; otherwise convert either input, output or both to
4970 wider mode. If the integer mode is wider than the mode of FROM,
4971 we can do the conversion signed even if the input is unsigned. */
4973 for (fmode = GET_MODE (to); fmode != VOIDmode;
4974 fmode = GET_MODE_WIDER_MODE (fmode))
4975 for (imode = GET_MODE (from); imode != VOIDmode;
4976 imode = GET_MODE_WIDER_MODE (imode))
4978 int doing_unsigned = unsignedp;
4980 if (fmode != GET_MODE (to)
4981 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4982 continue;
4984 icode = can_float_p (fmode, imode, unsignedp);
4985 if (icode == CODE_FOR_nothing && unsignedp)
4987 enum insn_code scode = can_float_p (fmode, imode, 0);
4988 if (scode != CODE_FOR_nothing)
4989 can_do_signed = true;
4990 if (imode != GET_MODE (from))
4991 icode = scode, doing_unsigned = 0;
4994 if (icode != CODE_FOR_nothing)
4996 if (imode != GET_MODE (from))
4997 from = convert_to_mode (imode, from, unsignedp);
4999 if (fmode != GET_MODE (to))
5000 target = gen_reg_rtx (fmode);
5002 emit_unop_insn (icode, target, from,
5003 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
5005 if (target != to)
5006 convert_move (to, target, 0);
5007 return;
5011 /* Unsigned integer, and no way to convert directly. For binary
5012 floating point modes, convert as signed, then conditionally adjust
5013 the result. */
5014 if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
5016 rtx label = gen_label_rtx ();
5017 rtx temp;
5018 REAL_VALUE_TYPE offset;
5020 /* Look for a usable floating mode FMODE wider than the source and at
5021 least as wide as the target. Using FMODE will avoid rounding woes
5022 with unsigned values greater than the signed maximum value. */
5024 for (fmode = GET_MODE (to); fmode != VOIDmode;
5025 fmode = GET_MODE_WIDER_MODE (fmode))
5026 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
5027 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
5028 break;
5030 if (fmode == VOIDmode)
5032 /* There is no such mode. Pretend the target is wide enough. */
5033 fmode = GET_MODE (to);
5035 /* Avoid double-rounding when TO is narrower than FROM. */
5036 if ((significand_size (fmode) + 1)
5037 < GET_MODE_BITSIZE (GET_MODE (from)))
5039 rtx temp1;
5040 rtx neglabel = gen_label_rtx ();
5042 /* Don't use TARGET if it isn't a register, is a hard register,
5043 or is the wrong mode. */
5044 if (!REG_P (target)
5045 || REGNO (target) < FIRST_PSEUDO_REGISTER
5046 || GET_MODE (target) != fmode)
5047 target = gen_reg_rtx (fmode);
5049 imode = GET_MODE (from);
5050 do_pending_stack_adjust ();
5052 /* Test whether the sign bit is set. */
5053 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
5054 0, neglabel);
5056 /* The sign bit is not set. Convert as signed. */
5057 expand_float (target, from, 0);
5058 emit_jump_insn (gen_jump (label));
5059 emit_barrier ();
5061 /* The sign bit is set.
5062 Convert to a usable (positive signed) value by shifting right
5063 one bit, while remembering if a nonzero bit was shifted
5064 out; i.e., compute (from & 1) | (from >> 1). */
5066 emit_label (neglabel);
5067 temp = expand_binop (imode, and_optab, from, const1_rtx,
5068 NULL_RTX, 1, OPTAB_LIB_WIDEN);
5069 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
5070 NULL_RTX, 1);
5071 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
5072 OPTAB_LIB_WIDEN);
5073 expand_float (target, temp, 0);
5075 /* Multiply by 2 to undo the shift above. */
5076 temp = expand_binop (fmode, add_optab, target, target,
5077 target, 0, OPTAB_LIB_WIDEN);
5078 if (temp != target)
5079 emit_move_insn (target, temp);
5081 do_pending_stack_adjust ();
5082 emit_label (label);
5083 goto done;
5087 /* If we are about to do some arithmetic to correct for an
5088 unsigned operand, do it in a pseudo-register. */
5090 if (GET_MODE (to) != fmode
5091 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
5092 target = gen_reg_rtx (fmode);
5094 /* Convert as signed integer to floating. */
5095 expand_float (target, from, 0);
5097 /* If FROM is negative (and therefore TO is negative),
5098 correct its value by 2**bitwidth. */
5100 do_pending_stack_adjust ();
5101 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
5102 0, label);
5105 real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
5106 temp = expand_binop (fmode, add_optab, target,
5107 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
5108 target, 0, OPTAB_LIB_WIDEN);
5109 if (temp != target)
5110 emit_move_insn (target, temp);
5112 do_pending_stack_adjust ();
5113 emit_label (label);
5114 goto done;
5117 /* No hardware instruction available; call a library routine. */
5119 rtx libfunc;
5120 rtx insns;
5121 rtx value;
5122 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
5124 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
5125 from = convert_to_mode (SImode, from, unsignedp);
5127 libfunc = convert_optab_handler (tab, GET_MODE (to),
5128 GET_MODE (from))->libfunc;
5129 gcc_assert (libfunc);
5131 start_sequence ();
5133 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5134 GET_MODE (to), 1, from,
5135 GET_MODE (from));
5136 insns = get_insns ();
5137 end_sequence ();
5139 emit_libcall_block (insns, target, value,
5140 gen_rtx_FLOAT (GET_MODE (to), from));
5143 done:
5145 /* Copy result to requested destination
5146 if we have been computing in a temp location. */
5148 if (target != to)
5150 if (GET_MODE (target) == GET_MODE (to))
5151 emit_move_insn (to, target);
5152 else
5153 convert_move (to, target, 0);
5157 /* Generate code to convert FROM to fixed point and store in TO. FROM
5158 must be floating point. */
5160 void
5161 expand_fix (rtx to, rtx from, int unsignedp)
5163 enum insn_code icode;
5164 rtx target = to;
5165 enum machine_mode fmode, imode;
5166 int must_trunc = 0;
5168 /* We first try to find a pair of modes, one real and one integer, at
5169 least as wide as FROM and TO, respectively, in which we can open-code
5170 this conversion. If the integer mode is wider than the mode of TO,
5171 we can do the conversion either signed or unsigned. */
5173 for (fmode = GET_MODE (from); fmode != VOIDmode;
5174 fmode = GET_MODE_WIDER_MODE (fmode))
5175 for (imode = GET_MODE (to); imode != VOIDmode;
5176 imode = GET_MODE_WIDER_MODE (imode))
5178 int doing_unsigned = unsignedp;
5180 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
5181 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
5182 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
5184 if (icode != CODE_FOR_nothing)
5186 if (fmode != GET_MODE (from))
5187 from = convert_to_mode (fmode, from, 0);
5189 if (must_trunc)
5191 rtx temp = gen_reg_rtx (GET_MODE (from));
5192 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
5193 temp, 0);
5196 if (imode != GET_MODE (to))
5197 target = gen_reg_rtx (imode);
5199 emit_unop_insn (icode, target, from,
5200 doing_unsigned ? UNSIGNED_FIX : FIX);
5201 if (target != to)
5202 convert_move (to, target, unsignedp);
5203 return;
5207 /* For an unsigned conversion, there is one more way to do it.
5208 If we have a signed conversion, we generate code that compares
5209 the real value to the largest representable positive number. If if
5210 is smaller, the conversion is done normally. Otherwise, subtract
5211 one plus the highest signed number, convert, and add it back.
5213 We only need to check all real modes, since we know we didn't find
5214 anything with a wider integer mode.
5216 This code used to extend FP value into mode wider than the destination.
5217 This is not needed. Consider, for instance conversion from SFmode
5218 into DImode.
5220 The hot path through the code is dealing with inputs smaller than 2^63
5221 and doing just the conversion, so there is no bits to lose.
5223 In the other path we know the value is positive in the range 2^63..2^64-1
5224 inclusive. (as for other imput overflow happens and result is undefined)
5225 So we know that the most important bit set in mantissa corresponds to
5226 2^63. The subtraction of 2^63 should not generate any rounding as it
5227 simply clears out that bit. The rest is trivial. */
5229 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
5230 for (fmode = GET_MODE (from); fmode != VOIDmode;
5231 fmode = GET_MODE_WIDER_MODE (fmode))
5232 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
5233 &must_trunc))
5235 int bitsize;
5236 REAL_VALUE_TYPE offset;
5237 rtx limit, lab1, lab2, insn;
5239 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
5240 real_2expN (&offset, bitsize - 1);
5241 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
5242 lab1 = gen_label_rtx ();
5243 lab2 = gen_label_rtx ();
5245 if (fmode != GET_MODE (from))
5246 from = convert_to_mode (fmode, from, 0);
5248 /* See if we need to do the subtraction. */
5249 do_pending_stack_adjust ();
5250 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
5251 0, lab1);
5253 /* If not, do the signed "fix" and branch around fixup code. */
5254 expand_fix (to, from, 0);
5255 emit_jump_insn (gen_jump (lab2));
5256 emit_barrier ();
5258 /* Otherwise, subtract 2**(N-1), convert to signed number,
5259 then add 2**(N-1). Do the addition using XOR since this
5260 will often generate better code. */
5261 emit_label (lab1);
5262 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
5263 NULL_RTX, 0, OPTAB_LIB_WIDEN);
5264 expand_fix (to, target, 0);
5265 target = expand_binop (GET_MODE (to), xor_optab, to,
5266 gen_int_mode
5267 ((HOST_WIDE_INT) 1 << (bitsize - 1),
5268 GET_MODE (to)),
5269 to, 1, OPTAB_LIB_WIDEN);
5271 if (target != to)
5272 emit_move_insn (to, target);
5274 emit_label (lab2);
5276 if (optab_handler (mov_optab, GET_MODE (to))->insn_code
5277 != CODE_FOR_nothing)
5279 /* Make a place for a REG_NOTE and add it. */
5280 insn = emit_move_insn (to, to);
5281 set_unique_reg_note (insn,
5282 REG_EQUAL,
5283 gen_rtx_fmt_e (UNSIGNED_FIX,
5284 GET_MODE (to),
5285 copy_rtx (from)));
5288 return;
5291 /* We can't do it with an insn, so use a library call. But first ensure
5292 that the mode of TO is at least as wide as SImode, since those are the
5293 only library calls we know about. */
5295 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
5297 target = gen_reg_rtx (SImode);
5299 expand_fix (target, from, unsignedp);
5301 else
5303 rtx insns;
5304 rtx value;
5305 rtx libfunc;
5307 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
5308 libfunc = convert_optab_handler (tab, GET_MODE (to),
5309 GET_MODE (from))->libfunc;
5310 gcc_assert (libfunc);
5312 start_sequence ();
5314 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
5315 GET_MODE (to), 1, from,
5316 GET_MODE (from));
5317 insns = get_insns ();
5318 end_sequence ();
5320 emit_libcall_block (insns, target, value,
5321 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
5322 GET_MODE (to), from));
5325 if (target != to)
5327 if (GET_MODE (to) == GET_MODE (target))
5328 emit_move_insn (to, target);
5329 else
5330 convert_move (to, target, 0);
5334 /* Generate code to convert FROM to fixed point and store in TO. FROM
5335 must be floating point, TO must be signed. Use the conversion optab
5336 TAB to do the conversion. */
5338 bool
5339 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
5341 enum insn_code icode;
5342 rtx target = to;
5343 enum machine_mode fmode, imode;
5345 /* We first try to find a pair of modes, one real and one integer, at
5346 least as wide as FROM and TO, respectively, in which we can open-code
5347 this conversion. If the integer mode is wider than the mode of TO,
5348 we can do the conversion either signed or unsigned. */
5350 for (fmode = GET_MODE (from); fmode != VOIDmode;
5351 fmode = GET_MODE_WIDER_MODE (fmode))
5352 for (imode = GET_MODE (to); imode != VOIDmode;
5353 imode = GET_MODE_WIDER_MODE (imode))
5355 icode = convert_optab_handler (tab, imode, fmode)->insn_code;
5356 if (icode != CODE_FOR_nothing)
5358 if (fmode != GET_MODE (from))
5359 from = convert_to_mode (fmode, from, 0);
5361 if (imode != GET_MODE (to))
5362 target = gen_reg_rtx (imode);
5364 emit_unop_insn (icode, target, from, UNKNOWN);
5365 if (target != to)
5366 convert_move (to, target, 0);
5367 return true;
5371 return false;
5374 /* Report whether we have an instruction to perform the operation
5375 specified by CODE on operands of mode MODE. */
5377 have_insn_for (enum rtx_code code, enum machine_mode mode)
5379 return (code_to_optab[(int) code] != 0
5380 && (optab_handler (code_to_optab[(int) code], mode)->insn_code
5381 != CODE_FOR_nothing));
5384 /* Create a blank optab. */
5385 static optab
5386 new_optab (void)
5388 int i;
5389 optab op = ggc_alloc (sizeof (struct optab));
5390 for (i = 0; i < NUM_MACHINE_MODES; i++)
5392 optab_handler (op, i)->insn_code = CODE_FOR_nothing;
5393 optab_handler (op, i)->libfunc = 0;
5396 return op;
5399 static convert_optab
5400 new_convert_optab (void)
5402 int i, j;
5403 convert_optab op = ggc_alloc (sizeof (struct convert_optab));
5404 for (i = 0; i < NUM_MACHINE_MODES; i++)
5405 for (j = 0; j < NUM_MACHINE_MODES; j++)
5407 convert_optab_handler (op, i, j)->insn_code = CODE_FOR_nothing;
5408 convert_optab_handler (op, i, j)->libfunc = 0;
5410 return op;
5413 /* Same, but fill in its code as CODE, and write it into the
5414 code_to_optab table. */
5415 static inline optab
5416 init_optab (enum rtx_code code)
5418 optab op = new_optab ();
5419 op->code = code;
5420 code_to_optab[(int) code] = op;
5421 return op;
5424 /* Same, but fill in its code as CODE, and do _not_ write it into
5425 the code_to_optab table. */
5426 static inline optab
5427 init_optabv (enum rtx_code code)
5429 optab op = new_optab ();
5430 op->code = code;
5431 return op;
5434 /* Conversion optabs never go in the code_to_optab table. */
5435 static inline convert_optab
5436 init_convert_optab (enum rtx_code code)
5438 convert_optab op = new_convert_optab ();
5439 op->code = code;
5440 return op;
5443 /* Initialize the libfunc fields of an entire group of entries in some
5444 optab. Each entry is set equal to a string consisting of a leading
5445 pair of underscores followed by a generic operation name followed by
5446 a mode name (downshifted to lowercase) followed by a single character
5447 representing the number of operands for the given operation (which is
5448 usually one of the characters '2', '3', or '4').
5450 OPTABLE is the table in which libfunc fields are to be initialized.
5451 FIRST_MODE is the first machine mode index in the given optab to
5452 initialize.
5453 LAST_MODE is the last machine mode index in the given optab to
5454 initialize.
5455 OPNAME is the generic (string) name of the operation.
5456 SUFFIX is the character which specifies the number of operands for
5457 the given generic operation.
5460 static void
5461 init_libfuncs (optab optable, int first_mode, int last_mode,
5462 const char *opname, int suffix)
5464 int mode;
5465 unsigned opname_len = strlen (opname);
5467 for (mode = first_mode; (int) mode <= (int) last_mode;
5468 mode = (enum machine_mode) ((int) mode + 1))
5470 const char *mname = GET_MODE_NAME (mode);
5471 unsigned mname_len = strlen (mname);
5472 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5473 char *p;
5474 const char *q;
5476 p = libfunc_name;
5477 *p++ = '_';
5478 *p++ = '_';
5479 for (q = opname; *q; )
5480 *p++ = *q++;
5481 for (q = mname; *q; q++)
5482 *p++ = TOLOWER (*q);
5483 *p++ = suffix;
5484 *p = '\0';
5486 optab_handler (optable, mode)->libfunc
5487 = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
5491 /* Initialize the libfunc fields of an entire group of entries in some
5492 optab which correspond to all integer mode operations. The parameters
5493 have the same meaning as similarly named ones for the `init_libfuncs'
5494 routine. (See above). */
5496 static void
5497 init_integral_libfuncs (optab optable, const char *opname, int suffix)
5499 int maxsize = 2*BITS_PER_WORD;
5500 if (maxsize < LONG_LONG_TYPE_SIZE)
5501 maxsize = LONG_LONG_TYPE_SIZE;
5502 init_libfuncs (optable, word_mode,
5503 mode_for_size (maxsize, MODE_INT, 0),
5504 opname, suffix);
5507 /* Initialize the libfunc fields of an entire group of entries in some
5508 optab which correspond to all real mode operations. The parameters
5509 have the same meaning as similarly named ones for the `init_libfuncs'
5510 routine. (See above). */
5512 static void
5513 init_floating_libfuncs (optab optable, const char *opname, int suffix)
5515 char *dec_opname = alloca (sizeof (DECIMAL_PREFIX) + strlen (opname));
5517 /* For BID support, change the name to have either a bid_ or dpd_ prefix
5518 depending on the low level floating format used. */
5519 memcpy (dec_opname, DECIMAL_PREFIX, sizeof (DECIMAL_PREFIX) - 1);
5520 strcpy (dec_opname + sizeof (DECIMAL_PREFIX) - 1, opname);
5522 init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
5523 init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
5524 dec_opname, suffix);
5527 /* Initialize the libfunc fields of an entire group of entries of an
5528 inter-mode-class conversion optab. The string formation rules are
5529 similar to the ones for init_libfuncs, above, but instead of having
5530 a mode name and an operand count these functions have two mode names
5531 and no operand count. */
5532 static void
5533 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
5534 enum mode_class from_class,
5535 enum mode_class to_class)
5537 enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5538 enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5539 size_t opname_len = strlen (opname);
5540 size_t max_mname_len = 0;
5542 enum machine_mode fmode, tmode;
5543 const char *fname, *tname;
5544 const char *q;
5545 char *libfunc_name, *suffix;
5546 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5547 char *p;
5549 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5550 depends on which underlying decimal floating point format is used. */
5551 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5553 for (fmode = first_from_mode;
5554 fmode != VOIDmode;
5555 fmode = GET_MODE_WIDER_MODE (fmode))
5556 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5558 for (tmode = first_to_mode;
5559 tmode != VOIDmode;
5560 tmode = GET_MODE_WIDER_MODE (tmode))
5561 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5563 nondec_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5564 nondec_name[0] = '_';
5565 nondec_name[1] = '_';
5566 memcpy (&nondec_name[2], opname, opname_len);
5567 nondec_suffix = nondec_name + opname_len + 2;
5569 dec_name = alloca (2 + dec_len + opname_len + 2*max_mname_len + 1 + 1);
5570 dec_name[0] = '_';
5571 dec_name[1] = '_';
5572 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5573 memcpy (&dec_name[2+dec_len], opname, opname_len);
5574 dec_suffix = dec_name + dec_len + opname_len + 2;
5576 for (fmode = first_from_mode; fmode != VOIDmode;
5577 fmode = GET_MODE_WIDER_MODE (fmode))
5578 for (tmode = first_to_mode; tmode != VOIDmode;
5579 tmode = GET_MODE_WIDER_MODE (tmode))
5581 fname = GET_MODE_NAME (fmode);
5582 tname = GET_MODE_NAME (tmode);
5584 if (DECIMAL_FLOAT_MODE_P(fmode) || DECIMAL_FLOAT_MODE_P(tmode))
5586 libfunc_name = dec_name;
5587 suffix = dec_suffix;
5589 else
5591 libfunc_name = nondec_name;
5592 suffix = nondec_suffix;
5595 p = suffix;
5596 for (q = fname; *q; p++, q++)
5597 *p = TOLOWER (*q);
5598 for (q = tname; *q; p++, q++)
5599 *p = TOLOWER (*q);
5601 *p = '\0';
5603 convert_optab_handler (tab, tmode, fmode)->libfunc
5604 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5605 p - libfunc_name));
5609 /* Initialize the libfunc fields of an entire group of entries of an
5610 intra-mode-class conversion optab. The string formation rules are
5611 similar to the ones for init_libfunc, above. WIDENING says whether
5612 the optab goes from narrow to wide modes or vice versa. These functions
5613 have two mode names _and_ an operand count. */
5614 static void
5615 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
5616 enum mode_class class, bool widening)
5618 enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5619 size_t opname_len = strlen (opname);
5620 size_t max_mname_len = 0;
5622 enum machine_mode nmode, wmode;
5623 const char *nname, *wname;
5624 const char *q;
5625 char *nondec_name, *dec_name, *nondec_suffix, *dec_suffix;
5626 char *libfunc_name, *suffix;
5627 char *p;
5629 /* If this is a decimal conversion, add the current BID vs. DPD prefix that
5630 depends on which underlying decimal floating point format is used. */
5631 const size_t dec_len = sizeof (DECIMAL_PREFIX) - 1;
5633 for (nmode = first_mode; nmode != VOIDmode;
5634 nmode = GET_MODE_WIDER_MODE (nmode))
5635 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5637 nondec_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5638 nondec_name[0] = '_';
5639 nondec_name[1] = '_';
5640 memcpy (&nondec_name[2], opname, opname_len);
5641 nondec_suffix = nondec_name + opname_len + 2;
5643 dec_name = alloca (2 + dec_len + opname_len + 2*max_mname_len + 1 + 1);
5644 dec_name[0] = '_';
5645 dec_name[1] = '_';
5646 memcpy (&dec_name[2], DECIMAL_PREFIX, dec_len);
5647 memcpy (&dec_name[2 + dec_len], opname, opname_len);
5648 dec_suffix = dec_name + dec_len + opname_len + 2;
5650 for (nmode = first_mode; nmode != VOIDmode;
5651 nmode = GET_MODE_WIDER_MODE (nmode))
5652 for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5653 wmode = GET_MODE_WIDER_MODE (wmode))
5655 nname = GET_MODE_NAME (nmode);
5656 wname = GET_MODE_NAME (wmode);
5658 if (DECIMAL_FLOAT_MODE_P(nmode) || DECIMAL_FLOAT_MODE_P(wmode))
5660 libfunc_name = dec_name;
5661 suffix = dec_suffix;
5663 else
5665 libfunc_name = nondec_name;
5666 suffix = nondec_suffix;
5669 p = suffix;
5670 for (q = widening ? nname : wname; *q; p++, q++)
5671 *p = TOLOWER (*q);
5672 for (q = widening ? wname : nname; *q; p++, q++)
5673 *p = TOLOWER (*q);
5675 *p++ = '2';
5676 *p = '\0';
5678 convert_optab_handler(tab, widening ? wmode : nmode,
5679 widening ? nmode : wmode)->libfunc
5680 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5681 p - libfunc_name));
5687 init_one_libfunc (const char *name)
5689 rtx symbol;
5691 /* Create a FUNCTION_DECL that can be passed to
5692 targetm.encode_section_info. */
5693 /* ??? We don't have any type information except for this is
5694 a function. Pretend this is "int foo()". */
5695 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5696 build_function_type (integer_type_node, NULL_TREE));
5697 DECL_ARTIFICIAL (decl) = 1;
5698 DECL_EXTERNAL (decl) = 1;
5699 TREE_PUBLIC (decl) = 1;
5701 symbol = XEXP (DECL_RTL (decl), 0);
5703 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
5704 are the flags assigned by targetm.encode_section_info. */
5705 SET_SYMBOL_REF_DECL (symbol, 0);
5707 return symbol;
5710 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5711 MODE to NAME, which should be either 0 or a string constant. */
5712 void
5713 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5715 if (name)
5716 optab_handler (optable, mode)->libfunc = init_one_libfunc (name);
5717 else
5718 optab_handler (optable, mode)->libfunc = 0;
5721 /* Call this to reset the function entry for one conversion optab
5722 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5723 either 0 or a string constant. */
5724 void
5725 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5726 enum machine_mode fmode, const char *name)
5728 if (name)
5729 convert_optab_handler (optable, tmode, fmode)->libfunc
5730 = init_one_libfunc (name);
5731 else
5732 convert_optab_handler (optable, tmode, fmode)->libfunc = 0;
5735 /* Call this to initialize the contents of the optabs
5736 appropriately for the current target machine. */
5738 void
5739 init_optabs (void)
5741 unsigned int i;
5742 enum machine_mode int_mode;
5744 /* Start by initializing all tables to contain CODE_FOR_nothing. */
5746 for (i = 0; i < NUM_RTX_CODE; i++)
5747 setcc_gen_code[i] = CODE_FOR_nothing;
5749 #ifdef HAVE_conditional_move
5750 for (i = 0; i < NUM_MACHINE_MODES; i++)
5751 movcc_gen_code[i] = CODE_FOR_nothing;
5752 #endif
5754 for (i = 0; i < NUM_MACHINE_MODES; i++)
5756 vcond_gen_code[i] = CODE_FOR_nothing;
5757 vcondu_gen_code[i] = CODE_FOR_nothing;
5760 add_optab = init_optab (PLUS);
5761 addv_optab = init_optabv (PLUS);
5762 sub_optab = init_optab (MINUS);
5763 subv_optab = init_optabv (MINUS);
5764 smul_optab = init_optab (MULT);
5765 smulv_optab = init_optabv (MULT);
5766 smul_highpart_optab = init_optab (UNKNOWN);
5767 umul_highpart_optab = init_optab (UNKNOWN);
5768 smul_widen_optab = init_optab (UNKNOWN);
5769 umul_widen_optab = init_optab (UNKNOWN);
5770 usmul_widen_optab = init_optab (UNKNOWN);
5771 smadd_widen_optab = init_optab (UNKNOWN);
5772 umadd_widen_optab = init_optab (UNKNOWN);
5773 smsub_widen_optab = init_optab (UNKNOWN);
5774 umsub_widen_optab = init_optab (UNKNOWN);
5775 sdiv_optab = init_optab (DIV);
5776 sdivv_optab = init_optabv (DIV);
5777 sdivmod_optab = init_optab (UNKNOWN);
5778 udiv_optab = init_optab (UDIV);
5779 udivmod_optab = init_optab (UNKNOWN);
5780 smod_optab = init_optab (MOD);
5781 umod_optab = init_optab (UMOD);
5782 fmod_optab = init_optab (UNKNOWN);
5783 remainder_optab = init_optab (UNKNOWN);
5784 ftrunc_optab = init_optab (UNKNOWN);
5785 and_optab = init_optab (AND);
5786 ior_optab = init_optab (IOR);
5787 xor_optab = init_optab (XOR);
5788 ashl_optab = init_optab (ASHIFT);
5789 ashr_optab = init_optab (ASHIFTRT);
5790 lshr_optab = init_optab (LSHIFTRT);
5791 rotl_optab = init_optab (ROTATE);
5792 rotr_optab = init_optab (ROTATERT);
5793 smin_optab = init_optab (SMIN);
5794 smax_optab = init_optab (SMAX);
5795 umin_optab = init_optab (UMIN);
5796 umax_optab = init_optab (UMAX);
5797 pow_optab = init_optab (UNKNOWN);
5798 atan2_optab = init_optab (UNKNOWN);
5800 /* These three have codes assigned exclusively for the sake of
5801 have_insn_for. */
5802 mov_optab = init_optab (SET);
5803 movstrict_optab = init_optab (STRICT_LOW_PART);
5804 cmp_optab = init_optab (COMPARE);
5806 storent_optab = init_optab (UNKNOWN);
5808 ucmp_optab = init_optab (UNKNOWN);
5809 tst_optab = init_optab (UNKNOWN);
5811 eq_optab = init_optab (EQ);
5812 ne_optab = init_optab (NE);
5813 gt_optab = init_optab (GT);
5814 ge_optab = init_optab (GE);
5815 lt_optab = init_optab (LT);
5816 le_optab = init_optab (LE);
5817 unord_optab = init_optab (UNORDERED);
5819 neg_optab = init_optab (NEG);
5820 negv_optab = init_optabv (NEG);
5821 abs_optab = init_optab (ABS);
5822 absv_optab = init_optabv (ABS);
5823 addcc_optab = init_optab (UNKNOWN);
5824 one_cmpl_optab = init_optab (NOT);
5825 bswap_optab = init_optab (BSWAP);
5826 ffs_optab = init_optab (FFS);
5827 clz_optab = init_optab (CLZ);
5828 ctz_optab = init_optab (CTZ);
5829 popcount_optab = init_optab (POPCOUNT);
5830 parity_optab = init_optab (PARITY);
5831 sqrt_optab = init_optab (SQRT);
5832 floor_optab = init_optab (UNKNOWN);
5833 ceil_optab = init_optab (UNKNOWN);
5834 round_optab = init_optab (UNKNOWN);
5835 btrunc_optab = init_optab (UNKNOWN);
5836 nearbyint_optab = init_optab (UNKNOWN);
5837 rint_optab = init_optab (UNKNOWN);
5838 sincos_optab = init_optab (UNKNOWN);
5839 sin_optab = init_optab (UNKNOWN);
5840 asin_optab = init_optab (UNKNOWN);
5841 cos_optab = init_optab (UNKNOWN);
5842 acos_optab = init_optab (UNKNOWN);
5843 exp_optab = init_optab (UNKNOWN);
5844 exp10_optab = init_optab (UNKNOWN);
5845 exp2_optab = init_optab (UNKNOWN);
5846 expm1_optab = init_optab (UNKNOWN);
5847 ldexp_optab = init_optab (UNKNOWN);
5848 scalb_optab = init_optab (UNKNOWN);
5849 logb_optab = init_optab (UNKNOWN);
5850 ilogb_optab = init_optab (UNKNOWN);
5851 log_optab = init_optab (UNKNOWN);
5852 log10_optab = init_optab (UNKNOWN);
5853 log2_optab = init_optab (UNKNOWN);
5854 log1p_optab = init_optab (UNKNOWN);
5855 tan_optab = init_optab (UNKNOWN);
5856 atan_optab = init_optab (UNKNOWN);
5857 copysign_optab = init_optab (UNKNOWN);
5858 signbit_optab = init_optab (UNKNOWN);
5860 isinf_optab = init_optab (UNKNOWN);
5862 strlen_optab = init_optab (UNKNOWN);
5863 cbranch_optab = init_optab (UNKNOWN);
5864 cmov_optab = init_optab (UNKNOWN);
5865 cstore_optab = init_optab (UNKNOWN);
5866 push_optab = init_optab (UNKNOWN);
5868 reduc_smax_optab = init_optab (UNKNOWN);
5869 reduc_umax_optab = init_optab (UNKNOWN);
5870 reduc_smin_optab = init_optab (UNKNOWN);
5871 reduc_umin_optab = init_optab (UNKNOWN);
5872 reduc_splus_optab = init_optab (UNKNOWN);
5873 reduc_uplus_optab = init_optab (UNKNOWN);
5875 ssum_widen_optab = init_optab (UNKNOWN);
5876 usum_widen_optab = init_optab (UNKNOWN);
5877 sdot_prod_optab = init_optab (UNKNOWN);
5878 udot_prod_optab = init_optab (UNKNOWN);
5880 vec_extract_optab = init_optab (UNKNOWN);
5881 vec_extract_even_optab = init_optab (UNKNOWN);
5882 vec_extract_odd_optab = init_optab (UNKNOWN);
5883 vec_interleave_high_optab = init_optab (UNKNOWN);
5884 vec_interleave_low_optab = init_optab (UNKNOWN);
5885 vec_set_optab = init_optab (UNKNOWN);
5886 vec_init_optab = init_optab (UNKNOWN);
5887 vec_shl_optab = init_optab (UNKNOWN);
5888 vec_shr_optab = init_optab (UNKNOWN);
5889 vec_realign_load_optab = init_optab (UNKNOWN);
5890 movmisalign_optab = init_optab (UNKNOWN);
5891 vec_widen_umult_hi_optab = init_optab (UNKNOWN);
5892 vec_widen_umult_lo_optab = init_optab (UNKNOWN);
5893 vec_widen_smult_hi_optab = init_optab (UNKNOWN);
5894 vec_widen_smult_lo_optab = init_optab (UNKNOWN);
5895 vec_unpacks_hi_optab = init_optab (UNKNOWN);
5896 vec_unpacks_lo_optab = init_optab (UNKNOWN);
5897 vec_unpacku_hi_optab = init_optab (UNKNOWN);
5898 vec_unpacku_lo_optab = init_optab (UNKNOWN);
5899 vec_unpacks_float_hi_optab = init_optab (UNKNOWN);
5900 vec_unpacks_float_lo_optab = init_optab (UNKNOWN);
5901 vec_unpacku_float_hi_optab = init_optab (UNKNOWN);
5902 vec_unpacku_float_lo_optab = init_optab (UNKNOWN);
5903 vec_pack_trunc_optab = init_optab (UNKNOWN);
5904 vec_pack_usat_optab = init_optab (UNKNOWN);
5905 vec_pack_ssat_optab = init_optab (UNKNOWN);
5906 vec_pack_ufix_trunc_optab = init_optab (UNKNOWN);
5907 vec_pack_sfix_trunc_optab = init_optab (UNKNOWN);
5909 powi_optab = init_optab (UNKNOWN);
5911 /* Conversions. */
5912 sext_optab = init_convert_optab (SIGN_EXTEND);
5913 zext_optab = init_convert_optab (ZERO_EXTEND);
5914 trunc_optab = init_convert_optab (TRUNCATE);
5915 sfix_optab = init_convert_optab (FIX);
5916 ufix_optab = init_convert_optab (UNSIGNED_FIX);
5917 sfixtrunc_optab = init_convert_optab (UNKNOWN);
5918 ufixtrunc_optab = init_convert_optab (UNKNOWN);
5919 sfloat_optab = init_convert_optab (FLOAT);
5920 ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5921 lrint_optab = init_convert_optab (UNKNOWN);
5922 lround_optab = init_convert_optab (UNKNOWN);
5923 lfloor_optab = init_convert_optab (UNKNOWN);
5924 lceil_optab = init_convert_optab (UNKNOWN);
5926 for (i = 0; i < NUM_MACHINE_MODES; i++)
5928 movmem_optab[i] = CODE_FOR_nothing;
5929 cmpstr_optab[i] = CODE_FOR_nothing;
5930 cmpstrn_optab[i] = CODE_FOR_nothing;
5931 cmpmem_optab[i] = CODE_FOR_nothing;
5932 setmem_optab[i] = CODE_FOR_nothing;
5934 sync_add_optab[i] = CODE_FOR_nothing;
5935 sync_sub_optab[i] = CODE_FOR_nothing;
5936 sync_ior_optab[i] = CODE_FOR_nothing;
5937 sync_and_optab[i] = CODE_FOR_nothing;
5938 sync_xor_optab[i] = CODE_FOR_nothing;
5939 sync_nand_optab[i] = CODE_FOR_nothing;
5940 sync_old_add_optab[i] = CODE_FOR_nothing;
5941 sync_old_sub_optab[i] = CODE_FOR_nothing;
5942 sync_old_ior_optab[i] = CODE_FOR_nothing;
5943 sync_old_and_optab[i] = CODE_FOR_nothing;
5944 sync_old_xor_optab[i] = CODE_FOR_nothing;
5945 sync_old_nand_optab[i] = CODE_FOR_nothing;
5946 sync_new_add_optab[i] = CODE_FOR_nothing;
5947 sync_new_sub_optab[i] = CODE_FOR_nothing;
5948 sync_new_ior_optab[i] = CODE_FOR_nothing;
5949 sync_new_and_optab[i] = CODE_FOR_nothing;
5950 sync_new_xor_optab[i] = CODE_FOR_nothing;
5951 sync_new_nand_optab[i] = CODE_FOR_nothing;
5952 sync_compare_and_swap[i] = CODE_FOR_nothing;
5953 sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5954 sync_lock_test_and_set[i] = CODE_FOR_nothing;
5955 sync_lock_release[i] = CODE_FOR_nothing;
5957 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5960 /* Fill in the optabs with the insns we support. */
5961 init_all_optabs ();
5963 /* The ffs function operates on `int'. Fall back on it if we do not
5964 have a libgcc2 function for that width. */
5965 int_mode = mode_for_size (INT_TYPE_SIZE, MODE_INT, 0);
5966 optab_handler (ffs_optab, int_mode)->libfunc = init_one_libfunc ("ffs");
5968 /* Initialize the optabs with the names of the library functions. */
5969 init_integral_libfuncs (add_optab, "add", '3');
5970 init_floating_libfuncs (add_optab, "add", '3');
5971 init_integral_libfuncs (addv_optab, "addv", '3');
5972 init_floating_libfuncs (addv_optab, "add", '3');
5973 init_integral_libfuncs (sub_optab, "sub", '3');
5974 init_floating_libfuncs (sub_optab, "sub", '3');
5975 init_integral_libfuncs (subv_optab, "subv", '3');
5976 init_floating_libfuncs (subv_optab, "sub", '3');
5977 init_integral_libfuncs (smul_optab, "mul", '3');
5978 init_floating_libfuncs (smul_optab, "mul", '3');
5979 init_integral_libfuncs (smulv_optab, "mulv", '3');
5980 init_floating_libfuncs (smulv_optab, "mul", '3');
5981 init_integral_libfuncs (sdiv_optab, "div", '3');
5982 init_floating_libfuncs (sdiv_optab, "div", '3');
5983 init_integral_libfuncs (sdivv_optab, "divv", '3');
5984 init_integral_libfuncs (udiv_optab, "udiv", '3');
5985 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5986 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5987 init_integral_libfuncs (smod_optab, "mod", '3');
5988 init_integral_libfuncs (umod_optab, "umod", '3');
5989 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5990 init_integral_libfuncs (and_optab, "and", '3');
5991 init_integral_libfuncs (ior_optab, "ior", '3');
5992 init_integral_libfuncs (xor_optab, "xor", '3');
5993 init_integral_libfuncs (ashl_optab, "ashl", '3');
5994 init_integral_libfuncs (ashr_optab, "ashr", '3');
5995 init_integral_libfuncs (lshr_optab, "lshr", '3');
5996 init_integral_libfuncs (smin_optab, "min", '3');
5997 init_floating_libfuncs (smin_optab, "min", '3');
5998 init_integral_libfuncs (smax_optab, "max", '3');
5999 init_floating_libfuncs (smax_optab, "max", '3');
6000 init_integral_libfuncs (umin_optab, "umin", '3');
6001 init_integral_libfuncs (umax_optab, "umax", '3');
6002 init_integral_libfuncs (neg_optab, "neg", '2');
6003 init_floating_libfuncs (neg_optab, "neg", '2');
6004 init_integral_libfuncs (negv_optab, "negv", '2');
6005 init_floating_libfuncs (negv_optab, "neg", '2');
6006 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
6007 init_integral_libfuncs (ffs_optab, "ffs", '2');
6008 init_integral_libfuncs (clz_optab, "clz", '2');
6009 init_integral_libfuncs (ctz_optab, "ctz", '2');
6010 init_integral_libfuncs (popcount_optab, "popcount", '2');
6011 init_integral_libfuncs (parity_optab, "parity", '2');
6013 /* Comparison libcalls for integers MUST come in pairs,
6014 signed/unsigned. */
6015 init_integral_libfuncs (cmp_optab, "cmp", '2');
6016 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
6017 init_floating_libfuncs (cmp_optab, "cmp", '2');
6019 /* EQ etc are floating point only. */
6020 init_floating_libfuncs (eq_optab, "eq", '2');
6021 init_floating_libfuncs (ne_optab, "ne", '2');
6022 init_floating_libfuncs (gt_optab, "gt", '2');
6023 init_floating_libfuncs (ge_optab, "ge", '2');
6024 init_floating_libfuncs (lt_optab, "lt", '2');
6025 init_floating_libfuncs (le_optab, "le", '2');
6026 init_floating_libfuncs (unord_optab, "unord", '2');
6028 init_floating_libfuncs (powi_optab, "powi", '2');
6030 /* Conversions. */
6031 init_interclass_conv_libfuncs (sfloat_optab, "float",
6032 MODE_INT, MODE_FLOAT);
6033 init_interclass_conv_libfuncs (sfloat_optab, "float",
6034 MODE_INT, MODE_DECIMAL_FLOAT);
6035 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
6036 MODE_INT, MODE_FLOAT);
6037 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
6038 MODE_INT, MODE_DECIMAL_FLOAT);
6039 init_interclass_conv_libfuncs (sfix_optab, "fix",
6040 MODE_FLOAT, MODE_INT);
6041 init_interclass_conv_libfuncs (sfix_optab, "fix",
6042 MODE_DECIMAL_FLOAT, MODE_INT);
6043 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
6044 MODE_FLOAT, MODE_INT);
6045 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
6046 MODE_DECIMAL_FLOAT, MODE_INT);
6047 init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
6048 MODE_INT, MODE_DECIMAL_FLOAT);
6049 init_interclass_conv_libfuncs (lrint_optab, "lrint",
6050 MODE_INT, MODE_FLOAT);
6051 init_interclass_conv_libfuncs (lround_optab, "lround",
6052 MODE_INT, MODE_FLOAT);
6053 init_interclass_conv_libfuncs (lfloor_optab, "lfloor",
6054 MODE_INT, MODE_FLOAT);
6055 init_interclass_conv_libfuncs (lceil_optab, "lceil",
6056 MODE_INT, MODE_FLOAT);
6058 /* sext_optab is also used for FLOAT_EXTEND. */
6059 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
6060 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
6061 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
6062 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
6063 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
6064 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
6065 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
6066 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
6068 /* Explicitly initialize the bswap libfuncs since we need them to be
6069 valid for things other than word_mode. */
6070 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
6071 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
6073 /* Use cabs for double complex abs, since systems generally have cabs.
6074 Don't define any libcall for float complex, so that cabs will be used. */
6075 if (complex_double_type_node)
6076 optab_handler (abs_optab, TYPE_MODE (complex_double_type_node))->libfunc
6077 = init_one_libfunc ("cabs");
6079 abort_libfunc = init_one_libfunc ("abort");
6080 memcpy_libfunc = init_one_libfunc ("memcpy");
6081 memmove_libfunc = init_one_libfunc ("memmove");
6082 memcmp_libfunc = init_one_libfunc ("memcmp");
6083 memset_libfunc = init_one_libfunc ("memset");
6084 setbits_libfunc = init_one_libfunc ("__setbits");
6086 #ifndef DONT_USE_BUILTIN_SETJMP
6087 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
6088 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
6089 #else
6090 setjmp_libfunc = init_one_libfunc ("setjmp");
6091 longjmp_libfunc = init_one_libfunc ("longjmp");
6092 #endif
6093 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
6094 unwind_sjlj_unregister_libfunc
6095 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6097 /* For function entry/exit instrumentation. */
6098 profile_function_entry_libfunc
6099 = init_one_libfunc ("__cyg_profile_func_enter");
6100 profile_function_exit_libfunc
6101 = init_one_libfunc ("__cyg_profile_func_exit");
6103 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
6105 if (HAVE_conditional_trap)
6106 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
6108 /* Allow the target to add more libcalls or rename some, etc. */
6109 targetm.init_libfuncs ();
6112 #ifdef DEBUG
6114 /* Print information about the current contents of the optabs on
6115 STDERR. */
6117 static void
6118 debug_optab_libfuncs (void)
6120 int i;
6121 int j;
6122 int k;
6124 /* Dump the arithmetic optabs. */
6125 for (i = 0; i != (int) OTI_MAX; i++)
6126 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6128 optab o;
6129 struct optab_handlers *h;
6131 o = optab_table[i];
6132 h = optab_handler (o, j);
6133 if (h->libfunc)
6135 gcc_assert (GET_CODE (h->libfunc) == SYMBOL_REF);
6136 fprintf (stderr, "%s\t%s:\t%s\n",
6137 GET_RTX_NAME (o->code),
6138 GET_MODE_NAME (j),
6139 XSTR (h->libfunc, 0));
6143 /* Dump the conversion optabs. */
6144 for (i = 0; i < (int) COI_MAX; ++i)
6145 for (j = 0; j < NUM_MACHINE_MODES; ++j)
6146 for (k = 0; k < NUM_MACHINE_MODES; ++k)
6148 convert_optab o;
6149 struct optab_handlers *h;
6151 o = &convert_optab_table[i];
6152 h = convert_optab_handler(o, j, k);
6153 if (h->libfunc)
6155 gcc_assert (GET_CODE (h->libfunc) == SYMBOL_REF);
6156 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
6157 GET_RTX_NAME (o->code),
6158 GET_MODE_NAME (j),
6159 GET_MODE_NAME (k),
6160 XSTR (h->libfunc, 0));
6165 #endif /* DEBUG */
6168 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
6169 CODE. Return 0 on failure. */
6172 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
6173 rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
6175 enum machine_mode mode = GET_MODE (op1);
6176 enum insn_code icode;
6177 rtx insn;
6179 if (!HAVE_conditional_trap)
6180 return 0;
6182 if (mode == VOIDmode)
6183 return 0;
6185 icode = optab_handler (cmp_optab, mode)->insn_code;
6186 if (icode == CODE_FOR_nothing)
6187 return 0;
6189 start_sequence ();
6190 op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
6191 op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
6192 if (!op1 || !op2)
6194 end_sequence ();
6195 return 0;
6197 emit_insn (GEN_FCN (icode) (op1, op2));
6199 PUT_CODE (trap_rtx, code);
6200 gcc_assert (HAVE_conditional_trap);
6201 insn = gen_conditional_trap (trap_rtx, tcode);
6202 if (insn)
6204 emit_insn (insn);
6205 insn = get_insns ();
6207 end_sequence ();
6209 return insn;
6212 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
6213 or unsigned operation code. */
6215 static enum rtx_code
6216 get_rtx_code (enum tree_code tcode, bool unsignedp)
6218 enum rtx_code code;
6219 switch (tcode)
6221 case EQ_EXPR:
6222 code = EQ;
6223 break;
6224 case NE_EXPR:
6225 code = NE;
6226 break;
6227 case LT_EXPR:
6228 code = unsignedp ? LTU : LT;
6229 break;
6230 case LE_EXPR:
6231 code = unsignedp ? LEU : LE;
6232 break;
6233 case GT_EXPR:
6234 code = unsignedp ? GTU : GT;
6235 break;
6236 case GE_EXPR:
6237 code = unsignedp ? GEU : GE;
6238 break;
6240 case UNORDERED_EXPR:
6241 code = UNORDERED;
6242 break;
6243 case ORDERED_EXPR:
6244 code = ORDERED;
6245 break;
6246 case UNLT_EXPR:
6247 code = UNLT;
6248 break;
6249 case UNLE_EXPR:
6250 code = UNLE;
6251 break;
6252 case UNGT_EXPR:
6253 code = UNGT;
6254 break;
6255 case UNGE_EXPR:
6256 code = UNGE;
6257 break;
6258 case UNEQ_EXPR:
6259 code = UNEQ;
6260 break;
6261 case LTGT_EXPR:
6262 code = LTGT;
6263 break;
6265 default:
6266 gcc_unreachable ();
6268 return code;
6271 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
6272 unsigned operators. Do not generate compare instruction. */
6274 static rtx
6275 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
6277 enum rtx_code rcode;
6278 tree t_op0, t_op1;
6279 rtx rtx_op0, rtx_op1;
6281 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
6282 ensures that condition is a relational operation. */
6283 gcc_assert (COMPARISON_CLASS_P (cond));
6285 rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
6286 t_op0 = TREE_OPERAND (cond, 0);
6287 t_op1 = TREE_OPERAND (cond, 1);
6289 /* Expand operands. */
6290 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)),
6291 EXPAND_STACK_PARM);
6292 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)),
6293 EXPAND_STACK_PARM);
6295 if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
6296 && GET_MODE (rtx_op0) != VOIDmode)
6297 rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
6299 if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
6300 && GET_MODE (rtx_op1) != VOIDmode)
6301 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
6303 return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
6306 /* Return insn code for VEC_COND_EXPR EXPR. */
6308 static inline enum insn_code
6309 get_vcond_icode (tree expr, enum machine_mode mode)
6311 enum insn_code icode = CODE_FOR_nothing;
6313 if (TYPE_UNSIGNED (TREE_TYPE (expr)))
6314 icode = vcondu_gen_code[mode];
6315 else
6316 icode = vcond_gen_code[mode];
6317 return icode;
6320 /* Return TRUE iff, appropriate vector insns are available
6321 for vector cond expr expr in VMODE mode. */
6323 bool
6324 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
6326 if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
6327 return false;
6328 return true;
6331 /* Generate insns for VEC_COND_EXPR. */
6334 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
6336 enum insn_code icode;
6337 rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
6338 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
6339 bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
6341 icode = get_vcond_icode (vec_cond_expr, mode);
6342 if (icode == CODE_FOR_nothing)
6343 return 0;
6345 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6346 target = gen_reg_rtx (mode);
6348 /* Get comparison rtx. First expand both cond expr operands. */
6349 comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
6350 unsignedp, icode);
6351 cc_op0 = XEXP (comparison, 0);
6352 cc_op1 = XEXP (comparison, 1);
6353 /* Expand both operands and force them in reg, if required. */
6354 rtx_op1 = expand_normal (TREE_OPERAND (vec_cond_expr, 1));
6355 if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
6356 && mode != VOIDmode)
6357 rtx_op1 = force_reg (mode, rtx_op1);
6359 rtx_op2 = expand_normal (TREE_OPERAND (vec_cond_expr, 2));
6360 if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
6361 && mode != VOIDmode)
6362 rtx_op2 = force_reg (mode, rtx_op2);
6364 /* Emit instruction! */
6365 emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
6366 comparison, cc_op0, cc_op1));
6368 return target;
6372 /* This is an internal subroutine of the other compare_and_swap expanders.
6373 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
6374 operation. TARGET is an optional place to store the value result of
6375 the operation. ICODE is the particular instruction to expand. Return
6376 the result of the operation. */
6378 static rtx
6379 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
6380 rtx target, enum insn_code icode)
6382 enum machine_mode mode = GET_MODE (mem);
6383 rtx insn;
6385 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6386 target = gen_reg_rtx (mode);
6388 if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
6389 old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
6390 if (!insn_data[icode].operand[2].predicate (old_val, mode))
6391 old_val = force_reg (mode, old_val);
6393 if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
6394 new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
6395 if (!insn_data[icode].operand[3].predicate (new_val, mode))
6396 new_val = force_reg (mode, new_val);
6398 insn = GEN_FCN (icode) (target, mem, old_val, new_val);
6399 if (insn == NULL_RTX)
6400 return NULL_RTX;
6401 emit_insn (insn);
6403 return target;
6406 /* Expand a compare-and-swap operation and return its value. */
6409 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
6411 enum machine_mode mode = GET_MODE (mem);
6412 enum insn_code icode = sync_compare_and_swap[mode];
6414 if (icode == CODE_FOR_nothing)
6415 return NULL_RTX;
6417 return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
6420 /* Expand a compare-and-swap operation and store true into the result if
6421 the operation was successful and false otherwise. Return the result.
6422 Unlike other routines, TARGET is not optional. */
6425 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
6427 enum machine_mode mode = GET_MODE (mem);
6428 enum insn_code icode;
6429 rtx subtarget, label0, label1;
6431 /* If the target supports a compare-and-swap pattern that simultaneously
6432 sets some flag for success, then use it. Otherwise use the regular
6433 compare-and-swap and follow that immediately with a compare insn. */
6434 icode = sync_compare_and_swap_cc[mode];
6435 switch (icode)
6437 default:
6438 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
6439 NULL_RTX, icode);
6440 if (subtarget != NULL_RTX)
6441 break;
6443 /* FALLTHRU */
6444 case CODE_FOR_nothing:
6445 icode = sync_compare_and_swap[mode];
6446 if (icode == CODE_FOR_nothing)
6447 return NULL_RTX;
6449 /* Ensure that if old_val == mem, that we're not comparing
6450 against an old value. */
6451 if (MEM_P (old_val))
6452 old_val = force_reg (mode, old_val);
6454 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
6455 NULL_RTX, icode);
6456 if (subtarget == NULL_RTX)
6457 return NULL_RTX;
6459 emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
6462 /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
6463 setcc instruction from the beginning. We don't work too hard here,
6464 but it's nice to not be stupid about initial code gen either. */
6465 if (STORE_FLAG_VALUE == 1)
6467 icode = setcc_gen_code[EQ];
6468 if (icode != CODE_FOR_nothing)
6470 enum machine_mode cmode = insn_data[icode].operand[0].mode;
6471 rtx insn;
6473 subtarget = target;
6474 if (!insn_data[icode].operand[0].predicate (target, cmode))
6475 subtarget = gen_reg_rtx (cmode);
6477 insn = GEN_FCN (icode) (subtarget);
6478 if (insn)
6480 emit_insn (insn);
6481 if (GET_MODE (target) != GET_MODE (subtarget))
6483 convert_move (target, subtarget, 1);
6484 subtarget = target;
6486 return subtarget;
6491 /* Without an appropriate setcc instruction, use a set of branches to
6492 get 1 and 0 stored into target. Presumably if the target has a
6493 STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt. */
6495 label0 = gen_label_rtx ();
6496 label1 = gen_label_rtx ();
6498 emit_jump_insn (bcc_gen_fctn[EQ] (label0));
6499 emit_move_insn (target, const0_rtx);
6500 emit_jump_insn (gen_jump (label1));
6501 emit_barrier ();
6502 emit_label (label0);
6503 emit_move_insn (target, const1_rtx);
6504 emit_label (label1);
6506 return target;
6509 /* This is a helper function for the other atomic operations. This function
6510 emits a loop that contains SEQ that iterates until a compare-and-swap
6511 operation at the end succeeds. MEM is the memory to be modified. SEQ is
6512 a set of instructions that takes a value from OLD_REG as an input and
6513 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
6514 set to the current contents of MEM. After SEQ, a compare-and-swap will
6515 attempt to update MEM with NEW_REG. The function returns true when the
6516 loop was generated successfully. */
6518 static bool
6519 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
6521 enum machine_mode mode = GET_MODE (mem);
6522 enum insn_code icode;
6523 rtx label, cmp_reg, subtarget;
6525 /* The loop we want to generate looks like
6527 cmp_reg = mem;
6528 label:
6529 old_reg = cmp_reg;
6530 seq;
6531 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
6532 if (cmp_reg != old_reg)
6533 goto label;
6535 Note that we only do the plain load from memory once. Subsequent
6536 iterations use the value loaded by the compare-and-swap pattern. */
6538 label = gen_label_rtx ();
6539 cmp_reg = gen_reg_rtx (mode);
6541 emit_move_insn (cmp_reg, mem);
6542 emit_label (label);
6543 emit_move_insn (old_reg, cmp_reg);
6544 if (seq)
6545 emit_insn (seq);
6547 /* If the target supports a compare-and-swap pattern that simultaneously
6548 sets some flag for success, then use it. Otherwise use the regular
6549 compare-and-swap and follow that immediately with a compare insn. */
6550 icode = sync_compare_and_swap_cc[mode];
6551 switch (icode)
6553 default:
6554 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6555 cmp_reg, icode);
6556 if (subtarget != NULL_RTX)
6558 gcc_assert (subtarget == cmp_reg);
6559 break;
6562 /* FALLTHRU */
6563 case CODE_FOR_nothing:
6564 icode = sync_compare_and_swap[mode];
6565 if (icode == CODE_FOR_nothing)
6566 return false;
6568 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6569 cmp_reg, icode);
6570 if (subtarget == NULL_RTX)
6571 return false;
6572 if (subtarget != cmp_reg)
6573 emit_move_insn (cmp_reg, subtarget);
6575 emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
6578 /* ??? Mark this jump predicted not taken? */
6579 emit_jump_insn (bcc_gen_fctn[NE] (label));
6581 return true;
6584 /* This function generates the atomic operation MEM CODE= VAL. In this
6585 case, we do not care about any resulting value. Returns NULL if we
6586 cannot generate the operation. */
6589 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
6591 enum machine_mode mode = GET_MODE (mem);
6592 enum insn_code icode;
6593 rtx insn;
6595 /* Look to see if the target supports the operation directly. */
6596 switch (code)
6598 case PLUS:
6599 icode = sync_add_optab[mode];
6600 break;
6601 case IOR:
6602 icode = sync_ior_optab[mode];
6603 break;
6604 case XOR:
6605 icode = sync_xor_optab[mode];
6606 break;
6607 case AND:
6608 icode = sync_and_optab[mode];
6609 break;
6610 case NOT:
6611 icode = sync_nand_optab[mode];
6612 break;
6614 case MINUS:
6615 icode = sync_sub_optab[mode];
6616 if (icode == CODE_FOR_nothing)
6618 icode = sync_add_optab[mode];
6619 if (icode != CODE_FOR_nothing)
6621 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6622 code = PLUS;
6625 break;
6627 default:
6628 gcc_unreachable ();
6631 /* Generate the direct operation, if present. */
6632 if (icode != CODE_FOR_nothing)
6634 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6635 val = convert_modes (mode, GET_MODE (val), val, 1);
6636 if (!insn_data[icode].operand[1].predicate (val, mode))
6637 val = force_reg (mode, val);
6639 insn = GEN_FCN (icode) (mem, val);
6640 if (insn)
6642 emit_insn (insn);
6643 return const0_rtx;
6647 /* Failing that, generate a compare-and-swap loop in which we perform the
6648 operation with normal arithmetic instructions. */
6649 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6651 rtx t0 = gen_reg_rtx (mode), t1;
6653 start_sequence ();
6655 t1 = t0;
6656 if (code == NOT)
6658 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6659 code = AND;
6661 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6662 true, OPTAB_LIB_WIDEN);
6664 insn = get_insns ();
6665 end_sequence ();
6667 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6668 return const0_rtx;
6671 return NULL_RTX;
6674 /* This function generates the atomic operation MEM CODE= VAL. In this
6675 case, we do care about the resulting value: if AFTER is true then
6676 return the value MEM holds after the operation, if AFTER is false
6677 then return the value MEM holds before the operation. TARGET is an
6678 optional place for the result value to be stored. */
6681 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
6682 bool after, rtx target)
6684 enum machine_mode mode = GET_MODE (mem);
6685 enum insn_code old_code, new_code, icode;
6686 bool compensate;
6687 rtx insn;
6689 /* Look to see if the target supports the operation directly. */
6690 switch (code)
6692 case PLUS:
6693 old_code = sync_old_add_optab[mode];
6694 new_code = sync_new_add_optab[mode];
6695 break;
6696 case IOR:
6697 old_code = sync_old_ior_optab[mode];
6698 new_code = sync_new_ior_optab[mode];
6699 break;
6700 case XOR:
6701 old_code = sync_old_xor_optab[mode];
6702 new_code = sync_new_xor_optab[mode];
6703 break;
6704 case AND:
6705 old_code = sync_old_and_optab[mode];
6706 new_code = sync_new_and_optab[mode];
6707 break;
6708 case NOT:
6709 old_code = sync_old_nand_optab[mode];
6710 new_code = sync_new_nand_optab[mode];
6711 break;
6713 case MINUS:
6714 old_code = sync_old_sub_optab[mode];
6715 new_code = sync_new_sub_optab[mode];
6716 if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
6718 old_code = sync_old_add_optab[mode];
6719 new_code = sync_new_add_optab[mode];
6720 if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
6722 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6723 code = PLUS;
6726 break;
6728 default:
6729 gcc_unreachable ();
6732 /* If the target does supports the proper new/old operation, great. But
6733 if we only support the opposite old/new operation, check to see if we
6734 can compensate. In the case in which the old value is supported, then
6735 we can always perform the operation again with normal arithmetic. In
6736 the case in which the new value is supported, then we can only handle
6737 this in the case the operation is reversible. */
6738 compensate = false;
6739 if (after)
6741 icode = new_code;
6742 if (icode == CODE_FOR_nothing)
6744 icode = old_code;
6745 if (icode != CODE_FOR_nothing)
6746 compensate = true;
6749 else
6751 icode = old_code;
6752 if (icode == CODE_FOR_nothing
6753 && (code == PLUS || code == MINUS || code == XOR))
6755 icode = new_code;
6756 if (icode != CODE_FOR_nothing)
6757 compensate = true;
6761 /* If we found something supported, great. */
6762 if (icode != CODE_FOR_nothing)
6764 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6765 target = gen_reg_rtx (mode);
6767 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6768 val = convert_modes (mode, GET_MODE (val), val, 1);
6769 if (!insn_data[icode].operand[2].predicate (val, mode))
6770 val = force_reg (mode, val);
6772 insn = GEN_FCN (icode) (target, mem, val);
6773 if (insn)
6775 emit_insn (insn);
6777 /* If we need to compensate for using an operation with the
6778 wrong return value, do so now. */
6779 if (compensate)
6781 if (!after)
6783 if (code == PLUS)
6784 code = MINUS;
6785 else if (code == MINUS)
6786 code = PLUS;
6789 if (code == NOT)
6790 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
6791 target = expand_simple_binop (mode, code, target, val, NULL_RTX,
6792 true, OPTAB_LIB_WIDEN);
6795 return target;
6799 /* Failing that, generate a compare-and-swap loop in which we perform the
6800 operation with normal arithmetic instructions. */
6801 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6803 rtx t0 = gen_reg_rtx (mode), t1;
6805 if (!target || !register_operand (target, mode))
6806 target = gen_reg_rtx (mode);
6808 start_sequence ();
6810 if (!after)
6811 emit_move_insn (target, t0);
6812 t1 = t0;
6813 if (code == NOT)
6815 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6816 code = AND;
6818 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6819 true, OPTAB_LIB_WIDEN);
6820 if (after)
6821 emit_move_insn (target, t1);
6823 insn = get_insns ();
6824 end_sequence ();
6826 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6827 return target;
6830 return NULL_RTX;
6833 /* This function expands a test-and-set operation. Ideally we atomically
6834 store VAL in MEM and return the previous value in MEM. Some targets
6835 may not support this operation and only support VAL with the constant 1;
6836 in this case while the return value will be 0/1, but the exact value
6837 stored in MEM is target defined. TARGET is an option place to stick
6838 the return value. */
6841 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
6843 enum machine_mode mode = GET_MODE (mem);
6844 enum insn_code icode;
6845 rtx insn;
6847 /* If the target supports the test-and-set directly, great. */
6848 icode = sync_lock_test_and_set[mode];
6849 if (icode != CODE_FOR_nothing)
6851 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6852 target = gen_reg_rtx (mode);
6854 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6855 val = convert_modes (mode, GET_MODE (val), val, 1);
6856 if (!insn_data[icode].operand[2].predicate (val, mode))
6857 val = force_reg (mode, val);
6859 insn = GEN_FCN (icode) (target, mem, val);
6860 if (insn)
6862 emit_insn (insn);
6863 return target;
6867 /* Otherwise, use a compare-and-swap loop for the exchange. */
6868 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6870 if (!target || !register_operand (target, mode))
6871 target = gen_reg_rtx (mode);
6872 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6873 val = convert_modes (mode, GET_MODE (val), val, 1);
6874 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6875 return target;
6878 return NULL_RTX;
6881 #include "gt-optabs.h"