2005-06-19 Andreas Krebbel <krebbel1@de.ibm.com>
[official-gcc.git] / gcc / optabs.c
blobcd4f2cbe6d097a59c66c581742af8285f385e582
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 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, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, 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[CTI_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 reduc_plus_optab;
306 default:
307 break;
310 trapv = flag_trapv && INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type);
311 switch (code)
313 case PLUS_EXPR:
314 return trapv ? addv_optab : add_optab;
316 case MINUS_EXPR:
317 return trapv ? subv_optab : sub_optab;
319 case MULT_EXPR:
320 return trapv ? smulv_optab : smul_optab;
322 case NEGATE_EXPR:
323 return trapv ? negv_optab : neg_optab;
325 case ABS_EXPR:
326 return trapv ? absv_optab : abs_optab;
328 default:
329 return NULL;
334 /* Generate code to perform an operation specified by TERNARY_OPTAB
335 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
337 UNSIGNEDP is for the case where we have to widen the operands
338 to perform the operation. It says to use zero-extension.
340 If TARGET is nonzero, the value
341 is generated there, if it is convenient to do so.
342 In all cases an rtx is returned for the locus of the value;
343 this may or may not be TARGET. */
346 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
347 rtx op1, rtx op2, rtx target, int unsignedp)
349 int icode = (int) ternary_optab->handlers[(int) mode].insn_code;
350 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
351 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
352 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
353 rtx temp;
354 rtx pat;
355 rtx xop0 = op0, xop1 = op1, xop2 = op2;
357 gcc_assert (ternary_optab->handlers[(int) mode].insn_code
358 != CODE_FOR_nothing);
360 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
361 temp = gen_reg_rtx (mode);
362 else
363 temp = target;
365 /* In case the insn wants input operands in modes different from
366 those of the actual operands, convert the operands. It would
367 seem that we don't need to convert CONST_INTs, but we do, so
368 that they're properly zero-extended, sign-extended or truncated
369 for their mode. */
371 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
372 xop0 = convert_modes (mode0,
373 GET_MODE (op0) != VOIDmode
374 ? GET_MODE (op0)
375 : mode,
376 xop0, unsignedp);
378 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
379 xop1 = convert_modes (mode1,
380 GET_MODE (op1) != VOIDmode
381 ? GET_MODE (op1)
382 : mode,
383 xop1, unsignedp);
385 if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
386 xop2 = convert_modes (mode2,
387 GET_MODE (op2) != VOIDmode
388 ? GET_MODE (op2)
389 : mode,
390 xop2, unsignedp);
392 /* Now, if insn's predicates don't allow our operands, put them into
393 pseudo regs. */
395 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
396 && mode0 != VOIDmode)
397 xop0 = copy_to_mode_reg (mode0, xop0);
399 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
400 && mode1 != VOIDmode)
401 xop1 = copy_to_mode_reg (mode1, xop1);
403 if (!insn_data[icode].operand[3].predicate (xop2, mode2)
404 && mode2 != VOIDmode)
405 xop2 = copy_to_mode_reg (mode2, xop2);
407 pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
409 emit_insn (pat);
410 return temp;
414 /* Like expand_binop, but return a constant rtx if the result can be
415 calculated at compile time. The arguments and return value are
416 otherwise the same as for expand_binop. */
418 static rtx
419 simplify_expand_binop (enum machine_mode mode, optab binoptab,
420 rtx op0, rtx op1, rtx target, int unsignedp,
421 enum optab_methods methods)
423 if (CONSTANT_P (op0) && CONSTANT_P (op1))
424 return simplify_gen_binary (binoptab->code, mode, op0, op1);
425 else
426 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
429 /* Like simplify_expand_binop, but always put the result in TARGET.
430 Return true if the expansion succeeded. */
432 bool
433 force_expand_binop (enum machine_mode mode, optab binoptab,
434 rtx op0, rtx op1, rtx target, int unsignedp,
435 enum optab_methods methods)
437 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
438 target, unsignedp, methods);
439 if (x == 0)
440 return false;
441 if (x != target)
442 emit_move_insn (target, x);
443 return true;
446 /* This subroutine of expand_doubleword_shift handles the cases in which
447 the effective shift value is >= BITS_PER_WORD. The arguments and return
448 value are the same as for the parent routine, except that SUPERWORD_OP1
449 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
450 INTO_TARGET may be null if the caller has decided to calculate it. */
452 static bool
453 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
454 rtx outof_target, rtx into_target,
455 int unsignedp, enum optab_methods methods)
457 if (into_target != 0)
458 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
459 into_target, unsignedp, methods))
460 return false;
462 if (outof_target != 0)
464 /* For a signed right shift, we must fill OUTOF_TARGET with copies
465 of the sign bit, otherwise we must fill it with zeros. */
466 if (binoptab != ashr_optab)
467 emit_move_insn (outof_target, CONST0_RTX (word_mode));
468 else
469 if (!force_expand_binop (word_mode, binoptab,
470 outof_input, GEN_INT (BITS_PER_WORD - 1),
471 outof_target, unsignedp, methods))
472 return false;
474 return true;
477 /* This subroutine of expand_doubleword_shift handles the cases in which
478 the effective shift value is < BITS_PER_WORD. The arguments and return
479 value are the same as for the parent routine. */
481 static bool
482 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
483 rtx outof_input, rtx into_input, rtx op1,
484 rtx outof_target, rtx into_target,
485 int unsignedp, enum optab_methods methods,
486 unsigned HOST_WIDE_INT shift_mask)
488 optab reverse_unsigned_shift, unsigned_shift;
489 rtx tmp, carries;
491 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
492 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
494 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
495 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
496 the opposite direction to BINOPTAB. */
497 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
499 carries = outof_input;
500 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
501 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
502 0, true, methods);
504 else
506 /* We must avoid shifting by BITS_PER_WORD bits since that is either
507 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
508 has unknown behavior. Do a single shift first, then shift by the
509 remainder. It's OK to use ~OP1 as the remainder if shift counts
510 are truncated to the mode size. */
511 carries = expand_binop (word_mode, reverse_unsigned_shift,
512 outof_input, const1_rtx, 0, unsignedp, methods);
513 if (shift_mask == BITS_PER_WORD - 1)
515 tmp = immed_double_const (-1, -1, op1_mode);
516 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
517 0, true, methods);
519 else
521 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
522 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
523 0, true, methods);
526 if (tmp == 0 || carries == 0)
527 return false;
528 carries = expand_binop (word_mode, reverse_unsigned_shift,
529 carries, tmp, 0, unsignedp, methods);
530 if (carries == 0)
531 return false;
533 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
534 so the result can go directly into INTO_TARGET if convenient. */
535 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
536 into_target, unsignedp, methods);
537 if (tmp == 0)
538 return false;
540 /* Now OR in the bits carried over from OUTOF_INPUT. */
541 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
542 into_target, unsignedp, methods))
543 return false;
545 /* Use a standard word_mode shift for the out-of half. */
546 if (outof_target != 0)
547 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
548 outof_target, unsignedp, methods))
549 return false;
551 return true;
555 #ifdef HAVE_conditional_move
556 /* Try implementing expand_doubleword_shift using conditional moves.
557 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
558 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
559 are the shift counts to use in the former and latter case. All other
560 arguments are the same as the parent routine. */
562 static bool
563 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
564 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
565 rtx outof_input, rtx into_input,
566 rtx subword_op1, rtx superword_op1,
567 rtx outof_target, rtx into_target,
568 int unsignedp, enum optab_methods methods,
569 unsigned HOST_WIDE_INT shift_mask)
571 rtx outof_superword, into_superword;
573 /* Put the superword version of the output into OUTOF_SUPERWORD and
574 INTO_SUPERWORD. */
575 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
576 if (outof_target != 0 && subword_op1 == superword_op1)
578 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
579 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
580 into_superword = outof_target;
581 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
582 outof_superword, 0, unsignedp, methods))
583 return false;
585 else
587 into_superword = gen_reg_rtx (word_mode);
588 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
589 outof_superword, into_superword,
590 unsignedp, methods))
591 return false;
594 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
595 if (!expand_subword_shift (op1_mode, binoptab,
596 outof_input, into_input, subword_op1,
597 outof_target, into_target,
598 unsignedp, methods, shift_mask))
599 return false;
601 /* Select between them. Do the INTO half first because INTO_SUPERWORD
602 might be the current value of OUTOF_TARGET. */
603 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
604 into_target, into_superword, word_mode, false))
605 return false;
607 if (outof_target != 0)
608 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
609 outof_target, outof_superword,
610 word_mode, false))
611 return false;
613 return true;
615 #endif
617 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
618 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
619 input operand; the shift moves bits in the direction OUTOF_INPUT->
620 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
621 of the target. OP1 is the shift count and OP1_MODE is its mode.
622 If OP1 is constant, it will have been truncated as appropriate
623 and is known to be nonzero.
625 If SHIFT_MASK is zero, the result of word shifts is undefined when the
626 shift count is outside the range [0, BITS_PER_WORD). This routine must
627 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
629 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
630 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
631 fill with zeros or sign bits as appropriate.
633 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
634 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
635 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
636 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
637 are undefined.
639 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
640 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
641 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
642 function wants to calculate it itself.
644 Return true if the shift could be successfully synthesized. */
646 static bool
647 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
648 rtx outof_input, rtx into_input, rtx op1,
649 rtx outof_target, rtx into_target,
650 int unsignedp, enum optab_methods methods,
651 unsigned HOST_WIDE_INT shift_mask)
653 rtx superword_op1, tmp, cmp1, cmp2;
654 rtx subword_label, done_label;
655 enum rtx_code cmp_code;
657 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
658 fill the result with sign or zero bits as appropriate. If so, the value
659 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
660 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
661 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
663 This isn't worthwhile for constant shifts since the optimizers will
664 cope better with in-range shift counts. */
665 if (shift_mask >= BITS_PER_WORD
666 && outof_target != 0
667 && !CONSTANT_P (op1))
669 if (!expand_doubleword_shift (op1_mode, binoptab,
670 outof_input, into_input, op1,
671 0, into_target,
672 unsignedp, methods, shift_mask))
673 return false;
674 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
675 outof_target, unsignedp, methods))
676 return false;
677 return true;
680 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
681 is true when the effective shift value is less than BITS_PER_WORD.
682 Set SUPERWORD_OP1 to the shift count that should be used to shift
683 OUTOF_INPUT into INTO_TARGET when the condition is false. */
684 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
685 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
687 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
688 is a subword shift count. */
689 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
690 0, true, methods);
691 cmp2 = CONST0_RTX (op1_mode);
692 cmp_code = EQ;
693 superword_op1 = op1;
695 else
697 /* Set CMP1 to OP1 - BITS_PER_WORD. */
698 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
699 0, true, methods);
700 cmp2 = CONST0_RTX (op1_mode);
701 cmp_code = LT;
702 superword_op1 = cmp1;
704 if (cmp1 == 0)
705 return false;
707 /* If we can compute the condition at compile time, pick the
708 appropriate subroutine. */
709 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
710 if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
712 if (tmp == const0_rtx)
713 return expand_superword_shift (binoptab, outof_input, superword_op1,
714 outof_target, into_target,
715 unsignedp, methods);
716 else
717 return expand_subword_shift (op1_mode, binoptab,
718 outof_input, into_input, op1,
719 outof_target, into_target,
720 unsignedp, methods, shift_mask);
723 #ifdef HAVE_conditional_move
724 /* Try using conditional moves to generate straight-line code. */
726 rtx start = get_last_insn ();
727 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
728 cmp_code, cmp1, cmp2,
729 outof_input, into_input,
730 op1, superword_op1,
731 outof_target, into_target,
732 unsignedp, methods, shift_mask))
733 return true;
734 delete_insns_since (start);
736 #endif
738 /* As a last resort, use branches to select the correct alternative. */
739 subword_label = gen_label_rtx ();
740 done_label = gen_label_rtx ();
742 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
743 0, 0, subword_label);
745 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
746 outof_target, into_target,
747 unsignedp, methods))
748 return false;
750 emit_jump_insn (gen_jump (done_label));
751 emit_barrier ();
752 emit_label (subword_label);
754 if (!expand_subword_shift (op1_mode, binoptab,
755 outof_input, into_input, op1,
756 outof_target, into_target,
757 unsignedp, methods, shift_mask))
758 return false;
760 emit_label (done_label);
761 return true;
764 /* Subroutine of expand_binop. Perform a double word multiplication of
765 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
766 as the target's word_mode. This function return NULL_RTX if anything
767 goes wrong, in which case it may have already emitted instructions
768 which need to be deleted.
770 If we want to multiply two two-word values and have normal and widening
771 multiplies of single-word values, we can do this with three smaller
772 multiplications. Note that we do not make a REG_NO_CONFLICT block here
773 because we are not operating on one word at a time.
775 The multiplication proceeds as follows:
776 _______________________
777 [__op0_high_|__op0_low__]
778 _______________________
779 * [__op1_high_|__op1_low__]
780 _______________________________________________
781 _______________________
782 (1) [__op0_low__*__op1_low__]
783 _______________________
784 (2a) [__op0_low__*__op1_high_]
785 _______________________
786 (2b) [__op0_high_*__op1_low__]
787 _______________________
788 (3) [__op0_high_*__op1_high_]
791 This gives a 4-word result. Since we are only interested in the
792 lower 2 words, partial result (3) and the upper words of (2a) and
793 (2b) don't need to be calculated. Hence (2a) and (2b) can be
794 calculated using non-widening multiplication.
796 (1), however, needs to be calculated with an unsigned widening
797 multiplication. If this operation is not directly supported we
798 try using a signed widening multiplication and adjust the result.
799 This adjustment works as follows:
801 If both operands are positive then no adjustment is needed.
803 If the operands have different signs, for example op0_low < 0 and
804 op1_low >= 0, the instruction treats the most significant bit of
805 op0_low as a sign bit instead of a bit with significance
806 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
807 with 2**BITS_PER_WORD - op0_low, and two's complements the
808 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
809 the result.
811 Similarly, if both operands are negative, we need to add
812 (op0_low + op1_low) * 2**BITS_PER_WORD.
814 We use a trick to adjust quickly. We logically shift op0_low right
815 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
816 op0_high (op1_high) before it is used to calculate 2b (2a). If no
817 logical shift exists, we do an arithmetic right shift and subtract
818 the 0 or -1. */
820 static rtx
821 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
822 bool umulp, enum optab_methods methods)
824 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
825 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
826 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
827 rtx product, adjust, product_high, temp;
829 rtx op0_high = operand_subword_force (op0, high, mode);
830 rtx op0_low = operand_subword_force (op0, low, mode);
831 rtx op1_high = operand_subword_force (op1, high, mode);
832 rtx op1_low = operand_subword_force (op1, low, mode);
834 /* If we're using an unsigned multiply to directly compute the product
835 of the low-order words of the operands and perform any required
836 adjustments of the operands, we begin by trying two more multiplications
837 and then computing the appropriate sum.
839 We have checked above that the required addition is provided.
840 Full-word addition will normally always succeed, especially if
841 it is provided at all, so we don't worry about its failure. The
842 multiplication may well fail, however, so we do handle that. */
844 if (!umulp)
846 /* ??? This could be done with emit_store_flag where available. */
847 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
848 NULL_RTX, 1, methods);
849 if (temp)
850 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
851 NULL_RTX, 0, OPTAB_DIRECT);
852 else
854 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
855 NULL_RTX, 0, methods);
856 if (!temp)
857 return NULL_RTX;
858 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
859 NULL_RTX, 0, OPTAB_DIRECT);
862 if (!op0_high)
863 return NULL_RTX;
866 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
867 NULL_RTX, 0, OPTAB_DIRECT);
868 if (!adjust)
869 return NULL_RTX;
871 /* OP0_HIGH should now be dead. */
873 if (!umulp)
875 /* ??? This could be done with emit_store_flag where available. */
876 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
877 NULL_RTX, 1, methods);
878 if (temp)
879 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
880 NULL_RTX, 0, OPTAB_DIRECT);
881 else
883 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
884 NULL_RTX, 0, methods);
885 if (!temp)
886 return NULL_RTX;
887 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
888 NULL_RTX, 0, OPTAB_DIRECT);
891 if (!op1_high)
892 return NULL_RTX;
895 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
896 NULL_RTX, 0, OPTAB_DIRECT);
897 if (!temp)
898 return NULL_RTX;
900 /* OP1_HIGH should now be dead. */
902 adjust = expand_binop (word_mode, add_optab, adjust, temp,
903 adjust, 0, OPTAB_DIRECT);
905 if (target && !REG_P (target))
906 target = NULL_RTX;
908 if (umulp)
909 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
910 target, 1, OPTAB_DIRECT);
911 else
912 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
913 target, 1, OPTAB_DIRECT);
915 if (!product)
916 return NULL_RTX;
918 product_high = operand_subword (product, high, 1, mode);
919 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
920 REG_P (product_high) ? product_high : adjust,
921 0, OPTAB_DIRECT);
922 emit_move_insn (product_high, adjust);
923 return product;
926 /* Wrapper around expand_binop which takes an rtx code to specify
927 the operation to perform, not an optab pointer. All other
928 arguments are the same. */
930 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
931 rtx op1, rtx target, int unsignedp,
932 enum optab_methods methods)
934 optab binop = code_to_optab[(int) code];
935 gcc_assert (binop);
937 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
940 /* Generate code to perform an operation specified by BINOPTAB
941 on operands OP0 and OP1, with result having machine-mode MODE.
943 UNSIGNEDP is for the case where we have to widen the operands
944 to perform the operation. It says to use zero-extension.
946 If TARGET is nonzero, the value
947 is generated there, if it is convenient to do so.
948 In all cases an rtx is returned for the locus of the value;
949 this may or may not be TARGET. */
952 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
953 rtx target, int unsignedp, enum optab_methods methods)
955 enum optab_methods next_methods
956 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
957 ? OPTAB_WIDEN : methods);
958 enum mode_class class;
959 enum machine_mode wider_mode;
960 rtx temp;
961 int commutative_op = 0;
962 int shift_op = (binoptab->code == ASHIFT
963 || binoptab->code == ASHIFTRT
964 || binoptab->code == LSHIFTRT
965 || binoptab->code == ROTATE
966 || binoptab->code == ROTATERT);
967 rtx entry_last = get_last_insn ();
968 rtx last;
970 class = GET_MODE_CLASS (mode);
972 if (flag_force_mem)
974 /* Load duplicate non-volatile operands once. */
975 if (rtx_equal_p (op0, op1) && ! volatile_refs_p (op0))
977 op0 = force_not_mem (op0);
978 op1 = op0;
980 else
982 op0 = force_not_mem (op0);
983 op1 = force_not_mem (op1);
987 /* If subtracting an integer constant, convert this into an addition of
988 the negated constant. */
990 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
992 op1 = negate_rtx (mode, op1);
993 binoptab = add_optab;
996 /* If we are inside an appropriately-short loop and we are optimizing,
997 force expensive constants into a register. */
998 if (CONSTANT_P (op0) && optimize
999 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1001 if (GET_MODE (op0) != VOIDmode)
1002 op0 = convert_modes (mode, VOIDmode, op0, unsignedp);
1003 op0 = force_reg (mode, op0);
1006 if (CONSTANT_P (op1) && optimize
1007 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1009 if (GET_MODE (op1) != VOIDmode)
1010 op1 = convert_modes (mode, VOIDmode, op1, unsignedp);
1011 op1 = force_reg (mode, op1);
1014 /* Record where to delete back to if we backtrack. */
1015 last = get_last_insn ();
1017 /* If operation is commutative,
1018 try to make the first operand a register.
1019 Even better, try to make it the same as the target.
1020 Also try to make the last operand a constant. */
1021 if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1022 || binoptab == smul_widen_optab
1023 || binoptab == umul_widen_optab
1024 || binoptab == smul_highpart_optab
1025 || binoptab == umul_highpart_optab)
1027 commutative_op = 1;
1029 if (((target == 0 || REG_P (target))
1030 ? ((REG_P (op1)
1031 && !REG_P (op0))
1032 || target == op1)
1033 : rtx_equal_p (op1, target))
1034 || GET_CODE (op0) == CONST_INT)
1036 temp = op1;
1037 op1 = op0;
1038 op0 = temp;
1042 /* If we can do it with a three-operand insn, do so. */
1044 if (methods != OPTAB_MUST_WIDEN
1045 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1047 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1048 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1049 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1050 rtx pat;
1051 rtx xop0 = op0, xop1 = op1;
1053 if (target)
1054 temp = target;
1055 else
1056 temp = gen_reg_rtx (mode);
1058 /* If it is a commutative operator and the modes would match
1059 if we would swap the operands, we can save the conversions. */
1060 if (commutative_op)
1062 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
1063 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
1065 rtx tmp;
1067 tmp = op0; op0 = op1; op1 = tmp;
1068 tmp = xop0; xop0 = xop1; xop1 = tmp;
1072 /* In case the insn wants input operands in modes different from
1073 those of the actual operands, convert the operands. It would
1074 seem that we don't need to convert CONST_INTs, but we do, so
1075 that they're properly zero-extended, sign-extended or truncated
1076 for their mode. */
1078 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
1079 xop0 = convert_modes (mode0,
1080 GET_MODE (op0) != VOIDmode
1081 ? GET_MODE (op0)
1082 : mode,
1083 xop0, unsignedp);
1085 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
1086 xop1 = convert_modes (mode1,
1087 GET_MODE (op1) != VOIDmode
1088 ? GET_MODE (op1)
1089 : mode,
1090 xop1, unsignedp);
1092 /* Now, if insn's predicates don't allow our operands, put them into
1093 pseudo regs. */
1095 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1096 && mode0 != VOIDmode)
1097 xop0 = copy_to_mode_reg (mode0, xop0);
1099 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1100 && mode1 != VOIDmode)
1101 xop1 = copy_to_mode_reg (mode1, xop1);
1103 if (!insn_data[icode].operand[0].predicate (temp, mode))
1104 temp = gen_reg_rtx (mode);
1106 pat = GEN_FCN (icode) (temp, xop0, xop1);
1107 if (pat)
1109 /* If PAT is composed of more than one insn, try to add an appropriate
1110 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1111 operand, call ourselves again, this time without a target. */
1112 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1113 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1115 delete_insns_since (last);
1116 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1117 unsignedp, methods);
1120 emit_insn (pat);
1121 return temp;
1123 else
1124 delete_insns_since (last);
1127 /* If this is a multiply, see if we can do a widening operation that
1128 takes operands of this mode and makes a wider mode. */
1130 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
1131 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1132 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
1133 != CODE_FOR_nothing))
1135 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1136 unsignedp ? umul_widen_optab : smul_widen_optab,
1137 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1139 if (temp != 0)
1141 if (GET_MODE_CLASS (mode) == MODE_INT)
1142 return gen_lowpart (mode, temp);
1143 else
1144 return convert_to_mode (mode, temp, unsignedp);
1148 /* Look for a wider mode of the same class for which we think we
1149 can open-code the operation. Check for a widening multiply at the
1150 wider mode as well. */
1152 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1153 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1154 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1155 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1157 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
1158 || (binoptab == smul_optab
1159 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1160 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1161 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
1162 != CODE_FOR_nothing)))
1164 rtx xop0 = op0, xop1 = op1;
1165 int no_extend = 0;
1167 /* For certain integer operations, we need not actually extend
1168 the narrow operands, as long as we will truncate
1169 the results to the same narrowness. */
1171 if ((binoptab == ior_optab || binoptab == and_optab
1172 || binoptab == xor_optab
1173 || binoptab == add_optab || binoptab == sub_optab
1174 || binoptab == smul_optab || binoptab == ashl_optab)
1175 && class == MODE_INT)
1176 no_extend = 1;
1178 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1180 /* The second operand of a shift must always be extended. */
1181 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1182 no_extend && binoptab != ashl_optab);
1184 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1185 unsignedp, OPTAB_DIRECT);
1186 if (temp)
1188 if (class != MODE_INT)
1190 if (target == 0)
1191 target = gen_reg_rtx (mode);
1192 convert_move (target, temp, 0);
1193 return target;
1195 else
1196 return gen_lowpart (mode, temp);
1198 else
1199 delete_insns_since (last);
1203 /* These can be done a word at a time. */
1204 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1205 && class == MODE_INT
1206 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1207 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1209 int i;
1210 rtx insns;
1211 rtx equiv_value;
1213 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1214 won't be accurate, so use a new target. */
1215 if (target == 0 || target == op0 || target == op1)
1216 target = gen_reg_rtx (mode);
1218 start_sequence ();
1220 /* Do the actual arithmetic. */
1221 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1223 rtx target_piece = operand_subword (target, i, 1, mode);
1224 rtx x = expand_binop (word_mode, binoptab,
1225 operand_subword_force (op0, i, mode),
1226 operand_subword_force (op1, i, mode),
1227 target_piece, unsignedp, next_methods);
1229 if (x == 0)
1230 break;
1232 if (target_piece != x)
1233 emit_move_insn (target_piece, x);
1236 insns = get_insns ();
1237 end_sequence ();
1239 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1241 if (binoptab->code != UNKNOWN)
1242 equiv_value
1243 = gen_rtx_fmt_ee (binoptab->code, mode,
1244 copy_rtx (op0), copy_rtx (op1));
1245 else
1246 equiv_value = 0;
1248 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1249 return target;
1253 /* Synthesize double word shifts from single word shifts. */
1254 if ((binoptab == lshr_optab || binoptab == ashl_optab
1255 || binoptab == ashr_optab)
1256 && class == MODE_INT
1257 && (GET_CODE (op1) == CONST_INT || !optimize_size)
1258 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1259 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1260 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1261 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1263 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1264 enum machine_mode op1_mode;
1266 double_shift_mask = targetm.shift_truncation_mask (mode);
1267 shift_mask = targetm.shift_truncation_mask (word_mode);
1268 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1270 /* Apply the truncation to constant shifts. */
1271 if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1272 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1274 if (op1 == CONST0_RTX (op1_mode))
1275 return op0;
1277 /* Make sure that this is a combination that expand_doubleword_shift
1278 can handle. See the comments there for details. */
1279 if (double_shift_mask == 0
1280 || (shift_mask == BITS_PER_WORD - 1
1281 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1283 rtx insns, equiv_value;
1284 rtx into_target, outof_target;
1285 rtx into_input, outof_input;
1286 int left_shift, outof_word;
1288 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1289 won't be accurate, so use a new target. */
1290 if (target == 0 || target == op0 || target == op1)
1291 target = gen_reg_rtx (mode);
1293 start_sequence ();
1295 /* OUTOF_* is the word we are shifting bits away from, and
1296 INTO_* is the word that we are shifting bits towards, thus
1297 they differ depending on the direction of the shift and
1298 WORDS_BIG_ENDIAN. */
1300 left_shift = binoptab == ashl_optab;
1301 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1303 outof_target = operand_subword (target, outof_word, 1, mode);
1304 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1306 outof_input = operand_subword_force (op0, outof_word, mode);
1307 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1309 if (expand_doubleword_shift (op1_mode, binoptab,
1310 outof_input, into_input, op1,
1311 outof_target, into_target,
1312 unsignedp, methods, shift_mask))
1314 insns = get_insns ();
1315 end_sequence ();
1317 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1318 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1319 return target;
1321 end_sequence ();
1325 /* Synthesize double word rotates from single word shifts. */
1326 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1327 && class == MODE_INT
1328 && GET_CODE (op1) == CONST_INT
1329 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1330 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1331 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1333 rtx insns, equiv_value;
1334 rtx into_target, outof_target;
1335 rtx into_input, outof_input;
1336 rtx inter;
1337 int shift_count, left_shift, outof_word;
1339 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1340 won't be accurate, so use a new target. Do this also if target is not
1341 a REG, first because having a register instead may open optimization
1342 opportunities, and second because if target and op0 happen to be MEMs
1343 designating the same location, we would risk clobbering it too early
1344 in the code sequence we generate below. */
1345 if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1346 target = gen_reg_rtx (mode);
1348 start_sequence ();
1350 shift_count = INTVAL (op1);
1352 /* OUTOF_* is the word we are shifting bits away from, and
1353 INTO_* is the word that we are shifting bits towards, thus
1354 they differ depending on the direction of the shift and
1355 WORDS_BIG_ENDIAN. */
1357 left_shift = (binoptab == rotl_optab);
1358 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1360 outof_target = operand_subword (target, outof_word, 1, mode);
1361 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1363 outof_input = operand_subword_force (op0, outof_word, mode);
1364 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1366 if (shift_count == BITS_PER_WORD)
1368 /* This is just a word swap. */
1369 emit_move_insn (outof_target, into_input);
1370 emit_move_insn (into_target, outof_input);
1371 inter = const0_rtx;
1373 else
1375 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1376 rtx first_shift_count, second_shift_count;
1377 optab reverse_unsigned_shift, unsigned_shift;
1379 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1380 ? lshr_optab : ashl_optab);
1382 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1383 ? ashl_optab : lshr_optab);
1385 if (shift_count > BITS_PER_WORD)
1387 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1388 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1390 else
1392 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1393 second_shift_count = GEN_INT (shift_count);
1396 into_temp1 = expand_binop (word_mode, unsigned_shift,
1397 outof_input, first_shift_count,
1398 NULL_RTX, unsignedp, next_methods);
1399 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1400 into_input, second_shift_count,
1401 NULL_RTX, unsignedp, next_methods);
1403 if (into_temp1 != 0 && into_temp2 != 0)
1404 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1405 into_target, unsignedp, next_methods);
1406 else
1407 inter = 0;
1409 if (inter != 0 && inter != into_target)
1410 emit_move_insn (into_target, inter);
1412 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1413 into_input, first_shift_count,
1414 NULL_RTX, unsignedp, next_methods);
1415 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1416 outof_input, second_shift_count,
1417 NULL_RTX, unsignedp, next_methods);
1419 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1420 inter = expand_binop (word_mode, ior_optab,
1421 outof_temp1, outof_temp2,
1422 outof_target, unsignedp, next_methods);
1424 if (inter != 0 && inter != outof_target)
1425 emit_move_insn (outof_target, inter);
1428 insns = get_insns ();
1429 end_sequence ();
1431 if (inter != 0)
1433 if (binoptab->code != UNKNOWN)
1434 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1435 else
1436 equiv_value = 0;
1438 /* We can't make this a no conflict block if this is a word swap,
1439 because the word swap case fails if the input and output values
1440 are in the same register. */
1441 if (shift_count != BITS_PER_WORD)
1442 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1443 else
1444 emit_insn (insns);
1447 return target;
1451 /* These can be done a word at a time by propagating carries. */
1452 if ((binoptab == add_optab || binoptab == sub_optab)
1453 && class == MODE_INT
1454 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1455 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1457 unsigned int i;
1458 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1459 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1460 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1461 rtx xop0, xop1, xtarget;
1463 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1464 value is one of those, use it. Otherwise, use 1 since it is the
1465 one easiest to get. */
1466 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1467 int normalizep = STORE_FLAG_VALUE;
1468 #else
1469 int normalizep = 1;
1470 #endif
1472 /* Prepare the operands. */
1473 xop0 = force_reg (mode, op0);
1474 xop1 = force_reg (mode, op1);
1476 xtarget = gen_reg_rtx (mode);
1478 if (target == 0 || !REG_P (target))
1479 target = xtarget;
1481 /* Indicate for flow that the entire target reg is being set. */
1482 if (REG_P (target))
1483 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1485 /* Do the actual arithmetic. */
1486 for (i = 0; i < nwords; i++)
1488 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1489 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1490 rtx op0_piece = operand_subword_force (xop0, index, mode);
1491 rtx op1_piece = operand_subword_force (xop1, index, mode);
1492 rtx x;
1494 /* Main add/subtract of the input operands. */
1495 x = expand_binop (word_mode, binoptab,
1496 op0_piece, op1_piece,
1497 target_piece, unsignedp, next_methods);
1498 if (x == 0)
1499 break;
1501 if (i + 1 < nwords)
1503 /* Store carry from main add/subtract. */
1504 carry_out = gen_reg_rtx (word_mode);
1505 carry_out = emit_store_flag_force (carry_out,
1506 (binoptab == add_optab
1507 ? LT : GT),
1508 x, op0_piece,
1509 word_mode, 1, normalizep);
1512 if (i > 0)
1514 rtx newx;
1516 /* Add/subtract previous carry to main result. */
1517 newx = expand_binop (word_mode,
1518 normalizep == 1 ? binoptab : otheroptab,
1519 x, carry_in,
1520 NULL_RTX, 1, next_methods);
1522 if (i + 1 < nwords)
1524 /* Get out carry from adding/subtracting carry in. */
1525 rtx carry_tmp = gen_reg_rtx (word_mode);
1526 carry_tmp = emit_store_flag_force (carry_tmp,
1527 (binoptab == add_optab
1528 ? LT : GT),
1529 newx, x,
1530 word_mode, 1, normalizep);
1532 /* Logical-ior the two poss. carry together. */
1533 carry_out = expand_binop (word_mode, ior_optab,
1534 carry_out, carry_tmp,
1535 carry_out, 0, next_methods);
1536 if (carry_out == 0)
1537 break;
1539 emit_move_insn (target_piece, newx);
1541 else
1543 if (x != target_piece)
1544 emit_move_insn (target_piece, x);
1547 carry_in = carry_out;
1550 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1552 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
1553 || ! rtx_equal_p (target, xtarget))
1555 rtx temp = emit_move_insn (target, xtarget);
1557 set_unique_reg_note (temp,
1558 REG_EQUAL,
1559 gen_rtx_fmt_ee (binoptab->code, mode,
1560 copy_rtx (xop0),
1561 copy_rtx (xop1)));
1563 else
1564 target = xtarget;
1566 return target;
1569 else
1570 delete_insns_since (last);
1573 /* Attempt to synthesize double word multiplies using a sequence of word
1574 mode multiplications. We first attempt to generate a sequence using a
1575 more efficient unsigned widening multiply, and if that fails we then
1576 try using a signed widening multiply. */
1578 if (binoptab == smul_optab
1579 && class == MODE_INT
1580 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1581 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1582 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1584 rtx product = NULL_RTX;
1586 if (umul_widen_optab->handlers[(int) mode].insn_code
1587 != CODE_FOR_nothing)
1589 product = expand_doubleword_mult (mode, op0, op1, target,
1590 true, methods);
1591 if (!product)
1592 delete_insns_since (last);
1595 if (product == NULL_RTX
1596 && smul_widen_optab->handlers[(int) mode].insn_code
1597 != CODE_FOR_nothing)
1599 product = expand_doubleword_mult (mode, op0, op1, target,
1600 false, methods);
1601 if (!product)
1602 delete_insns_since (last);
1605 if (product != NULL_RTX)
1607 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1609 temp = emit_move_insn (target ? target : product, product);
1610 set_unique_reg_note (temp,
1611 REG_EQUAL,
1612 gen_rtx_fmt_ee (MULT, mode,
1613 copy_rtx (op0),
1614 copy_rtx (op1)));
1616 return product;
1620 /* It can't be open-coded in this mode.
1621 Use a library call if one is available and caller says that's ok. */
1623 if (binoptab->handlers[(int) mode].libfunc
1624 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1626 rtx insns;
1627 rtx op1x = op1;
1628 enum machine_mode op1_mode = mode;
1629 rtx value;
1631 start_sequence ();
1633 if (shift_op)
1635 op1_mode = word_mode;
1636 /* Specify unsigned here,
1637 since negative shift counts are meaningless. */
1638 op1x = convert_to_mode (word_mode, op1, 1);
1641 if (GET_MODE (op0) != VOIDmode
1642 && GET_MODE (op0) != mode)
1643 op0 = convert_to_mode (mode, op0, unsignedp);
1645 /* Pass 1 for NO_QUEUE so we don't lose any increments
1646 if the libcall is cse'd or moved. */
1647 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1648 NULL_RTX, LCT_CONST, mode, 2,
1649 op0, mode, op1x, op1_mode);
1651 insns = get_insns ();
1652 end_sequence ();
1654 target = gen_reg_rtx (mode);
1655 emit_libcall_block (insns, target, value,
1656 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1658 return target;
1661 delete_insns_since (last);
1663 /* It can't be done in this mode. Can we do it in a wider mode? */
1665 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1666 || methods == OPTAB_MUST_WIDEN))
1668 /* Caller says, don't even try. */
1669 delete_insns_since (entry_last);
1670 return 0;
1673 /* Compute the value of METHODS to pass to recursive calls.
1674 Don't allow widening to be tried recursively. */
1676 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1678 /* Look for a wider mode of the same class for which it appears we can do
1679 the operation. */
1681 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1683 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1684 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1686 if ((binoptab->handlers[(int) wider_mode].insn_code
1687 != CODE_FOR_nothing)
1688 || (methods == OPTAB_LIB
1689 && binoptab->handlers[(int) wider_mode].libfunc))
1691 rtx xop0 = op0, xop1 = op1;
1692 int no_extend = 0;
1694 /* For certain integer operations, we need not actually extend
1695 the narrow operands, as long as we will truncate
1696 the results to the same narrowness. */
1698 if ((binoptab == ior_optab || binoptab == and_optab
1699 || binoptab == xor_optab
1700 || binoptab == add_optab || binoptab == sub_optab
1701 || binoptab == smul_optab || binoptab == ashl_optab)
1702 && class == MODE_INT)
1703 no_extend = 1;
1705 xop0 = widen_operand (xop0, wider_mode, mode,
1706 unsignedp, no_extend);
1708 /* The second operand of a shift must always be extended. */
1709 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1710 no_extend && binoptab != ashl_optab);
1712 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1713 unsignedp, methods);
1714 if (temp)
1716 if (class != MODE_INT)
1718 if (target == 0)
1719 target = gen_reg_rtx (mode);
1720 convert_move (target, temp, 0);
1721 return target;
1723 else
1724 return gen_lowpart (mode, temp);
1726 else
1727 delete_insns_since (last);
1732 delete_insns_since (entry_last);
1733 return 0;
1736 /* Expand a binary operator which has both signed and unsigned forms.
1737 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1738 signed operations.
1740 If we widen unsigned operands, we may use a signed wider operation instead
1741 of an unsigned wider operation, since the result would be the same. */
1744 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
1745 rtx op0, rtx op1, rtx target, int unsignedp,
1746 enum optab_methods methods)
1748 rtx temp;
1749 optab direct_optab = unsignedp ? uoptab : soptab;
1750 struct optab wide_soptab;
1752 /* Do it without widening, if possible. */
1753 temp = expand_binop (mode, direct_optab, op0, op1, target,
1754 unsignedp, OPTAB_DIRECT);
1755 if (temp || methods == OPTAB_DIRECT)
1756 return temp;
1758 /* Try widening to a signed int. Make a fake signed optab that
1759 hides any signed insn for direct use. */
1760 wide_soptab = *soptab;
1761 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1762 wide_soptab.handlers[(int) mode].libfunc = 0;
1764 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1765 unsignedp, OPTAB_WIDEN);
1767 /* For unsigned operands, try widening to an unsigned int. */
1768 if (temp == 0 && unsignedp)
1769 temp = expand_binop (mode, uoptab, op0, op1, target,
1770 unsignedp, OPTAB_WIDEN);
1771 if (temp || methods == OPTAB_WIDEN)
1772 return temp;
1774 /* Use the right width lib call if that exists. */
1775 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1776 if (temp || methods == OPTAB_LIB)
1777 return temp;
1779 /* Must widen and use a lib call, use either signed or unsigned. */
1780 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1781 unsignedp, methods);
1782 if (temp != 0)
1783 return temp;
1784 if (unsignedp)
1785 return expand_binop (mode, uoptab, op0, op1, target,
1786 unsignedp, methods);
1787 return 0;
1790 /* Generate code to perform an operation specified by UNOPPTAB
1791 on operand OP0, with two results to TARG0 and TARG1.
1792 We assume that the order of the operands for the instruction
1793 is TARG0, TARG1, OP0.
1795 Either TARG0 or TARG1 may be zero, but what that means is that
1796 the result is not actually wanted. We will generate it into
1797 a dummy pseudo-reg and discard it. They may not both be zero.
1799 Returns 1 if this operation can be performed; 0 if not. */
1802 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
1803 int unsignedp)
1805 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1806 enum mode_class class;
1807 enum machine_mode wider_mode;
1808 rtx entry_last = get_last_insn ();
1809 rtx last;
1811 class = GET_MODE_CLASS (mode);
1813 if (flag_force_mem)
1814 op0 = force_not_mem (op0);
1816 if (!targ0)
1817 targ0 = gen_reg_rtx (mode);
1818 if (!targ1)
1819 targ1 = gen_reg_rtx (mode);
1821 /* Record where to go back to if we fail. */
1822 last = get_last_insn ();
1824 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1826 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1827 enum machine_mode mode0 = insn_data[icode].operand[2].mode;
1828 rtx pat;
1829 rtx xop0 = op0;
1831 if (GET_MODE (xop0) != VOIDmode
1832 && GET_MODE (xop0) != mode0)
1833 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1835 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1836 if (!insn_data[icode].operand[2].predicate (xop0, mode0))
1837 xop0 = copy_to_mode_reg (mode0, xop0);
1839 /* We could handle this, but we should always be called with a pseudo
1840 for our targets and all insns should take them as outputs. */
1841 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
1842 gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
1844 pat = GEN_FCN (icode) (targ0, targ1, xop0);
1845 if (pat)
1847 emit_insn (pat);
1848 return 1;
1850 else
1851 delete_insns_since (last);
1854 /* It can't be done in this mode. Can we do it in a wider mode? */
1856 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1858 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1859 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1861 if (unoptab->handlers[(int) wider_mode].insn_code
1862 != CODE_FOR_nothing)
1864 rtx t0 = gen_reg_rtx (wider_mode);
1865 rtx t1 = gen_reg_rtx (wider_mode);
1866 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1868 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
1870 convert_move (targ0, t0, unsignedp);
1871 convert_move (targ1, t1, unsignedp);
1872 return 1;
1874 else
1875 delete_insns_since (last);
1880 delete_insns_since (entry_last);
1881 return 0;
1884 /* Generate code to perform an operation specified by BINOPTAB
1885 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1886 We assume that the order of the operands for the instruction
1887 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1888 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1890 Either TARG0 or TARG1 may be zero, but what that means is that
1891 the result is not actually wanted. We will generate it into
1892 a dummy pseudo-reg and discard it. They may not both be zero.
1894 Returns 1 if this operation can be performed; 0 if not. */
1897 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
1898 int unsignedp)
1900 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1901 enum mode_class class;
1902 enum machine_mode wider_mode;
1903 rtx entry_last = get_last_insn ();
1904 rtx last;
1906 class = GET_MODE_CLASS (mode);
1908 if (flag_force_mem)
1910 op0 = force_not_mem (op0);
1911 op1 = force_not_mem (op1);
1914 /* If we are inside an appropriately-short loop and we are optimizing,
1915 force expensive constants into a register. */
1916 if (CONSTANT_P (op0) && optimize
1917 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1918 op0 = force_reg (mode, op0);
1920 if (CONSTANT_P (op1) && optimize
1921 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1922 op1 = force_reg (mode, op1);
1924 if (!targ0)
1925 targ0 = gen_reg_rtx (mode);
1926 if (!targ1)
1927 targ1 = gen_reg_rtx (mode);
1929 /* Record where to go back to if we fail. */
1930 last = get_last_insn ();
1932 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1934 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1935 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1936 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1937 rtx pat;
1938 rtx xop0 = op0, xop1 = op1;
1940 /* In case the insn wants input operands in modes different from
1941 those of the actual operands, convert the operands. It would
1942 seem that we don't need to convert CONST_INTs, but we do, so
1943 that they're properly zero-extended, sign-extended or truncated
1944 for their mode. */
1946 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
1947 xop0 = convert_modes (mode0,
1948 GET_MODE (op0) != VOIDmode
1949 ? GET_MODE (op0)
1950 : mode,
1951 xop0, unsignedp);
1953 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
1954 xop1 = convert_modes (mode1,
1955 GET_MODE (op1) != VOIDmode
1956 ? GET_MODE (op1)
1957 : mode,
1958 xop1, unsignedp);
1960 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1961 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
1962 xop0 = copy_to_mode_reg (mode0, xop0);
1964 if (!insn_data[icode].operand[2].predicate (xop1, mode1))
1965 xop1 = copy_to_mode_reg (mode1, xop1);
1967 /* We could handle this, but we should always be called with a pseudo
1968 for our targets and all insns should take them as outputs. */
1969 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
1970 gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
1972 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1973 if (pat)
1975 emit_insn (pat);
1976 return 1;
1978 else
1979 delete_insns_since (last);
1982 /* It can't be done in this mode. Can we do it in a wider mode? */
1984 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1986 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1987 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1989 if (binoptab->handlers[(int) wider_mode].insn_code
1990 != CODE_FOR_nothing)
1992 rtx t0 = gen_reg_rtx (wider_mode);
1993 rtx t1 = gen_reg_rtx (wider_mode);
1994 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1995 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
1997 if (expand_twoval_binop (binoptab, cop0, cop1,
1998 t0, t1, unsignedp))
2000 convert_move (targ0, t0, unsignedp);
2001 convert_move (targ1, t1, unsignedp);
2002 return 1;
2004 else
2005 delete_insns_since (last);
2010 delete_insns_since (entry_last);
2011 return 0;
2014 /* Expand the two-valued library call indicated by BINOPTAB, but
2015 preserve only one of the values. If TARG0 is non-NULL, the first
2016 value is placed into TARG0; otherwise the second value is placed
2017 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2018 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2019 This routine assumes that the value returned by the library call is
2020 as if the return value was of an integral mode twice as wide as the
2021 mode of OP0. Returns 1 if the call was successful. */
2023 bool
2024 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2025 rtx targ0, rtx targ1, enum rtx_code code)
2027 enum machine_mode mode;
2028 enum machine_mode libval_mode;
2029 rtx libval;
2030 rtx insns;
2032 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2033 gcc_assert (!targ0 != !targ1);
2035 mode = GET_MODE (op0);
2036 if (!binoptab->handlers[(int) mode].libfunc)
2037 return false;
2039 /* The value returned by the library function will have twice as
2040 many bits as the nominal MODE. */
2041 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2042 MODE_INT);
2043 start_sequence ();
2044 libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
2045 NULL_RTX, LCT_CONST,
2046 libval_mode, 2,
2047 op0, mode,
2048 op1, mode);
2049 /* Get the part of VAL containing the value that we want. */
2050 libval = simplify_gen_subreg (mode, libval, libval_mode,
2051 targ0 ? 0 : GET_MODE_SIZE (mode));
2052 insns = get_insns ();
2053 end_sequence ();
2054 /* Move the into the desired location. */
2055 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2056 gen_rtx_fmt_ee (code, mode, op0, op1));
2058 return true;
2062 /* Wrapper around expand_unop which takes an rtx code to specify
2063 the operation to perform, not an optab pointer. All other
2064 arguments are the same. */
2066 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2067 rtx target, int unsignedp)
2069 optab unop = code_to_optab[(int) code];
2070 gcc_assert (unop);
2072 return expand_unop (mode, unop, op0, target, unsignedp);
2075 /* Try calculating
2076 (clz:narrow x)
2078 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2079 static rtx
2080 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2082 enum mode_class class = GET_MODE_CLASS (mode);
2083 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2085 enum machine_mode wider_mode;
2086 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2087 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2089 if (clz_optab->handlers[(int) wider_mode].insn_code
2090 != CODE_FOR_nothing)
2092 rtx xop0, temp, last;
2094 last = get_last_insn ();
2096 if (target == 0)
2097 target = gen_reg_rtx (mode);
2098 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2099 temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2100 if (temp != 0)
2101 temp = expand_binop (wider_mode, sub_optab, temp,
2102 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2103 - GET_MODE_BITSIZE (mode)),
2104 target, true, OPTAB_DIRECT);
2105 if (temp == 0)
2106 delete_insns_since (last);
2108 return temp;
2112 return 0;
2115 /* Try calculating (parity x) as (and (popcount x) 1), where
2116 popcount can also be done in a wider mode. */
2117 static rtx
2118 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2120 enum mode_class class = GET_MODE_CLASS (mode);
2121 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2123 enum machine_mode wider_mode;
2124 for (wider_mode = mode; wider_mode != VOIDmode;
2125 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2127 if (popcount_optab->handlers[(int) wider_mode].insn_code
2128 != CODE_FOR_nothing)
2130 rtx xop0, temp, last;
2132 last = get_last_insn ();
2134 if (target == 0)
2135 target = gen_reg_rtx (mode);
2136 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2137 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2138 true);
2139 if (temp != 0)
2140 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2141 target, true, OPTAB_DIRECT);
2142 if (temp == 0)
2143 delete_insns_since (last);
2145 return temp;
2149 return 0;
2152 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2153 conditions, VAL may already be a SUBREG against which we cannot generate
2154 a further SUBREG. In this case, we expect forcing the value into a
2155 register will work around the situation. */
2157 static rtx
2158 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2159 enum machine_mode imode)
2161 rtx ret;
2162 ret = lowpart_subreg (omode, val, imode);
2163 if (ret == NULL)
2165 val = force_reg (imode, val);
2166 ret = lowpart_subreg (omode, val, imode);
2167 gcc_assert (ret != NULL);
2169 return ret;
2172 /* Expand a floating point absolute value or negation operation via a
2173 logical operation on the sign bit. */
2175 static rtx
2176 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2177 rtx op0, rtx target)
2179 const struct real_format *fmt;
2180 int bitpos, word, nwords, i;
2181 enum machine_mode imode;
2182 HOST_WIDE_INT hi, lo;
2183 rtx temp, insns;
2185 /* The format has to have a simple sign bit. */
2186 fmt = REAL_MODE_FORMAT (mode);
2187 if (fmt == NULL)
2188 return NULL_RTX;
2190 bitpos = fmt->signbit_rw;
2191 if (bitpos < 0)
2192 return NULL_RTX;
2194 /* Don't create negative zeros if the format doesn't support them. */
2195 if (code == NEG && !fmt->has_signed_zero)
2196 return NULL_RTX;
2198 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2200 imode = int_mode_for_mode (mode);
2201 if (imode == BLKmode)
2202 return NULL_RTX;
2203 word = 0;
2204 nwords = 1;
2206 else
2208 imode = word_mode;
2210 if (FLOAT_WORDS_BIG_ENDIAN)
2211 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2212 else
2213 word = bitpos / BITS_PER_WORD;
2214 bitpos = bitpos % BITS_PER_WORD;
2215 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2218 if (bitpos < HOST_BITS_PER_WIDE_INT)
2220 hi = 0;
2221 lo = (HOST_WIDE_INT) 1 << bitpos;
2223 else
2225 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2226 lo = 0;
2228 if (code == ABS)
2229 lo = ~lo, hi = ~hi;
2231 if (target == 0 || target == op0)
2232 target = gen_reg_rtx (mode);
2234 if (nwords > 1)
2236 start_sequence ();
2238 for (i = 0; i < nwords; ++i)
2240 rtx targ_piece = operand_subword (target, i, 1, mode);
2241 rtx op0_piece = operand_subword_force (op0, i, mode);
2243 if (i == word)
2245 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2246 op0_piece,
2247 immed_double_const (lo, hi, imode),
2248 targ_piece, 1, OPTAB_LIB_WIDEN);
2249 if (temp != targ_piece)
2250 emit_move_insn (targ_piece, temp);
2252 else
2253 emit_move_insn (targ_piece, op0_piece);
2256 insns = get_insns ();
2257 end_sequence ();
2259 temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2260 emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2262 else
2264 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2265 gen_lowpart (imode, op0),
2266 immed_double_const (lo, hi, imode),
2267 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2268 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2270 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2271 gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2274 return target;
2277 /* Generate code to perform an operation specified by UNOPTAB
2278 on operand OP0, with result having machine-mode MODE.
2280 UNSIGNEDP is for the case where we have to widen the operands
2281 to perform the operation. It says to use zero-extension.
2283 If TARGET is nonzero, the value
2284 is generated there, if it is convenient to do so.
2285 In all cases an rtx is returned for the locus of the value;
2286 this may or may not be TARGET. */
2289 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2290 int unsignedp)
2292 enum mode_class class;
2293 enum machine_mode wider_mode;
2294 rtx temp;
2295 rtx last = get_last_insn ();
2296 rtx pat;
2298 class = GET_MODE_CLASS (mode);
2300 if (flag_force_mem)
2301 op0 = force_not_mem (op0);
2303 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2305 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2306 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2307 rtx xop0 = op0;
2309 if (target)
2310 temp = target;
2311 else
2312 temp = gen_reg_rtx (mode);
2314 if (GET_MODE (xop0) != VOIDmode
2315 && GET_MODE (xop0) != mode0)
2316 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2318 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2320 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2321 xop0 = copy_to_mode_reg (mode0, xop0);
2323 if (!insn_data[icode].operand[0].predicate (temp, mode))
2324 temp = gen_reg_rtx (mode);
2326 pat = GEN_FCN (icode) (temp, xop0);
2327 if (pat)
2329 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2330 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2332 delete_insns_since (last);
2333 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2336 emit_insn (pat);
2338 return temp;
2340 else
2341 delete_insns_since (last);
2344 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2346 /* Widening clz needs special treatment. */
2347 if (unoptab == clz_optab)
2349 temp = widen_clz (mode, op0, target);
2350 if (temp)
2351 return temp;
2352 else
2353 goto try_libcall;
2356 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2357 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2358 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2360 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2362 rtx xop0 = op0;
2364 /* For certain operations, we need not actually extend
2365 the narrow operand, as long as we will truncate the
2366 results to the same narrowness. */
2368 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2369 (unoptab == neg_optab
2370 || unoptab == one_cmpl_optab)
2371 && class == MODE_INT);
2373 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2374 unsignedp);
2376 if (temp)
2378 if (class != MODE_INT)
2380 if (target == 0)
2381 target = gen_reg_rtx (mode);
2382 convert_move (target, temp, 0);
2383 return target;
2385 else
2386 return gen_lowpart (mode, temp);
2388 else
2389 delete_insns_since (last);
2393 /* These can be done a word at a time. */
2394 if (unoptab == one_cmpl_optab
2395 && class == MODE_INT
2396 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2397 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2399 int i;
2400 rtx insns;
2402 if (target == 0 || target == op0)
2403 target = gen_reg_rtx (mode);
2405 start_sequence ();
2407 /* Do the actual arithmetic. */
2408 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2410 rtx target_piece = operand_subword (target, i, 1, mode);
2411 rtx x = expand_unop (word_mode, unoptab,
2412 operand_subword_force (op0, i, mode),
2413 target_piece, unsignedp);
2415 if (target_piece != x)
2416 emit_move_insn (target_piece, x);
2419 insns = get_insns ();
2420 end_sequence ();
2422 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2423 gen_rtx_fmt_e (unoptab->code, mode,
2424 copy_rtx (op0)));
2425 return target;
2428 if (unoptab->code == NEG)
2430 /* Try negating floating point values by flipping the sign bit. */
2431 if (class == MODE_FLOAT)
2433 temp = expand_absneg_bit (NEG, mode, op0, target);
2434 if (temp)
2435 return temp;
2438 /* If there is no negation pattern, and we have no negative zero,
2439 try subtracting from zero. */
2440 if (!HONOR_SIGNED_ZEROS (mode))
2442 temp = expand_binop (mode, (unoptab == negv_optab
2443 ? subv_optab : sub_optab),
2444 CONST0_RTX (mode), op0, target,
2445 unsignedp, OPTAB_DIRECT);
2446 if (temp)
2447 return temp;
2451 /* Try calculating parity (x) as popcount (x) % 2. */
2452 if (unoptab == parity_optab)
2454 temp = expand_parity (mode, op0, target);
2455 if (temp)
2456 return temp;
2459 try_libcall:
2460 /* Now try a library call in this mode. */
2461 if (unoptab->handlers[(int) mode].libfunc)
2463 rtx insns;
2464 rtx value;
2465 enum machine_mode outmode = mode;
2467 /* All of these functions return small values. Thus we choose to
2468 have them return something that isn't a double-word. */
2469 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2470 || unoptab == popcount_optab || unoptab == parity_optab)
2471 outmode
2472 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2474 start_sequence ();
2476 /* Pass 1 for NO_QUEUE so we don't lose any increments
2477 if the libcall is cse'd or moved. */
2478 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2479 NULL_RTX, LCT_CONST, outmode,
2480 1, op0, mode);
2481 insns = get_insns ();
2482 end_sequence ();
2484 target = gen_reg_rtx (outmode);
2485 emit_libcall_block (insns, target, value,
2486 gen_rtx_fmt_e (unoptab->code, mode, op0));
2488 return target;
2491 /* It can't be done in this mode. Can we do it in a wider mode? */
2493 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2495 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2496 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2498 if ((unoptab->handlers[(int) wider_mode].insn_code
2499 != CODE_FOR_nothing)
2500 || unoptab->handlers[(int) wider_mode].libfunc)
2502 rtx xop0 = op0;
2504 /* For certain operations, we need not actually extend
2505 the narrow operand, as long as we will truncate the
2506 results to the same narrowness. */
2508 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2509 (unoptab == neg_optab
2510 || unoptab == one_cmpl_optab)
2511 && class == MODE_INT);
2513 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2514 unsignedp);
2516 /* If we are generating clz using wider mode, adjust the
2517 result. */
2518 if (unoptab == clz_optab && temp != 0)
2519 temp = expand_binop (wider_mode, sub_optab, temp,
2520 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2521 - GET_MODE_BITSIZE (mode)),
2522 target, true, OPTAB_DIRECT);
2524 if (temp)
2526 if (class != MODE_INT)
2528 if (target == 0)
2529 target = gen_reg_rtx (mode);
2530 convert_move (target, temp, 0);
2531 return target;
2533 else
2534 return gen_lowpart (mode, temp);
2536 else
2537 delete_insns_since (last);
2542 /* One final attempt at implementing negation via subtraction,
2543 this time allowing widening of the operand. */
2544 if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
2546 rtx temp;
2547 temp = expand_binop (mode,
2548 unoptab == negv_optab ? subv_optab : sub_optab,
2549 CONST0_RTX (mode), op0,
2550 target, unsignedp, OPTAB_LIB_WIDEN);
2551 if (temp)
2552 return temp;
2555 return 0;
2558 /* Emit code to compute the absolute value of OP0, with result to
2559 TARGET if convenient. (TARGET may be 0.) The return value says
2560 where the result actually is to be found.
2562 MODE is the mode of the operand; the mode of the result is
2563 different but can be deduced from MODE.
2568 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2569 int result_unsignedp)
2571 rtx temp;
2573 if (! flag_trapv)
2574 result_unsignedp = 1;
2576 /* First try to do it with a special abs instruction. */
2577 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2578 op0, target, 0);
2579 if (temp != 0)
2580 return temp;
2582 /* For floating point modes, try clearing the sign bit. */
2583 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2585 temp = expand_absneg_bit (ABS, mode, op0, target);
2586 if (temp)
2587 return temp;
2590 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2591 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
2592 && !HONOR_SIGNED_ZEROS (mode))
2594 rtx last = get_last_insn ();
2596 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2597 if (temp != 0)
2598 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2599 OPTAB_WIDEN);
2601 if (temp != 0)
2602 return temp;
2604 delete_insns_since (last);
2607 /* If this machine has expensive jumps, we can do integer absolute
2608 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2609 where W is the width of MODE. */
2611 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2613 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2614 size_int (GET_MODE_BITSIZE (mode) - 1),
2615 NULL_RTX, 0);
2617 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2618 OPTAB_LIB_WIDEN);
2619 if (temp != 0)
2620 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2621 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2623 if (temp != 0)
2624 return temp;
2627 return NULL_RTX;
2631 expand_abs (enum machine_mode mode, rtx op0, rtx target,
2632 int result_unsignedp, int safe)
2634 rtx temp, op1;
2636 if (! flag_trapv)
2637 result_unsignedp = 1;
2639 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2640 if (temp != 0)
2641 return temp;
2643 /* If that does not win, use conditional jump and negate. */
2645 /* It is safe to use the target if it is the same
2646 as the source if this is also a pseudo register */
2647 if (op0 == target && REG_P (op0)
2648 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2649 safe = 1;
2651 op1 = gen_label_rtx ();
2652 if (target == 0 || ! safe
2653 || GET_MODE (target) != mode
2654 || (MEM_P (target) && MEM_VOLATILE_P (target))
2655 || (REG_P (target)
2656 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2657 target = gen_reg_rtx (mode);
2659 emit_move_insn (target, op0);
2660 NO_DEFER_POP;
2662 /* If this mode is an integer too wide to compare properly,
2663 compare word by word. Rely on CSE to optimize constant cases. */
2664 if (GET_MODE_CLASS (mode) == MODE_INT
2665 && ! can_compare_p (GE, mode, ccp_jump))
2666 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2667 NULL_RTX, op1);
2668 else
2669 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2670 NULL_RTX, NULL_RTX, op1);
2672 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2673 target, target, 0);
2674 if (op0 != target)
2675 emit_move_insn (target, op0);
2676 emit_label (op1);
2677 OK_DEFER_POP;
2678 return target;
2681 /* A subroutine of expand_copysign, perform the copysign operation using the
2682 abs and neg primitives advertised to exist on the target. The assumption
2683 is that we have a split register file, and leaving op0 in fp registers,
2684 and not playing with subregs so much, will help the register allocator. */
2686 static rtx
2687 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2688 int bitpos, bool op0_is_abs)
2690 enum machine_mode imode;
2691 HOST_WIDE_INT hi, lo;
2692 int word;
2693 rtx label;
2695 if (target == op1)
2696 target = NULL_RTX;
2698 if (!op0_is_abs)
2700 op0 = expand_unop (mode, abs_optab, op0, target, 0);
2701 if (op0 == NULL)
2702 return NULL_RTX;
2703 target = op0;
2705 else
2707 if (target == NULL_RTX)
2708 target = copy_to_reg (op0);
2709 else
2710 emit_move_insn (target, op0);
2713 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2715 imode = int_mode_for_mode (mode);
2716 if (imode == BLKmode)
2717 return NULL_RTX;
2718 op1 = gen_lowpart (imode, op1);
2720 else
2722 imode = word_mode;
2723 if (FLOAT_WORDS_BIG_ENDIAN)
2724 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2725 else
2726 word = bitpos / BITS_PER_WORD;
2727 bitpos = bitpos % BITS_PER_WORD;
2728 op1 = operand_subword_force (op1, word, mode);
2731 if (bitpos < HOST_BITS_PER_WIDE_INT)
2733 hi = 0;
2734 lo = (HOST_WIDE_INT) 1 << bitpos;
2736 else
2738 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2739 lo = 0;
2742 op1 = expand_binop (imode, and_optab, op1,
2743 immed_double_const (lo, hi, imode),
2744 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2746 label = gen_label_rtx ();
2747 emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label);
2749 if (GET_CODE (op0) == CONST_DOUBLE)
2750 op0 = simplify_unary_operation (NEG, mode, op0, mode);
2751 else
2752 op0 = expand_unop (mode, neg_optab, op0, target, 0);
2753 if (op0 != target)
2754 emit_move_insn (target, op0);
2756 emit_label (label);
2758 return target;
2762 /* A subroutine of expand_copysign, perform the entire copysign operation
2763 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
2764 is true if op0 is known to have its sign bit clear. */
2766 static rtx
2767 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2768 int bitpos, bool op0_is_abs)
2770 enum machine_mode imode;
2771 HOST_WIDE_INT hi, lo;
2772 int word, nwords, i;
2773 rtx temp, insns;
2775 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2777 imode = int_mode_for_mode (mode);
2778 if (imode == BLKmode)
2779 return NULL_RTX;
2780 word = 0;
2781 nwords = 1;
2783 else
2785 imode = word_mode;
2787 if (FLOAT_WORDS_BIG_ENDIAN)
2788 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2789 else
2790 word = bitpos / BITS_PER_WORD;
2791 bitpos = bitpos % BITS_PER_WORD;
2792 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2795 if (bitpos < HOST_BITS_PER_WIDE_INT)
2797 hi = 0;
2798 lo = (HOST_WIDE_INT) 1 << bitpos;
2800 else
2802 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2803 lo = 0;
2806 if (target == 0 || target == op0 || target == op1)
2807 target = gen_reg_rtx (mode);
2809 if (nwords > 1)
2811 start_sequence ();
2813 for (i = 0; i < nwords; ++i)
2815 rtx targ_piece = operand_subword (target, i, 1, mode);
2816 rtx op0_piece = operand_subword_force (op0, i, mode);
2818 if (i == word)
2820 if (!op0_is_abs)
2821 op0_piece = expand_binop (imode, and_optab, op0_piece,
2822 immed_double_const (~lo, ~hi, imode),
2823 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2825 op1 = expand_binop (imode, and_optab,
2826 operand_subword_force (op1, i, mode),
2827 immed_double_const (lo, hi, imode),
2828 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2830 temp = expand_binop (imode, ior_optab, op0_piece, op1,
2831 targ_piece, 1, OPTAB_LIB_WIDEN);
2832 if (temp != targ_piece)
2833 emit_move_insn (targ_piece, temp);
2835 else
2836 emit_move_insn (targ_piece, op0_piece);
2839 insns = get_insns ();
2840 end_sequence ();
2842 emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
2844 else
2846 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
2847 immed_double_const (lo, hi, imode),
2848 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2850 op0 = gen_lowpart (imode, op0);
2851 if (!op0_is_abs)
2852 op0 = expand_binop (imode, and_optab, op0,
2853 immed_double_const (~lo, ~hi, imode),
2854 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2856 temp = expand_binop (imode, ior_optab, op0, op1,
2857 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2858 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2861 return target;
2864 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
2865 scalar floating point mode. Return NULL if we do not know how to
2866 expand the operation inline. */
2869 expand_copysign (rtx op0, rtx op1, rtx target)
2871 enum machine_mode mode = GET_MODE (op0);
2872 const struct real_format *fmt;
2873 bool op0_is_abs;
2874 rtx temp;
2876 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
2877 gcc_assert (GET_MODE (op1) == mode);
2879 /* First try to do it with a special instruction. */
2880 temp = expand_binop (mode, copysign_optab, op0, op1,
2881 target, 0, OPTAB_DIRECT);
2882 if (temp)
2883 return temp;
2885 fmt = REAL_MODE_FORMAT (mode);
2886 if (fmt == NULL || !fmt->has_signed_zero)
2887 return NULL_RTX;
2889 op0_is_abs = false;
2890 if (GET_CODE (op0) == CONST_DOUBLE)
2892 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
2893 op0 = simplify_unary_operation (ABS, mode, op0, mode);
2894 op0_is_abs = true;
2897 if (fmt->signbit_ro >= 0
2898 && (GET_CODE (op0) == CONST_DOUBLE
2899 || (neg_optab->handlers[mode].insn_code != CODE_FOR_nothing
2900 && abs_optab->handlers[mode].insn_code != CODE_FOR_nothing)))
2902 temp = expand_copysign_absneg (mode, op0, op1, target,
2903 fmt->signbit_ro, op0_is_abs);
2904 if (temp)
2905 return temp;
2908 if (fmt->signbit_rw < 0)
2909 return NULL_RTX;
2910 return expand_copysign_bit (mode, op0, op1, target,
2911 fmt->signbit_rw, op0_is_abs);
2914 /* Generate an instruction whose insn-code is INSN_CODE,
2915 with two operands: an output TARGET and an input OP0.
2916 TARGET *must* be nonzero, and the output is always stored there.
2917 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2918 the value that is stored into TARGET. */
2920 void
2921 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
2923 rtx temp;
2924 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2925 rtx pat;
2927 temp = target;
2929 /* Sign and zero extension from memory is often done specially on
2930 RISC machines, so forcing into a register here can pessimize
2931 code. */
2932 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2933 op0 = force_not_mem (op0);
2935 /* Now, if insn does not accept our operands, put them into pseudos. */
2937 if (!insn_data[icode].operand[1].predicate (op0, mode0))
2938 op0 = copy_to_mode_reg (mode0, op0);
2940 if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp))
2941 || (flag_force_mem && MEM_P (temp)))
2942 temp = gen_reg_rtx (GET_MODE (temp));
2944 pat = GEN_FCN (icode) (temp, op0);
2946 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
2947 add_equal_note (pat, temp, code, op0, NULL_RTX);
2949 emit_insn (pat);
2951 if (temp != target)
2952 emit_move_insn (target, temp);
2955 struct no_conflict_data
2957 rtx target, first, insn;
2958 bool must_stay;
2961 /* Called via note_stores by emit_no_conflict_block. Set P->must_stay
2962 if the currently examined clobber / store has to stay in the list of
2963 insns that constitute the actual no_conflict block. */
2964 static void
2965 no_conflict_move_test (rtx dest, rtx set, void *p0)
2967 struct no_conflict_data *p= p0;
2969 /* If this inns directly contributes to setting the target, it must stay. */
2970 if (reg_overlap_mentioned_p (p->target, dest))
2971 p->must_stay = true;
2972 /* If we haven't committed to keeping any other insns in the list yet,
2973 there is nothing more to check. */
2974 else if (p->insn == p->first)
2975 return;
2976 /* If this insn sets / clobbers a register that feeds one of the insns
2977 already in the list, this insn has to stay too. */
2978 else if (reg_mentioned_p (dest, PATTERN (p->first))
2979 || reg_used_between_p (dest, p->first, p->insn)
2980 /* Likewise if this insn depends on a register set by a previous
2981 insn in the list. */
2982 || (GET_CODE (set) == SET
2983 && (modified_in_p (SET_SRC (set), p->first)
2984 || modified_between_p (SET_SRC (set), p->first, p->insn))))
2985 p->must_stay = true;
2988 /* Emit code to perform a series of operations on a multi-word quantity, one
2989 word at a time.
2991 Such a block is preceded by a CLOBBER of the output, consists of multiple
2992 insns, each setting one word of the output, and followed by a SET copying
2993 the output to itself.
2995 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2996 note indicating that it doesn't conflict with the (also multi-word)
2997 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2998 notes.
3000 INSNS is a block of code generated to perform the operation, not including
3001 the CLOBBER and final copy. All insns that compute intermediate values
3002 are first emitted, followed by the block as described above.
3004 TARGET, OP0, and OP1 are the output and inputs of the operations,
3005 respectively. OP1 may be zero for a unary operation.
3007 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3008 on the last insn.
3010 If TARGET is not a register, INSNS is simply emitted with no special
3011 processing. Likewise if anything in INSNS is not an INSN or if
3012 there is a libcall block inside INSNS.
3014 The final insn emitted is returned. */
3017 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3019 rtx prev, next, first, last, insn;
3021 if (!REG_P (target) || reload_in_progress)
3022 return emit_insn (insns);
3023 else
3024 for (insn = insns; insn; insn = NEXT_INSN (insn))
3025 if (!NONJUMP_INSN_P (insn)
3026 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3027 return emit_insn (insns);
3029 /* First emit all insns that do not store into words of the output and remove
3030 these from the list. */
3031 for (insn = insns; insn; insn = next)
3033 rtx note;
3034 struct no_conflict_data data;
3036 next = NEXT_INSN (insn);
3038 /* Some ports (cris) create a libcall regions at their own. We must
3039 avoid any potential nesting of LIBCALLs. */
3040 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3041 remove_note (insn, note);
3042 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3043 remove_note (insn, note);
3045 data.target = target;
3046 data.first = insns;
3047 data.insn = insn;
3048 data.must_stay = 0;
3049 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3050 if (! data.must_stay)
3052 if (PREV_INSN (insn))
3053 NEXT_INSN (PREV_INSN (insn)) = next;
3054 else
3055 insns = next;
3057 if (next)
3058 PREV_INSN (next) = PREV_INSN (insn);
3060 add_insn (insn);
3064 prev = get_last_insn ();
3066 /* Now write the CLOBBER of the output, followed by the setting of each
3067 of the words, followed by the final copy. */
3068 if (target != op0 && target != op1)
3069 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3071 for (insn = insns; insn; insn = next)
3073 next = NEXT_INSN (insn);
3074 add_insn (insn);
3076 if (op1 && REG_P (op1))
3077 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3078 REG_NOTES (insn));
3080 if (op0 && REG_P (op0))
3081 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3082 REG_NOTES (insn));
3085 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3086 != CODE_FOR_nothing)
3088 last = emit_move_insn (target, target);
3089 if (equiv)
3090 set_unique_reg_note (last, REG_EQUAL, equiv);
3092 else
3094 last = get_last_insn ();
3096 /* Remove any existing REG_EQUAL note from "last", or else it will
3097 be mistaken for a note referring to the full contents of the
3098 alleged libcall value when found together with the REG_RETVAL
3099 note added below. An existing note can come from an insn
3100 expansion at "last". */
3101 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3104 if (prev == 0)
3105 first = get_insns ();
3106 else
3107 first = NEXT_INSN (prev);
3109 /* Encapsulate the block so it gets manipulated as a unit. */
3110 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3111 REG_NOTES (first));
3112 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
3114 return last;
3117 /* Emit code to make a call to a constant function or a library call.
3119 INSNS is a list containing all insns emitted in the call.
3120 These insns leave the result in RESULT. Our block is to copy RESULT
3121 to TARGET, which is logically equivalent to EQUIV.
3123 We first emit any insns that set a pseudo on the assumption that these are
3124 loading constants into registers; doing so allows them to be safely cse'ed
3125 between blocks. Then we emit all the other insns in the block, followed by
3126 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3127 note with an operand of EQUIV.
3129 Moving assignments to pseudos outside of the block is done to improve
3130 the generated code, but is not required to generate correct code,
3131 hence being unable to move an assignment is not grounds for not making
3132 a libcall block. There are two reasons why it is safe to leave these
3133 insns inside the block: First, we know that these pseudos cannot be
3134 used in generated RTL outside the block since they are created for
3135 temporary purposes within the block. Second, CSE will not record the
3136 values of anything set inside a libcall block, so we know they must
3137 be dead at the end of the block.
3139 Except for the first group of insns (the ones setting pseudos), the
3140 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3142 void
3143 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3145 rtx final_dest = target;
3146 rtx prev, next, first, last, insn;
3148 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3149 into a MEM later. Protect the libcall block from this change. */
3150 if (! REG_P (target) || REG_USERVAR_P (target))
3151 target = gen_reg_rtx (GET_MODE (target));
3153 /* If we're using non-call exceptions, a libcall corresponding to an
3154 operation that may trap may also trap. */
3155 if (flag_non_call_exceptions && may_trap_p (equiv))
3157 for (insn = insns; insn; insn = NEXT_INSN (insn))
3158 if (CALL_P (insn))
3160 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3162 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3163 remove_note (insn, note);
3166 else
3167 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3168 reg note to indicate that this call cannot throw or execute a nonlocal
3169 goto (unless there is already a REG_EH_REGION note, in which case
3170 we update it). */
3171 for (insn = insns; insn; insn = NEXT_INSN (insn))
3172 if (CALL_P (insn))
3174 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3176 if (note != 0)
3177 XEXP (note, 0) = constm1_rtx;
3178 else
3179 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3180 REG_NOTES (insn));
3183 /* First emit all insns that set pseudos. Remove them from the list as
3184 we go. Avoid insns that set pseudos which were referenced in previous
3185 insns. These can be generated by move_by_pieces, for example,
3186 to update an address. Similarly, avoid insns that reference things
3187 set in previous insns. */
3189 for (insn = insns; insn; insn = next)
3191 rtx set = single_set (insn);
3192 rtx note;
3194 /* Some ports (cris) create a libcall regions at their own. We must
3195 avoid any potential nesting of LIBCALLs. */
3196 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3197 remove_note (insn, note);
3198 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3199 remove_note (insn, note);
3201 next = NEXT_INSN (insn);
3203 if (set != 0 && REG_P (SET_DEST (set))
3204 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
3205 && (insn == insns
3206 || ((! INSN_P(insns)
3207 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
3208 && ! reg_used_between_p (SET_DEST (set), insns, insn)
3209 && ! modified_in_p (SET_SRC (set), insns)
3210 && ! modified_between_p (SET_SRC (set), insns, insn))))
3212 if (PREV_INSN (insn))
3213 NEXT_INSN (PREV_INSN (insn)) = next;
3214 else
3215 insns = next;
3217 if (next)
3218 PREV_INSN (next) = PREV_INSN (insn);
3220 add_insn (insn);
3223 /* Some ports use a loop to copy large arguments onto the stack.
3224 Don't move anything outside such a loop. */
3225 if (LABEL_P (insn))
3226 break;
3229 prev = get_last_insn ();
3231 /* Write the remaining insns followed by the final copy. */
3233 for (insn = insns; insn; insn = next)
3235 next = NEXT_INSN (insn);
3237 add_insn (insn);
3240 last = emit_move_insn (target, result);
3241 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3242 != CODE_FOR_nothing)
3243 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3244 else
3246 /* Remove any existing REG_EQUAL note from "last", or else it will
3247 be mistaken for a note referring to the full contents of the
3248 libcall value when found together with the REG_RETVAL note added
3249 below. An existing note can come from an insn expansion at
3250 "last". */
3251 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3254 if (final_dest != target)
3255 emit_move_insn (final_dest, target);
3257 if (prev == 0)
3258 first = get_insns ();
3259 else
3260 first = NEXT_INSN (prev);
3262 /* Encapsulate the block so it gets manipulated as a unit. */
3263 if (!flag_non_call_exceptions || !may_trap_p (equiv))
3265 /* We can't attach the REG_LIBCALL and REG_RETVAL notes
3266 when the encapsulated region would not be in one basic block,
3267 i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
3269 bool attach_libcall_retval_notes = true;
3270 next = NEXT_INSN (last);
3271 for (insn = first; insn != next; insn = NEXT_INSN (insn))
3272 if (control_flow_insn_p (insn))
3274 attach_libcall_retval_notes = false;
3275 break;
3278 if (attach_libcall_retval_notes)
3280 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3281 REG_NOTES (first));
3282 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3283 REG_NOTES (last));
3288 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3289 PURPOSE describes how this comparison will be used. CODE is the rtx
3290 comparison code we will be using.
3292 ??? Actually, CODE is slightly weaker than that. A target is still
3293 required to implement all of the normal bcc operations, but not
3294 required to implement all (or any) of the unordered bcc operations. */
3297 can_compare_p (enum rtx_code code, enum machine_mode mode,
3298 enum can_compare_purpose purpose)
3302 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3304 if (purpose == ccp_jump)
3305 return bcc_gen_fctn[(int) code] != NULL;
3306 else if (purpose == ccp_store_flag)
3307 return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3308 else
3309 /* There's only one cmov entry point, and it's allowed to fail. */
3310 return 1;
3312 if (purpose == ccp_jump
3313 && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3314 return 1;
3315 if (purpose == ccp_cmov
3316 && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3317 return 1;
3318 if (purpose == ccp_store_flag
3319 && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3320 return 1;
3321 mode = GET_MODE_WIDER_MODE (mode);
3323 while (mode != VOIDmode);
3325 return 0;
3328 /* This function is called when we are going to emit a compare instruction that
3329 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3331 *PMODE is the mode of the inputs (in case they are const_int).
3332 *PUNSIGNEDP nonzero says that the operands are unsigned;
3333 this matters if they need to be widened.
3335 If they have mode BLKmode, then SIZE specifies the size of both operands.
3337 This function performs all the setup necessary so that the caller only has
3338 to emit a single comparison insn. This setup can involve doing a BLKmode
3339 comparison or emitting a library call to perform the comparison if no insn
3340 is available to handle it.
3341 The values which are passed in through pointers can be modified; the caller
3342 should perform the comparison on the modified values. Constant
3343 comparisons must have already been folded. */
3345 static void
3346 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3347 enum machine_mode *pmode, int *punsignedp,
3348 enum can_compare_purpose purpose)
3350 enum machine_mode mode = *pmode;
3351 rtx x = *px, y = *py;
3352 int unsignedp = *punsignedp;
3353 enum mode_class class;
3355 class = GET_MODE_CLASS (mode);
3357 if (mode != BLKmode && flag_force_mem)
3359 /* Load duplicate non-volatile operands once. */
3360 if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
3362 x = force_not_mem (x);
3363 y = x;
3365 else
3367 x = force_not_mem (x);
3368 y = force_not_mem (y);
3372 /* If we are inside an appropriately-short loop and we are optimizing,
3373 force expensive constants into a register. */
3374 if (CONSTANT_P (x) && optimize
3375 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3376 x = force_reg (mode, x);
3378 if (CONSTANT_P (y) && optimize
3379 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3380 y = force_reg (mode, y);
3382 #ifdef HAVE_cc0
3383 /* Make sure if we have a canonical comparison. The RTL
3384 documentation states that canonical comparisons are required only
3385 for targets which have cc0. */
3386 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3387 #endif
3389 /* Don't let both operands fail to indicate the mode. */
3390 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3391 x = force_reg (mode, x);
3393 /* Handle all BLKmode compares. */
3395 if (mode == BLKmode)
3397 enum machine_mode cmp_mode, result_mode;
3398 enum insn_code cmp_code;
3399 tree length_type;
3400 rtx libfunc;
3401 rtx result;
3402 rtx opalign
3403 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3405 gcc_assert (size);
3407 /* Try to use a memory block compare insn - either cmpstr
3408 or cmpmem will do. */
3409 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3410 cmp_mode != VOIDmode;
3411 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3413 cmp_code = cmpmem_optab[cmp_mode];
3414 if (cmp_code == CODE_FOR_nothing)
3415 cmp_code = cmpstr_optab[cmp_mode];
3416 if (cmp_code == CODE_FOR_nothing)
3417 continue;
3419 /* Must make sure the size fits the insn's mode. */
3420 if ((GET_CODE (size) == CONST_INT
3421 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3422 || (GET_MODE_BITSIZE (GET_MODE (size))
3423 > GET_MODE_BITSIZE (cmp_mode)))
3424 continue;
3426 result_mode = insn_data[cmp_code].operand[0].mode;
3427 result = gen_reg_rtx (result_mode);
3428 size = convert_to_mode (cmp_mode, size, 1);
3429 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3431 *px = result;
3432 *py = const0_rtx;
3433 *pmode = result_mode;
3434 return;
3437 /* Otherwise call a library function, memcmp. */
3438 libfunc = memcmp_libfunc;
3439 length_type = sizetype;
3440 result_mode = TYPE_MODE (integer_type_node);
3441 cmp_mode = TYPE_MODE (length_type);
3442 size = convert_to_mode (TYPE_MODE (length_type), size,
3443 TYPE_UNSIGNED (length_type));
3445 result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3446 result_mode, 3,
3447 XEXP (x, 0), Pmode,
3448 XEXP (y, 0), Pmode,
3449 size, cmp_mode);
3450 *px = result;
3451 *py = const0_rtx;
3452 *pmode = result_mode;
3453 return;
3456 /* Don't allow operands to the compare to trap, as that can put the
3457 compare and branch in different basic blocks. */
3458 if (flag_non_call_exceptions)
3460 if (may_trap_p (x))
3461 x = force_reg (mode, x);
3462 if (may_trap_p (y))
3463 y = force_reg (mode, y);
3466 *px = x;
3467 *py = y;
3468 if (can_compare_p (*pcomparison, mode, purpose))
3469 return;
3471 /* Handle a lib call just for the mode we are using. */
3473 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3475 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3476 rtx result;
3478 /* If we want unsigned, and this mode has a distinct unsigned
3479 comparison routine, use that. */
3480 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3481 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3483 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3484 word_mode, 2, x, mode, y, mode);
3486 *px = result;
3487 *pmode = word_mode;
3488 if (TARGET_LIB_INT_CMP_BIASED)
3489 /* Integer comparison returns a result that must be compared
3490 against 1, so that even if we do an unsigned compare
3491 afterward, there is still a value that can represent the
3492 result "less than". */
3493 *py = const1_rtx;
3494 else
3496 *py = const0_rtx;
3497 *punsignedp = 1;
3499 return;
3502 gcc_assert (class == MODE_FLOAT);
3503 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3506 /* Before emitting an insn with code ICODE, make sure that X, which is going
3507 to be used for operand OPNUM of the insn, is converted from mode MODE to
3508 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3509 that it is accepted by the operand predicate. Return the new value. */
3511 static rtx
3512 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3513 enum machine_mode wider_mode, int unsignedp)
3515 if (mode != wider_mode)
3516 x = convert_modes (wider_mode, mode, x, unsignedp);
3518 if (!insn_data[icode].operand[opnum].predicate
3519 (x, insn_data[icode].operand[opnum].mode))
3521 if (no_new_pseudos)
3522 return NULL_RTX;
3523 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3526 return x;
3529 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3530 we can do the comparison.
3531 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3532 be NULL_RTX which indicates that only a comparison is to be generated. */
3534 static void
3535 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3536 enum rtx_code comparison, int unsignedp, rtx label)
3538 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3539 enum mode_class class = GET_MODE_CLASS (mode);
3540 enum machine_mode wider_mode = mode;
3542 /* Try combined insns first. */
3545 enum insn_code icode;
3546 PUT_MODE (test, wider_mode);
3548 if (label)
3550 icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3552 if (icode != CODE_FOR_nothing
3553 && insn_data[icode].operand[0].predicate (test, wider_mode))
3555 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3556 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3557 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3558 return;
3562 /* Handle some compares against zero. */
3563 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3564 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3566 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3567 emit_insn (GEN_FCN (icode) (x));
3568 if (label)
3569 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3570 return;
3573 /* Handle compares for which there is a directly suitable insn. */
3575 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3576 if (icode != CODE_FOR_nothing)
3578 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3579 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3580 emit_insn (GEN_FCN (icode) (x, y));
3581 if (label)
3582 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3583 return;
3586 if (class != MODE_INT && class != MODE_FLOAT
3587 && class != MODE_COMPLEX_FLOAT)
3588 break;
3590 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3592 while (wider_mode != VOIDmode);
3594 gcc_unreachable ();
3597 /* Generate code to compare X with Y so that the condition codes are
3598 set and to jump to LABEL if the condition is true. If X is a
3599 constant and Y is not a constant, then the comparison is swapped to
3600 ensure that the comparison RTL has the canonical form.
3602 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3603 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3604 the proper branch condition code.
3606 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3608 MODE is the mode of the inputs (in case they are const_int).
3610 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3611 be passed unchanged to emit_cmp_insn, then potentially converted into an
3612 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3614 void
3615 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3616 enum machine_mode mode, int unsignedp, rtx label)
3618 rtx op0 = x, op1 = y;
3620 /* Swap operands and condition to ensure canonical RTL. */
3621 if (swap_commutative_operands_p (x, y))
3623 /* If we're not emitting a branch, this means some caller
3624 is out of sync. */
3625 gcc_assert (label);
3627 op0 = y, op1 = x;
3628 comparison = swap_condition (comparison);
3631 #ifdef HAVE_cc0
3632 /* If OP0 is still a constant, then both X and Y must be constants.
3633 Force X into a register to create canonical RTL. */
3634 if (CONSTANT_P (op0))
3635 op0 = force_reg (mode, op0);
3636 #endif
3638 if (unsignedp)
3639 comparison = unsigned_condition (comparison);
3641 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3642 ccp_jump);
3643 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3646 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3648 void
3649 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3650 enum machine_mode mode, int unsignedp)
3652 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3655 /* Emit a library call comparison between floating point X and Y.
3656 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3658 static void
3659 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3660 enum machine_mode *pmode, int *punsignedp)
3662 enum rtx_code comparison = *pcomparison;
3663 enum rtx_code swapped = swap_condition (comparison);
3664 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3665 rtx x = *px;
3666 rtx y = *py;
3667 enum machine_mode orig_mode = GET_MODE (x);
3668 enum machine_mode mode;
3669 rtx value, target, insns, equiv;
3670 rtx libfunc = 0;
3671 bool reversed_p = false;
3673 for (mode = orig_mode; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
3675 if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3676 break;
3678 if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
3680 rtx tmp;
3681 tmp = x; x = y; y = tmp;
3682 comparison = swapped;
3683 break;
3686 if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
3687 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
3689 comparison = reversed;
3690 reversed_p = true;
3691 break;
3695 gcc_assert (mode != VOIDmode);
3697 if (mode != orig_mode)
3699 x = convert_to_mode (mode, x, 0);
3700 y = convert_to_mode (mode, y, 0);
3703 /* Attach a REG_EQUAL note describing the semantics of the libcall to
3704 the RTL. The allows the RTL optimizers to delete the libcall if the
3705 condition can be determined at compile-time. */
3706 if (comparison == UNORDERED)
3708 rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
3709 equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
3710 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3711 temp, const_true_rtx, equiv);
3713 else
3715 equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
3716 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3718 rtx true_rtx, false_rtx;
3720 switch (comparison)
3722 case EQ:
3723 true_rtx = const0_rtx;
3724 false_rtx = const_true_rtx;
3725 break;
3727 case NE:
3728 true_rtx = const_true_rtx;
3729 false_rtx = const0_rtx;
3730 break;
3732 case GT:
3733 true_rtx = const1_rtx;
3734 false_rtx = const0_rtx;
3735 break;
3737 case GE:
3738 true_rtx = const0_rtx;
3739 false_rtx = constm1_rtx;
3740 break;
3742 case LT:
3743 true_rtx = constm1_rtx;
3744 false_rtx = const0_rtx;
3745 break;
3747 case LE:
3748 true_rtx = const0_rtx;
3749 false_rtx = const1_rtx;
3750 break;
3752 default:
3753 gcc_unreachable ();
3755 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3756 equiv, true_rtx, false_rtx);
3760 start_sequence ();
3761 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3762 word_mode, 2, x, mode, y, mode);
3763 insns = get_insns ();
3764 end_sequence ();
3766 target = gen_reg_rtx (word_mode);
3767 emit_libcall_block (insns, target, value, equiv);
3769 if (comparison == UNORDERED
3770 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3771 comparison = reversed_p ? EQ : NE;
3773 *px = target;
3774 *py = const0_rtx;
3775 *pmode = word_mode;
3776 *pcomparison = comparison;
3777 *punsignedp = 0;
3780 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3782 void
3783 emit_indirect_jump (rtx loc)
3785 if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
3786 (loc, Pmode))
3787 loc = copy_to_mode_reg (Pmode, loc);
3789 emit_jump_insn (gen_indirect_jump (loc));
3790 emit_barrier ();
3793 #ifdef HAVE_conditional_move
3795 /* Emit a conditional move instruction if the machine supports one for that
3796 condition and machine mode.
3798 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3799 the mode to use should they be constants. If it is VOIDmode, they cannot
3800 both be constants.
3802 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3803 should be stored there. MODE is the mode to use should they be constants.
3804 If it is VOIDmode, they cannot both be constants.
3806 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3807 is not supported. */
3810 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
3811 enum machine_mode cmode, rtx op2, rtx op3,
3812 enum machine_mode mode, int unsignedp)
3814 rtx tem, subtarget, comparison, insn;
3815 enum insn_code icode;
3816 enum rtx_code reversed;
3818 /* If one operand is constant, make it the second one. Only do this
3819 if the other operand is not constant as well. */
3821 if (swap_commutative_operands_p (op0, op1))
3823 tem = op0;
3824 op0 = op1;
3825 op1 = tem;
3826 code = swap_condition (code);
3829 /* get_condition will prefer to generate LT and GT even if the old
3830 comparison was against zero, so undo that canonicalization here since
3831 comparisons against zero are cheaper. */
3832 if (code == LT && op1 == const1_rtx)
3833 code = LE, op1 = const0_rtx;
3834 else if (code == GT && op1 == constm1_rtx)
3835 code = GE, op1 = const0_rtx;
3837 if (cmode == VOIDmode)
3838 cmode = GET_MODE (op0);
3840 if (swap_commutative_operands_p (op2, op3)
3841 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
3842 != UNKNOWN))
3844 tem = op2;
3845 op2 = op3;
3846 op3 = tem;
3847 code = reversed;
3850 if (mode == VOIDmode)
3851 mode = GET_MODE (op2);
3853 icode = movcc_gen_code[mode];
3855 if (icode == CODE_FOR_nothing)
3856 return 0;
3858 if (flag_force_mem)
3860 op2 = force_not_mem (op2);
3861 op3 = force_not_mem (op3);
3864 if (!target)
3865 target = gen_reg_rtx (mode);
3867 subtarget = target;
3869 /* If the insn doesn't accept these operands, put them in pseudos. */
3871 if (!insn_data[icode].operand[0].predicate
3872 (subtarget, insn_data[icode].operand[0].mode))
3873 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3875 if (!insn_data[icode].operand[2].predicate
3876 (op2, insn_data[icode].operand[2].mode))
3877 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3879 if (!insn_data[icode].operand[3].predicate
3880 (op3, insn_data[icode].operand[3].mode))
3881 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3883 /* Everything should now be in the suitable form, so emit the compare insn
3884 and then the conditional move. */
3886 comparison
3887 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
3889 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3890 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3891 return NULL and let the caller figure out how best to deal with this
3892 situation. */
3893 if (GET_CODE (comparison) != code)
3894 return NULL_RTX;
3896 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3898 /* If that failed, then give up. */
3899 if (insn == 0)
3900 return 0;
3902 emit_insn (insn);
3904 if (subtarget != target)
3905 convert_move (target, subtarget, 0);
3907 return target;
3910 /* Return nonzero if a conditional move of mode MODE is supported.
3912 This function is for combine so it can tell whether an insn that looks
3913 like a conditional move is actually supported by the hardware. If we
3914 guess wrong we lose a bit on optimization, but that's it. */
3915 /* ??? sparc64 supports conditionally moving integers values based on fp
3916 comparisons, and vice versa. How do we handle them? */
3919 can_conditionally_move_p (enum machine_mode mode)
3921 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3922 return 1;
3924 return 0;
3927 #endif /* HAVE_conditional_move */
3929 /* Emit a conditional addition instruction if the machine supports one for that
3930 condition and machine mode.
3932 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3933 the mode to use should they be constants. If it is VOIDmode, they cannot
3934 both be constants.
3936 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
3937 should be stored there. MODE is the mode to use should they be constants.
3938 If it is VOIDmode, they cannot both be constants.
3940 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3941 is not supported. */
3944 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
3945 enum machine_mode cmode, rtx op2, rtx op3,
3946 enum machine_mode mode, int unsignedp)
3948 rtx tem, subtarget, comparison, insn;
3949 enum insn_code icode;
3950 enum rtx_code reversed;
3952 /* If one operand is constant, make it the second one. Only do this
3953 if the other operand is not constant as well. */
3955 if (swap_commutative_operands_p (op0, op1))
3957 tem = op0;
3958 op0 = op1;
3959 op1 = tem;
3960 code = swap_condition (code);
3963 /* get_condition will prefer to generate LT and GT even if the old
3964 comparison was against zero, so undo that canonicalization here since
3965 comparisons against zero are cheaper. */
3966 if (code == LT && op1 == const1_rtx)
3967 code = LE, op1 = const0_rtx;
3968 else if (code == GT && op1 == constm1_rtx)
3969 code = GE, op1 = const0_rtx;
3971 if (cmode == VOIDmode)
3972 cmode = GET_MODE (op0);
3974 if (swap_commutative_operands_p (op2, op3)
3975 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
3976 != UNKNOWN))
3978 tem = op2;
3979 op2 = op3;
3980 op3 = tem;
3981 code = reversed;
3984 if (mode == VOIDmode)
3985 mode = GET_MODE (op2);
3987 icode = addcc_optab->handlers[(int) mode].insn_code;
3989 if (icode == CODE_FOR_nothing)
3990 return 0;
3992 if (flag_force_mem)
3994 op2 = force_not_mem (op2);
3995 op3 = force_not_mem (op3);
3998 if (!target)
3999 target = gen_reg_rtx (mode);
4001 /* If the insn doesn't accept these operands, put them in pseudos. */
4003 if (!insn_data[icode].operand[0].predicate
4004 (target, insn_data[icode].operand[0].mode))
4005 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4006 else
4007 subtarget = target;
4009 if (!insn_data[icode].operand[2].predicate
4010 (op2, insn_data[icode].operand[2].mode))
4011 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4013 if (!insn_data[icode].operand[3].predicate
4014 (op3, insn_data[icode].operand[3].mode))
4015 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4017 /* Everything should now be in the suitable form, so emit the compare insn
4018 and then the conditional move. */
4020 comparison
4021 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4023 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4024 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4025 return NULL and let the caller figure out how best to deal with this
4026 situation. */
4027 if (GET_CODE (comparison) != code)
4028 return NULL_RTX;
4030 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4032 /* If that failed, then give up. */
4033 if (insn == 0)
4034 return 0;
4036 emit_insn (insn);
4038 if (subtarget != target)
4039 convert_move (target, subtarget, 0);
4041 return target;
4044 /* These functions attempt to generate an insn body, rather than
4045 emitting the insn, but if the gen function already emits them, we
4046 make no attempt to turn them back into naked patterns. */
4048 /* Generate and return an insn body to add Y to X. */
4051 gen_add2_insn (rtx x, rtx y)
4053 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4055 gcc_assert (insn_data[icode].operand[0].predicate
4056 (x, insn_data[icode].operand[0].mode));
4057 gcc_assert (insn_data[icode].operand[1].predicate
4058 (x, insn_data[icode].operand[1].mode));
4059 gcc_assert (insn_data[icode].operand[2].predicate
4060 (y, insn_data[icode].operand[2].mode));
4062 return GEN_FCN (icode) (x, x, y);
4065 /* Generate and return an insn body to add r1 and c,
4066 storing the result in r0. */
4068 gen_add3_insn (rtx r0, rtx r1, rtx c)
4070 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4072 if (icode == CODE_FOR_nothing
4073 || !(insn_data[icode].operand[0].predicate
4074 (r0, insn_data[icode].operand[0].mode))
4075 || !(insn_data[icode].operand[1].predicate
4076 (r1, insn_data[icode].operand[1].mode))
4077 || !(insn_data[icode].operand[2].predicate
4078 (c, insn_data[icode].operand[2].mode)))
4079 return NULL_RTX;
4081 return GEN_FCN (icode) (r0, r1, c);
4085 have_add2_insn (rtx x, rtx y)
4087 int icode;
4089 gcc_assert (GET_MODE (x) != VOIDmode);
4091 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4093 if (icode == CODE_FOR_nothing)
4094 return 0;
4096 if (!(insn_data[icode].operand[0].predicate
4097 (x, insn_data[icode].operand[0].mode))
4098 || !(insn_data[icode].operand[1].predicate
4099 (x, insn_data[icode].operand[1].mode))
4100 || !(insn_data[icode].operand[2].predicate
4101 (y, insn_data[icode].operand[2].mode)))
4102 return 0;
4104 return 1;
4107 /* Generate and return an insn body to subtract Y from X. */
4110 gen_sub2_insn (rtx x, rtx y)
4112 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4114 gcc_assert (insn_data[icode].operand[0].predicate
4115 (x, insn_data[icode].operand[0].mode));
4116 gcc_assert (insn_data[icode].operand[1].predicate
4117 (x, insn_data[icode].operand[1].mode));
4118 gcc_assert (insn_data[icode].operand[2].predicate
4119 (y, insn_data[icode].operand[2].mode));
4121 return GEN_FCN (icode) (x, x, y);
4124 /* Generate and return an insn body to subtract r1 and c,
4125 storing the result in r0. */
4127 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4129 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4131 if (icode == CODE_FOR_nothing
4132 || !(insn_data[icode].operand[0].predicate
4133 (r0, insn_data[icode].operand[0].mode))
4134 || !(insn_data[icode].operand[1].predicate
4135 (r1, insn_data[icode].operand[1].mode))
4136 || !(insn_data[icode].operand[2].predicate
4137 (c, insn_data[icode].operand[2].mode)))
4138 return NULL_RTX;
4140 return GEN_FCN (icode) (r0, r1, c);
4144 have_sub2_insn (rtx x, rtx y)
4146 int icode;
4148 gcc_assert (GET_MODE (x) != VOIDmode);
4150 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4152 if (icode == CODE_FOR_nothing)
4153 return 0;
4155 if (!(insn_data[icode].operand[0].predicate
4156 (x, insn_data[icode].operand[0].mode))
4157 || !(insn_data[icode].operand[1].predicate
4158 (x, insn_data[icode].operand[1].mode))
4159 || !(insn_data[icode].operand[2].predicate
4160 (y, insn_data[icode].operand[2].mode)))
4161 return 0;
4163 return 1;
4166 /* Generate the body of an instruction to copy Y into X.
4167 It may be a list of insns, if one insn isn't enough. */
4170 gen_move_insn (rtx x, rtx y)
4172 rtx seq;
4174 start_sequence ();
4175 emit_move_insn_1 (x, y);
4176 seq = get_insns ();
4177 end_sequence ();
4178 return seq;
4181 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4182 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4183 no such operation exists, CODE_FOR_nothing will be returned. */
4185 enum insn_code
4186 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4187 int unsignedp)
4189 convert_optab tab;
4190 #ifdef HAVE_ptr_extend
4191 if (unsignedp < 0)
4192 return CODE_FOR_ptr_extend;
4193 #endif
4195 tab = unsignedp ? zext_optab : sext_optab;
4196 return tab->handlers[to_mode][from_mode].insn_code;
4199 /* Generate the body of an insn to extend Y (with mode MFROM)
4200 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4203 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4204 enum machine_mode mfrom, int unsignedp)
4206 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4207 return GEN_FCN (icode) (x, y);
4210 /* can_fix_p and can_float_p say whether the target machine
4211 can directly convert a given fixed point type to
4212 a given floating point type, or vice versa.
4213 The returned value is the CODE_FOR_... value to use,
4214 or CODE_FOR_nothing if these modes cannot be directly converted.
4216 *TRUNCP_PTR is set to 1 if it is necessary to output
4217 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4219 static enum insn_code
4220 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4221 int unsignedp, int *truncp_ptr)
4223 convert_optab tab;
4224 enum insn_code icode;
4226 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4227 icode = tab->handlers[fixmode][fltmode].insn_code;
4228 if (icode != CODE_FOR_nothing)
4230 *truncp_ptr = 0;
4231 return icode;
4234 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4235 for this to work. We need to rework the fix* and ftrunc* patterns
4236 and documentation. */
4237 tab = unsignedp ? ufix_optab : sfix_optab;
4238 icode = tab->handlers[fixmode][fltmode].insn_code;
4239 if (icode != CODE_FOR_nothing
4240 && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
4242 *truncp_ptr = 1;
4243 return icode;
4246 *truncp_ptr = 0;
4247 return CODE_FOR_nothing;
4250 static enum insn_code
4251 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4252 int unsignedp)
4254 convert_optab tab;
4256 tab = unsignedp ? ufloat_optab : sfloat_optab;
4257 return tab->handlers[fltmode][fixmode].insn_code;
4260 /* Generate code to convert FROM to floating point
4261 and store in TO. FROM must be fixed point and not VOIDmode.
4262 UNSIGNEDP nonzero means regard FROM as unsigned.
4263 Normally this is done by correcting the final value
4264 if it is negative. */
4266 void
4267 expand_float (rtx to, rtx from, int unsignedp)
4269 enum insn_code icode;
4270 rtx target = to;
4271 enum machine_mode fmode, imode;
4273 /* Crash now, because we won't be able to decide which mode to use. */
4274 gcc_assert (GET_MODE (from) != VOIDmode);
4276 /* Look for an insn to do the conversion. Do it in the specified
4277 modes if possible; otherwise convert either input, output or both to
4278 wider mode. If the integer mode is wider than the mode of FROM,
4279 we can do the conversion signed even if the input is unsigned. */
4281 for (fmode = GET_MODE (to); fmode != VOIDmode;
4282 fmode = GET_MODE_WIDER_MODE (fmode))
4283 for (imode = GET_MODE (from); imode != VOIDmode;
4284 imode = GET_MODE_WIDER_MODE (imode))
4286 int doing_unsigned = unsignedp;
4288 if (fmode != GET_MODE (to)
4289 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4290 continue;
4292 icode = can_float_p (fmode, imode, unsignedp);
4293 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4294 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4296 if (icode != CODE_FOR_nothing)
4298 if (imode != GET_MODE (from))
4299 from = convert_to_mode (imode, from, unsignedp);
4301 if (fmode != GET_MODE (to))
4302 target = gen_reg_rtx (fmode);
4304 emit_unop_insn (icode, target, from,
4305 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4307 if (target != to)
4308 convert_move (to, target, 0);
4309 return;
4313 /* Unsigned integer, and no way to convert directly.
4314 Convert as signed, then conditionally adjust the result. */
4315 if (unsignedp)
4317 rtx label = gen_label_rtx ();
4318 rtx temp;
4319 REAL_VALUE_TYPE offset;
4321 if (flag_force_mem)
4322 from = force_not_mem (from);
4324 /* Look for a usable floating mode FMODE wider than the source and at
4325 least as wide as the target. Using FMODE will avoid rounding woes
4326 with unsigned values greater than the signed maximum value. */
4328 for (fmode = GET_MODE (to); fmode != VOIDmode;
4329 fmode = GET_MODE_WIDER_MODE (fmode))
4330 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4331 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4332 break;
4334 if (fmode == VOIDmode)
4336 /* There is no such mode. Pretend the target is wide enough. */
4337 fmode = GET_MODE (to);
4339 /* Avoid double-rounding when TO is narrower than FROM. */
4340 if ((significand_size (fmode) + 1)
4341 < GET_MODE_BITSIZE (GET_MODE (from)))
4343 rtx temp1;
4344 rtx neglabel = gen_label_rtx ();
4346 /* Don't use TARGET if it isn't a register, is a hard register,
4347 or is the wrong mode. */
4348 if (!REG_P (target)
4349 || REGNO (target) < FIRST_PSEUDO_REGISTER
4350 || GET_MODE (target) != fmode)
4351 target = gen_reg_rtx (fmode);
4353 imode = GET_MODE (from);
4354 do_pending_stack_adjust ();
4356 /* Test whether the sign bit is set. */
4357 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4358 0, neglabel);
4360 /* The sign bit is not set. Convert as signed. */
4361 expand_float (target, from, 0);
4362 emit_jump_insn (gen_jump (label));
4363 emit_barrier ();
4365 /* The sign bit is set.
4366 Convert to a usable (positive signed) value by shifting right
4367 one bit, while remembering if a nonzero bit was shifted
4368 out; i.e., compute (from & 1) | (from >> 1). */
4370 emit_label (neglabel);
4371 temp = expand_binop (imode, and_optab, from, const1_rtx,
4372 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4373 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4374 NULL_RTX, 1);
4375 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4376 OPTAB_LIB_WIDEN);
4377 expand_float (target, temp, 0);
4379 /* Multiply by 2 to undo the shift above. */
4380 temp = expand_binop (fmode, add_optab, target, target,
4381 target, 0, OPTAB_LIB_WIDEN);
4382 if (temp != target)
4383 emit_move_insn (target, temp);
4385 do_pending_stack_adjust ();
4386 emit_label (label);
4387 goto done;
4391 /* If we are about to do some arithmetic to correct for an
4392 unsigned operand, do it in a pseudo-register. */
4394 if (GET_MODE (to) != fmode
4395 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4396 target = gen_reg_rtx (fmode);
4398 /* Convert as signed integer to floating. */
4399 expand_float (target, from, 0);
4401 /* If FROM is negative (and therefore TO is negative),
4402 correct its value by 2**bitwidth. */
4404 do_pending_stack_adjust ();
4405 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4406 0, label);
4409 real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4410 temp = expand_binop (fmode, add_optab, target,
4411 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4412 target, 0, OPTAB_LIB_WIDEN);
4413 if (temp != target)
4414 emit_move_insn (target, temp);
4416 do_pending_stack_adjust ();
4417 emit_label (label);
4418 goto done;
4421 /* No hardware instruction available; call a library routine. */
4423 rtx libfunc;
4424 rtx insns;
4425 rtx value;
4426 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4428 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4429 from = convert_to_mode (SImode, from, unsignedp);
4431 if (flag_force_mem)
4432 from = force_not_mem (from);
4434 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4435 gcc_assert (libfunc);
4437 start_sequence ();
4439 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4440 GET_MODE (to), 1, from,
4441 GET_MODE (from));
4442 insns = get_insns ();
4443 end_sequence ();
4445 emit_libcall_block (insns, target, value,
4446 gen_rtx_FLOAT (GET_MODE (to), from));
4449 done:
4451 /* Copy result to requested destination
4452 if we have been computing in a temp location. */
4454 if (target != to)
4456 if (GET_MODE (target) == GET_MODE (to))
4457 emit_move_insn (to, target);
4458 else
4459 convert_move (to, target, 0);
4463 /* Generate code to convert FROM to fixed point and store in TO. FROM
4464 must be floating point. */
4466 void
4467 expand_fix (rtx to, rtx from, int unsignedp)
4469 enum insn_code icode;
4470 rtx target = to;
4471 enum machine_mode fmode, imode;
4472 int must_trunc = 0;
4474 /* We first try to find a pair of modes, one real and one integer, at
4475 least as wide as FROM and TO, respectively, in which we can open-code
4476 this conversion. If the integer mode is wider than the mode of TO,
4477 we can do the conversion either signed or unsigned. */
4479 for (fmode = GET_MODE (from); fmode != VOIDmode;
4480 fmode = GET_MODE_WIDER_MODE (fmode))
4481 for (imode = GET_MODE (to); imode != VOIDmode;
4482 imode = GET_MODE_WIDER_MODE (imode))
4484 int doing_unsigned = unsignedp;
4486 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4487 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4488 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4490 if (icode != CODE_FOR_nothing)
4492 if (fmode != GET_MODE (from))
4493 from = convert_to_mode (fmode, from, 0);
4495 if (must_trunc)
4497 rtx temp = gen_reg_rtx (GET_MODE (from));
4498 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4499 temp, 0);
4502 if (imode != GET_MODE (to))
4503 target = gen_reg_rtx (imode);
4505 emit_unop_insn (icode, target, from,
4506 doing_unsigned ? UNSIGNED_FIX : FIX);
4507 if (target != to)
4508 convert_move (to, target, unsignedp);
4509 return;
4513 /* For an unsigned conversion, there is one more way to do it.
4514 If we have a signed conversion, we generate code that compares
4515 the real value to the largest representable positive number. If if
4516 is smaller, the conversion is done normally. Otherwise, subtract
4517 one plus the highest signed number, convert, and add it back.
4519 We only need to check all real modes, since we know we didn't find
4520 anything with a wider integer mode.
4522 This code used to extend FP value into mode wider than the destination.
4523 This is not needed. Consider, for instance conversion from SFmode
4524 into DImode.
4526 The hot path trought the code is dealing with inputs smaller than 2^63
4527 and doing just the conversion, so there is no bits to lose.
4529 In the other path we know the value is positive in the range 2^63..2^64-1
4530 inclusive. (as for other imput overflow happens and result is undefined)
4531 So we know that the most important bit set in mantissa corresponds to
4532 2^63. The subtraction of 2^63 should not generate any rounding as it
4533 simply clears out that bit. The rest is trivial. */
4535 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4536 for (fmode = GET_MODE (from); fmode != VOIDmode;
4537 fmode = GET_MODE_WIDER_MODE (fmode))
4538 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4539 &must_trunc))
4541 int bitsize;
4542 REAL_VALUE_TYPE offset;
4543 rtx limit, lab1, lab2, insn;
4545 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4546 real_2expN (&offset, bitsize - 1);
4547 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4548 lab1 = gen_label_rtx ();
4549 lab2 = gen_label_rtx ();
4551 if (flag_force_mem)
4552 from = force_not_mem (from);
4554 if (fmode != GET_MODE (from))
4555 from = convert_to_mode (fmode, from, 0);
4557 /* See if we need to do the subtraction. */
4558 do_pending_stack_adjust ();
4559 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4560 0, lab1);
4562 /* If not, do the signed "fix" and branch around fixup code. */
4563 expand_fix (to, from, 0);
4564 emit_jump_insn (gen_jump (lab2));
4565 emit_barrier ();
4567 /* Otherwise, subtract 2**(N-1), convert to signed number,
4568 then add 2**(N-1). Do the addition using XOR since this
4569 will often generate better code. */
4570 emit_label (lab1);
4571 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4572 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4573 expand_fix (to, target, 0);
4574 target = expand_binop (GET_MODE (to), xor_optab, to,
4575 gen_int_mode
4576 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4577 GET_MODE (to)),
4578 to, 1, OPTAB_LIB_WIDEN);
4580 if (target != to)
4581 emit_move_insn (to, target);
4583 emit_label (lab2);
4585 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4586 != CODE_FOR_nothing)
4588 /* Make a place for a REG_NOTE and add it. */
4589 insn = emit_move_insn (to, to);
4590 set_unique_reg_note (insn,
4591 REG_EQUAL,
4592 gen_rtx_fmt_e (UNSIGNED_FIX,
4593 GET_MODE (to),
4594 copy_rtx (from)));
4597 return;
4600 /* We can't do it with an insn, so use a library call. But first ensure
4601 that the mode of TO is at least as wide as SImode, since those are the
4602 only library calls we know about. */
4604 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4606 target = gen_reg_rtx (SImode);
4608 expand_fix (target, from, unsignedp);
4610 else
4612 rtx insns;
4613 rtx value;
4614 rtx libfunc;
4616 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4617 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4618 gcc_assert (libfunc);
4620 if (flag_force_mem)
4621 from = force_not_mem (from);
4623 start_sequence ();
4625 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4626 GET_MODE (to), 1, from,
4627 GET_MODE (from));
4628 insns = get_insns ();
4629 end_sequence ();
4631 emit_libcall_block (insns, target, value,
4632 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4633 GET_MODE (to), from));
4636 if (target != to)
4638 if (GET_MODE (to) == GET_MODE (target))
4639 emit_move_insn (to, target);
4640 else
4641 convert_move (to, target, 0);
4645 /* Report whether we have an instruction to perform the operation
4646 specified by CODE on operands of mode MODE. */
4648 have_insn_for (enum rtx_code code, enum machine_mode mode)
4650 return (code_to_optab[(int) code] != 0
4651 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4652 != CODE_FOR_nothing));
4655 /* Create a blank optab. */
4656 static optab
4657 new_optab (void)
4659 int i;
4660 optab op = ggc_alloc (sizeof (struct optab));
4661 for (i = 0; i < NUM_MACHINE_MODES; i++)
4663 op->handlers[i].insn_code = CODE_FOR_nothing;
4664 op->handlers[i].libfunc = 0;
4667 return op;
4670 static convert_optab
4671 new_convert_optab (void)
4673 int i, j;
4674 convert_optab op = ggc_alloc (sizeof (struct convert_optab));
4675 for (i = 0; i < NUM_MACHINE_MODES; i++)
4676 for (j = 0; j < NUM_MACHINE_MODES; j++)
4678 op->handlers[i][j].insn_code = CODE_FOR_nothing;
4679 op->handlers[i][j].libfunc = 0;
4681 return op;
4684 /* Same, but fill in its code as CODE, and write it into the
4685 code_to_optab table. */
4686 static inline optab
4687 init_optab (enum rtx_code code)
4689 optab op = new_optab ();
4690 op->code = code;
4691 code_to_optab[(int) code] = op;
4692 return op;
4695 /* Same, but fill in its code as CODE, and do _not_ write it into
4696 the code_to_optab table. */
4697 static inline optab
4698 init_optabv (enum rtx_code code)
4700 optab op = new_optab ();
4701 op->code = code;
4702 return op;
4705 /* Conversion optabs never go in the code_to_optab table. */
4706 static inline convert_optab
4707 init_convert_optab (enum rtx_code code)
4709 convert_optab op = new_convert_optab ();
4710 op->code = code;
4711 return op;
4714 /* Initialize the libfunc fields of an entire group of entries in some
4715 optab. Each entry is set equal to a string consisting of a leading
4716 pair of underscores followed by a generic operation name followed by
4717 a mode name (downshifted to lowercase) followed by a single character
4718 representing the number of operands for the given operation (which is
4719 usually one of the characters '2', '3', or '4').
4721 OPTABLE is the table in which libfunc fields are to be initialized.
4722 FIRST_MODE is the first machine mode index in the given optab to
4723 initialize.
4724 LAST_MODE is the last machine mode index in the given optab to
4725 initialize.
4726 OPNAME is the generic (string) name of the operation.
4727 SUFFIX is the character which specifies the number of operands for
4728 the given generic operation.
4731 static void
4732 init_libfuncs (optab optable, int first_mode, int last_mode,
4733 const char *opname, int suffix)
4735 int mode;
4736 unsigned opname_len = strlen (opname);
4738 for (mode = first_mode; (int) mode <= (int) last_mode;
4739 mode = (enum machine_mode) ((int) mode + 1))
4741 const char *mname = GET_MODE_NAME (mode);
4742 unsigned mname_len = strlen (mname);
4743 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4744 char *p;
4745 const char *q;
4747 p = libfunc_name;
4748 *p++ = '_';
4749 *p++ = '_';
4750 for (q = opname; *q; )
4751 *p++ = *q++;
4752 for (q = mname; *q; q++)
4753 *p++ = TOLOWER (*q);
4754 *p++ = suffix;
4755 *p = '\0';
4757 optable->handlers[(int) mode].libfunc
4758 = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
4762 /* Initialize the libfunc fields of an entire group of entries in some
4763 optab which correspond to all integer mode operations. The parameters
4764 have the same meaning as similarly named ones for the `init_libfuncs'
4765 routine. (See above). */
4767 static void
4768 init_integral_libfuncs (optab optable, const char *opname, int suffix)
4770 int maxsize = 2*BITS_PER_WORD;
4771 if (maxsize < LONG_LONG_TYPE_SIZE)
4772 maxsize = LONG_LONG_TYPE_SIZE;
4773 init_libfuncs (optable, word_mode,
4774 mode_for_size (maxsize, MODE_INT, 0),
4775 opname, suffix);
4778 /* Initialize the libfunc fields of an entire group of entries in some
4779 optab which correspond to all real mode operations. The parameters
4780 have the same meaning as similarly named ones for the `init_libfuncs'
4781 routine. (See above). */
4783 static void
4784 init_floating_libfuncs (optab optable, const char *opname, int suffix)
4786 init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
4789 /* Initialize the libfunc fields of an entire group of entries of an
4790 inter-mode-class conversion optab. The string formation rules are
4791 similar to the ones for init_libfuncs, above, but instead of having
4792 a mode name and an operand count these functions have two mode names
4793 and no operand count. */
4794 static void
4795 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
4796 enum mode_class from_class,
4797 enum mode_class to_class)
4799 enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
4800 enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
4801 size_t opname_len = strlen (opname);
4802 size_t max_mname_len = 0;
4804 enum machine_mode fmode, tmode;
4805 const char *fname, *tname;
4806 const char *q;
4807 char *libfunc_name, *suffix;
4808 char *p;
4810 for (fmode = first_from_mode;
4811 fmode != VOIDmode;
4812 fmode = GET_MODE_WIDER_MODE (fmode))
4813 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
4815 for (tmode = first_to_mode;
4816 tmode != VOIDmode;
4817 tmode = GET_MODE_WIDER_MODE (tmode))
4818 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
4820 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
4821 libfunc_name[0] = '_';
4822 libfunc_name[1] = '_';
4823 memcpy (&libfunc_name[2], opname, opname_len);
4824 suffix = libfunc_name + opname_len + 2;
4826 for (fmode = first_from_mode; fmode != VOIDmode;
4827 fmode = GET_MODE_WIDER_MODE (fmode))
4828 for (tmode = first_to_mode; tmode != VOIDmode;
4829 tmode = GET_MODE_WIDER_MODE (tmode))
4831 fname = GET_MODE_NAME (fmode);
4832 tname = GET_MODE_NAME (tmode);
4834 p = suffix;
4835 for (q = fname; *q; p++, q++)
4836 *p = TOLOWER (*q);
4837 for (q = tname; *q; p++, q++)
4838 *p = TOLOWER (*q);
4840 *p = '\0';
4842 tab->handlers[tmode][fmode].libfunc
4843 = init_one_libfunc (ggc_alloc_string (libfunc_name,
4844 p - libfunc_name));
4848 /* Initialize the libfunc fields of an entire group of entries of an
4849 intra-mode-class conversion optab. The string formation rules are
4850 similar to the ones for init_libfunc, above. WIDENING says whether
4851 the optab goes from narrow to wide modes or vice versa. These functions
4852 have two mode names _and_ an operand count. */
4853 static void
4854 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
4855 enum mode_class class, bool widening)
4857 enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
4858 size_t opname_len = strlen (opname);
4859 size_t max_mname_len = 0;
4861 enum machine_mode nmode, wmode;
4862 const char *nname, *wname;
4863 const char *q;
4864 char *libfunc_name, *suffix;
4865 char *p;
4867 for (nmode = first_mode; nmode != VOIDmode;
4868 nmode = GET_MODE_WIDER_MODE (nmode))
4869 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
4871 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
4872 libfunc_name[0] = '_';
4873 libfunc_name[1] = '_';
4874 memcpy (&libfunc_name[2], opname, opname_len);
4875 suffix = libfunc_name + opname_len + 2;
4877 for (nmode = first_mode; nmode != VOIDmode;
4878 nmode = GET_MODE_WIDER_MODE (nmode))
4879 for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
4880 wmode = GET_MODE_WIDER_MODE (wmode))
4882 nname = GET_MODE_NAME (nmode);
4883 wname = GET_MODE_NAME (wmode);
4885 p = suffix;
4886 for (q = widening ? nname : wname; *q; p++, q++)
4887 *p = TOLOWER (*q);
4888 for (q = widening ? wname : nname; *q; p++, q++)
4889 *p = TOLOWER (*q);
4891 *p++ = '2';
4892 *p = '\0';
4894 tab->handlers[widening ? wmode : nmode]
4895 [widening ? nmode : wmode].libfunc
4896 = init_one_libfunc (ggc_alloc_string (libfunc_name,
4897 p - libfunc_name));
4903 init_one_libfunc (const char *name)
4905 rtx symbol;
4907 /* Create a FUNCTION_DECL that can be passed to
4908 targetm.encode_section_info. */
4909 /* ??? We don't have any type information except for this is
4910 a function. Pretend this is "int foo()". */
4911 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
4912 build_function_type (integer_type_node, NULL_TREE));
4913 DECL_ARTIFICIAL (decl) = 1;
4914 DECL_EXTERNAL (decl) = 1;
4915 TREE_PUBLIC (decl) = 1;
4917 symbol = XEXP (DECL_RTL (decl), 0);
4919 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
4920 are the flags assigned by targetm.encode_section_info. */
4921 SYMBOL_REF_DECL (symbol) = 0;
4923 return symbol;
4926 /* Call this to reset the function entry for one optab (OPTABLE) in mode
4927 MODE to NAME, which should be either 0 or a string constant. */
4928 void
4929 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
4931 if (name)
4932 optable->handlers[mode].libfunc = init_one_libfunc (name);
4933 else
4934 optable->handlers[mode].libfunc = 0;
4937 /* Call this to reset the function entry for one conversion optab
4938 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
4939 either 0 or a string constant. */
4940 void
4941 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
4942 enum machine_mode fmode, const char *name)
4944 if (name)
4945 optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
4946 else
4947 optable->handlers[tmode][fmode].libfunc = 0;
4950 /* Call this once to initialize the contents of the optabs
4951 appropriately for the current target machine. */
4953 void
4954 init_optabs (void)
4956 unsigned int i;
4958 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4960 for (i = 0; i < NUM_RTX_CODE; i++)
4961 setcc_gen_code[i] = CODE_FOR_nothing;
4963 #ifdef HAVE_conditional_move
4964 for (i = 0; i < NUM_MACHINE_MODES; i++)
4965 movcc_gen_code[i] = CODE_FOR_nothing;
4966 #endif
4968 for (i = 0; i < NUM_MACHINE_MODES; i++)
4970 vcond_gen_code[i] = CODE_FOR_nothing;
4971 vcondu_gen_code[i] = CODE_FOR_nothing;
4974 add_optab = init_optab (PLUS);
4975 addv_optab = init_optabv (PLUS);
4976 sub_optab = init_optab (MINUS);
4977 subv_optab = init_optabv (MINUS);
4978 smul_optab = init_optab (MULT);
4979 smulv_optab = init_optabv (MULT);
4980 smul_highpart_optab = init_optab (UNKNOWN);
4981 umul_highpart_optab = init_optab (UNKNOWN);
4982 smul_widen_optab = init_optab (UNKNOWN);
4983 umul_widen_optab = init_optab (UNKNOWN);
4984 sdiv_optab = init_optab (DIV);
4985 sdivv_optab = init_optabv (DIV);
4986 sdivmod_optab = init_optab (UNKNOWN);
4987 udiv_optab = init_optab (UDIV);
4988 udivmod_optab = init_optab (UNKNOWN);
4989 smod_optab = init_optab (MOD);
4990 umod_optab = init_optab (UMOD);
4991 fmod_optab = init_optab (UNKNOWN);
4992 drem_optab = init_optab (UNKNOWN);
4993 ftrunc_optab = init_optab (UNKNOWN);
4994 and_optab = init_optab (AND);
4995 ior_optab = init_optab (IOR);
4996 xor_optab = init_optab (XOR);
4997 ashl_optab = init_optab (ASHIFT);
4998 ashr_optab = init_optab (ASHIFTRT);
4999 lshr_optab = init_optab (LSHIFTRT);
5000 rotl_optab = init_optab (ROTATE);
5001 rotr_optab = init_optab (ROTATERT);
5002 smin_optab = init_optab (SMIN);
5003 smax_optab = init_optab (SMAX);
5004 umin_optab = init_optab (UMIN);
5005 umax_optab = init_optab (UMAX);
5006 pow_optab = init_optab (UNKNOWN);
5007 atan2_optab = init_optab (UNKNOWN);
5009 /* These three have codes assigned exclusively for the sake of
5010 have_insn_for. */
5011 mov_optab = init_optab (SET);
5012 movstrict_optab = init_optab (STRICT_LOW_PART);
5013 cmp_optab = init_optab (COMPARE);
5015 ucmp_optab = init_optab (UNKNOWN);
5016 tst_optab = init_optab (UNKNOWN);
5018 eq_optab = init_optab (EQ);
5019 ne_optab = init_optab (NE);
5020 gt_optab = init_optab (GT);
5021 ge_optab = init_optab (GE);
5022 lt_optab = init_optab (LT);
5023 le_optab = init_optab (LE);
5024 unord_optab = init_optab (UNORDERED);
5026 neg_optab = init_optab (NEG);
5027 negv_optab = init_optabv (NEG);
5028 abs_optab = init_optab (ABS);
5029 absv_optab = init_optabv (ABS);
5030 addcc_optab = init_optab (UNKNOWN);
5031 one_cmpl_optab = init_optab (NOT);
5032 ffs_optab = init_optab (FFS);
5033 clz_optab = init_optab (CLZ);
5034 ctz_optab = init_optab (CTZ);
5035 popcount_optab = init_optab (POPCOUNT);
5036 parity_optab = init_optab (PARITY);
5037 sqrt_optab = init_optab (SQRT);
5038 floor_optab = init_optab (UNKNOWN);
5039 lfloor_optab = init_optab (UNKNOWN);
5040 ceil_optab = init_optab (UNKNOWN);
5041 lceil_optab = init_optab (UNKNOWN);
5042 round_optab = init_optab (UNKNOWN);
5043 btrunc_optab = init_optab (UNKNOWN);
5044 nearbyint_optab = init_optab (UNKNOWN);
5045 rint_optab = init_optab (UNKNOWN);
5046 lrint_optab = init_optab (UNKNOWN);
5047 sincos_optab = init_optab (UNKNOWN);
5048 sin_optab = init_optab (UNKNOWN);
5049 asin_optab = init_optab (UNKNOWN);
5050 cos_optab = init_optab (UNKNOWN);
5051 acos_optab = init_optab (UNKNOWN);
5052 exp_optab = init_optab (UNKNOWN);
5053 exp10_optab = init_optab (UNKNOWN);
5054 exp2_optab = init_optab (UNKNOWN);
5055 expm1_optab = init_optab (UNKNOWN);
5056 ldexp_optab = init_optab (UNKNOWN);
5057 logb_optab = init_optab (UNKNOWN);
5058 ilogb_optab = init_optab (UNKNOWN);
5059 log_optab = init_optab (UNKNOWN);
5060 log10_optab = init_optab (UNKNOWN);
5061 log2_optab = init_optab (UNKNOWN);
5062 log1p_optab = init_optab (UNKNOWN);
5063 tan_optab = init_optab (UNKNOWN);
5064 atan_optab = init_optab (UNKNOWN);
5065 copysign_optab = init_optab (UNKNOWN);
5067 strlen_optab = init_optab (UNKNOWN);
5068 cbranch_optab = init_optab (UNKNOWN);
5069 cmov_optab = init_optab (UNKNOWN);
5070 cstore_optab = init_optab (UNKNOWN);
5071 push_optab = init_optab (UNKNOWN);
5073 reduc_smax_optab = init_optab (UNKNOWN);
5074 reduc_umax_optab = init_optab (UNKNOWN);
5075 reduc_smin_optab = init_optab (UNKNOWN);
5076 reduc_umin_optab = init_optab (UNKNOWN);
5077 reduc_plus_optab = init_optab (UNKNOWN);
5079 vec_extract_optab = init_optab (UNKNOWN);
5080 vec_set_optab = init_optab (UNKNOWN);
5081 vec_init_optab = init_optab (UNKNOWN);
5082 vec_realign_load_optab = init_optab (UNKNOWN);
5083 movmisalign_optab = init_optab (UNKNOWN);
5085 powi_optab = init_optab (UNKNOWN);
5087 /* Conversions. */
5088 sext_optab = init_convert_optab (SIGN_EXTEND);
5089 zext_optab = init_convert_optab (ZERO_EXTEND);
5090 trunc_optab = init_convert_optab (TRUNCATE);
5091 sfix_optab = init_convert_optab (FIX);
5092 ufix_optab = init_convert_optab (UNSIGNED_FIX);
5093 sfixtrunc_optab = init_convert_optab (UNKNOWN);
5094 ufixtrunc_optab = init_convert_optab (UNKNOWN);
5095 sfloat_optab = init_convert_optab (FLOAT);
5096 ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5098 for (i = 0; i < NUM_MACHINE_MODES; i++)
5100 movmem_optab[i] = CODE_FOR_nothing;
5101 clrmem_optab[i] = CODE_FOR_nothing;
5102 cmpstr_optab[i] = CODE_FOR_nothing;
5103 cmpmem_optab[i] = CODE_FOR_nothing;
5105 sync_add_optab[i] = CODE_FOR_nothing;
5106 sync_sub_optab[i] = CODE_FOR_nothing;
5107 sync_ior_optab[i] = CODE_FOR_nothing;
5108 sync_and_optab[i] = CODE_FOR_nothing;
5109 sync_xor_optab[i] = CODE_FOR_nothing;
5110 sync_nand_optab[i] = CODE_FOR_nothing;
5111 sync_old_add_optab[i] = CODE_FOR_nothing;
5112 sync_old_sub_optab[i] = CODE_FOR_nothing;
5113 sync_old_ior_optab[i] = CODE_FOR_nothing;
5114 sync_old_and_optab[i] = CODE_FOR_nothing;
5115 sync_old_xor_optab[i] = CODE_FOR_nothing;
5116 sync_old_nand_optab[i] = CODE_FOR_nothing;
5117 sync_new_add_optab[i] = CODE_FOR_nothing;
5118 sync_new_sub_optab[i] = CODE_FOR_nothing;
5119 sync_new_ior_optab[i] = CODE_FOR_nothing;
5120 sync_new_and_optab[i] = CODE_FOR_nothing;
5121 sync_new_xor_optab[i] = CODE_FOR_nothing;
5122 sync_new_nand_optab[i] = CODE_FOR_nothing;
5123 sync_compare_and_swap[i] = CODE_FOR_nothing;
5124 sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5125 sync_lock_test_and_set[i] = CODE_FOR_nothing;
5126 sync_lock_release[i] = CODE_FOR_nothing;
5128 #ifdef HAVE_SECONDARY_RELOADS
5129 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5130 #endif
5133 /* Fill in the optabs with the insns we support. */
5134 init_all_optabs ();
5136 /* Initialize the optabs with the names of the library functions. */
5137 init_integral_libfuncs (add_optab, "add", '3');
5138 init_floating_libfuncs (add_optab, "add", '3');
5139 init_integral_libfuncs (addv_optab, "addv", '3');
5140 init_floating_libfuncs (addv_optab, "add", '3');
5141 init_integral_libfuncs (sub_optab, "sub", '3');
5142 init_floating_libfuncs (sub_optab, "sub", '3');
5143 init_integral_libfuncs (subv_optab, "subv", '3');
5144 init_floating_libfuncs (subv_optab, "sub", '3');
5145 init_integral_libfuncs (smul_optab, "mul", '3');
5146 init_floating_libfuncs (smul_optab, "mul", '3');
5147 init_integral_libfuncs (smulv_optab, "mulv", '3');
5148 init_floating_libfuncs (smulv_optab, "mul", '3');
5149 init_integral_libfuncs (sdiv_optab, "div", '3');
5150 init_floating_libfuncs (sdiv_optab, "div", '3');
5151 init_integral_libfuncs (sdivv_optab, "divv", '3');
5152 init_integral_libfuncs (udiv_optab, "udiv", '3');
5153 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5154 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5155 init_integral_libfuncs (smod_optab, "mod", '3');
5156 init_integral_libfuncs (umod_optab, "umod", '3');
5157 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5158 init_integral_libfuncs (and_optab, "and", '3');
5159 init_integral_libfuncs (ior_optab, "ior", '3');
5160 init_integral_libfuncs (xor_optab, "xor", '3');
5161 init_integral_libfuncs (ashl_optab, "ashl", '3');
5162 init_integral_libfuncs (ashr_optab, "ashr", '3');
5163 init_integral_libfuncs (lshr_optab, "lshr", '3');
5164 init_integral_libfuncs (smin_optab, "min", '3');
5165 init_floating_libfuncs (smin_optab, "min", '3');
5166 init_integral_libfuncs (smax_optab, "max", '3');
5167 init_floating_libfuncs (smax_optab, "max", '3');
5168 init_integral_libfuncs (umin_optab, "umin", '3');
5169 init_integral_libfuncs (umax_optab, "umax", '3');
5170 init_integral_libfuncs (neg_optab, "neg", '2');
5171 init_floating_libfuncs (neg_optab, "neg", '2');
5172 init_integral_libfuncs (negv_optab, "negv", '2');
5173 init_floating_libfuncs (negv_optab, "neg", '2');
5174 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5175 init_integral_libfuncs (ffs_optab, "ffs", '2');
5176 init_integral_libfuncs (clz_optab, "clz", '2');
5177 init_integral_libfuncs (ctz_optab, "ctz", '2');
5178 init_integral_libfuncs (popcount_optab, "popcount", '2');
5179 init_integral_libfuncs (parity_optab, "parity", '2');
5181 /* Comparison libcalls for integers MUST come in pairs,
5182 signed/unsigned. */
5183 init_integral_libfuncs (cmp_optab, "cmp", '2');
5184 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5185 init_floating_libfuncs (cmp_optab, "cmp", '2');
5187 /* EQ etc are floating point only. */
5188 init_floating_libfuncs (eq_optab, "eq", '2');
5189 init_floating_libfuncs (ne_optab, "ne", '2');
5190 init_floating_libfuncs (gt_optab, "gt", '2');
5191 init_floating_libfuncs (ge_optab, "ge", '2');
5192 init_floating_libfuncs (lt_optab, "lt", '2');
5193 init_floating_libfuncs (le_optab, "le", '2');
5194 init_floating_libfuncs (unord_optab, "unord", '2');
5196 init_floating_libfuncs (powi_optab, "powi", '2');
5198 /* Conversions. */
5199 init_interclass_conv_libfuncs (sfloat_optab, "float",
5200 MODE_INT, MODE_FLOAT);
5201 init_interclass_conv_libfuncs (sfix_optab, "fix",
5202 MODE_FLOAT, MODE_INT);
5203 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5204 MODE_FLOAT, MODE_INT);
5206 /* sext_optab is also used for FLOAT_EXTEND. */
5207 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5208 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5210 /* Use cabs for double complex abs, since systems generally have cabs.
5211 Don't define any libcall for float complex, so that cabs will be used. */
5212 if (complex_double_type_node)
5213 abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5214 = init_one_libfunc ("cabs");
5216 /* The ffs function operates on `int'. */
5217 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5218 = init_one_libfunc ("ffs");
5220 abort_libfunc = init_one_libfunc ("abort");
5221 memcpy_libfunc = init_one_libfunc ("memcpy");
5222 memmove_libfunc = init_one_libfunc ("memmove");
5223 memcmp_libfunc = init_one_libfunc ("memcmp");
5224 memset_libfunc = init_one_libfunc ("memset");
5225 setbits_libfunc = init_one_libfunc ("__setbits");
5227 unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5228 ? "_Unwind_SjLj_Resume"
5229 : "_Unwind_Resume");
5230 #ifndef DONT_USE_BUILTIN_SETJMP
5231 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5232 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5233 #else
5234 setjmp_libfunc = init_one_libfunc ("setjmp");
5235 longjmp_libfunc = init_one_libfunc ("longjmp");
5236 #endif
5237 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5238 unwind_sjlj_unregister_libfunc
5239 = init_one_libfunc ("_Unwind_SjLj_Unregister");
5241 /* For function entry/exit instrumentation. */
5242 profile_function_entry_libfunc
5243 = init_one_libfunc ("__cyg_profile_func_enter");
5244 profile_function_exit_libfunc
5245 = init_one_libfunc ("__cyg_profile_func_exit");
5247 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5249 if (HAVE_conditional_trap)
5250 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5252 /* Allow the target to add more libcalls or rename some, etc. */
5253 targetm.init_libfuncs ();
5256 #ifdef DEBUG
5258 /* Print information about the current contents of the optabs on
5259 STDERR. */
5261 static void
5262 debug_optab_libfuncs (void)
5264 int i;
5265 int j;
5266 int k;
5268 /* Dump the arithmetic optabs. */
5269 for (i = 0; i != (int) OTI_MAX; i++)
5270 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5272 optab o;
5273 struct optab_handlers *h;
5275 o = optab_table[i];
5276 h = &o->handlers[j];
5277 if (h->libfunc)
5279 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5280 fprintf (stderr, "%s\t%s:\t%s\n",
5281 GET_RTX_NAME (o->code),
5282 GET_MODE_NAME (j),
5283 XSTR (h->libfunc, 0));
5287 /* Dump the conversion optabs. */
5288 for (i = 0; i < (int) CTI_MAX; ++i)
5289 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5290 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5292 convert_optab o;
5293 struct optab_handlers *h;
5295 o = &convert_optab_table[i];
5296 h = &o->handlers[j][k];
5297 if (h->libfunc)
5299 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5300 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5301 GET_RTX_NAME (o->code),
5302 GET_MODE_NAME (j),
5303 GET_MODE_NAME (k),
5304 XSTR (h->libfunc, 0));
5309 #endif /* DEBUG */
5312 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5313 CODE. Return 0 on failure. */
5316 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5317 rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
5319 enum machine_mode mode = GET_MODE (op1);
5320 enum insn_code icode;
5321 rtx insn;
5323 if (!HAVE_conditional_trap)
5324 return 0;
5326 if (mode == VOIDmode)
5327 return 0;
5329 icode = cmp_optab->handlers[(int) mode].insn_code;
5330 if (icode == CODE_FOR_nothing)
5331 return 0;
5333 start_sequence ();
5334 op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5335 op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
5336 if (!op1 || !op2)
5338 end_sequence ();
5339 return 0;
5341 emit_insn (GEN_FCN (icode) (op1, op2));
5343 PUT_CODE (trap_rtx, code);
5344 gcc_assert (HAVE_conditional_trap);
5345 insn = gen_conditional_trap (trap_rtx, tcode);
5346 if (insn)
5348 emit_insn (insn);
5349 insn = get_insns ();
5351 end_sequence ();
5353 return insn;
5356 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5357 or unsigned operation code. */
5359 static enum rtx_code
5360 get_rtx_code (enum tree_code tcode, bool unsignedp)
5362 enum rtx_code code;
5363 switch (tcode)
5365 case EQ_EXPR:
5366 code = EQ;
5367 break;
5368 case NE_EXPR:
5369 code = NE;
5370 break;
5371 case LT_EXPR:
5372 code = unsignedp ? LTU : LT;
5373 break;
5374 case LE_EXPR:
5375 code = unsignedp ? LEU : LE;
5376 break;
5377 case GT_EXPR:
5378 code = unsignedp ? GTU : GT;
5379 break;
5380 case GE_EXPR:
5381 code = unsignedp ? GEU : GE;
5382 break;
5384 case UNORDERED_EXPR:
5385 code = UNORDERED;
5386 break;
5387 case ORDERED_EXPR:
5388 code = ORDERED;
5389 break;
5390 case UNLT_EXPR:
5391 code = UNLT;
5392 break;
5393 case UNLE_EXPR:
5394 code = UNLE;
5395 break;
5396 case UNGT_EXPR:
5397 code = UNGT;
5398 break;
5399 case UNGE_EXPR:
5400 code = UNGE;
5401 break;
5402 case UNEQ_EXPR:
5403 code = UNEQ;
5404 break;
5405 case LTGT_EXPR:
5406 code = LTGT;
5407 break;
5409 default:
5410 gcc_unreachable ();
5412 return code;
5415 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5416 unsigned operators. Do not generate compare instruction. */
5418 static rtx
5419 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
5421 enum rtx_code rcode;
5422 tree t_op0, t_op1;
5423 rtx rtx_op0, rtx_op1;
5425 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
5426 ensures that condition is a relational operation. */
5427 gcc_assert (COMPARISON_CLASS_P (cond));
5429 rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
5430 t_op0 = TREE_OPERAND (cond, 0);
5431 t_op1 = TREE_OPERAND (cond, 1);
5433 /* Expand operands. */
5434 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)), 1);
5435 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)), 1);
5437 if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
5438 && GET_MODE (rtx_op0) != VOIDmode)
5439 rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
5441 if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
5442 && GET_MODE (rtx_op1) != VOIDmode)
5443 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5445 return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
5448 /* Return insn code for VEC_COND_EXPR EXPR. */
5450 static inline enum insn_code
5451 get_vcond_icode (tree expr, enum machine_mode mode)
5453 enum insn_code icode = CODE_FOR_nothing;
5455 if (TYPE_UNSIGNED (TREE_TYPE (expr)))
5456 icode = vcondu_gen_code[mode];
5457 else
5458 icode = vcond_gen_code[mode];
5459 return icode;
5462 /* Return TRUE iff, appropriate vector insns are available
5463 for vector cond expr expr in VMODE mode. */
5465 bool
5466 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
5468 if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
5469 return false;
5470 return true;
5473 /* Generate insns for VEC_COND_EXPR. */
5476 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
5478 enum insn_code icode;
5479 rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
5480 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
5481 bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
5483 icode = get_vcond_icode (vec_cond_expr, mode);
5484 if (icode == CODE_FOR_nothing)
5485 return 0;
5487 if (!target)
5488 target = gen_reg_rtx (mode);
5490 /* Get comparison rtx. First expand both cond expr operands. */
5491 comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
5492 unsignedp, icode);
5493 cc_op0 = XEXP (comparison, 0);
5494 cc_op1 = XEXP (comparison, 1);
5495 /* Expand both operands and force them in reg, if required. */
5496 rtx_op1 = expand_expr (TREE_OPERAND (vec_cond_expr, 1),
5497 NULL_RTX, VOIDmode, 1);
5498 if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
5499 && mode != VOIDmode)
5500 rtx_op1 = force_reg (mode, rtx_op1);
5502 rtx_op2 = expand_expr (TREE_OPERAND (vec_cond_expr, 2),
5503 NULL_RTX, VOIDmode, 1);
5504 if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
5505 && mode != VOIDmode)
5506 rtx_op2 = force_reg (mode, rtx_op2);
5508 /* Emit instruction! */
5509 emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
5510 comparison, cc_op0, cc_op1));
5512 return target;
5516 /* This is an internal subroutine of the other compare_and_swap expanders.
5517 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
5518 operation. TARGET is an optional place to store the value result of
5519 the operation. ICODE is the particular instruction to expand. Return
5520 the result of the operation. */
5522 static rtx
5523 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
5524 rtx target, enum insn_code icode)
5526 enum machine_mode mode = GET_MODE (mem);
5527 rtx insn;
5529 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5530 target = gen_reg_rtx (mode);
5532 if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
5533 old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
5534 if (!insn_data[icode].operand[2].predicate (old_val, mode))
5535 old_val = force_reg (mode, old_val);
5537 if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
5538 new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
5539 if (!insn_data[icode].operand[3].predicate (new_val, mode))
5540 new_val = force_reg (mode, new_val);
5542 insn = GEN_FCN (icode) (target, mem, old_val, new_val);
5543 if (insn == NULL_RTX)
5544 return NULL_RTX;
5545 emit_insn (insn);
5547 return target;
5550 /* Expand a compare-and-swap operation and return its value. */
5553 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5555 enum machine_mode mode = GET_MODE (mem);
5556 enum insn_code icode = sync_compare_and_swap[mode];
5558 if (icode == CODE_FOR_nothing)
5559 return NULL_RTX;
5561 return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
5564 /* Expand a compare-and-swap operation and store true into the result if
5565 the operation was successful and false otherwise. Return the result.
5566 Unlike other routines, TARGET is not optional. */
5569 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5571 enum machine_mode mode = GET_MODE (mem);
5572 enum insn_code icode;
5573 rtx subtarget, label0, label1;
5575 /* If the target supports a compare-and-swap pattern that simultaneously
5576 sets some flag for success, then use it. Otherwise use the regular
5577 compare-and-swap and follow that immediately with a compare insn. */
5578 icode = sync_compare_and_swap_cc[mode];
5579 switch (icode)
5581 default:
5582 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5583 NULL_RTX, icode);
5584 if (subtarget != NULL_RTX)
5585 break;
5587 /* FALLTHRU */
5588 case CODE_FOR_nothing:
5589 icode = sync_compare_and_swap[mode];
5590 if (icode == CODE_FOR_nothing)
5591 return NULL_RTX;
5593 /* Ensure that if old_val == mem, that we're not comparing
5594 against an old value. */
5595 if (MEM_P (old_val))
5596 old_val = force_reg (mode, old_val);
5598 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5599 NULL_RTX, icode);
5600 if (subtarget == NULL_RTX)
5601 return NULL_RTX;
5603 emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
5606 /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
5607 setcc instruction from the beginning. We don't work too hard here,
5608 but it's nice to not be stupid about initial code gen either. */
5609 if (STORE_FLAG_VALUE == 1)
5611 icode = setcc_gen_code[EQ];
5612 if (icode != CODE_FOR_nothing)
5614 enum machine_mode cmode = insn_data[icode].operand[0].mode;
5615 rtx insn;
5617 subtarget = target;
5618 if (!insn_data[icode].operand[0].predicate (target, cmode))
5619 subtarget = gen_reg_rtx (cmode);
5621 insn = GEN_FCN (icode) (subtarget);
5622 if (insn)
5624 emit_insn (insn);
5625 if (GET_MODE (target) != GET_MODE (subtarget))
5627 convert_move (target, subtarget, 1);
5628 subtarget = target;
5630 return subtarget;
5635 /* Without an appropriate setcc instruction, use a set of branches to
5636 get 1 and 0 stored into target. Presumably if the target has a
5637 STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt. */
5639 label0 = gen_label_rtx ();
5640 label1 = gen_label_rtx ();
5642 emit_jump_insn (bcc_gen_fctn[EQ] (label0));
5643 emit_move_insn (target, const0_rtx);
5644 emit_jump_insn (gen_jump (label1));
5645 emit_barrier ();
5646 emit_label (label0);
5647 emit_move_insn (target, const1_rtx);
5648 emit_label (label1);
5650 return target;
5653 /* This is a helper function for the other atomic operations. This function
5654 emits a loop that contains SEQ that iterates until a compare-and-swap
5655 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5656 a set of instructions that takes a value from OLD_REG as an input and
5657 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5658 set to the current contents of MEM. After SEQ, a compare-and-swap will
5659 attempt to update MEM with NEW_REG. The function returns true when the
5660 loop was generated successfully. */
5662 static bool
5663 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5665 enum machine_mode mode = GET_MODE (mem);
5666 enum insn_code icode;
5667 rtx label, cmp_reg, subtarget;
5669 /* The loop we want to generate looks like
5671 cmp_reg = mem;
5672 label:
5673 old_reg = cmp_reg;
5674 seq;
5675 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
5676 if (cmp_reg != old_reg)
5677 goto label;
5679 Note that we only do the plain load from memory once. Subsequent
5680 iterations use the value loaded by the compare-and-swap pattern. */
5682 label = gen_label_rtx ();
5683 cmp_reg = gen_reg_rtx (mode);
5685 emit_move_insn (cmp_reg, mem);
5686 emit_label (label);
5687 emit_move_insn (old_reg, cmp_reg);
5688 if (seq)
5689 emit_insn (seq);
5691 /* If the target supports a compare-and-swap pattern that simultaneously
5692 sets some flag for success, then use it. Otherwise use the regular
5693 compare-and-swap and follow that immediately with a compare insn. */
5694 icode = sync_compare_and_swap_cc[mode];
5695 switch (icode)
5697 default:
5698 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5699 cmp_reg, icode);
5700 if (subtarget != NULL_RTX)
5702 gcc_assert (subtarget == cmp_reg);
5703 break;
5706 /* FALLTHRU */
5707 case CODE_FOR_nothing:
5708 icode = sync_compare_and_swap[mode];
5709 if (icode == CODE_FOR_nothing)
5710 return false;
5712 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5713 cmp_reg, icode);
5714 if (subtarget == NULL_RTX)
5715 return false;
5716 if (subtarget != cmp_reg)
5717 emit_move_insn (cmp_reg, subtarget);
5719 emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
5722 /* ??? Mark this jump predicted not taken? */
5723 emit_jump_insn (bcc_gen_fctn[NE] (label));
5725 return true;
5728 /* This function generates the atomic operation MEM CODE= VAL. In this
5729 case, we do not care about any resulting value. Returns NULL if we
5730 cannot generate the operation. */
5733 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
5735 enum machine_mode mode = GET_MODE (mem);
5736 enum insn_code icode;
5737 rtx insn;
5739 /* Look to see if the target supports the operation directly. */
5740 switch (code)
5742 case PLUS:
5743 icode = sync_add_optab[mode];
5744 break;
5745 case IOR:
5746 icode = sync_ior_optab[mode];
5747 break;
5748 case XOR:
5749 icode = sync_xor_optab[mode];
5750 break;
5751 case AND:
5752 icode = sync_and_optab[mode];
5753 break;
5754 case NOT:
5755 icode = sync_nand_optab[mode];
5756 break;
5758 case MINUS:
5759 icode = sync_sub_optab[mode];
5760 if (icode == CODE_FOR_nothing)
5762 icode = sync_add_optab[mode];
5763 if (icode != CODE_FOR_nothing)
5765 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
5766 code = PLUS;
5769 break;
5771 default:
5772 gcc_unreachable ();
5775 /* Generate the direct operation, if present. */
5776 if (icode != CODE_FOR_nothing)
5778 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5779 val = convert_modes (mode, GET_MODE (val), val, 1);
5780 if (!insn_data[icode].operand[1].predicate (val, mode))
5781 val = force_reg (mode, val);
5783 insn = GEN_FCN (icode) (mem, val);
5784 if (insn)
5786 emit_insn (insn);
5787 return const0_rtx;
5791 /* Failing that, generate a compare-and-swap loop in which we perform the
5792 operation with normal arithmetic instructions. */
5793 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
5795 rtx t0 = gen_reg_rtx (mode), t1;
5797 start_sequence ();
5799 t1 = t0;
5800 if (code == NOT)
5802 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
5803 code = AND;
5805 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
5806 true, OPTAB_LIB_WIDEN);
5808 insn = get_insns ();
5809 end_sequence ();
5811 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
5812 return const0_rtx;
5815 return NULL_RTX;
5818 /* This function generates the atomic operation MEM CODE= VAL. In this
5819 case, we do care about the resulting value: if AFTER is true then
5820 return the value MEM holds after the operation, if AFTER is false
5821 then return the value MEM holds before the operation. TARGET is an
5822 optional place for the result value to be stored. */
5825 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
5826 bool after, rtx target)
5828 enum machine_mode mode = GET_MODE (mem);
5829 enum insn_code old_code, new_code, icode;
5830 bool compensate;
5831 rtx insn;
5833 /* Look to see if the target supports the operation directly. */
5834 switch (code)
5836 case PLUS:
5837 old_code = sync_old_add_optab[mode];
5838 new_code = sync_new_add_optab[mode];
5839 break;
5840 case IOR:
5841 old_code = sync_old_ior_optab[mode];
5842 new_code = sync_new_ior_optab[mode];
5843 break;
5844 case XOR:
5845 old_code = sync_old_xor_optab[mode];
5846 new_code = sync_new_xor_optab[mode];
5847 break;
5848 case AND:
5849 old_code = sync_old_and_optab[mode];
5850 new_code = sync_new_and_optab[mode];
5851 break;
5852 case NOT:
5853 old_code = sync_old_nand_optab[mode];
5854 new_code = sync_new_nand_optab[mode];
5855 break;
5857 case MINUS:
5858 old_code = sync_old_sub_optab[mode];
5859 new_code = sync_new_sub_optab[mode];
5860 if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
5862 old_code = sync_old_add_optab[mode];
5863 new_code = sync_new_add_optab[mode];
5864 if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
5866 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
5867 code = PLUS;
5870 break;
5872 default:
5873 gcc_unreachable ();
5876 /* If the target does supports the proper new/old operation, great. But
5877 if we only support the opposite old/new operation, check to see if we
5878 can compensate. In the case in which the old value is supported, then
5879 we can always perform the operation again with normal arithmetic. In
5880 the case in which the new value is supported, then we can only handle
5881 this in the case the operation is reversible. */
5882 compensate = false;
5883 if (after)
5885 icode = new_code;
5886 if (icode == CODE_FOR_nothing)
5888 icode = old_code;
5889 if (icode != CODE_FOR_nothing)
5890 compensate = true;
5893 else
5895 icode = old_code;
5896 if (icode == CODE_FOR_nothing
5897 && (code == PLUS || code == MINUS || code == XOR))
5899 icode = new_code;
5900 if (icode != CODE_FOR_nothing)
5901 compensate = true;
5905 /* If we found something supported, great. */
5906 if (icode != CODE_FOR_nothing)
5908 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5909 target = gen_reg_rtx (mode);
5911 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5912 val = convert_modes (mode, GET_MODE (val), val, 1);
5913 if (!insn_data[icode].operand[2].predicate (val, mode))
5914 val = force_reg (mode, val);
5916 insn = GEN_FCN (icode) (target, mem, val);
5917 if (insn)
5919 emit_insn (insn);
5921 /* If we need to compensate for using an operation with the
5922 wrong return value, do so now. */
5923 if (compensate)
5925 if (!after)
5927 if (code == PLUS)
5928 code = MINUS;
5929 else if (code == MINUS)
5930 code = PLUS;
5933 if (code == NOT)
5934 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
5935 target = expand_simple_binop (mode, code, target, val, NULL_RTX,
5936 true, OPTAB_LIB_WIDEN);
5939 return target;
5943 /* Failing that, generate a compare-and-swap loop in which we perform the
5944 operation with normal arithmetic instructions. */
5945 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
5947 rtx t0 = gen_reg_rtx (mode), t1;
5949 if (!target || !register_operand (target, mode))
5950 target = gen_reg_rtx (mode);
5952 start_sequence ();
5954 if (!after)
5955 emit_move_insn (target, t0);
5956 t1 = t0;
5957 if (code == NOT)
5959 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
5960 code = AND;
5962 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
5963 true, OPTAB_LIB_WIDEN);
5964 if (after)
5965 emit_move_insn (target, t1);
5967 insn = get_insns ();
5968 end_sequence ();
5970 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
5971 return target;
5974 return NULL_RTX;
5977 /* This function expands a test-and-set operation. Ideally we atomically
5978 store VAL in MEM and return the previous value in MEM. Some targets
5979 may not support this operation and only support VAL with the constant 1;
5980 in this case while the return value will be 0/1, but the exact value
5981 stored in MEM is target defined. TARGET is an option place to stick
5982 the return value. */
5985 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
5987 enum machine_mode mode = GET_MODE (mem);
5988 enum insn_code icode;
5989 rtx insn;
5991 /* If the target supports the test-and-set directly, great. */
5992 icode = sync_lock_test_and_set[mode];
5993 if (icode != CODE_FOR_nothing)
5995 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5996 target = gen_reg_rtx (mode);
5998 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5999 val = convert_modes (mode, GET_MODE (val), val, 1);
6000 if (!insn_data[icode].operand[2].predicate (val, mode))
6001 val = force_reg (mode, val);
6003 insn = GEN_FCN (icode) (target, mem, val);
6004 if (insn)
6006 emit_insn (insn);
6007 return target;
6011 /* Otherwise, use a compare-and-swap loop for the exchange. */
6012 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6014 if (!target || !register_operand (target, mode))
6015 target = gen_reg_rtx (mode);
6016 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6017 val = convert_modes (mode, GET_MODE (val), val, 1);
6018 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6019 return target;
6022 return NULL_RTX;
6025 #include "gt-optabs.h"