include:
[official-gcc.git] / gcc / optabs.c
blob5a87ac0335a26ee3da2135a1c314b0736ab8c6d3
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 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
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 int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx);
99 static rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int,
100 int);
101 static void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx,
102 enum machine_mode *, int *,
103 enum can_compare_purpose);
104 static enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
105 int *);
106 static enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
107 static optab new_optab (void);
108 static convert_optab new_convert_optab (void);
109 static inline optab init_optab (enum rtx_code);
110 static inline optab init_optabv (enum rtx_code);
111 static inline convert_optab init_convert_optab (enum rtx_code);
112 static void init_libfuncs (optab, int, int, const char *, int);
113 static void init_integral_libfuncs (optab, const char *, int);
114 static void init_floating_libfuncs (optab, const char *, int);
115 static void init_interclass_conv_libfuncs (convert_optab, const char *,
116 enum mode_class, enum mode_class);
117 static void init_intraclass_conv_libfuncs (convert_optab, const char *,
118 enum mode_class, bool);
119 static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
120 enum rtx_code, int, rtx);
121 static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
122 enum machine_mode *, int *);
123 static rtx widen_clz (enum machine_mode, rtx, rtx);
124 static rtx expand_parity (enum machine_mode, rtx, rtx);
125 static enum rtx_code get_rtx_code (enum tree_code, bool);
126 static rtx vector_compare_rtx (tree, bool, enum insn_code);
128 #ifndef HAVE_conditional_trap
129 #define HAVE_conditional_trap 0
130 #define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
131 #endif
133 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
134 the result of operation CODE applied to OP0 (and OP1 if it is a binary
135 operation).
137 If the last insn does not set TARGET, don't do anything, but return 1.
139 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
140 don't add the REG_EQUAL note but return 0. Our caller can then try
141 again, ensuring that TARGET is not one of the operands. */
143 static int
144 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
146 rtx last_insn, insn, set;
147 rtx note;
149 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
151 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
152 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
153 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
154 && GET_RTX_CLASS (code) != RTX_COMPARE
155 && GET_RTX_CLASS (code) != RTX_UNARY)
156 return 1;
158 if (GET_CODE (target) == ZERO_EXTRACT)
159 return 1;
161 for (last_insn = insns;
162 NEXT_INSN (last_insn) != NULL_RTX;
163 last_insn = NEXT_INSN (last_insn))
166 set = single_set (last_insn);
167 if (set == NULL_RTX)
168 return 1;
170 if (! rtx_equal_p (SET_DEST (set), target)
171 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
172 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
173 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
174 return 1;
176 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
177 besides the last insn. */
178 if (reg_overlap_mentioned_p (target, op0)
179 || (op1 && reg_overlap_mentioned_p (target, op1)))
181 insn = PREV_INSN (last_insn);
182 while (insn != NULL_RTX)
184 if (reg_set_p (target, insn))
185 return 0;
187 insn = PREV_INSN (insn);
191 if (GET_RTX_CLASS (code) == RTX_UNARY)
192 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
193 else
194 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
196 set_unique_reg_note (last_insn, REG_EQUAL, note);
198 return 1;
201 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
202 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
203 not actually do a sign-extend or zero-extend, but can leave the
204 higher-order bits of the result rtx undefined, for example, in the case
205 of logical operations, but not right shifts. */
207 static rtx
208 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
209 int unsignedp, int no_extend)
211 rtx result;
213 /* If we don't have to extend and this is a constant, return it. */
214 if (no_extend && GET_MODE (op) == VOIDmode)
215 return op;
217 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
218 extend since it will be more efficient to do so unless the signedness of
219 a promoted object differs from our extension. */
220 if (! no_extend
221 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
222 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
223 return convert_modes (mode, oldmode, op, unsignedp);
225 /* If MODE is no wider than a single word, we return a paradoxical
226 SUBREG. */
227 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
228 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
230 /* Otherwise, get an object of MODE, clobber it, and set the low-order
231 part to OP. */
233 result = gen_reg_rtx (mode);
234 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
235 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
236 return result;
239 /* Return the optab used for computing the operation given by
240 the tree code, CODE. This function is not always usable (for
241 example, it cannot give complete results for multiplication
242 or division) but probably ought to be relied on more widely
243 throughout the expander. */
244 optab
245 optab_for_tree_code (enum tree_code code, tree type)
247 bool trapv;
248 switch (code)
250 case BIT_AND_EXPR:
251 return and_optab;
253 case BIT_IOR_EXPR:
254 return ior_optab;
256 case BIT_NOT_EXPR:
257 return one_cmpl_optab;
259 case BIT_XOR_EXPR:
260 return xor_optab;
262 case TRUNC_MOD_EXPR:
263 case CEIL_MOD_EXPR:
264 case FLOOR_MOD_EXPR:
265 case ROUND_MOD_EXPR:
266 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
268 case RDIV_EXPR:
269 case TRUNC_DIV_EXPR:
270 case CEIL_DIV_EXPR:
271 case FLOOR_DIV_EXPR:
272 case ROUND_DIV_EXPR:
273 case EXACT_DIV_EXPR:
274 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
276 case LSHIFT_EXPR:
277 return ashl_optab;
279 case RSHIFT_EXPR:
280 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
282 case LROTATE_EXPR:
283 return rotl_optab;
285 case RROTATE_EXPR:
286 return rotr_optab;
288 case MAX_EXPR:
289 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
291 case MIN_EXPR:
292 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
294 case REALIGN_LOAD_EXPR:
295 return vec_realign_load_optab;
297 case REDUC_MAX_EXPR:
298 return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
300 case REDUC_MIN_EXPR:
301 return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
303 case REDUC_PLUS_EXPR:
304 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
306 case VEC_LSHIFT_EXPR:
307 return vec_shl_optab;
309 case VEC_RSHIFT_EXPR:
310 return vec_shr_optab;
312 default:
313 break;
316 trapv = flag_trapv && INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type);
317 switch (code)
319 case PLUS_EXPR:
320 return trapv ? addv_optab : add_optab;
322 case MINUS_EXPR:
323 return trapv ? subv_optab : sub_optab;
325 case MULT_EXPR:
326 return trapv ? smulv_optab : smul_optab;
328 case NEGATE_EXPR:
329 return trapv ? negv_optab : neg_optab;
331 case ABS_EXPR:
332 return trapv ? absv_optab : abs_optab;
334 default:
335 return NULL;
340 /* Generate code to perform an operation specified by TERNARY_OPTAB
341 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
343 UNSIGNEDP is for the case where we have to widen the operands
344 to perform the operation. It says to use zero-extension.
346 If TARGET is nonzero, the value
347 is generated there, if it is convenient to do so.
348 In all cases an rtx is returned for the locus of the value;
349 this may or may not be TARGET. */
352 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
353 rtx op1, rtx op2, rtx target, int unsignedp)
355 int icode = (int) ternary_optab->handlers[(int) mode].insn_code;
356 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
357 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
358 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
359 rtx temp;
360 rtx pat;
361 rtx xop0 = op0, xop1 = op1, xop2 = op2;
363 gcc_assert (ternary_optab->handlers[(int) mode].insn_code
364 != CODE_FOR_nothing);
366 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
367 temp = gen_reg_rtx (mode);
368 else
369 temp = target;
371 /* In case the insn wants input operands in modes different from
372 those of the actual operands, convert the operands. It would
373 seem that we don't need to convert CONST_INTs, but we do, so
374 that they're properly zero-extended, sign-extended or truncated
375 for their mode. */
377 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
378 xop0 = convert_modes (mode0,
379 GET_MODE (op0) != VOIDmode
380 ? GET_MODE (op0)
381 : mode,
382 xop0, unsignedp);
384 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
385 xop1 = convert_modes (mode1,
386 GET_MODE (op1) != VOIDmode
387 ? GET_MODE (op1)
388 : mode,
389 xop1, unsignedp);
391 if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
392 xop2 = convert_modes (mode2,
393 GET_MODE (op2) != VOIDmode
394 ? GET_MODE (op2)
395 : mode,
396 xop2, unsignedp);
398 /* Now, if insn's predicates don't allow our operands, put them into
399 pseudo regs. */
401 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
402 && mode0 != VOIDmode)
403 xop0 = copy_to_mode_reg (mode0, xop0);
405 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
406 && mode1 != VOIDmode)
407 xop1 = copy_to_mode_reg (mode1, xop1);
409 if (!insn_data[icode].operand[3].predicate (xop2, mode2)
410 && mode2 != VOIDmode)
411 xop2 = copy_to_mode_reg (mode2, xop2);
413 pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
415 emit_insn (pat);
416 return temp;
420 /* Like expand_binop, but return a constant rtx if the result can be
421 calculated at compile time. The arguments and return value are
422 otherwise the same as for expand_binop. */
424 static rtx
425 simplify_expand_binop (enum machine_mode mode, optab binoptab,
426 rtx op0, rtx op1, rtx target, int unsignedp,
427 enum optab_methods methods)
429 if (CONSTANT_P (op0) && CONSTANT_P (op1))
431 rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
433 if (x)
434 return x;
437 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
440 /* Like simplify_expand_binop, but always put the result in TARGET.
441 Return true if the expansion succeeded. */
443 bool
444 force_expand_binop (enum machine_mode mode, optab binoptab,
445 rtx op0, rtx op1, rtx target, int unsignedp,
446 enum optab_methods methods)
448 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
449 target, unsignedp, methods);
450 if (x == 0)
451 return false;
452 if (x != target)
453 emit_move_insn (target, x);
454 return true;
457 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
460 expand_vec_shift_expr (tree vec_shift_expr, rtx target)
462 enum insn_code icode;
463 rtx rtx_op1, rtx_op2;
464 enum machine_mode mode1;
465 enum machine_mode mode2;
466 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr));
467 tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0);
468 tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1);
469 optab shift_optab;
470 rtx pat;
472 switch (TREE_CODE (vec_shift_expr))
474 case VEC_RSHIFT_EXPR:
475 shift_optab = vec_shr_optab;
476 break;
477 case VEC_LSHIFT_EXPR:
478 shift_optab = vec_shl_optab;
479 break;
480 default:
481 gcc_unreachable ();
484 icode = (int) shift_optab->handlers[(int) mode].insn_code;
485 gcc_assert (icode != CODE_FOR_nothing);
487 mode1 = insn_data[icode].operand[1].mode;
488 mode2 = insn_data[icode].operand[2].mode;
490 rtx_op1 = expand_expr (vec_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
491 if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
492 && mode1 != VOIDmode)
493 rtx_op1 = force_reg (mode1, rtx_op1);
495 rtx_op2 = expand_expr (shift_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
496 if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
497 && mode2 != VOIDmode)
498 rtx_op2 = force_reg (mode2, rtx_op2);
500 if (!target
501 || ! (*insn_data[icode].operand[0].predicate) (target, mode))
502 target = gen_reg_rtx (mode);
504 /* Emit instruction */
505 pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
506 gcc_assert (pat);
507 emit_insn (pat);
509 return target;
512 /* This subroutine of expand_doubleword_shift handles the cases in which
513 the effective shift value is >= BITS_PER_WORD. The arguments and return
514 value are the same as for the parent routine, except that SUPERWORD_OP1
515 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
516 INTO_TARGET may be null if the caller has decided to calculate it. */
518 static bool
519 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
520 rtx outof_target, rtx into_target,
521 int unsignedp, enum optab_methods methods)
523 if (into_target != 0)
524 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
525 into_target, unsignedp, methods))
526 return false;
528 if (outof_target != 0)
530 /* For a signed right shift, we must fill OUTOF_TARGET with copies
531 of the sign bit, otherwise we must fill it with zeros. */
532 if (binoptab != ashr_optab)
533 emit_move_insn (outof_target, CONST0_RTX (word_mode));
534 else
535 if (!force_expand_binop (word_mode, binoptab,
536 outof_input, GEN_INT (BITS_PER_WORD - 1),
537 outof_target, unsignedp, methods))
538 return false;
540 return true;
543 /* This subroutine of expand_doubleword_shift handles the cases in which
544 the effective shift value is < BITS_PER_WORD. The arguments and return
545 value are the same as for the parent routine. */
547 static bool
548 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
549 rtx outof_input, rtx into_input, rtx op1,
550 rtx outof_target, rtx into_target,
551 int unsignedp, enum optab_methods methods,
552 unsigned HOST_WIDE_INT shift_mask)
554 optab reverse_unsigned_shift, unsigned_shift;
555 rtx tmp, carries;
557 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
558 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
560 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
561 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
562 the opposite direction to BINOPTAB. */
563 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
565 carries = outof_input;
566 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
567 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
568 0, true, methods);
570 else
572 /* We must avoid shifting by BITS_PER_WORD bits since that is either
573 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
574 has unknown behavior. Do a single shift first, then shift by the
575 remainder. It's OK to use ~OP1 as the remainder if shift counts
576 are truncated to the mode size. */
577 carries = expand_binop (word_mode, reverse_unsigned_shift,
578 outof_input, const1_rtx, 0, unsignedp, methods);
579 if (shift_mask == BITS_PER_WORD - 1)
581 tmp = immed_double_const (-1, -1, op1_mode);
582 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
583 0, true, methods);
585 else
587 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
588 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
589 0, true, methods);
592 if (tmp == 0 || carries == 0)
593 return false;
594 carries = expand_binop (word_mode, reverse_unsigned_shift,
595 carries, tmp, 0, unsignedp, methods);
596 if (carries == 0)
597 return false;
599 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
600 so the result can go directly into INTO_TARGET if convenient. */
601 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
602 into_target, unsignedp, methods);
603 if (tmp == 0)
604 return false;
606 /* Now OR in the bits carried over from OUTOF_INPUT. */
607 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
608 into_target, unsignedp, methods))
609 return false;
611 /* Use a standard word_mode shift for the out-of half. */
612 if (outof_target != 0)
613 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
614 outof_target, unsignedp, methods))
615 return false;
617 return true;
621 #ifdef HAVE_conditional_move
622 /* Try implementing expand_doubleword_shift using conditional moves.
623 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
624 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
625 are the shift counts to use in the former and latter case. All other
626 arguments are the same as the parent routine. */
628 static bool
629 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
630 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
631 rtx outof_input, rtx into_input,
632 rtx subword_op1, rtx superword_op1,
633 rtx outof_target, rtx into_target,
634 int unsignedp, enum optab_methods methods,
635 unsigned HOST_WIDE_INT shift_mask)
637 rtx outof_superword, into_superword;
639 /* Put the superword version of the output into OUTOF_SUPERWORD and
640 INTO_SUPERWORD. */
641 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
642 if (outof_target != 0 && subword_op1 == superword_op1)
644 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
645 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
646 into_superword = outof_target;
647 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
648 outof_superword, 0, unsignedp, methods))
649 return false;
651 else
653 into_superword = gen_reg_rtx (word_mode);
654 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
655 outof_superword, into_superword,
656 unsignedp, methods))
657 return false;
660 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
661 if (!expand_subword_shift (op1_mode, binoptab,
662 outof_input, into_input, subword_op1,
663 outof_target, into_target,
664 unsignedp, methods, shift_mask))
665 return false;
667 /* Select between them. Do the INTO half first because INTO_SUPERWORD
668 might be the current value of OUTOF_TARGET. */
669 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
670 into_target, into_superword, word_mode, false))
671 return false;
673 if (outof_target != 0)
674 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
675 outof_target, outof_superword,
676 word_mode, false))
677 return false;
679 return true;
681 #endif
683 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
684 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
685 input operand; the shift moves bits in the direction OUTOF_INPUT->
686 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
687 of the target. OP1 is the shift count and OP1_MODE is its mode.
688 If OP1 is constant, it will have been truncated as appropriate
689 and is known to be nonzero.
691 If SHIFT_MASK is zero, the result of word shifts is undefined when the
692 shift count is outside the range [0, BITS_PER_WORD). This routine must
693 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
695 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
696 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
697 fill with zeros or sign bits as appropriate.
699 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
700 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
701 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
702 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
703 are undefined.
705 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
706 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
707 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
708 function wants to calculate it itself.
710 Return true if the shift could be successfully synthesized. */
712 static bool
713 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
714 rtx outof_input, rtx into_input, rtx op1,
715 rtx outof_target, rtx into_target,
716 int unsignedp, enum optab_methods methods,
717 unsigned HOST_WIDE_INT shift_mask)
719 rtx superword_op1, tmp, cmp1, cmp2;
720 rtx subword_label, done_label;
721 enum rtx_code cmp_code;
723 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
724 fill the result with sign or zero bits as appropriate. If so, the value
725 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
726 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
727 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
729 This isn't worthwhile for constant shifts since the optimizers will
730 cope better with in-range shift counts. */
731 if (shift_mask >= BITS_PER_WORD
732 && outof_target != 0
733 && !CONSTANT_P (op1))
735 if (!expand_doubleword_shift (op1_mode, binoptab,
736 outof_input, into_input, op1,
737 0, into_target,
738 unsignedp, methods, shift_mask))
739 return false;
740 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
741 outof_target, unsignedp, methods))
742 return false;
743 return true;
746 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
747 is true when the effective shift value is less than BITS_PER_WORD.
748 Set SUPERWORD_OP1 to the shift count that should be used to shift
749 OUTOF_INPUT into INTO_TARGET when the condition is false. */
750 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
751 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
753 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
754 is a subword shift count. */
755 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
756 0, true, methods);
757 cmp2 = CONST0_RTX (op1_mode);
758 cmp_code = EQ;
759 superword_op1 = op1;
761 else
763 /* Set CMP1 to OP1 - BITS_PER_WORD. */
764 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
765 0, true, methods);
766 cmp2 = CONST0_RTX (op1_mode);
767 cmp_code = LT;
768 superword_op1 = cmp1;
770 if (cmp1 == 0)
771 return false;
773 /* If we can compute the condition at compile time, pick the
774 appropriate subroutine. */
775 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
776 if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
778 if (tmp == const0_rtx)
779 return expand_superword_shift (binoptab, outof_input, superword_op1,
780 outof_target, into_target,
781 unsignedp, methods);
782 else
783 return expand_subword_shift (op1_mode, binoptab,
784 outof_input, into_input, op1,
785 outof_target, into_target,
786 unsignedp, methods, shift_mask);
789 #ifdef HAVE_conditional_move
790 /* Try using conditional moves to generate straight-line code. */
792 rtx start = get_last_insn ();
793 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
794 cmp_code, cmp1, cmp2,
795 outof_input, into_input,
796 op1, superword_op1,
797 outof_target, into_target,
798 unsignedp, methods, shift_mask))
799 return true;
800 delete_insns_since (start);
802 #endif
804 /* As a last resort, use branches to select the correct alternative. */
805 subword_label = gen_label_rtx ();
806 done_label = gen_label_rtx ();
808 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
809 0, 0, subword_label);
811 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
812 outof_target, into_target,
813 unsignedp, methods))
814 return false;
816 emit_jump_insn (gen_jump (done_label));
817 emit_barrier ();
818 emit_label (subword_label);
820 if (!expand_subword_shift (op1_mode, binoptab,
821 outof_input, into_input, op1,
822 outof_target, into_target,
823 unsignedp, methods, shift_mask))
824 return false;
826 emit_label (done_label);
827 return true;
830 /* Subroutine of expand_binop. Perform a double word multiplication of
831 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
832 as the target's word_mode. This function return NULL_RTX if anything
833 goes wrong, in which case it may have already emitted instructions
834 which need to be deleted.
836 If we want to multiply two two-word values and have normal and widening
837 multiplies of single-word values, we can do this with three smaller
838 multiplications. Note that we do not make a REG_NO_CONFLICT block here
839 because we are not operating on one word at a time.
841 The multiplication proceeds as follows:
842 _______________________
843 [__op0_high_|__op0_low__]
844 _______________________
845 * [__op1_high_|__op1_low__]
846 _______________________________________________
847 _______________________
848 (1) [__op0_low__*__op1_low__]
849 _______________________
850 (2a) [__op0_low__*__op1_high_]
851 _______________________
852 (2b) [__op0_high_*__op1_low__]
853 _______________________
854 (3) [__op0_high_*__op1_high_]
857 This gives a 4-word result. Since we are only interested in the
858 lower 2 words, partial result (3) and the upper words of (2a) and
859 (2b) don't need to be calculated. Hence (2a) and (2b) can be
860 calculated using non-widening multiplication.
862 (1), however, needs to be calculated with an unsigned widening
863 multiplication. If this operation is not directly supported we
864 try using a signed widening multiplication and adjust the result.
865 This adjustment works as follows:
867 If both operands are positive then no adjustment is needed.
869 If the operands have different signs, for example op0_low < 0 and
870 op1_low >= 0, the instruction treats the most significant bit of
871 op0_low as a sign bit instead of a bit with significance
872 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
873 with 2**BITS_PER_WORD - op0_low, and two's complements the
874 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
875 the result.
877 Similarly, if both operands are negative, we need to add
878 (op0_low + op1_low) * 2**BITS_PER_WORD.
880 We use a trick to adjust quickly. We logically shift op0_low right
881 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
882 op0_high (op1_high) before it is used to calculate 2b (2a). If no
883 logical shift exists, we do an arithmetic right shift and subtract
884 the 0 or -1. */
886 static rtx
887 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
888 bool umulp, enum optab_methods methods)
890 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
891 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
892 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
893 rtx product, adjust, product_high, temp;
895 rtx op0_high = operand_subword_force (op0, high, mode);
896 rtx op0_low = operand_subword_force (op0, low, mode);
897 rtx op1_high = operand_subword_force (op1, high, mode);
898 rtx op1_low = operand_subword_force (op1, low, mode);
900 /* If we're using an unsigned multiply to directly compute the product
901 of the low-order words of the operands and perform any required
902 adjustments of the operands, we begin by trying two more multiplications
903 and then computing the appropriate sum.
905 We have checked above that the required addition is provided.
906 Full-word addition will normally always succeed, especially if
907 it is provided at all, so we don't worry about its failure. The
908 multiplication may well fail, however, so we do handle that. */
910 if (!umulp)
912 /* ??? This could be done with emit_store_flag where available. */
913 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
914 NULL_RTX, 1, methods);
915 if (temp)
916 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
917 NULL_RTX, 0, OPTAB_DIRECT);
918 else
920 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
921 NULL_RTX, 0, methods);
922 if (!temp)
923 return NULL_RTX;
924 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
925 NULL_RTX, 0, OPTAB_DIRECT);
928 if (!op0_high)
929 return NULL_RTX;
932 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
933 NULL_RTX, 0, OPTAB_DIRECT);
934 if (!adjust)
935 return NULL_RTX;
937 /* OP0_HIGH should now be dead. */
939 if (!umulp)
941 /* ??? This could be done with emit_store_flag where available. */
942 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
943 NULL_RTX, 1, methods);
944 if (temp)
945 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
946 NULL_RTX, 0, OPTAB_DIRECT);
947 else
949 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
950 NULL_RTX, 0, methods);
951 if (!temp)
952 return NULL_RTX;
953 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
954 NULL_RTX, 0, OPTAB_DIRECT);
957 if (!op1_high)
958 return NULL_RTX;
961 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
962 NULL_RTX, 0, OPTAB_DIRECT);
963 if (!temp)
964 return NULL_RTX;
966 /* OP1_HIGH should now be dead. */
968 adjust = expand_binop (word_mode, add_optab, adjust, temp,
969 adjust, 0, OPTAB_DIRECT);
971 if (target && !REG_P (target))
972 target = NULL_RTX;
974 if (umulp)
975 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
976 target, 1, OPTAB_DIRECT);
977 else
978 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
979 target, 1, OPTAB_DIRECT);
981 if (!product)
982 return NULL_RTX;
984 product_high = operand_subword (product, high, 1, mode);
985 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
986 REG_P (product_high) ? product_high : adjust,
987 0, OPTAB_DIRECT);
988 emit_move_insn (product_high, adjust);
989 return product;
992 /* Wrapper around expand_binop which takes an rtx code to specify
993 the operation to perform, not an optab pointer. All other
994 arguments are the same. */
996 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
997 rtx op1, rtx target, int unsignedp,
998 enum optab_methods methods)
1000 optab binop = code_to_optab[(int) code];
1001 gcc_assert (binop);
1003 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1006 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1007 binop. Order them according to commutative_operand_precedence and, if
1008 possible, try to put TARGET or a pseudo first. */
1009 static bool
1010 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1012 int op0_prec = commutative_operand_precedence (op0);
1013 int op1_prec = commutative_operand_precedence (op1);
1015 if (op0_prec < op1_prec)
1016 return true;
1018 if (op0_prec > op1_prec)
1019 return false;
1021 /* With equal precedence, both orders are ok, but it is better if the
1022 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1023 if (target == 0 || REG_P (target))
1024 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1025 else
1026 return rtx_equal_p (op1, target);
1030 /* Generate code to perform an operation specified by BINOPTAB
1031 on operands OP0 and OP1, with result having machine-mode MODE.
1033 UNSIGNEDP is for the case where we have to widen the operands
1034 to perform the operation. It says to use zero-extension.
1036 If TARGET is nonzero, the value
1037 is generated there, if it is convenient to do so.
1038 In all cases an rtx is returned for the locus of the value;
1039 this may or may not be TARGET. */
1042 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1043 rtx target, int unsignedp, enum optab_methods methods)
1045 enum optab_methods next_methods
1046 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1047 ? OPTAB_WIDEN : methods);
1048 enum mode_class class;
1049 enum machine_mode wider_mode;
1050 rtx temp;
1051 int commutative_op = 0;
1052 int shift_op = (binoptab->code == ASHIFT
1053 || binoptab->code == ASHIFTRT
1054 || binoptab->code == LSHIFTRT
1055 || binoptab->code == ROTATE
1056 || binoptab->code == ROTATERT);
1057 rtx entry_last = get_last_insn ();
1058 rtx last;
1059 bool first_pass_p = true;
1061 class = GET_MODE_CLASS (mode);
1063 /* If subtracting an integer constant, convert this into an addition of
1064 the negated constant. */
1066 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
1068 op1 = negate_rtx (mode, op1);
1069 binoptab = add_optab;
1072 /* If we are inside an appropriately-short loop and we are optimizing,
1073 force expensive constants into a register. */
1074 if (CONSTANT_P (op0) && optimize
1075 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1077 if (GET_MODE (op0) != VOIDmode)
1078 op0 = convert_modes (mode, VOIDmode, op0, unsignedp);
1079 op0 = force_reg (mode, op0);
1082 if (CONSTANT_P (op1) && optimize
1083 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1085 if (GET_MODE (op1) != VOIDmode)
1086 op1 = convert_modes (mode, VOIDmode, op1, unsignedp);
1087 op1 = force_reg (mode, op1);
1090 /* Record where to delete back to if we backtrack. */
1091 last = get_last_insn ();
1093 /* If operation is commutative,
1094 try to make the first operand a register.
1095 Even better, try to make it the same as the target.
1096 Also try to make the last operand a constant. */
1097 if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1098 || binoptab == smul_widen_optab
1099 || binoptab == umul_widen_optab
1100 || binoptab == smul_highpart_optab
1101 || binoptab == umul_highpart_optab)
1103 commutative_op = 1;
1105 if (swap_commutative_operands_with_target (target, op0, op1))
1107 temp = op1;
1108 op1 = op0;
1109 op0 = temp;
1113 retry:
1115 /* If we can do it with a three-operand insn, do so. */
1117 if (methods != OPTAB_MUST_WIDEN
1118 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1120 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1121 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1122 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1123 rtx pat;
1124 rtx xop0 = op0, xop1 = op1;
1126 if (target)
1127 temp = target;
1128 else
1129 temp = gen_reg_rtx (mode);
1131 /* If it is a commutative operator and the modes would match
1132 if we would swap the operands, we can save the conversions. */
1133 if (commutative_op)
1135 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
1136 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
1138 rtx tmp;
1140 tmp = op0; op0 = op1; op1 = tmp;
1141 tmp = xop0; xop0 = xop1; xop1 = tmp;
1145 /* In case the insn wants input operands in modes different from
1146 those of the actual operands, convert the operands. It would
1147 seem that we don't need to convert CONST_INTs, but we do, so
1148 that they're properly zero-extended, sign-extended or truncated
1149 for their mode. */
1151 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
1152 xop0 = convert_modes (mode0,
1153 GET_MODE (op0) != VOIDmode
1154 ? GET_MODE (op0)
1155 : mode,
1156 xop0, unsignedp);
1158 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
1159 xop1 = convert_modes (mode1,
1160 GET_MODE (op1) != VOIDmode
1161 ? GET_MODE (op1)
1162 : mode,
1163 xop1, unsignedp);
1165 /* Now, if insn's predicates don't allow our operands, put them into
1166 pseudo regs. */
1168 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1169 && mode0 != VOIDmode)
1170 xop0 = copy_to_mode_reg (mode0, xop0);
1172 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1173 && mode1 != VOIDmode)
1174 xop1 = copy_to_mode_reg (mode1, xop1);
1176 if (!insn_data[icode].operand[0].predicate (temp, mode))
1177 temp = gen_reg_rtx (mode);
1179 pat = GEN_FCN (icode) (temp, xop0, xop1);
1180 if (pat)
1182 /* If PAT is composed of more than one insn, try to add an appropriate
1183 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1184 operand, call ourselves again, this time without a target. */
1185 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1186 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1188 delete_insns_since (last);
1189 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1190 unsignedp, methods);
1193 emit_insn (pat);
1194 return temp;
1196 else
1197 delete_insns_since (last);
1200 /* If we were trying to rotate by a constant value, and that didn't
1201 work, try rotating the other direction before falling back to
1202 shifts and bitwise-or. */
1203 if (first_pass_p
1204 && (binoptab == rotl_optab || binoptab == rotr_optab)
1205 && class == MODE_INT
1206 && GET_CODE (op1) == CONST_INT
1207 && INTVAL (op1) > 0
1208 && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode))
1210 first_pass_p = false;
1211 op1 = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1));
1212 binoptab = binoptab == rotl_optab ? rotr_optab : rotl_optab;
1213 goto retry;
1216 /* If this is a multiply, see if we can do a widening operation that
1217 takes operands of this mode and makes a wider mode. */
1219 if (binoptab == smul_optab
1220 && GET_MODE_WIDER_MODE (mode) != VOIDmode
1221 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1222 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
1223 != CODE_FOR_nothing))
1225 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1226 unsignedp ? umul_widen_optab : smul_widen_optab,
1227 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1229 if (temp != 0)
1231 if (GET_MODE_CLASS (mode) == MODE_INT
1232 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1233 GET_MODE_BITSIZE (GET_MODE (temp))))
1234 return gen_lowpart (mode, temp);
1235 else
1236 return convert_to_mode (mode, temp, unsignedp);
1240 /* Look for a wider mode of the same class for which we think we
1241 can open-code the operation. Check for a widening multiply at the
1242 wider mode as well. */
1244 if (CLASS_HAS_WIDER_MODES_P (class)
1245 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1246 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1247 wider_mode != VOIDmode;
1248 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1250 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
1251 || (binoptab == smul_optab
1252 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1253 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1254 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
1255 != CODE_FOR_nothing)))
1257 rtx xop0 = op0, xop1 = op1;
1258 int no_extend = 0;
1260 /* For certain integer operations, we need not actually extend
1261 the narrow operands, as long as we will truncate
1262 the results to the same narrowness. */
1264 if ((binoptab == ior_optab || binoptab == and_optab
1265 || binoptab == xor_optab
1266 || binoptab == add_optab || binoptab == sub_optab
1267 || binoptab == smul_optab || binoptab == ashl_optab)
1268 && class == MODE_INT)
1269 no_extend = 1;
1271 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1273 /* The second operand of a shift must always be extended. */
1274 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1275 no_extend && binoptab != ashl_optab);
1277 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1278 unsignedp, OPTAB_DIRECT);
1279 if (temp)
1281 if (class != MODE_INT
1282 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1283 GET_MODE_BITSIZE (wider_mode)))
1285 if (target == 0)
1286 target = gen_reg_rtx (mode);
1287 convert_move (target, temp, 0);
1288 return target;
1290 else
1291 return gen_lowpart (mode, temp);
1293 else
1294 delete_insns_since (last);
1298 /* These can be done a word at a time. */
1299 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1300 && class == MODE_INT
1301 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1302 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1304 int i;
1305 rtx insns;
1306 rtx equiv_value;
1308 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1309 won't be accurate, so use a new target. */
1310 if (target == 0 || target == op0 || target == op1)
1311 target = gen_reg_rtx (mode);
1313 start_sequence ();
1315 /* Do the actual arithmetic. */
1316 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1318 rtx target_piece = operand_subword (target, i, 1, mode);
1319 rtx x = expand_binop (word_mode, binoptab,
1320 operand_subword_force (op0, i, mode),
1321 operand_subword_force (op1, i, mode),
1322 target_piece, unsignedp, next_methods);
1324 if (x == 0)
1325 break;
1327 if (target_piece != x)
1328 emit_move_insn (target_piece, x);
1331 insns = get_insns ();
1332 end_sequence ();
1334 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1336 if (binoptab->code != UNKNOWN)
1337 equiv_value
1338 = gen_rtx_fmt_ee (binoptab->code, mode,
1339 copy_rtx (op0), copy_rtx (op1));
1340 else
1341 equiv_value = 0;
1343 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1344 return target;
1348 /* Synthesize double word shifts from single word shifts. */
1349 if ((binoptab == lshr_optab || binoptab == ashl_optab
1350 || binoptab == ashr_optab)
1351 && class == MODE_INT
1352 && (GET_CODE (op1) == CONST_INT || !optimize_size)
1353 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1354 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1355 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1356 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1358 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1359 enum machine_mode op1_mode;
1361 double_shift_mask = targetm.shift_truncation_mask (mode);
1362 shift_mask = targetm.shift_truncation_mask (word_mode);
1363 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1365 /* Apply the truncation to constant shifts. */
1366 if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1367 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1369 if (op1 == CONST0_RTX (op1_mode))
1370 return op0;
1372 /* Make sure that this is a combination that expand_doubleword_shift
1373 can handle. See the comments there for details. */
1374 if (double_shift_mask == 0
1375 || (shift_mask == BITS_PER_WORD - 1
1376 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1378 rtx insns, equiv_value;
1379 rtx into_target, outof_target;
1380 rtx into_input, outof_input;
1381 int left_shift, outof_word;
1383 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1384 won't be accurate, so use a new target. */
1385 if (target == 0 || target == op0 || target == op1)
1386 target = gen_reg_rtx (mode);
1388 start_sequence ();
1390 /* OUTOF_* is the word we are shifting bits away from, and
1391 INTO_* is the word that we are shifting bits towards, thus
1392 they differ depending on the direction of the shift and
1393 WORDS_BIG_ENDIAN. */
1395 left_shift = binoptab == ashl_optab;
1396 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1398 outof_target = operand_subword (target, outof_word, 1, mode);
1399 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1401 outof_input = operand_subword_force (op0, outof_word, mode);
1402 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1404 if (expand_doubleword_shift (op1_mode, binoptab,
1405 outof_input, into_input, op1,
1406 outof_target, into_target,
1407 unsignedp, methods, shift_mask))
1409 insns = get_insns ();
1410 end_sequence ();
1412 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1413 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1414 return target;
1416 end_sequence ();
1420 /* Synthesize double word rotates from single word shifts. */
1421 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1422 && class == MODE_INT
1423 && GET_CODE (op1) == CONST_INT
1424 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1425 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1426 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1428 rtx insns;
1429 rtx into_target, outof_target;
1430 rtx into_input, outof_input;
1431 rtx inter;
1432 int shift_count, left_shift, outof_word;
1434 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1435 won't be accurate, so use a new target. Do this also if target is not
1436 a REG, first because having a register instead may open optimization
1437 opportunities, and second because if target and op0 happen to be MEMs
1438 designating the same location, we would risk clobbering it too early
1439 in the code sequence we generate below. */
1440 if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1441 target = gen_reg_rtx (mode);
1443 start_sequence ();
1445 shift_count = INTVAL (op1);
1447 /* OUTOF_* is the word we are shifting bits away from, and
1448 INTO_* is the word that we are shifting bits towards, thus
1449 they differ depending on the direction of the shift and
1450 WORDS_BIG_ENDIAN. */
1452 left_shift = (binoptab == rotl_optab);
1453 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1455 outof_target = operand_subword (target, outof_word, 1, mode);
1456 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1458 outof_input = operand_subword_force (op0, outof_word, mode);
1459 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1461 if (shift_count == BITS_PER_WORD)
1463 /* This is just a word swap. */
1464 emit_move_insn (outof_target, into_input);
1465 emit_move_insn (into_target, outof_input);
1466 inter = const0_rtx;
1468 else
1470 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1471 rtx first_shift_count, second_shift_count;
1472 optab reverse_unsigned_shift, unsigned_shift;
1474 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1475 ? lshr_optab : ashl_optab);
1477 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1478 ? ashl_optab : lshr_optab);
1480 if (shift_count > BITS_PER_WORD)
1482 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1483 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1485 else
1487 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1488 second_shift_count = GEN_INT (shift_count);
1491 into_temp1 = expand_binop (word_mode, unsigned_shift,
1492 outof_input, first_shift_count,
1493 NULL_RTX, unsignedp, next_methods);
1494 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1495 into_input, second_shift_count,
1496 NULL_RTX, unsignedp, next_methods);
1498 if (into_temp1 != 0 && into_temp2 != 0)
1499 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1500 into_target, unsignedp, next_methods);
1501 else
1502 inter = 0;
1504 if (inter != 0 && inter != into_target)
1505 emit_move_insn (into_target, inter);
1507 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1508 into_input, first_shift_count,
1509 NULL_RTX, unsignedp, next_methods);
1510 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1511 outof_input, second_shift_count,
1512 NULL_RTX, unsignedp, next_methods);
1514 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1515 inter = expand_binop (word_mode, ior_optab,
1516 outof_temp1, outof_temp2,
1517 outof_target, unsignedp, next_methods);
1519 if (inter != 0 && inter != outof_target)
1520 emit_move_insn (outof_target, inter);
1523 insns = get_insns ();
1524 end_sequence ();
1526 if (inter != 0)
1528 /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1529 block to help the register allocator a bit. But a multi-word
1530 rotate will need all the input bits when setting the output
1531 bits, so there clearly is a conflict between the input and
1532 output registers. So we can't use a no-conflict block here. */
1533 emit_insn (insns);
1534 return target;
1538 /* These can be done a word at a time by propagating carries. */
1539 if ((binoptab == add_optab || binoptab == sub_optab)
1540 && class == MODE_INT
1541 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1542 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1544 unsigned int i;
1545 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1546 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1547 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1548 rtx xop0, xop1, xtarget;
1550 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1551 value is one of those, use it. Otherwise, use 1 since it is the
1552 one easiest to get. */
1553 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1554 int normalizep = STORE_FLAG_VALUE;
1555 #else
1556 int normalizep = 1;
1557 #endif
1559 /* Prepare the operands. */
1560 xop0 = force_reg (mode, op0);
1561 xop1 = force_reg (mode, op1);
1563 xtarget = gen_reg_rtx (mode);
1565 if (target == 0 || !REG_P (target))
1566 target = xtarget;
1568 /* Indicate for flow that the entire target reg is being set. */
1569 if (REG_P (target))
1570 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1572 /* Do the actual arithmetic. */
1573 for (i = 0; i < nwords; i++)
1575 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1576 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1577 rtx op0_piece = operand_subword_force (xop0, index, mode);
1578 rtx op1_piece = operand_subword_force (xop1, index, mode);
1579 rtx x;
1581 /* Main add/subtract of the input operands. */
1582 x = expand_binop (word_mode, binoptab,
1583 op0_piece, op1_piece,
1584 target_piece, unsignedp, next_methods);
1585 if (x == 0)
1586 break;
1588 if (i + 1 < nwords)
1590 /* Store carry from main add/subtract. */
1591 carry_out = gen_reg_rtx (word_mode);
1592 carry_out = emit_store_flag_force (carry_out,
1593 (binoptab == add_optab
1594 ? LT : GT),
1595 x, op0_piece,
1596 word_mode, 1, normalizep);
1599 if (i > 0)
1601 rtx newx;
1603 /* Add/subtract previous carry to main result. */
1604 newx = expand_binop (word_mode,
1605 normalizep == 1 ? binoptab : otheroptab,
1606 x, carry_in,
1607 NULL_RTX, 1, next_methods);
1609 if (i + 1 < nwords)
1611 /* Get out carry from adding/subtracting carry in. */
1612 rtx carry_tmp = gen_reg_rtx (word_mode);
1613 carry_tmp = emit_store_flag_force (carry_tmp,
1614 (binoptab == add_optab
1615 ? LT : GT),
1616 newx, x,
1617 word_mode, 1, normalizep);
1619 /* Logical-ior the two poss. carry together. */
1620 carry_out = expand_binop (word_mode, ior_optab,
1621 carry_out, carry_tmp,
1622 carry_out, 0, next_methods);
1623 if (carry_out == 0)
1624 break;
1626 emit_move_insn (target_piece, newx);
1628 else
1630 if (x != target_piece)
1631 emit_move_insn (target_piece, x);
1634 carry_in = carry_out;
1637 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1639 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
1640 || ! rtx_equal_p (target, xtarget))
1642 rtx temp = emit_move_insn (target, xtarget);
1644 set_unique_reg_note (temp,
1645 REG_EQUAL,
1646 gen_rtx_fmt_ee (binoptab->code, mode,
1647 copy_rtx (xop0),
1648 copy_rtx (xop1)));
1650 else
1651 target = xtarget;
1653 return target;
1656 else
1657 delete_insns_since (last);
1660 /* Attempt to synthesize double word multiplies using a sequence of word
1661 mode multiplications. We first attempt to generate a sequence using a
1662 more efficient unsigned widening multiply, and if that fails we then
1663 try using a signed widening multiply. */
1665 if (binoptab == smul_optab
1666 && class == MODE_INT
1667 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1668 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1669 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1671 rtx product = NULL_RTX;
1673 if (umul_widen_optab->handlers[(int) mode].insn_code
1674 != CODE_FOR_nothing)
1676 product = expand_doubleword_mult (mode, op0, op1, target,
1677 true, methods);
1678 if (!product)
1679 delete_insns_since (last);
1682 if (product == NULL_RTX
1683 && smul_widen_optab->handlers[(int) mode].insn_code
1684 != CODE_FOR_nothing)
1686 product = expand_doubleword_mult (mode, op0, op1, target,
1687 false, methods);
1688 if (!product)
1689 delete_insns_since (last);
1692 if (product != NULL_RTX)
1694 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1696 temp = emit_move_insn (target ? target : product, product);
1697 set_unique_reg_note (temp,
1698 REG_EQUAL,
1699 gen_rtx_fmt_ee (MULT, mode,
1700 copy_rtx (op0),
1701 copy_rtx (op1)));
1703 return product;
1707 /* It can't be open-coded in this mode.
1708 Use a library call if one is available and caller says that's ok. */
1710 if (binoptab->handlers[(int) mode].libfunc
1711 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1713 rtx insns;
1714 rtx op1x = op1;
1715 enum machine_mode op1_mode = mode;
1716 rtx value;
1718 start_sequence ();
1720 if (shift_op)
1722 op1_mode = word_mode;
1723 /* Specify unsigned here,
1724 since negative shift counts are meaningless. */
1725 op1x = convert_to_mode (word_mode, op1, 1);
1728 if (GET_MODE (op0) != VOIDmode
1729 && GET_MODE (op0) != mode)
1730 op0 = convert_to_mode (mode, op0, unsignedp);
1732 /* Pass 1 for NO_QUEUE so we don't lose any increments
1733 if the libcall is cse'd or moved. */
1734 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1735 NULL_RTX, LCT_CONST, mode, 2,
1736 op0, mode, op1x, op1_mode);
1738 insns = get_insns ();
1739 end_sequence ();
1741 target = gen_reg_rtx (mode);
1742 emit_libcall_block (insns, target, value,
1743 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1745 return target;
1748 delete_insns_since (last);
1750 /* It can't be done in this mode. Can we do it in a wider mode? */
1752 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1753 || methods == OPTAB_MUST_WIDEN))
1755 /* Caller says, don't even try. */
1756 delete_insns_since (entry_last);
1757 return 0;
1760 /* Compute the value of METHODS to pass to recursive calls.
1761 Don't allow widening to be tried recursively. */
1763 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1765 /* Look for a wider mode of the same class for which it appears we can do
1766 the operation. */
1768 if (CLASS_HAS_WIDER_MODES_P (class))
1770 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1771 wider_mode != VOIDmode;
1772 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1774 if ((binoptab->handlers[(int) wider_mode].insn_code
1775 != CODE_FOR_nothing)
1776 || (methods == OPTAB_LIB
1777 && binoptab->handlers[(int) wider_mode].libfunc))
1779 rtx xop0 = op0, xop1 = op1;
1780 int no_extend = 0;
1782 /* For certain integer operations, we need not actually extend
1783 the narrow operands, as long as we will truncate
1784 the results to the same narrowness. */
1786 if ((binoptab == ior_optab || binoptab == and_optab
1787 || binoptab == xor_optab
1788 || binoptab == add_optab || binoptab == sub_optab
1789 || binoptab == smul_optab || binoptab == ashl_optab)
1790 && class == MODE_INT)
1791 no_extend = 1;
1793 xop0 = widen_operand (xop0, wider_mode, mode,
1794 unsignedp, no_extend);
1796 /* The second operand of a shift must always be extended. */
1797 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1798 no_extend && binoptab != ashl_optab);
1800 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1801 unsignedp, methods);
1802 if (temp)
1804 if (class != MODE_INT
1805 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1806 GET_MODE_BITSIZE (wider_mode)))
1808 if (target == 0)
1809 target = gen_reg_rtx (mode);
1810 convert_move (target, temp, 0);
1811 return target;
1813 else
1814 return gen_lowpart (mode, temp);
1816 else
1817 delete_insns_since (last);
1822 delete_insns_since (entry_last);
1823 return 0;
1826 /* Expand a binary operator which has both signed and unsigned forms.
1827 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1828 signed operations.
1830 If we widen unsigned operands, we may use a signed wider operation instead
1831 of an unsigned wider operation, since the result would be the same. */
1834 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
1835 rtx op0, rtx op1, rtx target, int unsignedp,
1836 enum optab_methods methods)
1838 rtx temp;
1839 optab direct_optab = unsignedp ? uoptab : soptab;
1840 struct optab wide_soptab;
1842 /* Do it without widening, if possible. */
1843 temp = expand_binop (mode, direct_optab, op0, op1, target,
1844 unsignedp, OPTAB_DIRECT);
1845 if (temp || methods == OPTAB_DIRECT)
1846 return temp;
1848 /* Try widening to a signed int. Make a fake signed optab that
1849 hides any signed insn for direct use. */
1850 wide_soptab = *soptab;
1851 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1852 wide_soptab.handlers[(int) mode].libfunc = 0;
1854 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1855 unsignedp, OPTAB_WIDEN);
1857 /* For unsigned operands, try widening to an unsigned int. */
1858 if (temp == 0 && unsignedp)
1859 temp = expand_binop (mode, uoptab, op0, op1, target,
1860 unsignedp, OPTAB_WIDEN);
1861 if (temp || methods == OPTAB_WIDEN)
1862 return temp;
1864 /* Use the right width lib call if that exists. */
1865 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1866 if (temp || methods == OPTAB_LIB)
1867 return temp;
1869 /* Must widen and use a lib call, use either signed or unsigned. */
1870 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1871 unsignedp, methods);
1872 if (temp != 0)
1873 return temp;
1874 if (unsignedp)
1875 return expand_binop (mode, uoptab, op0, op1, target,
1876 unsignedp, methods);
1877 return 0;
1880 /* Generate code to perform an operation specified by UNOPPTAB
1881 on operand OP0, with two results to TARG0 and TARG1.
1882 We assume that the order of the operands for the instruction
1883 is TARG0, TARG1, OP0.
1885 Either TARG0 or TARG1 may be zero, but what that means is that
1886 the result is not actually wanted. We will generate it into
1887 a dummy pseudo-reg and discard it. They may not both be zero.
1889 Returns 1 if this operation can be performed; 0 if not. */
1892 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1893 int unsignedp)
1895 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1896 enum mode_class class;
1897 enum machine_mode wider_mode;
1898 rtx entry_last = get_last_insn ();
1899 rtx last;
1901 class = GET_MODE_CLASS (mode);
1903 if (!targ0)
1904 targ0 = gen_reg_rtx (mode);
1905 if (!targ1)
1906 targ1 = gen_reg_rtx (mode);
1908 /* Record where to go back to if we fail. */
1909 last = get_last_insn ();
1911 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1913 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1914 enum machine_mode mode0 = insn_data[icode].operand[2].mode;
1915 rtx pat;
1916 rtx xop0 = op0;
1918 if (GET_MODE (xop0) != VOIDmode
1919 && GET_MODE (xop0) != mode0)
1920 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1922 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1923 if (!insn_data[icode].operand[2].predicate (xop0, mode0))
1924 xop0 = copy_to_mode_reg (mode0, xop0);
1926 /* We could handle this, but we should always be called with a pseudo
1927 for our targets and all insns should take them as outputs. */
1928 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
1929 gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
1931 pat = GEN_FCN (icode) (targ0, targ1, xop0);
1932 if (pat)
1934 emit_insn (pat);
1935 return 1;
1937 else
1938 delete_insns_since (last);
1941 /* It can't be done in this mode. Can we do it in a wider mode? */
1943 if (CLASS_HAS_WIDER_MODES_P (class))
1945 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1946 wider_mode != VOIDmode;
1947 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1949 if (unoptab->handlers[(int) wider_mode].insn_code
1950 != CODE_FOR_nothing)
1952 rtx t0 = gen_reg_rtx (wider_mode);
1953 rtx t1 = gen_reg_rtx (wider_mode);
1954 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1956 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
1958 convert_move (targ0, t0, unsignedp);
1959 convert_move (targ1, t1, unsignedp);
1960 return 1;
1962 else
1963 delete_insns_since (last);
1968 delete_insns_since (entry_last);
1969 return 0;
1972 /* Generate code to perform an operation specified by BINOPTAB
1973 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1974 We assume that the order of the operands for the instruction
1975 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1976 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1978 Either TARG0 or TARG1 may be zero, but what that means is that
1979 the result is not actually wanted. We will generate it into
1980 a dummy pseudo-reg and discard it. They may not both be zero.
1982 Returns 1 if this operation can be performed; 0 if not. */
1985 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
1986 int unsignedp)
1988 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1989 enum mode_class class;
1990 enum machine_mode wider_mode;
1991 rtx entry_last = get_last_insn ();
1992 rtx last;
1994 class = GET_MODE_CLASS (mode);
1996 /* If we are inside an appropriately-short loop and we are optimizing,
1997 force expensive constants into a register. */
1998 if (CONSTANT_P (op0) && optimize
1999 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2000 op0 = force_reg (mode, op0);
2002 if (CONSTANT_P (op1) && optimize
2003 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2004 op1 = force_reg (mode, op1);
2006 if (!targ0)
2007 targ0 = gen_reg_rtx (mode);
2008 if (!targ1)
2009 targ1 = gen_reg_rtx (mode);
2011 /* Record where to go back to if we fail. */
2012 last = get_last_insn ();
2014 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2016 int icode = (int) binoptab->handlers[(int) mode].insn_code;
2017 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2018 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2019 rtx pat;
2020 rtx xop0 = op0, xop1 = op1;
2022 /* In case the insn wants input operands in modes different from
2023 those of the actual operands, convert the operands. It would
2024 seem that we don't need to convert CONST_INTs, but we do, so
2025 that they're properly zero-extended, sign-extended or truncated
2026 for their mode. */
2028 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2029 xop0 = convert_modes (mode0,
2030 GET_MODE (op0) != VOIDmode
2031 ? GET_MODE (op0)
2032 : mode,
2033 xop0, unsignedp);
2035 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2036 xop1 = convert_modes (mode1,
2037 GET_MODE (op1) != VOIDmode
2038 ? GET_MODE (op1)
2039 : mode,
2040 xop1, unsignedp);
2042 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2043 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2044 xop0 = copy_to_mode_reg (mode0, xop0);
2046 if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2047 xop1 = copy_to_mode_reg (mode1, xop1);
2049 /* We could handle this, but we should always be called with a pseudo
2050 for our targets and all insns should take them as outputs. */
2051 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2052 gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2054 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2055 if (pat)
2057 emit_insn (pat);
2058 return 1;
2060 else
2061 delete_insns_since (last);
2064 /* It can't be done in this mode. Can we do it in a wider mode? */
2066 if (CLASS_HAS_WIDER_MODES_P (class))
2068 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2069 wider_mode != VOIDmode;
2070 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2072 if (binoptab->handlers[(int) wider_mode].insn_code
2073 != CODE_FOR_nothing)
2075 rtx t0 = gen_reg_rtx (wider_mode);
2076 rtx t1 = gen_reg_rtx (wider_mode);
2077 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2078 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2080 if (expand_twoval_binop (binoptab, cop0, cop1,
2081 t0, t1, unsignedp))
2083 convert_move (targ0, t0, unsignedp);
2084 convert_move (targ1, t1, unsignedp);
2085 return 1;
2087 else
2088 delete_insns_since (last);
2093 delete_insns_since (entry_last);
2094 return 0;
2097 /* Expand the two-valued library call indicated by BINOPTAB, but
2098 preserve only one of the values. If TARG0 is non-NULL, the first
2099 value is placed into TARG0; otherwise the second value is placed
2100 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2101 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2102 This routine assumes that the value returned by the library call is
2103 as if the return value was of an integral mode twice as wide as the
2104 mode of OP0. Returns 1 if the call was successful. */
2106 bool
2107 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2108 rtx targ0, rtx targ1, enum rtx_code code)
2110 enum machine_mode mode;
2111 enum machine_mode libval_mode;
2112 rtx libval;
2113 rtx insns;
2115 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2116 gcc_assert (!targ0 != !targ1);
2118 mode = GET_MODE (op0);
2119 if (!binoptab->handlers[(int) mode].libfunc)
2120 return false;
2122 /* The value returned by the library function will have twice as
2123 many bits as the nominal MODE. */
2124 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2125 MODE_INT);
2126 start_sequence ();
2127 libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
2128 NULL_RTX, LCT_CONST,
2129 libval_mode, 2,
2130 op0, mode,
2131 op1, mode);
2132 /* Get the part of VAL containing the value that we want. */
2133 libval = simplify_gen_subreg (mode, libval, libval_mode,
2134 targ0 ? 0 : GET_MODE_SIZE (mode));
2135 insns = get_insns ();
2136 end_sequence ();
2137 /* Move the into the desired location. */
2138 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2139 gen_rtx_fmt_ee (code, mode, op0, op1));
2141 return true;
2145 /* Wrapper around expand_unop which takes an rtx code to specify
2146 the operation to perform, not an optab pointer. All other
2147 arguments are the same. */
2149 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2150 rtx target, int unsignedp)
2152 optab unop = code_to_optab[(int) code];
2153 gcc_assert (unop);
2155 return expand_unop (mode, unop, op0, target, unsignedp);
2158 /* Try calculating
2159 (clz:narrow x)
2161 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2162 static rtx
2163 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2165 enum mode_class class = GET_MODE_CLASS (mode);
2166 if (CLASS_HAS_WIDER_MODES_P (class))
2168 enum machine_mode wider_mode;
2169 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2170 wider_mode != VOIDmode;
2171 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2173 if (clz_optab->handlers[(int) wider_mode].insn_code
2174 != CODE_FOR_nothing)
2176 rtx xop0, temp, last;
2178 last = get_last_insn ();
2180 if (target == 0)
2181 target = gen_reg_rtx (mode);
2182 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2183 temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2184 if (temp != 0)
2185 temp = expand_binop (wider_mode, sub_optab, temp,
2186 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2187 - GET_MODE_BITSIZE (mode)),
2188 target, true, OPTAB_DIRECT);
2189 if (temp == 0)
2190 delete_insns_since (last);
2192 return temp;
2196 return 0;
2199 /* Try calculating (parity x) as (and (popcount x) 1), where
2200 popcount can also be done in a wider mode. */
2201 static rtx
2202 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2204 enum mode_class class = GET_MODE_CLASS (mode);
2205 if (CLASS_HAS_WIDER_MODES_P (class))
2207 enum machine_mode wider_mode;
2208 for (wider_mode = mode; wider_mode != VOIDmode;
2209 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2211 if (popcount_optab->handlers[(int) wider_mode].insn_code
2212 != CODE_FOR_nothing)
2214 rtx xop0, temp, last;
2216 last = get_last_insn ();
2218 if (target == 0)
2219 target = gen_reg_rtx (mode);
2220 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2221 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2222 true);
2223 if (temp != 0)
2224 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2225 target, true, OPTAB_DIRECT);
2226 if (temp == 0)
2227 delete_insns_since (last);
2229 return temp;
2233 return 0;
2236 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2237 conditions, VAL may already be a SUBREG against which we cannot generate
2238 a further SUBREG. In this case, we expect forcing the value into a
2239 register will work around the situation. */
2241 static rtx
2242 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2243 enum machine_mode imode)
2245 rtx ret;
2246 ret = lowpart_subreg (omode, val, imode);
2247 if (ret == NULL)
2249 val = force_reg (imode, val);
2250 ret = lowpart_subreg (omode, val, imode);
2251 gcc_assert (ret != NULL);
2253 return ret;
2256 /* Expand a floating point absolute value or negation operation via a
2257 logical operation on the sign bit. */
2259 static rtx
2260 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2261 rtx op0, rtx target)
2263 const struct real_format *fmt;
2264 int bitpos, word, nwords, i;
2265 enum machine_mode imode;
2266 HOST_WIDE_INT hi, lo;
2267 rtx temp, insns;
2269 /* The format has to have a simple sign bit. */
2270 fmt = REAL_MODE_FORMAT (mode);
2271 if (fmt == NULL)
2272 return NULL_RTX;
2274 bitpos = fmt->signbit_rw;
2275 if (bitpos < 0)
2276 return NULL_RTX;
2278 /* Don't create negative zeros if the format doesn't support them. */
2279 if (code == NEG && !fmt->has_signed_zero)
2280 return NULL_RTX;
2282 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2284 imode = int_mode_for_mode (mode);
2285 if (imode == BLKmode)
2286 return NULL_RTX;
2287 word = 0;
2288 nwords = 1;
2290 else
2292 imode = word_mode;
2294 if (FLOAT_WORDS_BIG_ENDIAN)
2295 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2296 else
2297 word = bitpos / BITS_PER_WORD;
2298 bitpos = bitpos % BITS_PER_WORD;
2299 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2302 if (bitpos < HOST_BITS_PER_WIDE_INT)
2304 hi = 0;
2305 lo = (HOST_WIDE_INT) 1 << bitpos;
2307 else
2309 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2310 lo = 0;
2312 if (code == ABS)
2313 lo = ~lo, hi = ~hi;
2315 if (target == 0 || target == op0)
2316 target = gen_reg_rtx (mode);
2318 if (nwords > 1)
2320 start_sequence ();
2322 for (i = 0; i < nwords; ++i)
2324 rtx targ_piece = operand_subword (target, i, 1, mode);
2325 rtx op0_piece = operand_subword_force (op0, i, mode);
2327 if (i == word)
2329 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2330 op0_piece,
2331 immed_double_const (lo, hi, imode),
2332 targ_piece, 1, OPTAB_LIB_WIDEN);
2333 if (temp != targ_piece)
2334 emit_move_insn (targ_piece, temp);
2336 else
2337 emit_move_insn (targ_piece, op0_piece);
2340 insns = get_insns ();
2341 end_sequence ();
2343 temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2344 emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2346 else
2348 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2349 gen_lowpart (imode, op0),
2350 immed_double_const (lo, hi, imode),
2351 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2352 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2354 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2355 gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2358 return target;
2361 /* Generate code to perform an operation specified by UNOPTAB
2362 on operand OP0, with result having machine-mode MODE.
2364 UNSIGNEDP is for the case where we have to widen the operands
2365 to perform the operation. It says to use zero-extension.
2367 If TARGET is nonzero, the value
2368 is generated there, if it is convenient to do so.
2369 In all cases an rtx is returned for the locus of the value;
2370 this may or may not be TARGET. */
2373 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2374 int unsignedp)
2376 enum mode_class class;
2377 enum machine_mode wider_mode;
2378 rtx temp;
2379 rtx last = get_last_insn ();
2380 rtx pat;
2382 class = GET_MODE_CLASS (mode);
2384 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2386 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2387 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2388 rtx xop0 = op0;
2390 if (target)
2391 temp = target;
2392 else
2393 temp = gen_reg_rtx (mode);
2395 if (GET_MODE (xop0) != VOIDmode
2396 && GET_MODE (xop0) != mode0)
2397 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2399 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2401 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2402 xop0 = copy_to_mode_reg (mode0, xop0);
2404 if (!insn_data[icode].operand[0].predicate (temp, mode))
2405 temp = gen_reg_rtx (mode);
2407 pat = GEN_FCN (icode) (temp, xop0);
2408 if (pat)
2410 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2411 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2413 delete_insns_since (last);
2414 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2417 emit_insn (pat);
2419 return temp;
2421 else
2422 delete_insns_since (last);
2425 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2427 /* Widening clz needs special treatment. */
2428 if (unoptab == clz_optab)
2430 temp = widen_clz (mode, op0, target);
2431 if (temp)
2432 return temp;
2433 else
2434 goto try_libcall;
2437 if (CLASS_HAS_WIDER_MODES_P (class))
2438 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2439 wider_mode != VOIDmode;
2440 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2442 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2444 rtx xop0 = op0;
2446 /* For certain operations, we need not actually extend
2447 the narrow operand, as long as we will truncate the
2448 results to the same narrowness. */
2450 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2451 (unoptab == neg_optab
2452 || unoptab == one_cmpl_optab)
2453 && class == MODE_INT);
2455 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2456 unsignedp);
2458 if (temp)
2460 if (class != MODE_INT
2461 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2462 GET_MODE_BITSIZE (wider_mode)))
2464 if (target == 0)
2465 target = gen_reg_rtx (mode);
2466 convert_move (target, temp, 0);
2467 return target;
2469 else
2470 return gen_lowpart (mode, temp);
2472 else
2473 delete_insns_since (last);
2477 /* These can be done a word at a time. */
2478 if (unoptab == one_cmpl_optab
2479 && class == MODE_INT
2480 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2481 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2483 int i;
2484 rtx insns;
2486 if (target == 0 || target == op0)
2487 target = gen_reg_rtx (mode);
2489 start_sequence ();
2491 /* Do the actual arithmetic. */
2492 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2494 rtx target_piece = operand_subword (target, i, 1, mode);
2495 rtx x = expand_unop (word_mode, unoptab,
2496 operand_subword_force (op0, i, mode),
2497 target_piece, unsignedp);
2499 if (target_piece != x)
2500 emit_move_insn (target_piece, x);
2503 insns = get_insns ();
2504 end_sequence ();
2506 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2507 gen_rtx_fmt_e (unoptab->code, mode,
2508 copy_rtx (op0)));
2509 return target;
2512 if (unoptab->code == NEG)
2514 /* Try negating floating point values by flipping the sign bit. */
2515 if (SCALAR_FLOAT_MODE_P (mode))
2517 temp = expand_absneg_bit (NEG, mode, op0, target);
2518 if (temp)
2519 return temp;
2522 /* If there is no negation pattern, and we have no negative zero,
2523 try subtracting from zero. */
2524 if (!HONOR_SIGNED_ZEROS (mode))
2526 temp = expand_binop (mode, (unoptab == negv_optab
2527 ? subv_optab : sub_optab),
2528 CONST0_RTX (mode), op0, target,
2529 unsignedp, OPTAB_DIRECT);
2530 if (temp)
2531 return temp;
2535 /* Try calculating parity (x) as popcount (x) % 2. */
2536 if (unoptab == parity_optab)
2538 temp = expand_parity (mode, op0, target);
2539 if (temp)
2540 return temp;
2543 try_libcall:
2544 /* Now try a library call in this mode. */
2545 if (unoptab->handlers[(int) mode].libfunc)
2547 rtx insns;
2548 rtx value;
2549 enum machine_mode outmode = mode;
2551 /* All of these functions return small values. Thus we choose to
2552 have them return something that isn't a double-word. */
2553 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2554 || unoptab == popcount_optab || unoptab == parity_optab)
2555 outmode
2556 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2558 start_sequence ();
2560 /* Pass 1 for NO_QUEUE so we don't lose any increments
2561 if the libcall is cse'd or moved. */
2562 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2563 NULL_RTX, LCT_CONST, outmode,
2564 1, op0, mode);
2565 insns = get_insns ();
2566 end_sequence ();
2568 target = gen_reg_rtx (outmode);
2569 emit_libcall_block (insns, target, value,
2570 gen_rtx_fmt_e (unoptab->code, mode, op0));
2572 return target;
2575 /* It can't be done in this mode. Can we do it in a wider mode? */
2577 if (CLASS_HAS_WIDER_MODES_P (class))
2579 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2580 wider_mode != VOIDmode;
2581 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2583 if ((unoptab->handlers[(int) wider_mode].insn_code
2584 != CODE_FOR_nothing)
2585 || unoptab->handlers[(int) wider_mode].libfunc)
2587 rtx xop0 = op0;
2589 /* For certain operations, we need not actually extend
2590 the narrow operand, as long as we will truncate the
2591 results to the same narrowness. */
2593 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2594 (unoptab == neg_optab
2595 || unoptab == one_cmpl_optab)
2596 && class == MODE_INT);
2598 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2599 unsignedp);
2601 /* If we are generating clz using wider mode, adjust the
2602 result. */
2603 if (unoptab == clz_optab && temp != 0)
2604 temp = expand_binop (wider_mode, sub_optab, temp,
2605 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2606 - GET_MODE_BITSIZE (mode)),
2607 target, true, OPTAB_DIRECT);
2609 if (temp)
2611 if (class != MODE_INT)
2613 if (target == 0)
2614 target = gen_reg_rtx (mode);
2615 convert_move (target, temp, 0);
2616 return target;
2618 else
2619 return gen_lowpart (mode, temp);
2621 else
2622 delete_insns_since (last);
2627 /* One final attempt at implementing negation via subtraction,
2628 this time allowing widening of the operand. */
2629 if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
2631 rtx temp;
2632 temp = expand_binop (mode,
2633 unoptab == negv_optab ? subv_optab : sub_optab,
2634 CONST0_RTX (mode), op0,
2635 target, unsignedp, OPTAB_LIB_WIDEN);
2636 if (temp)
2637 return temp;
2640 return 0;
2643 /* Emit code to compute the absolute value of OP0, with result to
2644 TARGET if convenient. (TARGET may be 0.) The return value says
2645 where the result actually is to be found.
2647 MODE is the mode of the operand; the mode of the result is
2648 different but can be deduced from MODE.
2653 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2654 int result_unsignedp)
2656 rtx temp;
2658 if (! flag_trapv)
2659 result_unsignedp = 1;
2661 /* First try to do it with a special abs instruction. */
2662 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2663 op0, target, 0);
2664 if (temp != 0)
2665 return temp;
2667 /* For floating point modes, try clearing the sign bit. */
2668 if (SCALAR_FLOAT_MODE_P (mode))
2670 temp = expand_absneg_bit (ABS, mode, op0, target);
2671 if (temp)
2672 return temp;
2675 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2676 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
2677 && !HONOR_SIGNED_ZEROS (mode))
2679 rtx last = get_last_insn ();
2681 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2682 if (temp != 0)
2683 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2684 OPTAB_WIDEN);
2686 if (temp != 0)
2687 return temp;
2689 delete_insns_since (last);
2692 /* If this machine has expensive jumps, we can do integer absolute
2693 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2694 where W is the width of MODE. */
2696 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2698 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2699 size_int (GET_MODE_BITSIZE (mode) - 1),
2700 NULL_RTX, 0);
2702 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2703 OPTAB_LIB_WIDEN);
2704 if (temp != 0)
2705 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2706 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2708 if (temp != 0)
2709 return temp;
2712 return NULL_RTX;
2716 expand_abs (enum machine_mode mode, rtx op0, rtx target,
2717 int result_unsignedp, int safe)
2719 rtx temp, op1;
2721 if (! flag_trapv)
2722 result_unsignedp = 1;
2724 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2725 if (temp != 0)
2726 return temp;
2728 /* If that does not win, use conditional jump and negate. */
2730 /* It is safe to use the target if it is the same
2731 as the source if this is also a pseudo register */
2732 if (op0 == target && REG_P (op0)
2733 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2734 safe = 1;
2736 op1 = gen_label_rtx ();
2737 if (target == 0 || ! safe
2738 || GET_MODE (target) != mode
2739 || (MEM_P (target) && MEM_VOLATILE_P (target))
2740 || (REG_P (target)
2741 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2742 target = gen_reg_rtx (mode);
2744 emit_move_insn (target, op0);
2745 NO_DEFER_POP;
2747 /* If this mode is an integer too wide to compare properly,
2748 compare word by word. Rely on CSE to optimize constant cases. */
2749 if (GET_MODE_CLASS (mode) == MODE_INT
2750 && ! can_compare_p (GE, mode, ccp_jump))
2751 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2752 NULL_RTX, op1);
2753 else
2754 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2755 NULL_RTX, NULL_RTX, op1);
2757 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2758 target, target, 0);
2759 if (op0 != target)
2760 emit_move_insn (target, op0);
2761 emit_label (op1);
2762 OK_DEFER_POP;
2763 return target;
2766 /* A subroutine of expand_copysign, perform the copysign operation using the
2767 abs and neg primitives advertised to exist on the target. The assumption
2768 is that we have a split register file, and leaving op0 in fp registers,
2769 and not playing with subregs so much, will help the register allocator. */
2771 static rtx
2772 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2773 int bitpos, bool op0_is_abs)
2775 enum machine_mode imode;
2776 HOST_WIDE_INT hi, lo;
2777 int word;
2778 rtx label;
2780 if (target == op1)
2781 target = NULL_RTX;
2783 if (!op0_is_abs)
2785 op0 = expand_unop (mode, abs_optab, op0, target, 0);
2786 if (op0 == NULL)
2787 return NULL_RTX;
2788 target = op0;
2790 else
2792 if (target == NULL_RTX)
2793 target = copy_to_reg (op0);
2794 else
2795 emit_move_insn (target, op0);
2798 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2800 imode = int_mode_for_mode (mode);
2801 if (imode == BLKmode)
2802 return NULL_RTX;
2803 op1 = gen_lowpart (imode, op1);
2805 else
2807 imode = word_mode;
2808 if (FLOAT_WORDS_BIG_ENDIAN)
2809 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2810 else
2811 word = bitpos / BITS_PER_WORD;
2812 bitpos = bitpos % BITS_PER_WORD;
2813 op1 = operand_subword_force (op1, word, mode);
2816 if (bitpos < HOST_BITS_PER_WIDE_INT)
2818 hi = 0;
2819 lo = (HOST_WIDE_INT) 1 << bitpos;
2821 else
2823 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2824 lo = 0;
2827 op1 = expand_binop (imode, and_optab, op1,
2828 immed_double_const (lo, hi, imode),
2829 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2831 label = gen_label_rtx ();
2832 emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label);
2834 if (GET_CODE (op0) == CONST_DOUBLE)
2835 op0 = simplify_unary_operation (NEG, mode, op0, mode);
2836 else
2837 op0 = expand_unop (mode, neg_optab, op0, target, 0);
2838 if (op0 != target)
2839 emit_move_insn (target, op0);
2841 emit_label (label);
2843 return target;
2847 /* A subroutine of expand_copysign, perform the entire copysign operation
2848 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
2849 is true if op0 is known to have its sign bit clear. */
2851 static rtx
2852 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2853 int bitpos, bool op0_is_abs)
2855 enum machine_mode imode;
2856 HOST_WIDE_INT hi, lo;
2857 int word, nwords, i;
2858 rtx temp, insns;
2860 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2862 imode = int_mode_for_mode (mode);
2863 if (imode == BLKmode)
2864 return NULL_RTX;
2865 word = 0;
2866 nwords = 1;
2868 else
2870 imode = word_mode;
2872 if (FLOAT_WORDS_BIG_ENDIAN)
2873 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2874 else
2875 word = bitpos / BITS_PER_WORD;
2876 bitpos = bitpos % BITS_PER_WORD;
2877 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2880 if (bitpos < HOST_BITS_PER_WIDE_INT)
2882 hi = 0;
2883 lo = (HOST_WIDE_INT) 1 << bitpos;
2885 else
2887 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2888 lo = 0;
2891 if (target == 0 || target == op0 || target == op1)
2892 target = gen_reg_rtx (mode);
2894 if (nwords > 1)
2896 start_sequence ();
2898 for (i = 0; i < nwords; ++i)
2900 rtx targ_piece = operand_subword (target, i, 1, mode);
2901 rtx op0_piece = operand_subword_force (op0, i, mode);
2903 if (i == word)
2905 if (!op0_is_abs)
2906 op0_piece = expand_binop (imode, and_optab, op0_piece,
2907 immed_double_const (~lo, ~hi, imode),
2908 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2910 op1 = expand_binop (imode, and_optab,
2911 operand_subword_force (op1, i, mode),
2912 immed_double_const (lo, hi, imode),
2913 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2915 temp = expand_binop (imode, ior_optab, op0_piece, op1,
2916 targ_piece, 1, OPTAB_LIB_WIDEN);
2917 if (temp != targ_piece)
2918 emit_move_insn (targ_piece, temp);
2920 else
2921 emit_move_insn (targ_piece, op0_piece);
2924 insns = get_insns ();
2925 end_sequence ();
2927 emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
2929 else
2931 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
2932 immed_double_const (lo, hi, imode),
2933 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2935 op0 = gen_lowpart (imode, op0);
2936 if (!op0_is_abs)
2937 op0 = expand_binop (imode, and_optab, op0,
2938 immed_double_const (~lo, ~hi, imode),
2939 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2941 temp = expand_binop (imode, ior_optab, op0, op1,
2942 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2943 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2946 return target;
2949 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
2950 scalar floating point mode. Return NULL if we do not know how to
2951 expand the operation inline. */
2954 expand_copysign (rtx op0, rtx op1, rtx target)
2956 enum machine_mode mode = GET_MODE (op0);
2957 const struct real_format *fmt;
2958 bool op0_is_abs;
2959 rtx temp;
2961 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
2962 gcc_assert (GET_MODE (op1) == mode);
2964 /* First try to do it with a special instruction. */
2965 temp = expand_binop (mode, copysign_optab, op0, op1,
2966 target, 0, OPTAB_DIRECT);
2967 if (temp)
2968 return temp;
2970 fmt = REAL_MODE_FORMAT (mode);
2971 if (fmt == NULL || !fmt->has_signed_zero)
2972 return NULL_RTX;
2974 op0_is_abs = false;
2975 if (GET_CODE (op0) == CONST_DOUBLE)
2977 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
2978 op0 = simplify_unary_operation (ABS, mode, op0, mode);
2979 op0_is_abs = true;
2982 if (fmt->signbit_ro >= 0
2983 && (GET_CODE (op0) == CONST_DOUBLE
2984 || (neg_optab->handlers[mode].insn_code != CODE_FOR_nothing
2985 && abs_optab->handlers[mode].insn_code != CODE_FOR_nothing)))
2987 temp = expand_copysign_absneg (mode, op0, op1, target,
2988 fmt->signbit_ro, op0_is_abs);
2989 if (temp)
2990 return temp;
2993 if (fmt->signbit_rw < 0)
2994 return NULL_RTX;
2995 return expand_copysign_bit (mode, op0, op1, target,
2996 fmt->signbit_rw, op0_is_abs);
2999 /* Generate an instruction whose insn-code is INSN_CODE,
3000 with two operands: an output TARGET and an input OP0.
3001 TARGET *must* be nonzero, and the output is always stored there.
3002 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3003 the value that is stored into TARGET. */
3005 void
3006 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3008 rtx temp;
3009 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3010 rtx pat;
3012 temp = target;
3014 /* Now, if insn does not accept our operands, put them into pseudos. */
3016 if (!insn_data[icode].operand[1].predicate (op0, mode0))
3017 op0 = copy_to_mode_reg (mode0, op0);
3019 if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3020 temp = gen_reg_rtx (GET_MODE (temp));
3022 pat = GEN_FCN (icode) (temp, op0);
3024 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3025 add_equal_note (pat, temp, code, op0, NULL_RTX);
3027 emit_insn (pat);
3029 if (temp != target)
3030 emit_move_insn (target, temp);
3033 struct no_conflict_data
3035 rtx target, first, insn;
3036 bool must_stay;
3039 /* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3040 Set P->must_stay if the currently examined clobber / store has to stay
3041 in the list of insns that constitute the actual no_conflict block /
3042 libcall block. */
3043 static void
3044 no_conflict_move_test (rtx dest, rtx set, void *p0)
3046 struct no_conflict_data *p= p0;
3048 /* If this inns directly contributes to setting the target, it must stay. */
3049 if (reg_overlap_mentioned_p (p->target, dest))
3050 p->must_stay = true;
3051 /* If we haven't committed to keeping any other insns in the list yet,
3052 there is nothing more to check. */
3053 else if (p->insn == p->first)
3054 return;
3055 /* If this insn sets / clobbers a register that feeds one of the insns
3056 already in the list, this insn has to stay too. */
3057 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3058 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3059 || reg_used_between_p (dest, p->first, p->insn)
3060 /* Likewise if this insn depends on a register set by a previous
3061 insn in the list, or if it sets a result (presumably a hard
3062 register) that is set or clobbered by a previous insn.
3063 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3064 SET_DEST perform the former check on the address, and the latter
3065 check on the MEM. */
3066 || (GET_CODE (set) == SET
3067 && (modified_in_p (SET_SRC (set), p->first)
3068 || modified_in_p (SET_DEST (set), p->first)
3069 || modified_between_p (SET_SRC (set), p->first, p->insn)
3070 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3071 p->must_stay = true;
3074 /* Emit code to perform a series of operations on a multi-word quantity, one
3075 word at a time.
3077 Such a block is preceded by a CLOBBER of the output, consists of multiple
3078 insns, each setting one word of the output, and followed by a SET copying
3079 the output to itself.
3081 Each of the insns setting words of the output receives a REG_NO_CONFLICT
3082 note indicating that it doesn't conflict with the (also multi-word)
3083 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3084 notes.
3086 INSNS is a block of code generated to perform the operation, not including
3087 the CLOBBER and final copy. All insns that compute intermediate values
3088 are first emitted, followed by the block as described above.
3090 TARGET, OP0, and OP1 are the output and inputs of the operations,
3091 respectively. OP1 may be zero for a unary operation.
3093 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3094 on the last insn.
3096 If TARGET is not a register, INSNS is simply emitted with no special
3097 processing. Likewise if anything in INSNS is not an INSN or if
3098 there is a libcall block inside INSNS.
3100 The final insn emitted is returned. */
3103 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3105 rtx prev, next, first, last, insn;
3107 if (!REG_P (target) || reload_in_progress)
3108 return emit_insn (insns);
3109 else
3110 for (insn = insns; insn; insn = NEXT_INSN (insn))
3111 if (!NONJUMP_INSN_P (insn)
3112 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3113 return emit_insn (insns);
3115 /* First emit all insns that do not store into words of the output and remove
3116 these from the list. */
3117 for (insn = insns; insn; insn = next)
3119 rtx note;
3120 struct no_conflict_data data;
3122 next = NEXT_INSN (insn);
3124 /* Some ports (cris) create a libcall regions at their own. We must
3125 avoid any potential nesting of LIBCALLs. */
3126 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3127 remove_note (insn, note);
3128 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3129 remove_note (insn, note);
3131 data.target = target;
3132 data.first = insns;
3133 data.insn = insn;
3134 data.must_stay = 0;
3135 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3136 if (! data.must_stay)
3138 if (PREV_INSN (insn))
3139 NEXT_INSN (PREV_INSN (insn)) = next;
3140 else
3141 insns = next;
3143 if (next)
3144 PREV_INSN (next) = PREV_INSN (insn);
3146 add_insn (insn);
3150 prev = get_last_insn ();
3152 /* Now write the CLOBBER of the output, followed by the setting of each
3153 of the words, followed by the final copy. */
3154 if (target != op0 && target != op1)
3155 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3157 for (insn = insns; insn; insn = next)
3159 next = NEXT_INSN (insn);
3160 add_insn (insn);
3162 if (op1 && REG_P (op1))
3163 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3164 REG_NOTES (insn));
3166 if (op0 && REG_P (op0))
3167 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3168 REG_NOTES (insn));
3171 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3172 != CODE_FOR_nothing)
3174 last = emit_move_insn (target, target);
3175 if (equiv)
3176 set_unique_reg_note (last, REG_EQUAL, equiv);
3178 else
3180 last = get_last_insn ();
3182 /* Remove any existing REG_EQUAL note from "last", or else it will
3183 be mistaken for a note referring to the full contents of the
3184 alleged libcall value when found together with the REG_RETVAL
3185 note added below. An existing note can come from an insn
3186 expansion at "last". */
3187 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3190 if (prev == 0)
3191 first = get_insns ();
3192 else
3193 first = NEXT_INSN (prev);
3195 /* Encapsulate the block so it gets manipulated as a unit. */
3196 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3197 REG_NOTES (first));
3198 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3200 return last;
3203 /* Emit code to make a call to a constant function or a library call.
3205 INSNS is a list containing all insns emitted in the call.
3206 These insns leave the result in RESULT. Our block is to copy RESULT
3207 to TARGET, which is logically equivalent to EQUIV.
3209 We first emit any insns that set a pseudo on the assumption that these are
3210 loading constants into registers; doing so allows them to be safely cse'ed
3211 between blocks. Then we emit all the other insns in the block, followed by
3212 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3213 note with an operand of EQUIV.
3215 Moving assignments to pseudos outside of the block is done to improve
3216 the generated code, but is not required to generate correct code,
3217 hence being unable to move an assignment is not grounds for not making
3218 a libcall block. There are two reasons why it is safe to leave these
3219 insns inside the block: First, we know that these pseudos cannot be
3220 used in generated RTL outside the block since they are created for
3221 temporary purposes within the block. Second, CSE will not record the
3222 values of anything set inside a libcall block, so we know they must
3223 be dead at the end of the block.
3225 Except for the first group of insns (the ones setting pseudos), the
3226 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3228 void
3229 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3231 rtx final_dest = target;
3232 rtx prev, next, first, last, insn;
3234 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3235 into a MEM later. Protect the libcall block from this change. */
3236 if (! REG_P (target) || REG_USERVAR_P (target))
3237 target = gen_reg_rtx (GET_MODE (target));
3239 /* If we're using non-call exceptions, a libcall corresponding to an
3240 operation that may trap may also trap. */
3241 if (flag_non_call_exceptions && may_trap_p (equiv))
3243 for (insn = insns; insn; insn = NEXT_INSN (insn))
3244 if (CALL_P (insn))
3246 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3248 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3249 remove_note (insn, note);
3252 else
3253 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3254 reg note to indicate that this call cannot throw or execute a nonlocal
3255 goto (unless there is already a REG_EH_REGION note, in which case
3256 we update it). */
3257 for (insn = insns; insn; insn = NEXT_INSN (insn))
3258 if (CALL_P (insn))
3260 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3262 if (note != 0)
3263 XEXP (note, 0) = constm1_rtx;
3264 else
3265 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3266 REG_NOTES (insn));
3269 /* First emit all insns that set pseudos. Remove them from the list as
3270 we go. Avoid insns that set pseudos which were referenced in previous
3271 insns. These can be generated by move_by_pieces, for example,
3272 to update an address. Similarly, avoid insns that reference things
3273 set in previous insns. */
3275 for (insn = insns; insn; insn = next)
3277 rtx set = single_set (insn);
3278 rtx note;
3280 /* Some ports (cris) create a libcall regions at their own. We must
3281 avoid any potential nesting of LIBCALLs. */
3282 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3283 remove_note (insn, note);
3284 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3285 remove_note (insn, note);
3287 next = NEXT_INSN (insn);
3289 if (set != 0 && REG_P (SET_DEST (set))
3290 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3292 struct no_conflict_data data;
3294 data.target = const0_rtx;
3295 data.first = insns;
3296 data.insn = insn;
3297 data.must_stay = 0;
3298 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3299 if (! data.must_stay)
3301 if (PREV_INSN (insn))
3302 NEXT_INSN (PREV_INSN (insn)) = next;
3303 else
3304 insns = next;
3306 if (next)
3307 PREV_INSN (next) = PREV_INSN (insn);
3309 add_insn (insn);
3313 /* Some ports use a loop to copy large arguments onto the stack.
3314 Don't move anything outside such a loop. */
3315 if (LABEL_P (insn))
3316 break;
3319 prev = get_last_insn ();
3321 /* Write the remaining insns followed by the final copy. */
3323 for (insn = insns; insn; insn = next)
3325 next = NEXT_INSN (insn);
3327 add_insn (insn);
3330 last = emit_move_insn (target, result);
3331 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3332 != CODE_FOR_nothing)
3333 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3334 else
3336 /* Remove any existing REG_EQUAL note from "last", or else it will
3337 be mistaken for a note referring to the full contents of the
3338 libcall value when found together with the REG_RETVAL note added
3339 below. An existing note can come from an insn expansion at
3340 "last". */
3341 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3344 if (final_dest != target)
3345 emit_move_insn (final_dest, target);
3347 if (prev == 0)
3348 first = get_insns ();
3349 else
3350 first = NEXT_INSN (prev);
3352 /* Encapsulate the block so it gets manipulated as a unit. */
3353 if (!flag_non_call_exceptions || !may_trap_p (equiv))
3355 /* We can't attach the REG_LIBCALL and REG_RETVAL notes
3356 when the encapsulated region would not be in one basic block,
3357 i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
3359 bool attach_libcall_retval_notes = true;
3360 next = NEXT_INSN (last);
3361 for (insn = first; insn != next; insn = NEXT_INSN (insn))
3362 if (control_flow_insn_p (insn))
3364 attach_libcall_retval_notes = false;
3365 break;
3368 if (attach_libcall_retval_notes)
3370 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3371 REG_NOTES (first));
3372 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3373 REG_NOTES (last));
3378 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3379 PURPOSE describes how this comparison will be used. CODE is the rtx
3380 comparison code we will be using.
3382 ??? Actually, CODE is slightly weaker than that. A target is still
3383 required to implement all of the normal bcc operations, but not
3384 required to implement all (or any) of the unordered bcc operations. */
3387 can_compare_p (enum rtx_code code, enum machine_mode mode,
3388 enum can_compare_purpose purpose)
3392 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3394 if (purpose == ccp_jump)
3395 return bcc_gen_fctn[(int) code] != NULL;
3396 else if (purpose == ccp_store_flag)
3397 return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3398 else
3399 /* There's only one cmov entry point, and it's allowed to fail. */
3400 return 1;
3402 if (purpose == ccp_jump
3403 && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3404 return 1;
3405 if (purpose == ccp_cmov
3406 && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3407 return 1;
3408 if (purpose == ccp_store_flag
3409 && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3410 return 1;
3411 mode = GET_MODE_WIDER_MODE (mode);
3413 while (mode != VOIDmode);
3415 return 0;
3418 /* This function is called when we are going to emit a compare instruction that
3419 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3421 *PMODE is the mode of the inputs (in case they are const_int).
3422 *PUNSIGNEDP nonzero says that the operands are unsigned;
3423 this matters if they need to be widened.
3425 If they have mode BLKmode, then SIZE specifies the size of both operands.
3427 This function performs all the setup necessary so that the caller only has
3428 to emit a single comparison insn. This setup can involve doing a BLKmode
3429 comparison or emitting a library call to perform the comparison if no insn
3430 is available to handle it.
3431 The values which are passed in through pointers can be modified; the caller
3432 should perform the comparison on the modified values. Constant
3433 comparisons must have already been folded. */
3435 static void
3436 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3437 enum machine_mode *pmode, int *punsignedp,
3438 enum can_compare_purpose purpose)
3440 enum machine_mode mode = *pmode;
3441 rtx x = *px, y = *py;
3442 int unsignedp = *punsignedp;
3444 /* If we are inside an appropriately-short loop and we are optimizing,
3445 force expensive constants into a register. */
3446 if (CONSTANT_P (x) && optimize
3447 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3448 x = force_reg (mode, x);
3450 if (CONSTANT_P (y) && optimize
3451 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3452 y = force_reg (mode, y);
3454 #ifdef HAVE_cc0
3455 /* Make sure if we have a canonical comparison. The RTL
3456 documentation states that canonical comparisons are required only
3457 for targets which have cc0. */
3458 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3459 #endif
3461 /* Don't let both operands fail to indicate the mode. */
3462 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3463 x = force_reg (mode, x);
3465 /* Handle all BLKmode compares. */
3467 if (mode == BLKmode)
3469 enum machine_mode cmp_mode, result_mode;
3470 enum insn_code cmp_code;
3471 tree length_type;
3472 rtx libfunc;
3473 rtx result;
3474 rtx opalign
3475 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3477 gcc_assert (size);
3479 /* Try to use a memory block compare insn - either cmpstr
3480 or cmpmem will do. */
3481 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3482 cmp_mode != VOIDmode;
3483 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3485 cmp_code = cmpmem_optab[cmp_mode];
3486 if (cmp_code == CODE_FOR_nothing)
3487 cmp_code = cmpstr_optab[cmp_mode];
3488 if (cmp_code == CODE_FOR_nothing)
3489 cmp_code = cmpstrn_optab[cmp_mode];
3490 if (cmp_code == CODE_FOR_nothing)
3491 continue;
3493 /* Must make sure the size fits the insn's mode. */
3494 if ((GET_CODE (size) == CONST_INT
3495 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3496 || (GET_MODE_BITSIZE (GET_MODE (size))
3497 > GET_MODE_BITSIZE (cmp_mode)))
3498 continue;
3500 result_mode = insn_data[cmp_code].operand[0].mode;
3501 result = gen_reg_rtx (result_mode);
3502 size = convert_to_mode (cmp_mode, size, 1);
3503 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3505 *px = result;
3506 *py = const0_rtx;
3507 *pmode = result_mode;
3508 return;
3511 /* Otherwise call a library function, memcmp. */
3512 libfunc = memcmp_libfunc;
3513 length_type = sizetype;
3514 result_mode = TYPE_MODE (integer_type_node);
3515 cmp_mode = TYPE_MODE (length_type);
3516 size = convert_to_mode (TYPE_MODE (length_type), size,
3517 TYPE_UNSIGNED (length_type));
3519 result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3520 result_mode, 3,
3521 XEXP (x, 0), Pmode,
3522 XEXP (y, 0), Pmode,
3523 size, cmp_mode);
3524 *px = result;
3525 *py = const0_rtx;
3526 *pmode = result_mode;
3527 return;
3530 /* Don't allow operands to the compare to trap, as that can put the
3531 compare and branch in different basic blocks. */
3532 if (flag_non_call_exceptions)
3534 if (may_trap_p (x))
3535 x = force_reg (mode, x);
3536 if (may_trap_p (y))
3537 y = force_reg (mode, y);
3540 *px = x;
3541 *py = y;
3542 if (can_compare_p (*pcomparison, mode, purpose))
3543 return;
3545 /* Handle a lib call just for the mode we are using. */
3547 if (cmp_optab->handlers[(int) mode].libfunc && !SCALAR_FLOAT_MODE_P (mode))
3549 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3550 rtx result;
3552 /* If we want unsigned, and this mode has a distinct unsigned
3553 comparison routine, use that. */
3554 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3555 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3557 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3558 word_mode, 2, x, mode, y, mode);
3560 *px = result;
3561 *pmode = word_mode;
3562 if (TARGET_LIB_INT_CMP_BIASED)
3563 /* Integer comparison returns a result that must be compared
3564 against 1, so that even if we do an unsigned compare
3565 afterward, there is still a value that can represent the
3566 result "less than". */
3567 *py = const1_rtx;
3568 else
3570 *py = const0_rtx;
3571 *punsignedp = 1;
3573 return;
3576 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3577 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3580 /* Before emitting an insn with code ICODE, make sure that X, which is going
3581 to be used for operand OPNUM of the insn, is converted from mode MODE to
3582 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3583 that it is accepted by the operand predicate. Return the new value. */
3585 static rtx
3586 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3587 enum machine_mode wider_mode, int unsignedp)
3589 if (mode != wider_mode)
3590 x = convert_modes (wider_mode, mode, x, unsignedp);
3592 if (!insn_data[icode].operand[opnum].predicate
3593 (x, insn_data[icode].operand[opnum].mode))
3595 if (no_new_pseudos)
3596 return NULL_RTX;
3597 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3600 return x;
3603 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3604 we can do the comparison.
3605 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3606 be NULL_RTX which indicates that only a comparison is to be generated. */
3608 static void
3609 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3610 enum rtx_code comparison, int unsignedp, rtx label)
3612 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3613 enum mode_class class = GET_MODE_CLASS (mode);
3614 enum machine_mode wider_mode = mode;
3616 /* Try combined insns first. */
3619 enum insn_code icode;
3620 PUT_MODE (test, wider_mode);
3622 if (label)
3624 icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3626 if (icode != CODE_FOR_nothing
3627 && insn_data[icode].operand[0].predicate (test, wider_mode))
3629 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3630 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3631 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3632 return;
3636 /* Handle some compares against zero. */
3637 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3638 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3640 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3641 emit_insn (GEN_FCN (icode) (x));
3642 if (label)
3643 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3644 return;
3647 /* Handle compares for which there is a directly suitable insn. */
3649 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3650 if (icode != CODE_FOR_nothing)
3652 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3653 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3654 emit_insn (GEN_FCN (icode) (x, y));
3655 if (label)
3656 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3657 return;
3660 if (!CLASS_HAS_WIDER_MODES_P (class))
3661 break;
3663 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3665 while (wider_mode != VOIDmode);
3667 gcc_unreachable ();
3670 /* Generate code to compare X with Y so that the condition codes are
3671 set and to jump to LABEL if the condition is true. If X is a
3672 constant and Y is not a constant, then the comparison is swapped to
3673 ensure that the comparison RTL has the canonical form.
3675 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3676 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3677 the proper branch condition code.
3679 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3681 MODE is the mode of the inputs (in case they are const_int).
3683 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3684 be passed unchanged to emit_cmp_insn, then potentially converted into an
3685 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3687 void
3688 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3689 enum machine_mode mode, int unsignedp, rtx label)
3691 rtx op0 = x, op1 = y;
3693 /* Swap operands and condition to ensure canonical RTL. */
3694 if (swap_commutative_operands_p (x, y))
3696 /* If we're not emitting a branch, this means some caller
3697 is out of sync. */
3698 gcc_assert (label);
3700 op0 = y, op1 = x;
3701 comparison = swap_condition (comparison);
3704 #ifdef HAVE_cc0
3705 /* If OP0 is still a constant, then both X and Y must be constants.
3706 Force X into a register to create canonical RTL. */
3707 if (CONSTANT_P (op0))
3708 op0 = force_reg (mode, op0);
3709 #endif
3711 if (unsignedp)
3712 comparison = unsigned_condition (comparison);
3714 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3715 ccp_jump);
3716 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3719 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3721 void
3722 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3723 enum machine_mode mode, int unsignedp)
3725 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3728 /* Emit a library call comparison between floating point X and Y.
3729 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3731 static void
3732 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3733 enum machine_mode *pmode, int *punsignedp)
3735 enum rtx_code comparison = *pcomparison;
3736 enum rtx_code swapped = swap_condition (comparison);
3737 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3738 rtx x = *px;
3739 rtx y = *py;
3740 enum machine_mode orig_mode = GET_MODE (x);
3741 enum machine_mode mode;
3742 rtx value, target, insns, equiv;
3743 rtx libfunc = 0;
3744 bool reversed_p = false;
3746 for (mode = orig_mode;
3747 mode != VOIDmode;
3748 mode = GET_MODE_WIDER_MODE (mode))
3750 if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3751 break;
3753 if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
3755 rtx tmp;
3756 tmp = x; x = y; y = tmp;
3757 comparison = swapped;
3758 break;
3761 if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
3762 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
3764 comparison = reversed;
3765 reversed_p = true;
3766 break;
3770 gcc_assert (mode != VOIDmode);
3772 if (mode != orig_mode)
3774 x = convert_to_mode (mode, x, 0);
3775 y = convert_to_mode (mode, y, 0);
3778 /* Attach a REG_EQUAL note describing the semantics of the libcall to
3779 the RTL. The allows the RTL optimizers to delete the libcall if the
3780 condition can be determined at compile-time. */
3781 if (comparison == UNORDERED)
3783 rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
3784 equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
3785 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3786 temp, const_true_rtx, equiv);
3788 else
3790 equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
3791 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3793 rtx true_rtx, false_rtx;
3795 switch (comparison)
3797 case EQ:
3798 true_rtx = const0_rtx;
3799 false_rtx = const_true_rtx;
3800 break;
3802 case NE:
3803 true_rtx = const_true_rtx;
3804 false_rtx = const0_rtx;
3805 break;
3807 case GT:
3808 true_rtx = const1_rtx;
3809 false_rtx = const0_rtx;
3810 break;
3812 case GE:
3813 true_rtx = const0_rtx;
3814 false_rtx = constm1_rtx;
3815 break;
3817 case LT:
3818 true_rtx = constm1_rtx;
3819 false_rtx = const0_rtx;
3820 break;
3822 case LE:
3823 true_rtx = const0_rtx;
3824 false_rtx = const1_rtx;
3825 break;
3827 default:
3828 gcc_unreachable ();
3830 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3831 equiv, true_rtx, false_rtx);
3835 start_sequence ();
3836 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3837 word_mode, 2, x, mode, y, mode);
3838 insns = get_insns ();
3839 end_sequence ();
3841 target = gen_reg_rtx (word_mode);
3842 emit_libcall_block (insns, target, value, equiv);
3844 if (comparison == UNORDERED
3845 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3846 comparison = reversed_p ? EQ : NE;
3848 *px = target;
3849 *py = const0_rtx;
3850 *pmode = word_mode;
3851 *pcomparison = comparison;
3852 *punsignedp = 0;
3855 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3857 void
3858 emit_indirect_jump (rtx loc)
3860 if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
3861 (loc, Pmode))
3862 loc = copy_to_mode_reg (Pmode, loc);
3864 emit_jump_insn (gen_indirect_jump (loc));
3865 emit_barrier ();
3868 #ifdef HAVE_conditional_move
3870 /* Emit a conditional move instruction if the machine supports one for that
3871 condition and machine mode.
3873 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3874 the mode to use should they be constants. If it is VOIDmode, they cannot
3875 both be constants.
3877 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3878 should be stored there. MODE is the mode to use should they be constants.
3879 If it is VOIDmode, they cannot both be constants.
3881 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3882 is not supported. */
3885 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
3886 enum machine_mode cmode, rtx op2, rtx op3,
3887 enum machine_mode mode, int unsignedp)
3889 rtx tem, subtarget, comparison, insn;
3890 enum insn_code icode;
3891 enum rtx_code reversed;
3893 /* If one operand is constant, make it the second one. Only do this
3894 if the other operand is not constant as well. */
3896 if (swap_commutative_operands_p (op0, op1))
3898 tem = op0;
3899 op0 = op1;
3900 op1 = tem;
3901 code = swap_condition (code);
3904 /* get_condition will prefer to generate LT and GT even if the old
3905 comparison was against zero, so undo that canonicalization here since
3906 comparisons against zero are cheaper. */
3907 if (code == LT && op1 == const1_rtx)
3908 code = LE, op1 = const0_rtx;
3909 else if (code == GT && op1 == constm1_rtx)
3910 code = GE, op1 = const0_rtx;
3912 if (cmode == VOIDmode)
3913 cmode = GET_MODE (op0);
3915 if (swap_commutative_operands_p (op2, op3)
3916 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
3917 != UNKNOWN))
3919 tem = op2;
3920 op2 = op3;
3921 op3 = tem;
3922 code = reversed;
3925 if (mode == VOIDmode)
3926 mode = GET_MODE (op2);
3928 icode = movcc_gen_code[mode];
3930 if (icode == CODE_FOR_nothing)
3931 return 0;
3933 if (!target)
3934 target = gen_reg_rtx (mode);
3936 subtarget = target;
3938 /* If the insn doesn't accept these operands, put them in pseudos. */
3940 if (!insn_data[icode].operand[0].predicate
3941 (subtarget, insn_data[icode].operand[0].mode))
3942 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3944 if (!insn_data[icode].operand[2].predicate
3945 (op2, insn_data[icode].operand[2].mode))
3946 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3948 if (!insn_data[icode].operand[3].predicate
3949 (op3, insn_data[icode].operand[3].mode))
3950 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3952 /* Everything should now be in the suitable form, so emit the compare insn
3953 and then the conditional move. */
3955 comparison
3956 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
3958 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3959 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3960 return NULL and let the caller figure out how best to deal with this
3961 situation. */
3962 if (GET_CODE (comparison) != code)
3963 return NULL_RTX;
3965 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3967 /* If that failed, then give up. */
3968 if (insn == 0)
3969 return 0;
3971 emit_insn (insn);
3973 if (subtarget != target)
3974 convert_move (target, subtarget, 0);
3976 return target;
3979 /* Return nonzero if a conditional move of mode MODE is supported.
3981 This function is for combine so it can tell whether an insn that looks
3982 like a conditional move is actually supported by the hardware. If we
3983 guess wrong we lose a bit on optimization, but that's it. */
3984 /* ??? sparc64 supports conditionally moving integers values based on fp
3985 comparisons, and vice versa. How do we handle them? */
3988 can_conditionally_move_p (enum machine_mode mode)
3990 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3991 return 1;
3993 return 0;
3996 #endif /* HAVE_conditional_move */
3998 /* Emit a conditional addition instruction if the machine supports one for that
3999 condition and machine mode.
4001 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4002 the mode to use should they be constants. If it is VOIDmode, they cannot
4003 both be constants.
4005 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4006 should be stored there. MODE is the mode to use should they be constants.
4007 If it is VOIDmode, they cannot both be constants.
4009 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4010 is not supported. */
4013 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4014 enum machine_mode cmode, rtx op2, rtx op3,
4015 enum machine_mode mode, int unsignedp)
4017 rtx tem, subtarget, comparison, insn;
4018 enum insn_code icode;
4019 enum rtx_code reversed;
4021 /* If one operand is constant, make it the second one. Only do this
4022 if the other operand is not constant as well. */
4024 if (swap_commutative_operands_p (op0, op1))
4026 tem = op0;
4027 op0 = op1;
4028 op1 = tem;
4029 code = swap_condition (code);
4032 /* get_condition will prefer to generate LT and GT even if the old
4033 comparison was against zero, so undo that canonicalization here since
4034 comparisons against zero are cheaper. */
4035 if (code == LT && op1 == const1_rtx)
4036 code = LE, op1 = const0_rtx;
4037 else if (code == GT && op1 == constm1_rtx)
4038 code = GE, op1 = const0_rtx;
4040 if (cmode == VOIDmode)
4041 cmode = GET_MODE (op0);
4043 if (swap_commutative_operands_p (op2, op3)
4044 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4045 != UNKNOWN))
4047 tem = op2;
4048 op2 = op3;
4049 op3 = tem;
4050 code = reversed;
4053 if (mode == VOIDmode)
4054 mode = GET_MODE (op2);
4056 icode = addcc_optab->handlers[(int) mode].insn_code;
4058 if (icode == CODE_FOR_nothing)
4059 return 0;
4061 if (!target)
4062 target = gen_reg_rtx (mode);
4064 /* If the insn doesn't accept these operands, put them in pseudos. */
4066 if (!insn_data[icode].operand[0].predicate
4067 (target, insn_data[icode].operand[0].mode))
4068 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4069 else
4070 subtarget = target;
4072 if (!insn_data[icode].operand[2].predicate
4073 (op2, insn_data[icode].operand[2].mode))
4074 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4076 if (!insn_data[icode].operand[3].predicate
4077 (op3, insn_data[icode].operand[3].mode))
4078 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4080 /* Everything should now be in the suitable form, so emit the compare insn
4081 and then the conditional move. */
4083 comparison
4084 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4086 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4087 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4088 return NULL and let the caller figure out how best to deal with this
4089 situation. */
4090 if (GET_CODE (comparison) != code)
4091 return NULL_RTX;
4093 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4095 /* If that failed, then give up. */
4096 if (insn == 0)
4097 return 0;
4099 emit_insn (insn);
4101 if (subtarget != target)
4102 convert_move (target, subtarget, 0);
4104 return target;
4107 /* These functions attempt to generate an insn body, rather than
4108 emitting the insn, but if the gen function already emits them, we
4109 make no attempt to turn them back into naked patterns. */
4111 /* Generate and return an insn body to add Y to X. */
4114 gen_add2_insn (rtx x, rtx y)
4116 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4118 gcc_assert (insn_data[icode].operand[0].predicate
4119 (x, insn_data[icode].operand[0].mode));
4120 gcc_assert (insn_data[icode].operand[1].predicate
4121 (x, insn_data[icode].operand[1].mode));
4122 gcc_assert (insn_data[icode].operand[2].predicate
4123 (y, insn_data[icode].operand[2].mode));
4125 return GEN_FCN (icode) (x, x, y);
4128 /* Generate and return an insn body to add r1 and c,
4129 storing the result in r0. */
4131 gen_add3_insn (rtx r0, rtx r1, rtx c)
4133 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4135 if (icode == CODE_FOR_nothing
4136 || !(insn_data[icode].operand[0].predicate
4137 (r0, insn_data[icode].operand[0].mode))
4138 || !(insn_data[icode].operand[1].predicate
4139 (r1, insn_data[icode].operand[1].mode))
4140 || !(insn_data[icode].operand[2].predicate
4141 (c, insn_data[icode].operand[2].mode)))
4142 return NULL_RTX;
4144 return GEN_FCN (icode) (r0, r1, c);
4148 have_add2_insn (rtx x, rtx y)
4150 int icode;
4152 gcc_assert (GET_MODE (x) != VOIDmode);
4154 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4156 if (icode == CODE_FOR_nothing)
4157 return 0;
4159 if (!(insn_data[icode].operand[0].predicate
4160 (x, insn_data[icode].operand[0].mode))
4161 || !(insn_data[icode].operand[1].predicate
4162 (x, insn_data[icode].operand[1].mode))
4163 || !(insn_data[icode].operand[2].predicate
4164 (y, insn_data[icode].operand[2].mode)))
4165 return 0;
4167 return 1;
4170 /* Generate and return an insn body to subtract Y from X. */
4173 gen_sub2_insn (rtx x, rtx y)
4175 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4177 gcc_assert (insn_data[icode].operand[0].predicate
4178 (x, insn_data[icode].operand[0].mode));
4179 gcc_assert (insn_data[icode].operand[1].predicate
4180 (x, insn_data[icode].operand[1].mode));
4181 gcc_assert (insn_data[icode].operand[2].predicate
4182 (y, insn_data[icode].operand[2].mode));
4184 return GEN_FCN (icode) (x, x, y);
4187 /* Generate and return an insn body to subtract r1 and c,
4188 storing the result in r0. */
4190 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4192 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4194 if (icode == CODE_FOR_nothing
4195 || !(insn_data[icode].operand[0].predicate
4196 (r0, insn_data[icode].operand[0].mode))
4197 || !(insn_data[icode].operand[1].predicate
4198 (r1, insn_data[icode].operand[1].mode))
4199 || !(insn_data[icode].operand[2].predicate
4200 (c, insn_data[icode].operand[2].mode)))
4201 return NULL_RTX;
4203 return GEN_FCN (icode) (r0, r1, c);
4207 have_sub2_insn (rtx x, rtx y)
4209 int icode;
4211 gcc_assert (GET_MODE (x) != VOIDmode);
4213 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4215 if (icode == CODE_FOR_nothing)
4216 return 0;
4218 if (!(insn_data[icode].operand[0].predicate
4219 (x, insn_data[icode].operand[0].mode))
4220 || !(insn_data[icode].operand[1].predicate
4221 (x, insn_data[icode].operand[1].mode))
4222 || !(insn_data[icode].operand[2].predicate
4223 (y, insn_data[icode].operand[2].mode)))
4224 return 0;
4226 return 1;
4229 /* Generate the body of an instruction to copy Y into X.
4230 It may be a list of insns, if one insn isn't enough. */
4233 gen_move_insn (rtx x, rtx y)
4235 rtx seq;
4237 start_sequence ();
4238 emit_move_insn_1 (x, y);
4239 seq = get_insns ();
4240 end_sequence ();
4241 return seq;
4244 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4245 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4246 no such operation exists, CODE_FOR_nothing will be returned. */
4248 enum insn_code
4249 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4250 int unsignedp)
4252 convert_optab tab;
4253 #ifdef HAVE_ptr_extend
4254 if (unsignedp < 0)
4255 return CODE_FOR_ptr_extend;
4256 #endif
4258 tab = unsignedp ? zext_optab : sext_optab;
4259 return tab->handlers[to_mode][from_mode].insn_code;
4262 /* Generate the body of an insn to extend Y (with mode MFROM)
4263 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4266 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4267 enum machine_mode mfrom, int unsignedp)
4269 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4270 return GEN_FCN (icode) (x, y);
4273 /* can_fix_p and can_float_p say whether the target machine
4274 can directly convert a given fixed point type to
4275 a given floating point type, or vice versa.
4276 The returned value is the CODE_FOR_... value to use,
4277 or CODE_FOR_nothing if these modes cannot be directly converted.
4279 *TRUNCP_PTR is set to 1 if it is necessary to output
4280 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4282 static enum insn_code
4283 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4284 int unsignedp, int *truncp_ptr)
4286 convert_optab tab;
4287 enum insn_code icode;
4289 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4290 icode = tab->handlers[fixmode][fltmode].insn_code;
4291 if (icode != CODE_FOR_nothing)
4293 *truncp_ptr = 0;
4294 return icode;
4297 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4298 for this to work. We need to rework the fix* and ftrunc* patterns
4299 and documentation. */
4300 tab = unsignedp ? ufix_optab : sfix_optab;
4301 icode = tab->handlers[fixmode][fltmode].insn_code;
4302 if (icode != CODE_FOR_nothing
4303 && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
4305 *truncp_ptr = 1;
4306 return icode;
4309 *truncp_ptr = 0;
4310 return CODE_FOR_nothing;
4313 static enum insn_code
4314 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4315 int unsignedp)
4317 convert_optab tab;
4319 tab = unsignedp ? ufloat_optab : sfloat_optab;
4320 return tab->handlers[fltmode][fixmode].insn_code;
4323 /* Generate code to convert FROM to floating point
4324 and store in TO. FROM must be fixed point and not VOIDmode.
4325 UNSIGNEDP nonzero means regard FROM as unsigned.
4326 Normally this is done by correcting the final value
4327 if it is negative. */
4329 void
4330 expand_float (rtx to, rtx from, int unsignedp)
4332 enum insn_code icode;
4333 rtx target = to;
4334 enum machine_mode fmode, imode;
4335 bool can_do_signed = false;
4337 /* Crash now, because we won't be able to decide which mode to use. */
4338 gcc_assert (GET_MODE (from) != VOIDmode);
4340 /* Look for an insn to do the conversion. Do it in the specified
4341 modes if possible; otherwise convert either input, output or both to
4342 wider mode. If the integer mode is wider than the mode of FROM,
4343 we can do the conversion signed even if the input is unsigned. */
4345 for (fmode = GET_MODE (to); fmode != VOIDmode;
4346 fmode = GET_MODE_WIDER_MODE (fmode))
4347 for (imode = GET_MODE (from); imode != VOIDmode;
4348 imode = GET_MODE_WIDER_MODE (imode))
4350 int doing_unsigned = unsignedp;
4352 if (fmode != GET_MODE (to)
4353 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4354 continue;
4356 icode = can_float_p (fmode, imode, unsignedp);
4357 if (icode == CODE_FOR_nothing && unsignedp)
4359 enum insn_code scode = can_float_p (fmode, imode, 0);
4360 if (scode != CODE_FOR_nothing)
4361 can_do_signed = true;
4362 if (imode != GET_MODE (from))
4363 icode = scode, doing_unsigned = 0;
4366 if (icode != CODE_FOR_nothing)
4368 if (imode != GET_MODE (from))
4369 from = convert_to_mode (imode, from, unsignedp);
4371 if (fmode != GET_MODE (to))
4372 target = gen_reg_rtx (fmode);
4374 emit_unop_insn (icode, target, from,
4375 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4377 if (target != to)
4378 convert_move (to, target, 0);
4379 return;
4383 /* Unsigned integer, and no way to convert directly. For binary
4384 floating point modes, convert as signed, then conditionally adjust
4385 the result. */
4386 if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
4388 rtx label = gen_label_rtx ();
4389 rtx temp;
4390 REAL_VALUE_TYPE offset;
4392 /* Look for a usable floating mode FMODE wider than the source and at
4393 least as wide as the target. Using FMODE will avoid rounding woes
4394 with unsigned values greater than the signed maximum value. */
4396 for (fmode = GET_MODE (to); fmode != VOIDmode;
4397 fmode = GET_MODE_WIDER_MODE (fmode))
4398 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4399 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4400 break;
4402 if (fmode == VOIDmode)
4404 /* There is no such mode. Pretend the target is wide enough. */
4405 fmode = GET_MODE (to);
4407 /* Avoid double-rounding when TO is narrower than FROM. */
4408 if ((significand_size (fmode) + 1)
4409 < GET_MODE_BITSIZE (GET_MODE (from)))
4411 rtx temp1;
4412 rtx neglabel = gen_label_rtx ();
4414 /* Don't use TARGET if it isn't a register, is a hard register,
4415 or is the wrong mode. */
4416 if (!REG_P (target)
4417 || REGNO (target) < FIRST_PSEUDO_REGISTER
4418 || GET_MODE (target) != fmode)
4419 target = gen_reg_rtx (fmode);
4421 imode = GET_MODE (from);
4422 do_pending_stack_adjust ();
4424 /* Test whether the sign bit is set. */
4425 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4426 0, neglabel);
4428 /* The sign bit is not set. Convert as signed. */
4429 expand_float (target, from, 0);
4430 emit_jump_insn (gen_jump (label));
4431 emit_barrier ();
4433 /* The sign bit is set.
4434 Convert to a usable (positive signed) value by shifting right
4435 one bit, while remembering if a nonzero bit was shifted
4436 out; i.e., compute (from & 1) | (from >> 1). */
4438 emit_label (neglabel);
4439 temp = expand_binop (imode, and_optab, from, const1_rtx,
4440 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4441 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4442 NULL_RTX, 1);
4443 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4444 OPTAB_LIB_WIDEN);
4445 expand_float (target, temp, 0);
4447 /* Multiply by 2 to undo the shift above. */
4448 temp = expand_binop (fmode, add_optab, target, target,
4449 target, 0, OPTAB_LIB_WIDEN);
4450 if (temp != target)
4451 emit_move_insn (target, temp);
4453 do_pending_stack_adjust ();
4454 emit_label (label);
4455 goto done;
4459 /* If we are about to do some arithmetic to correct for an
4460 unsigned operand, do it in a pseudo-register. */
4462 if (GET_MODE (to) != fmode
4463 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4464 target = gen_reg_rtx (fmode);
4466 /* Convert as signed integer to floating. */
4467 expand_float (target, from, 0);
4469 /* If FROM is negative (and therefore TO is negative),
4470 correct its value by 2**bitwidth. */
4472 do_pending_stack_adjust ();
4473 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4474 0, label);
4477 real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4478 temp = expand_binop (fmode, add_optab, target,
4479 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4480 target, 0, OPTAB_LIB_WIDEN);
4481 if (temp != target)
4482 emit_move_insn (target, temp);
4484 do_pending_stack_adjust ();
4485 emit_label (label);
4486 goto done;
4489 /* No hardware instruction available; call a library routine. */
4491 rtx libfunc;
4492 rtx insns;
4493 rtx value;
4494 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4496 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4497 from = convert_to_mode (SImode, from, unsignedp);
4499 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4500 gcc_assert (libfunc);
4502 start_sequence ();
4504 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4505 GET_MODE (to), 1, from,
4506 GET_MODE (from));
4507 insns = get_insns ();
4508 end_sequence ();
4510 emit_libcall_block (insns, target, value,
4511 gen_rtx_FLOAT (GET_MODE (to), from));
4514 done:
4516 /* Copy result to requested destination
4517 if we have been computing in a temp location. */
4519 if (target != to)
4521 if (GET_MODE (target) == GET_MODE (to))
4522 emit_move_insn (to, target);
4523 else
4524 convert_move (to, target, 0);
4528 /* Generate code to convert FROM to fixed point and store in TO. FROM
4529 must be floating point. */
4531 void
4532 expand_fix (rtx to, rtx from, int unsignedp)
4534 enum insn_code icode;
4535 rtx target = to;
4536 enum machine_mode fmode, imode;
4537 int must_trunc = 0;
4539 /* We first try to find a pair of modes, one real and one integer, at
4540 least as wide as FROM and TO, respectively, in which we can open-code
4541 this conversion. If the integer mode is wider than the mode of TO,
4542 we can do the conversion either signed or unsigned. */
4544 for (fmode = GET_MODE (from); fmode != VOIDmode;
4545 fmode = GET_MODE_WIDER_MODE (fmode))
4546 for (imode = GET_MODE (to); imode != VOIDmode;
4547 imode = GET_MODE_WIDER_MODE (imode))
4549 int doing_unsigned = unsignedp;
4551 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4552 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4553 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4555 if (icode != CODE_FOR_nothing)
4557 if (fmode != GET_MODE (from))
4558 from = convert_to_mode (fmode, from, 0);
4560 if (must_trunc)
4562 rtx temp = gen_reg_rtx (GET_MODE (from));
4563 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4564 temp, 0);
4567 if (imode != GET_MODE (to))
4568 target = gen_reg_rtx (imode);
4570 emit_unop_insn (icode, target, from,
4571 doing_unsigned ? UNSIGNED_FIX : FIX);
4572 if (target != to)
4573 convert_move (to, target, unsignedp);
4574 return;
4578 /* For an unsigned conversion, there is one more way to do it.
4579 If we have a signed conversion, we generate code that compares
4580 the real value to the largest representable positive number. If if
4581 is smaller, the conversion is done normally. Otherwise, subtract
4582 one plus the highest signed number, convert, and add it back.
4584 We only need to check all real modes, since we know we didn't find
4585 anything with a wider integer mode.
4587 This code used to extend FP value into mode wider than the destination.
4588 This is not needed. Consider, for instance conversion from SFmode
4589 into DImode.
4591 The hot path trought the code is dealing with inputs smaller than 2^63
4592 and doing just the conversion, so there is no bits to lose.
4594 In the other path we know the value is positive in the range 2^63..2^64-1
4595 inclusive. (as for other imput overflow happens and result is undefined)
4596 So we know that the most important bit set in mantissa corresponds to
4597 2^63. The subtraction of 2^63 should not generate any rounding as it
4598 simply clears out that bit. The rest is trivial. */
4600 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4601 for (fmode = GET_MODE (from); fmode != VOIDmode;
4602 fmode = GET_MODE_WIDER_MODE (fmode))
4603 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4604 &must_trunc))
4606 int bitsize;
4607 REAL_VALUE_TYPE offset;
4608 rtx limit, lab1, lab2, insn;
4610 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4611 real_2expN (&offset, bitsize - 1);
4612 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4613 lab1 = gen_label_rtx ();
4614 lab2 = gen_label_rtx ();
4616 if (fmode != GET_MODE (from))
4617 from = convert_to_mode (fmode, from, 0);
4619 /* See if we need to do the subtraction. */
4620 do_pending_stack_adjust ();
4621 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4622 0, lab1);
4624 /* If not, do the signed "fix" and branch around fixup code. */
4625 expand_fix (to, from, 0);
4626 emit_jump_insn (gen_jump (lab2));
4627 emit_barrier ();
4629 /* Otherwise, subtract 2**(N-1), convert to signed number,
4630 then add 2**(N-1). Do the addition using XOR since this
4631 will often generate better code. */
4632 emit_label (lab1);
4633 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4634 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4635 expand_fix (to, target, 0);
4636 target = expand_binop (GET_MODE (to), xor_optab, to,
4637 gen_int_mode
4638 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4639 GET_MODE (to)),
4640 to, 1, OPTAB_LIB_WIDEN);
4642 if (target != to)
4643 emit_move_insn (to, target);
4645 emit_label (lab2);
4647 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4648 != CODE_FOR_nothing)
4650 /* Make a place for a REG_NOTE and add it. */
4651 insn = emit_move_insn (to, to);
4652 set_unique_reg_note (insn,
4653 REG_EQUAL,
4654 gen_rtx_fmt_e (UNSIGNED_FIX,
4655 GET_MODE (to),
4656 copy_rtx (from)));
4659 return;
4662 /* We can't do it with an insn, so use a library call. But first ensure
4663 that the mode of TO is at least as wide as SImode, since those are the
4664 only library calls we know about. */
4666 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4668 target = gen_reg_rtx (SImode);
4670 expand_fix (target, from, unsignedp);
4672 else
4674 rtx insns;
4675 rtx value;
4676 rtx libfunc;
4678 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4679 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4680 gcc_assert (libfunc);
4682 start_sequence ();
4684 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4685 GET_MODE (to), 1, from,
4686 GET_MODE (from));
4687 insns = get_insns ();
4688 end_sequence ();
4690 emit_libcall_block (insns, target, value,
4691 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4692 GET_MODE (to), from));
4695 if (target != to)
4697 if (GET_MODE (to) == GET_MODE (target))
4698 emit_move_insn (to, target);
4699 else
4700 convert_move (to, target, 0);
4704 /* Report whether we have an instruction to perform the operation
4705 specified by CODE on operands of mode MODE. */
4707 have_insn_for (enum rtx_code code, enum machine_mode mode)
4709 return (code_to_optab[(int) code] != 0
4710 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4711 != CODE_FOR_nothing));
4714 /* Create a blank optab. */
4715 static optab
4716 new_optab (void)
4718 int i;
4719 optab op = ggc_alloc (sizeof (struct optab));
4720 for (i = 0; i < NUM_MACHINE_MODES; i++)
4722 op->handlers[i].insn_code = CODE_FOR_nothing;
4723 op->handlers[i].libfunc = 0;
4726 return op;
4729 static convert_optab
4730 new_convert_optab (void)
4732 int i, j;
4733 convert_optab op = ggc_alloc (sizeof (struct convert_optab));
4734 for (i = 0; i < NUM_MACHINE_MODES; i++)
4735 for (j = 0; j < NUM_MACHINE_MODES; j++)
4737 op->handlers[i][j].insn_code = CODE_FOR_nothing;
4738 op->handlers[i][j].libfunc = 0;
4740 return op;
4743 /* Same, but fill in its code as CODE, and write it into the
4744 code_to_optab table. */
4745 static inline optab
4746 init_optab (enum rtx_code code)
4748 optab op = new_optab ();
4749 op->code = code;
4750 code_to_optab[(int) code] = op;
4751 return op;
4754 /* Same, but fill in its code as CODE, and do _not_ write it into
4755 the code_to_optab table. */
4756 static inline optab
4757 init_optabv (enum rtx_code code)
4759 optab op = new_optab ();
4760 op->code = code;
4761 return op;
4764 /* Conversion optabs never go in the code_to_optab table. */
4765 static inline convert_optab
4766 init_convert_optab (enum rtx_code code)
4768 convert_optab op = new_convert_optab ();
4769 op->code = code;
4770 return op;
4773 /* Initialize the libfunc fields of an entire group of entries in some
4774 optab. Each entry is set equal to a string consisting of a leading
4775 pair of underscores followed by a generic operation name followed by
4776 a mode name (downshifted to lowercase) followed by a single character
4777 representing the number of operands for the given operation (which is
4778 usually one of the characters '2', '3', or '4').
4780 OPTABLE is the table in which libfunc fields are to be initialized.
4781 FIRST_MODE is the first machine mode index in the given optab to
4782 initialize.
4783 LAST_MODE is the last machine mode index in the given optab to
4784 initialize.
4785 OPNAME is the generic (string) name of the operation.
4786 SUFFIX is the character which specifies the number of operands for
4787 the given generic operation.
4790 static void
4791 init_libfuncs (optab optable, int first_mode, int last_mode,
4792 const char *opname, int suffix)
4794 int mode;
4795 unsigned opname_len = strlen (opname);
4797 for (mode = first_mode; (int) mode <= (int) last_mode;
4798 mode = (enum machine_mode) ((int) mode + 1))
4800 const char *mname = GET_MODE_NAME (mode);
4801 unsigned mname_len = strlen (mname);
4802 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4803 char *p;
4804 const char *q;
4806 p = libfunc_name;
4807 *p++ = '_';
4808 *p++ = '_';
4809 for (q = opname; *q; )
4810 *p++ = *q++;
4811 for (q = mname; *q; q++)
4812 *p++ = TOLOWER (*q);
4813 *p++ = suffix;
4814 *p = '\0';
4816 optable->handlers[(int) mode].libfunc
4817 = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
4821 /* Initialize the libfunc fields of an entire group of entries in some
4822 optab which correspond to all integer mode operations. The parameters
4823 have the same meaning as similarly named ones for the `init_libfuncs'
4824 routine. (See above). */
4826 static void
4827 init_integral_libfuncs (optab optable, const char *opname, int suffix)
4829 int maxsize = 2*BITS_PER_WORD;
4830 if (maxsize < LONG_LONG_TYPE_SIZE)
4831 maxsize = LONG_LONG_TYPE_SIZE;
4832 init_libfuncs (optable, word_mode,
4833 mode_for_size (maxsize, MODE_INT, 0),
4834 opname, suffix);
4837 /* Initialize the libfunc fields of an entire group of entries in some
4838 optab which correspond to all real mode operations. The parameters
4839 have the same meaning as similarly named ones for the `init_libfuncs'
4840 routine. (See above). */
4842 static void
4843 init_floating_libfuncs (optab optable, const char *opname, int suffix)
4845 init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
4846 init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
4847 opname, suffix);
4850 /* Initialize the libfunc fields of an entire group of entries of an
4851 inter-mode-class conversion optab. The string formation rules are
4852 similar to the ones for init_libfuncs, above, but instead of having
4853 a mode name and an operand count these functions have two mode names
4854 and no operand count. */
4855 static void
4856 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
4857 enum mode_class from_class,
4858 enum mode_class to_class)
4860 enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
4861 enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
4862 size_t opname_len = strlen (opname);
4863 size_t max_mname_len = 0;
4865 enum machine_mode fmode, tmode;
4866 const char *fname, *tname;
4867 const char *q;
4868 char *libfunc_name, *suffix;
4869 char *p;
4871 for (fmode = first_from_mode;
4872 fmode != VOIDmode;
4873 fmode = GET_MODE_WIDER_MODE (fmode))
4874 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
4876 for (tmode = first_to_mode;
4877 tmode != VOIDmode;
4878 tmode = GET_MODE_WIDER_MODE (tmode))
4879 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
4881 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
4882 libfunc_name[0] = '_';
4883 libfunc_name[1] = '_';
4884 memcpy (&libfunc_name[2], opname, opname_len);
4885 suffix = libfunc_name + opname_len + 2;
4887 for (fmode = first_from_mode; fmode != VOIDmode;
4888 fmode = GET_MODE_WIDER_MODE (fmode))
4889 for (tmode = first_to_mode; tmode != VOIDmode;
4890 tmode = GET_MODE_WIDER_MODE (tmode))
4892 fname = GET_MODE_NAME (fmode);
4893 tname = GET_MODE_NAME (tmode);
4895 p = suffix;
4896 for (q = fname; *q; p++, q++)
4897 *p = TOLOWER (*q);
4898 for (q = tname; *q; p++, q++)
4899 *p = TOLOWER (*q);
4901 *p = '\0';
4903 tab->handlers[tmode][fmode].libfunc
4904 = init_one_libfunc (ggc_alloc_string (libfunc_name,
4905 p - libfunc_name));
4909 /* Initialize the libfunc fields of an entire group of entries of an
4910 intra-mode-class conversion optab. The string formation rules are
4911 similar to the ones for init_libfunc, above. WIDENING says whether
4912 the optab goes from narrow to wide modes or vice versa. These functions
4913 have two mode names _and_ an operand count. */
4914 static void
4915 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
4916 enum mode_class class, bool widening)
4918 enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
4919 size_t opname_len = strlen (opname);
4920 size_t max_mname_len = 0;
4922 enum machine_mode nmode, wmode;
4923 const char *nname, *wname;
4924 const char *q;
4925 char *libfunc_name, *suffix;
4926 char *p;
4928 for (nmode = first_mode; nmode != VOIDmode;
4929 nmode = GET_MODE_WIDER_MODE (nmode))
4930 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
4932 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
4933 libfunc_name[0] = '_';
4934 libfunc_name[1] = '_';
4935 memcpy (&libfunc_name[2], opname, opname_len);
4936 suffix = libfunc_name + opname_len + 2;
4938 for (nmode = first_mode; nmode != VOIDmode;
4939 nmode = GET_MODE_WIDER_MODE (nmode))
4940 for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
4941 wmode = GET_MODE_WIDER_MODE (wmode))
4943 nname = GET_MODE_NAME (nmode);
4944 wname = GET_MODE_NAME (wmode);
4946 p = suffix;
4947 for (q = widening ? nname : wname; *q; p++, q++)
4948 *p = TOLOWER (*q);
4949 for (q = widening ? wname : nname; *q; p++, q++)
4950 *p = TOLOWER (*q);
4952 *p++ = '2';
4953 *p = '\0';
4955 tab->handlers[widening ? wmode : nmode]
4956 [widening ? nmode : wmode].libfunc
4957 = init_one_libfunc (ggc_alloc_string (libfunc_name,
4958 p - libfunc_name));
4964 init_one_libfunc (const char *name)
4966 rtx symbol;
4968 /* Create a FUNCTION_DECL that can be passed to
4969 targetm.encode_section_info. */
4970 /* ??? We don't have any type information except for this is
4971 a function. Pretend this is "int foo()". */
4972 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
4973 build_function_type (integer_type_node, NULL_TREE));
4974 DECL_ARTIFICIAL (decl) = 1;
4975 DECL_EXTERNAL (decl) = 1;
4976 TREE_PUBLIC (decl) = 1;
4978 symbol = XEXP (DECL_RTL (decl), 0);
4980 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
4981 are the flags assigned by targetm.encode_section_info. */
4982 SYMBOL_REF_DECL (symbol) = 0;
4984 return symbol;
4987 /* Call this to reset the function entry for one optab (OPTABLE) in mode
4988 MODE to NAME, which should be either 0 or a string constant. */
4989 void
4990 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
4992 if (name)
4993 optable->handlers[mode].libfunc = init_one_libfunc (name);
4994 else
4995 optable->handlers[mode].libfunc = 0;
4998 /* Call this to reset the function entry for one conversion optab
4999 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5000 either 0 or a string constant. */
5001 void
5002 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5003 enum machine_mode fmode, const char *name)
5005 if (name)
5006 optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
5007 else
5008 optable->handlers[tmode][fmode].libfunc = 0;
5011 /* Call this once to initialize the contents of the optabs
5012 appropriately for the current target machine. */
5014 void
5015 init_optabs (void)
5017 unsigned int i;
5019 /* Start by initializing all tables to contain CODE_FOR_nothing. */
5021 for (i = 0; i < NUM_RTX_CODE; i++)
5022 setcc_gen_code[i] = CODE_FOR_nothing;
5024 #ifdef HAVE_conditional_move
5025 for (i = 0; i < NUM_MACHINE_MODES; i++)
5026 movcc_gen_code[i] = CODE_FOR_nothing;
5027 #endif
5029 for (i = 0; i < NUM_MACHINE_MODES; i++)
5031 vcond_gen_code[i] = CODE_FOR_nothing;
5032 vcondu_gen_code[i] = CODE_FOR_nothing;
5035 add_optab = init_optab (PLUS);
5036 addv_optab = init_optabv (PLUS);
5037 sub_optab = init_optab (MINUS);
5038 subv_optab = init_optabv (MINUS);
5039 smul_optab = init_optab (MULT);
5040 smulv_optab = init_optabv (MULT);
5041 smul_highpart_optab = init_optab (UNKNOWN);
5042 umul_highpart_optab = init_optab (UNKNOWN);
5043 smul_widen_optab = init_optab (UNKNOWN);
5044 umul_widen_optab = init_optab (UNKNOWN);
5045 usmul_widen_optab = init_optab (UNKNOWN);
5046 sdiv_optab = init_optab (DIV);
5047 sdivv_optab = init_optabv (DIV);
5048 sdivmod_optab = init_optab (UNKNOWN);
5049 udiv_optab = init_optab (UDIV);
5050 udivmod_optab = init_optab (UNKNOWN);
5051 smod_optab = init_optab (MOD);
5052 umod_optab = init_optab (UMOD);
5053 fmod_optab = init_optab (UNKNOWN);
5054 drem_optab = init_optab (UNKNOWN);
5055 ftrunc_optab = init_optab (UNKNOWN);
5056 and_optab = init_optab (AND);
5057 ior_optab = init_optab (IOR);
5058 xor_optab = init_optab (XOR);
5059 ashl_optab = init_optab (ASHIFT);
5060 ashr_optab = init_optab (ASHIFTRT);
5061 lshr_optab = init_optab (LSHIFTRT);
5062 rotl_optab = init_optab (ROTATE);
5063 rotr_optab = init_optab (ROTATERT);
5064 smin_optab = init_optab (SMIN);
5065 smax_optab = init_optab (SMAX);
5066 umin_optab = init_optab (UMIN);
5067 umax_optab = init_optab (UMAX);
5068 pow_optab = init_optab (UNKNOWN);
5069 atan2_optab = init_optab (UNKNOWN);
5071 /* These three have codes assigned exclusively for the sake of
5072 have_insn_for. */
5073 mov_optab = init_optab (SET);
5074 movstrict_optab = init_optab (STRICT_LOW_PART);
5075 cmp_optab = init_optab (COMPARE);
5077 ucmp_optab = init_optab (UNKNOWN);
5078 tst_optab = init_optab (UNKNOWN);
5080 eq_optab = init_optab (EQ);
5081 ne_optab = init_optab (NE);
5082 gt_optab = init_optab (GT);
5083 ge_optab = init_optab (GE);
5084 lt_optab = init_optab (LT);
5085 le_optab = init_optab (LE);
5086 unord_optab = init_optab (UNORDERED);
5088 neg_optab = init_optab (NEG);
5089 negv_optab = init_optabv (NEG);
5090 abs_optab = init_optab (ABS);
5091 absv_optab = init_optabv (ABS);
5092 addcc_optab = init_optab (UNKNOWN);
5093 one_cmpl_optab = init_optab (NOT);
5094 ffs_optab = init_optab (FFS);
5095 clz_optab = init_optab (CLZ);
5096 ctz_optab = init_optab (CTZ);
5097 popcount_optab = init_optab (POPCOUNT);
5098 parity_optab = init_optab (PARITY);
5099 sqrt_optab = init_optab (SQRT);
5100 floor_optab = init_optab (UNKNOWN);
5101 lfloor_optab = init_optab (UNKNOWN);
5102 ceil_optab = init_optab (UNKNOWN);
5103 lceil_optab = init_optab (UNKNOWN);
5104 round_optab = init_optab (UNKNOWN);
5105 btrunc_optab = init_optab (UNKNOWN);
5106 nearbyint_optab = init_optab (UNKNOWN);
5107 rint_optab = init_optab (UNKNOWN);
5108 lrint_optab = init_optab (UNKNOWN);
5109 sincos_optab = init_optab (UNKNOWN);
5110 sin_optab = init_optab (UNKNOWN);
5111 asin_optab = init_optab (UNKNOWN);
5112 cos_optab = init_optab (UNKNOWN);
5113 acos_optab = init_optab (UNKNOWN);
5114 exp_optab = init_optab (UNKNOWN);
5115 exp10_optab = init_optab (UNKNOWN);
5116 exp2_optab = init_optab (UNKNOWN);
5117 expm1_optab = init_optab (UNKNOWN);
5118 ldexp_optab = init_optab (UNKNOWN);
5119 logb_optab = init_optab (UNKNOWN);
5120 ilogb_optab = init_optab (UNKNOWN);
5121 log_optab = init_optab (UNKNOWN);
5122 log10_optab = init_optab (UNKNOWN);
5123 log2_optab = init_optab (UNKNOWN);
5124 log1p_optab = init_optab (UNKNOWN);
5125 tan_optab = init_optab (UNKNOWN);
5126 atan_optab = init_optab (UNKNOWN);
5127 copysign_optab = init_optab (UNKNOWN);
5129 strlen_optab = init_optab (UNKNOWN);
5130 cbranch_optab = init_optab (UNKNOWN);
5131 cmov_optab = init_optab (UNKNOWN);
5132 cstore_optab = init_optab (UNKNOWN);
5133 push_optab = init_optab (UNKNOWN);
5135 reduc_smax_optab = init_optab (UNKNOWN);
5136 reduc_umax_optab = init_optab (UNKNOWN);
5137 reduc_smin_optab = init_optab (UNKNOWN);
5138 reduc_umin_optab = init_optab (UNKNOWN);
5139 reduc_splus_optab = init_optab (UNKNOWN);
5140 reduc_uplus_optab = init_optab (UNKNOWN);
5142 vec_extract_optab = init_optab (UNKNOWN);
5143 vec_set_optab = init_optab (UNKNOWN);
5144 vec_init_optab = init_optab (UNKNOWN);
5145 vec_shl_optab = init_optab (UNKNOWN);
5146 vec_shr_optab = init_optab (UNKNOWN);
5147 vec_realign_load_optab = init_optab (UNKNOWN);
5148 movmisalign_optab = init_optab (UNKNOWN);
5150 powi_optab = init_optab (UNKNOWN);
5152 /* Conversions. */
5153 sext_optab = init_convert_optab (SIGN_EXTEND);
5154 zext_optab = init_convert_optab (ZERO_EXTEND);
5155 trunc_optab = init_convert_optab (TRUNCATE);
5156 sfix_optab = init_convert_optab (FIX);
5157 ufix_optab = init_convert_optab (UNSIGNED_FIX);
5158 sfixtrunc_optab = init_convert_optab (UNKNOWN);
5159 ufixtrunc_optab = init_convert_optab (UNKNOWN);
5160 sfloat_optab = init_convert_optab (FLOAT);
5161 ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5163 for (i = 0; i < NUM_MACHINE_MODES; i++)
5165 movmem_optab[i] = CODE_FOR_nothing;
5166 cmpstr_optab[i] = CODE_FOR_nothing;
5167 cmpstrn_optab[i] = CODE_FOR_nothing;
5168 cmpmem_optab[i] = CODE_FOR_nothing;
5169 setmem_optab[i] = CODE_FOR_nothing;
5171 sync_add_optab[i] = CODE_FOR_nothing;
5172 sync_sub_optab[i] = CODE_FOR_nothing;
5173 sync_ior_optab[i] = CODE_FOR_nothing;
5174 sync_and_optab[i] = CODE_FOR_nothing;
5175 sync_xor_optab[i] = CODE_FOR_nothing;
5176 sync_nand_optab[i] = CODE_FOR_nothing;
5177 sync_old_add_optab[i] = CODE_FOR_nothing;
5178 sync_old_sub_optab[i] = CODE_FOR_nothing;
5179 sync_old_ior_optab[i] = CODE_FOR_nothing;
5180 sync_old_and_optab[i] = CODE_FOR_nothing;
5181 sync_old_xor_optab[i] = CODE_FOR_nothing;
5182 sync_old_nand_optab[i] = CODE_FOR_nothing;
5183 sync_new_add_optab[i] = CODE_FOR_nothing;
5184 sync_new_sub_optab[i] = CODE_FOR_nothing;
5185 sync_new_ior_optab[i] = CODE_FOR_nothing;
5186 sync_new_and_optab[i] = CODE_FOR_nothing;
5187 sync_new_xor_optab[i] = CODE_FOR_nothing;
5188 sync_new_nand_optab[i] = CODE_FOR_nothing;
5189 sync_compare_and_swap[i] = CODE_FOR_nothing;
5190 sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5191 sync_lock_test_and_set[i] = CODE_FOR_nothing;
5192 sync_lock_release[i] = CODE_FOR_nothing;
5194 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5197 /* Fill in the optabs with the insns we support. */
5198 init_all_optabs ();
5200 /* Initialize the optabs with the names of the library functions. */
5201 init_integral_libfuncs (add_optab, "add", '3');
5202 init_floating_libfuncs (add_optab, "add", '3');
5203 init_integral_libfuncs (addv_optab, "addv", '3');
5204 init_floating_libfuncs (addv_optab, "add", '3');
5205 init_integral_libfuncs (sub_optab, "sub", '3');
5206 init_floating_libfuncs (sub_optab, "sub", '3');
5207 init_integral_libfuncs (subv_optab, "subv", '3');
5208 init_floating_libfuncs (subv_optab, "sub", '3');
5209 init_integral_libfuncs (smul_optab, "mul", '3');
5210 init_floating_libfuncs (smul_optab, "mul", '3');
5211 init_integral_libfuncs (smulv_optab, "mulv", '3');
5212 init_floating_libfuncs (smulv_optab, "mul", '3');
5213 init_integral_libfuncs (sdiv_optab, "div", '3');
5214 init_floating_libfuncs (sdiv_optab, "div", '3');
5215 init_integral_libfuncs (sdivv_optab, "divv", '3');
5216 init_integral_libfuncs (udiv_optab, "udiv", '3');
5217 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5218 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5219 init_integral_libfuncs (smod_optab, "mod", '3');
5220 init_integral_libfuncs (umod_optab, "umod", '3');
5221 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5222 init_integral_libfuncs (and_optab, "and", '3');
5223 init_integral_libfuncs (ior_optab, "ior", '3');
5224 init_integral_libfuncs (xor_optab, "xor", '3');
5225 init_integral_libfuncs (ashl_optab, "ashl", '3');
5226 init_integral_libfuncs (ashr_optab, "ashr", '3');
5227 init_integral_libfuncs (lshr_optab, "lshr", '3');
5228 init_integral_libfuncs (smin_optab, "min", '3');
5229 init_floating_libfuncs (smin_optab, "min", '3');
5230 init_integral_libfuncs (smax_optab, "max", '3');
5231 init_floating_libfuncs (smax_optab, "max", '3');
5232 init_integral_libfuncs (umin_optab, "umin", '3');
5233 init_integral_libfuncs (umax_optab, "umax", '3');
5234 init_integral_libfuncs (neg_optab, "neg", '2');
5235 init_floating_libfuncs (neg_optab, "neg", '2');
5236 init_integral_libfuncs (negv_optab, "negv", '2');
5237 init_floating_libfuncs (negv_optab, "neg", '2');
5238 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5239 init_integral_libfuncs (ffs_optab, "ffs", '2');
5240 init_integral_libfuncs (clz_optab, "clz", '2');
5241 init_integral_libfuncs (ctz_optab, "ctz", '2');
5242 init_integral_libfuncs (popcount_optab, "popcount", '2');
5243 init_integral_libfuncs (parity_optab, "parity", '2');
5245 /* Comparison libcalls for integers MUST come in pairs,
5246 signed/unsigned. */
5247 init_integral_libfuncs (cmp_optab, "cmp", '2');
5248 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5249 init_floating_libfuncs (cmp_optab, "cmp", '2');
5251 /* EQ etc are floating point only. */
5252 init_floating_libfuncs (eq_optab, "eq", '2');
5253 init_floating_libfuncs (ne_optab, "ne", '2');
5254 init_floating_libfuncs (gt_optab, "gt", '2');
5255 init_floating_libfuncs (ge_optab, "ge", '2');
5256 init_floating_libfuncs (lt_optab, "lt", '2');
5257 init_floating_libfuncs (le_optab, "le", '2');
5258 init_floating_libfuncs (unord_optab, "unord", '2');
5260 init_floating_libfuncs (powi_optab, "powi", '2');
5262 /* Conversions. */
5263 init_interclass_conv_libfuncs (sfloat_optab, "float",
5264 MODE_INT, MODE_FLOAT);
5265 init_interclass_conv_libfuncs (sfloat_optab, "float",
5266 MODE_INT, MODE_DECIMAL_FLOAT);
5267 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5268 MODE_INT, MODE_FLOAT);
5269 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5270 MODE_INT, MODE_DECIMAL_FLOAT);
5271 init_interclass_conv_libfuncs (sfix_optab, "fix",
5272 MODE_FLOAT, MODE_INT);
5273 init_interclass_conv_libfuncs (sfix_optab, "fix",
5274 MODE_DECIMAL_FLOAT, MODE_INT);
5275 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5276 MODE_FLOAT, MODE_INT);
5277 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5278 MODE_DECIMAL_FLOAT, MODE_INT);
5279 init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
5280 MODE_INT, MODE_DECIMAL_FLOAT);
5282 /* sext_optab is also used for FLOAT_EXTEND. */
5283 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5284 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
5285 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5286 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5287 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5288 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
5289 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5290 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5292 /* Use cabs for double complex abs, since systems generally have cabs.
5293 Don't define any libcall for float complex, so that cabs will be used. */
5294 if (complex_double_type_node)
5295 abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5296 = init_one_libfunc ("cabs");
5298 /* The ffs function operates on `int'. */
5299 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5300 = init_one_libfunc ("ffs");
5302 abort_libfunc = init_one_libfunc ("abort");
5303 memcpy_libfunc = init_one_libfunc ("memcpy");
5304 memmove_libfunc = init_one_libfunc ("memmove");
5305 memcmp_libfunc = init_one_libfunc ("memcmp");
5306 memset_libfunc = init_one_libfunc ("memset");
5307 setbits_libfunc = init_one_libfunc ("__setbits");
5309 #ifndef DONT_USE_BUILTIN_SETJMP
5310 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5311 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5312 #else
5313 setjmp_libfunc = init_one_libfunc ("setjmp");
5314 longjmp_libfunc = init_one_libfunc ("longjmp");
5315 #endif
5316 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5317 unwind_sjlj_unregister_libfunc
5318 = init_one_libfunc ("_Unwind_SjLj_Unregister");
5320 /* For function entry/exit instrumentation. */
5321 profile_function_entry_libfunc
5322 = init_one_libfunc ("__cyg_profile_func_enter");
5323 profile_function_exit_libfunc
5324 = init_one_libfunc ("__cyg_profile_func_exit");
5326 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5328 if (HAVE_conditional_trap)
5329 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5331 /* Allow the target to add more libcalls or rename some, etc. */
5332 targetm.init_libfuncs ();
5335 #ifdef DEBUG
5337 /* Print information about the current contents of the optabs on
5338 STDERR. */
5340 static void
5341 debug_optab_libfuncs (void)
5343 int i;
5344 int j;
5345 int k;
5347 /* Dump the arithmetic optabs. */
5348 for (i = 0; i != (int) OTI_MAX; i++)
5349 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5351 optab o;
5352 struct optab_handlers *h;
5354 o = optab_table[i];
5355 h = &o->handlers[j];
5356 if (h->libfunc)
5358 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5359 fprintf (stderr, "%s\t%s:\t%s\n",
5360 GET_RTX_NAME (o->code),
5361 GET_MODE_NAME (j),
5362 XSTR (h->libfunc, 0));
5366 /* Dump the conversion optabs. */
5367 for (i = 0; i < (int) COI_MAX; ++i)
5368 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5369 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5371 convert_optab o;
5372 struct optab_handlers *h;
5374 o = &convert_optab_table[i];
5375 h = &o->handlers[j][k];
5376 if (h->libfunc)
5378 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5379 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5380 GET_RTX_NAME (o->code),
5381 GET_MODE_NAME (j),
5382 GET_MODE_NAME (k),
5383 XSTR (h->libfunc, 0));
5388 #endif /* DEBUG */
5391 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5392 CODE. Return 0 on failure. */
5395 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5396 rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
5398 enum machine_mode mode = GET_MODE (op1);
5399 enum insn_code icode;
5400 rtx insn;
5402 if (!HAVE_conditional_trap)
5403 return 0;
5405 if (mode == VOIDmode)
5406 return 0;
5408 icode = cmp_optab->handlers[(int) mode].insn_code;
5409 if (icode == CODE_FOR_nothing)
5410 return 0;
5412 start_sequence ();
5413 op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5414 op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
5415 if (!op1 || !op2)
5417 end_sequence ();
5418 return 0;
5420 emit_insn (GEN_FCN (icode) (op1, op2));
5422 PUT_CODE (trap_rtx, code);
5423 gcc_assert (HAVE_conditional_trap);
5424 insn = gen_conditional_trap (trap_rtx, tcode);
5425 if (insn)
5427 emit_insn (insn);
5428 insn = get_insns ();
5430 end_sequence ();
5432 return insn;
5435 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5436 or unsigned operation code. */
5438 static enum rtx_code
5439 get_rtx_code (enum tree_code tcode, bool unsignedp)
5441 enum rtx_code code;
5442 switch (tcode)
5444 case EQ_EXPR:
5445 code = EQ;
5446 break;
5447 case NE_EXPR:
5448 code = NE;
5449 break;
5450 case LT_EXPR:
5451 code = unsignedp ? LTU : LT;
5452 break;
5453 case LE_EXPR:
5454 code = unsignedp ? LEU : LE;
5455 break;
5456 case GT_EXPR:
5457 code = unsignedp ? GTU : GT;
5458 break;
5459 case GE_EXPR:
5460 code = unsignedp ? GEU : GE;
5461 break;
5463 case UNORDERED_EXPR:
5464 code = UNORDERED;
5465 break;
5466 case ORDERED_EXPR:
5467 code = ORDERED;
5468 break;
5469 case UNLT_EXPR:
5470 code = UNLT;
5471 break;
5472 case UNLE_EXPR:
5473 code = UNLE;
5474 break;
5475 case UNGT_EXPR:
5476 code = UNGT;
5477 break;
5478 case UNGE_EXPR:
5479 code = UNGE;
5480 break;
5481 case UNEQ_EXPR:
5482 code = UNEQ;
5483 break;
5484 case LTGT_EXPR:
5485 code = LTGT;
5486 break;
5488 default:
5489 gcc_unreachable ();
5491 return code;
5494 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5495 unsigned operators. Do not generate compare instruction. */
5497 static rtx
5498 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
5500 enum rtx_code rcode;
5501 tree t_op0, t_op1;
5502 rtx rtx_op0, rtx_op1;
5504 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
5505 ensures that condition is a relational operation. */
5506 gcc_assert (COMPARISON_CLASS_P (cond));
5508 rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
5509 t_op0 = TREE_OPERAND (cond, 0);
5510 t_op1 = TREE_OPERAND (cond, 1);
5512 /* Expand operands. */
5513 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)), 1);
5514 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)), 1);
5516 if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
5517 && GET_MODE (rtx_op0) != VOIDmode)
5518 rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
5520 if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
5521 && GET_MODE (rtx_op1) != VOIDmode)
5522 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5524 return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
5527 /* Return insn code for VEC_COND_EXPR EXPR. */
5529 static inline enum insn_code
5530 get_vcond_icode (tree expr, enum machine_mode mode)
5532 enum insn_code icode = CODE_FOR_nothing;
5534 if (TYPE_UNSIGNED (TREE_TYPE (expr)))
5535 icode = vcondu_gen_code[mode];
5536 else
5537 icode = vcond_gen_code[mode];
5538 return icode;
5541 /* Return TRUE iff, appropriate vector insns are available
5542 for vector cond expr expr in VMODE mode. */
5544 bool
5545 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
5547 if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
5548 return false;
5549 return true;
5552 /* Generate insns for VEC_COND_EXPR. */
5555 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
5557 enum insn_code icode;
5558 rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
5559 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
5560 bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
5562 icode = get_vcond_icode (vec_cond_expr, mode);
5563 if (icode == CODE_FOR_nothing)
5564 return 0;
5566 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5567 target = gen_reg_rtx (mode);
5569 /* Get comparison rtx. First expand both cond expr operands. */
5570 comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
5571 unsignedp, icode);
5572 cc_op0 = XEXP (comparison, 0);
5573 cc_op1 = XEXP (comparison, 1);
5574 /* Expand both operands and force them in reg, if required. */
5575 rtx_op1 = expand_expr (TREE_OPERAND (vec_cond_expr, 1),
5576 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5577 if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
5578 && mode != VOIDmode)
5579 rtx_op1 = force_reg (mode, rtx_op1);
5581 rtx_op2 = expand_expr (TREE_OPERAND (vec_cond_expr, 2),
5582 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5583 if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
5584 && mode != VOIDmode)
5585 rtx_op2 = force_reg (mode, rtx_op2);
5587 /* Emit instruction! */
5588 emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
5589 comparison, cc_op0, cc_op1));
5591 return target;
5595 /* This is an internal subroutine of the other compare_and_swap expanders.
5596 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
5597 operation. TARGET is an optional place to store the value result of
5598 the operation. ICODE is the particular instruction to expand. Return
5599 the result of the operation. */
5601 static rtx
5602 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
5603 rtx target, enum insn_code icode)
5605 enum machine_mode mode = GET_MODE (mem);
5606 rtx insn;
5608 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5609 target = gen_reg_rtx (mode);
5611 if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
5612 old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
5613 if (!insn_data[icode].operand[2].predicate (old_val, mode))
5614 old_val = force_reg (mode, old_val);
5616 if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
5617 new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
5618 if (!insn_data[icode].operand[3].predicate (new_val, mode))
5619 new_val = force_reg (mode, new_val);
5621 insn = GEN_FCN (icode) (target, mem, old_val, new_val);
5622 if (insn == NULL_RTX)
5623 return NULL_RTX;
5624 emit_insn (insn);
5626 return target;
5629 /* Expand a compare-and-swap operation and return its value. */
5632 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5634 enum machine_mode mode = GET_MODE (mem);
5635 enum insn_code icode = sync_compare_and_swap[mode];
5637 if (icode == CODE_FOR_nothing)
5638 return NULL_RTX;
5640 return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
5643 /* Expand a compare-and-swap operation and store true into the result if
5644 the operation was successful and false otherwise. Return the result.
5645 Unlike other routines, TARGET is not optional. */
5648 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5650 enum machine_mode mode = GET_MODE (mem);
5651 enum insn_code icode;
5652 rtx subtarget, label0, label1;
5654 /* If the target supports a compare-and-swap pattern that simultaneously
5655 sets some flag for success, then use it. Otherwise use the regular
5656 compare-and-swap and follow that immediately with a compare insn. */
5657 icode = sync_compare_and_swap_cc[mode];
5658 switch (icode)
5660 default:
5661 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5662 NULL_RTX, icode);
5663 if (subtarget != NULL_RTX)
5664 break;
5666 /* FALLTHRU */
5667 case CODE_FOR_nothing:
5668 icode = sync_compare_and_swap[mode];
5669 if (icode == CODE_FOR_nothing)
5670 return NULL_RTX;
5672 /* Ensure that if old_val == mem, that we're not comparing
5673 against an old value. */
5674 if (MEM_P (old_val))
5675 old_val = force_reg (mode, old_val);
5677 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5678 NULL_RTX, icode);
5679 if (subtarget == NULL_RTX)
5680 return NULL_RTX;
5682 emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
5685 /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
5686 setcc instruction from the beginning. We don't work too hard here,
5687 but it's nice to not be stupid about initial code gen either. */
5688 if (STORE_FLAG_VALUE == 1)
5690 icode = setcc_gen_code[EQ];
5691 if (icode != CODE_FOR_nothing)
5693 enum machine_mode cmode = insn_data[icode].operand[0].mode;
5694 rtx insn;
5696 subtarget = target;
5697 if (!insn_data[icode].operand[0].predicate (target, cmode))
5698 subtarget = gen_reg_rtx (cmode);
5700 insn = GEN_FCN (icode) (subtarget);
5701 if (insn)
5703 emit_insn (insn);
5704 if (GET_MODE (target) != GET_MODE (subtarget))
5706 convert_move (target, subtarget, 1);
5707 subtarget = target;
5709 return subtarget;
5714 /* Without an appropriate setcc instruction, use a set of branches to
5715 get 1 and 0 stored into target. Presumably if the target has a
5716 STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt. */
5718 label0 = gen_label_rtx ();
5719 label1 = gen_label_rtx ();
5721 emit_jump_insn (bcc_gen_fctn[EQ] (label0));
5722 emit_move_insn (target, const0_rtx);
5723 emit_jump_insn (gen_jump (label1));
5724 emit_barrier ();
5725 emit_label (label0);
5726 emit_move_insn (target, const1_rtx);
5727 emit_label (label1);
5729 return target;
5732 /* This is a helper function for the other atomic operations. This function
5733 emits a loop that contains SEQ that iterates until a compare-and-swap
5734 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5735 a set of instructions that takes a value from OLD_REG as an input and
5736 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5737 set to the current contents of MEM. After SEQ, a compare-and-swap will
5738 attempt to update MEM with NEW_REG. The function returns true when the
5739 loop was generated successfully. */
5741 static bool
5742 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5744 enum machine_mode mode = GET_MODE (mem);
5745 enum insn_code icode;
5746 rtx label, cmp_reg, subtarget;
5748 /* The loop we want to generate looks like
5750 cmp_reg = mem;
5751 label:
5752 old_reg = cmp_reg;
5753 seq;
5754 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
5755 if (cmp_reg != old_reg)
5756 goto label;
5758 Note that we only do the plain load from memory once. Subsequent
5759 iterations use the value loaded by the compare-and-swap pattern. */
5761 label = gen_label_rtx ();
5762 cmp_reg = gen_reg_rtx (mode);
5764 emit_move_insn (cmp_reg, mem);
5765 emit_label (label);
5766 emit_move_insn (old_reg, cmp_reg);
5767 if (seq)
5768 emit_insn (seq);
5770 /* If the target supports a compare-and-swap pattern that simultaneously
5771 sets some flag for success, then use it. Otherwise use the regular
5772 compare-and-swap and follow that immediately with a compare insn. */
5773 icode = sync_compare_and_swap_cc[mode];
5774 switch (icode)
5776 default:
5777 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5778 cmp_reg, icode);
5779 if (subtarget != NULL_RTX)
5781 gcc_assert (subtarget == cmp_reg);
5782 break;
5785 /* FALLTHRU */
5786 case CODE_FOR_nothing:
5787 icode = sync_compare_and_swap[mode];
5788 if (icode == CODE_FOR_nothing)
5789 return false;
5791 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5792 cmp_reg, icode);
5793 if (subtarget == NULL_RTX)
5794 return false;
5795 if (subtarget != cmp_reg)
5796 emit_move_insn (cmp_reg, subtarget);
5798 emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
5801 /* ??? Mark this jump predicted not taken? */
5802 emit_jump_insn (bcc_gen_fctn[NE] (label));
5804 return true;
5807 /* This function generates the atomic operation MEM CODE= VAL. In this
5808 case, we do not care about any resulting value. Returns NULL if we
5809 cannot generate the operation. */
5812 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
5814 enum machine_mode mode = GET_MODE (mem);
5815 enum insn_code icode;
5816 rtx insn;
5818 /* Look to see if the target supports the operation directly. */
5819 switch (code)
5821 case PLUS:
5822 icode = sync_add_optab[mode];
5823 break;
5824 case IOR:
5825 icode = sync_ior_optab[mode];
5826 break;
5827 case XOR:
5828 icode = sync_xor_optab[mode];
5829 break;
5830 case AND:
5831 icode = sync_and_optab[mode];
5832 break;
5833 case NOT:
5834 icode = sync_nand_optab[mode];
5835 break;
5837 case MINUS:
5838 icode = sync_sub_optab[mode];
5839 if (icode == CODE_FOR_nothing)
5841 icode = sync_add_optab[mode];
5842 if (icode != CODE_FOR_nothing)
5844 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
5845 code = PLUS;
5848 break;
5850 default:
5851 gcc_unreachable ();
5854 /* Generate the direct operation, if present. */
5855 if (icode != CODE_FOR_nothing)
5857 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5858 val = convert_modes (mode, GET_MODE (val), val, 1);
5859 if (!insn_data[icode].operand[1].predicate (val, mode))
5860 val = force_reg (mode, val);
5862 insn = GEN_FCN (icode) (mem, val);
5863 if (insn)
5865 emit_insn (insn);
5866 return const0_rtx;
5870 /* Failing that, generate a compare-and-swap loop in which we perform the
5871 operation with normal arithmetic instructions. */
5872 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
5874 rtx t0 = gen_reg_rtx (mode), t1;
5876 start_sequence ();
5878 t1 = t0;
5879 if (code == NOT)
5881 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
5882 code = AND;
5884 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
5885 true, OPTAB_LIB_WIDEN);
5887 insn = get_insns ();
5888 end_sequence ();
5890 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
5891 return const0_rtx;
5894 return NULL_RTX;
5897 /* This function generates the atomic operation MEM CODE= VAL. In this
5898 case, we do care about the resulting value: if AFTER is true then
5899 return the value MEM holds after the operation, if AFTER is false
5900 then return the value MEM holds before the operation. TARGET is an
5901 optional place for the result value to be stored. */
5904 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
5905 bool after, rtx target)
5907 enum machine_mode mode = GET_MODE (mem);
5908 enum insn_code old_code, new_code, icode;
5909 bool compensate;
5910 rtx insn;
5912 /* Look to see if the target supports the operation directly. */
5913 switch (code)
5915 case PLUS:
5916 old_code = sync_old_add_optab[mode];
5917 new_code = sync_new_add_optab[mode];
5918 break;
5919 case IOR:
5920 old_code = sync_old_ior_optab[mode];
5921 new_code = sync_new_ior_optab[mode];
5922 break;
5923 case XOR:
5924 old_code = sync_old_xor_optab[mode];
5925 new_code = sync_new_xor_optab[mode];
5926 break;
5927 case AND:
5928 old_code = sync_old_and_optab[mode];
5929 new_code = sync_new_and_optab[mode];
5930 break;
5931 case NOT:
5932 old_code = sync_old_nand_optab[mode];
5933 new_code = sync_new_nand_optab[mode];
5934 break;
5936 case MINUS:
5937 old_code = sync_old_sub_optab[mode];
5938 new_code = sync_new_sub_optab[mode];
5939 if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
5941 old_code = sync_old_add_optab[mode];
5942 new_code = sync_new_add_optab[mode];
5943 if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
5945 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
5946 code = PLUS;
5949 break;
5951 default:
5952 gcc_unreachable ();
5955 /* If the target does supports the proper new/old operation, great. But
5956 if we only support the opposite old/new operation, check to see if we
5957 can compensate. In the case in which the old value is supported, then
5958 we can always perform the operation again with normal arithmetic. In
5959 the case in which the new value is supported, then we can only handle
5960 this in the case the operation is reversible. */
5961 compensate = false;
5962 if (after)
5964 icode = new_code;
5965 if (icode == CODE_FOR_nothing)
5967 icode = old_code;
5968 if (icode != CODE_FOR_nothing)
5969 compensate = true;
5972 else
5974 icode = old_code;
5975 if (icode == CODE_FOR_nothing
5976 && (code == PLUS || code == MINUS || code == XOR))
5978 icode = new_code;
5979 if (icode != CODE_FOR_nothing)
5980 compensate = true;
5984 /* If we found something supported, great. */
5985 if (icode != CODE_FOR_nothing)
5987 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5988 target = gen_reg_rtx (mode);
5990 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5991 val = convert_modes (mode, GET_MODE (val), val, 1);
5992 if (!insn_data[icode].operand[2].predicate (val, mode))
5993 val = force_reg (mode, val);
5995 insn = GEN_FCN (icode) (target, mem, val);
5996 if (insn)
5998 emit_insn (insn);
6000 /* If we need to compensate for using an operation with the
6001 wrong return value, do so now. */
6002 if (compensate)
6004 if (!after)
6006 if (code == PLUS)
6007 code = MINUS;
6008 else if (code == MINUS)
6009 code = PLUS;
6012 if (code == NOT)
6013 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
6014 target = expand_simple_binop (mode, code, target, val, NULL_RTX,
6015 true, OPTAB_LIB_WIDEN);
6018 return target;
6022 /* Failing that, generate a compare-and-swap loop in which we perform the
6023 operation with normal arithmetic instructions. */
6024 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6026 rtx t0 = gen_reg_rtx (mode), t1;
6028 if (!target || !register_operand (target, mode))
6029 target = gen_reg_rtx (mode);
6031 start_sequence ();
6033 if (!after)
6034 emit_move_insn (target, t0);
6035 t1 = t0;
6036 if (code == NOT)
6038 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6039 code = AND;
6041 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6042 true, OPTAB_LIB_WIDEN);
6043 if (after)
6044 emit_move_insn (target, t1);
6046 insn = get_insns ();
6047 end_sequence ();
6049 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6050 return target;
6053 return NULL_RTX;
6056 /* This function expands a test-and-set operation. Ideally we atomically
6057 store VAL in MEM and return the previous value in MEM. Some targets
6058 may not support this operation and only support VAL with the constant 1;
6059 in this case while the return value will be 0/1, but the exact value
6060 stored in MEM is target defined. TARGET is an option place to stick
6061 the return value. */
6064 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
6066 enum machine_mode mode = GET_MODE (mem);
6067 enum insn_code icode;
6068 rtx insn;
6070 /* If the target supports the test-and-set directly, great. */
6071 icode = sync_lock_test_and_set[mode];
6072 if (icode != CODE_FOR_nothing)
6074 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6075 target = gen_reg_rtx (mode);
6077 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6078 val = convert_modes (mode, GET_MODE (val), val, 1);
6079 if (!insn_data[icode].operand[2].predicate (val, mode))
6080 val = force_reg (mode, val);
6082 insn = GEN_FCN (icode) (target, mem, val);
6083 if (insn)
6085 emit_insn (insn);
6086 return target;
6090 /* Otherwise, use a compare-and-swap loop for the exchange. */
6091 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6093 if (!target || !register_operand (target, mode))
6094 target = gen_reg_rtx (mode);
6095 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6096 val = convert_modes (mode, GET_MODE (val), val, 1);
6097 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6098 return target;
6101 return NULL_RTX;
6104 #include "gt-optabs.h"