Fix asm string.
[official-gcc.git] / gcc / optabs.c
blob92887ab6b8dc221bca27e7c8bf6232015ec54979
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "toplev.h"
29 /* Include insn-config.h before expr.h so that HAVE_conditional_move
30 is properly defined. */
31 #include "insn-config.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "tm_p.h"
35 #include "flags.h"
36 #include "function.h"
37 #include "except.h"
38 #include "expr.h"
39 #include "optabs.h"
40 #include "libfuncs.h"
41 #include "recog.h"
42 #include "reload.h"
43 #include "ggc.h"
44 #include "real.h"
45 #include "basic-block.h"
46 #include "target.h"
48 /* Each optab contains info on how this target machine
49 can perform a particular operation
50 for all sizes and kinds of operands.
52 The operation to be performed is often specified
53 by passing one of these optabs as an argument.
55 See expr.h for documentation of these optabs. */
57 optab optab_table[OTI_MAX];
59 rtx libfunc_table[LTI_MAX];
61 /* Tables of patterns for converting one mode to another. */
62 convert_optab convert_optab_table[COI_MAX];
64 /* Contains the optab used for each rtx code. */
65 optab code_to_optab[NUM_RTX_CODE + 1];
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68 gives the gen_function to make a branch to test that condition. */
70 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73 gives the insn code to make a store-condition insn
74 to test that condition. */
76 enum insn_code setcc_gen_code[NUM_RTX_CODE];
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
81 setcc_gen_code to cut down on the number of named patterns. Consider a day
82 when a lot more rtx codes are conditional (eg: for the ARM). */
84 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
85 #endif
87 /* Indexed by the machine mode, gives the insn code for vector conditional
88 operation. */
90 enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
91 enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
93 /* The insn generating function can not take an rtx_code argument.
94 TRAP_RTX is used as an rtx argument. Its code is replaced with
95 the code to be used in the trap insn and all other fields are ignored. */
96 static GTY(()) rtx trap_rtx;
98 static int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx);
99 static rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int,
100 int);
101 static void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx,
102 enum machine_mode *, int *,
103 enum can_compare_purpose);
104 static enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
105 int *);
106 static enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
107 static optab new_optab (void);
108 static convert_optab new_convert_optab (void);
109 static inline optab init_optab (enum rtx_code);
110 static inline optab init_optabv (enum rtx_code);
111 static inline convert_optab init_convert_optab (enum rtx_code);
112 static void init_libfuncs (optab, int, int, const char *, int);
113 static void init_integral_libfuncs (optab, const char *, int);
114 static void init_floating_libfuncs (optab, const char *, int);
115 static void init_interclass_conv_libfuncs (convert_optab, const char *,
116 enum mode_class, enum mode_class);
117 static void init_intraclass_conv_libfuncs (convert_optab, const char *,
118 enum mode_class, bool);
119 static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
120 enum rtx_code, int, rtx);
121 static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
122 enum machine_mode *, int *);
123 static rtx widen_clz (enum machine_mode, rtx, rtx);
124 static rtx expand_parity (enum machine_mode, rtx, rtx);
125 static enum rtx_code get_rtx_code (enum tree_code, bool);
126 static rtx vector_compare_rtx (tree, bool, enum insn_code);
128 #ifndef HAVE_conditional_trap
129 #define HAVE_conditional_trap 0
130 #define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
131 #endif
133 /* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
134 the result of operation CODE applied to OP0 (and OP1 if it is a binary
135 operation).
137 If the last insn does not set TARGET, don't do anything, but return 1.
139 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
140 don't add the REG_EQUAL note but return 0. Our caller can then try
141 again, ensuring that TARGET is not one of the operands. */
143 static int
144 add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
146 rtx last_insn, insn, set;
147 rtx note;
149 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
151 if (GET_RTX_CLASS (code) != RTX_COMM_ARITH
152 && GET_RTX_CLASS (code) != RTX_BIN_ARITH
153 && GET_RTX_CLASS (code) != RTX_COMM_COMPARE
154 && GET_RTX_CLASS (code) != RTX_COMPARE
155 && GET_RTX_CLASS (code) != RTX_UNARY)
156 return 1;
158 if (GET_CODE (target) == ZERO_EXTRACT)
159 return 1;
161 for (last_insn = insns;
162 NEXT_INSN (last_insn) != NULL_RTX;
163 last_insn = NEXT_INSN (last_insn))
166 set = single_set (last_insn);
167 if (set == NULL_RTX)
168 return 1;
170 if (! rtx_equal_p (SET_DEST (set), target)
171 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
172 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
173 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
174 return 1;
176 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
177 besides the last insn. */
178 if (reg_overlap_mentioned_p (target, op0)
179 || (op1 && reg_overlap_mentioned_p (target, op1)))
181 insn = PREV_INSN (last_insn);
182 while (insn != NULL_RTX)
184 if (reg_set_p (target, insn))
185 return 0;
187 insn = PREV_INSN (insn);
191 if (GET_RTX_CLASS (code) == RTX_UNARY)
192 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
193 else
194 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
196 set_unique_reg_note (last_insn, REG_EQUAL, note);
198 return 1;
201 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
202 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
203 not actually do a sign-extend or zero-extend, but can leave the
204 higher-order bits of the result rtx undefined, for example, in the case
205 of logical operations, but not right shifts. */
207 static rtx
208 widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
209 int unsignedp, int no_extend)
211 rtx result;
213 /* If we don't have to extend and this is a constant, return it. */
214 if (no_extend && GET_MODE (op) == VOIDmode)
215 return op;
217 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
218 extend since it will be more efficient to do so unless the signedness of
219 a promoted object differs from our extension. */
220 if (! no_extend
221 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
222 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
223 return convert_modes (mode, oldmode, op, unsignedp);
225 /* If MODE is no wider than a single word, we return a paradoxical
226 SUBREG. */
227 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
228 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
230 /* Otherwise, get an object of MODE, clobber it, and set the low-order
231 part to OP. */
233 result = gen_reg_rtx (mode);
234 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
235 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
236 return result;
239 /* Return the optab used for computing the operation given by
240 the tree code, CODE. This function is not always usable (for
241 example, it cannot give complete results for multiplication
242 or division) but probably ought to be relied on more widely
243 throughout the expander. */
244 optab
245 optab_for_tree_code (enum tree_code code, tree type)
247 bool trapv;
248 switch (code)
250 case BIT_AND_EXPR:
251 return and_optab;
253 case BIT_IOR_EXPR:
254 return ior_optab;
256 case BIT_NOT_EXPR:
257 return one_cmpl_optab;
259 case BIT_XOR_EXPR:
260 return xor_optab;
262 case TRUNC_MOD_EXPR:
263 case CEIL_MOD_EXPR:
264 case FLOOR_MOD_EXPR:
265 case ROUND_MOD_EXPR:
266 return TYPE_UNSIGNED (type) ? umod_optab : smod_optab;
268 case RDIV_EXPR:
269 case TRUNC_DIV_EXPR:
270 case CEIL_DIV_EXPR:
271 case FLOOR_DIV_EXPR:
272 case ROUND_DIV_EXPR:
273 case EXACT_DIV_EXPR:
274 return TYPE_UNSIGNED (type) ? udiv_optab : sdiv_optab;
276 case LSHIFT_EXPR:
277 return ashl_optab;
279 case RSHIFT_EXPR:
280 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
282 case LROTATE_EXPR:
283 return rotl_optab;
285 case RROTATE_EXPR:
286 return rotr_optab;
288 case MAX_EXPR:
289 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
291 case MIN_EXPR:
292 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
294 case REALIGN_LOAD_EXPR:
295 return vec_realign_load_optab;
297 case WIDEN_SUM_EXPR:
298 return TYPE_UNSIGNED (type) ? usum_widen_optab : ssum_widen_optab;
300 case DOT_PROD_EXPR:
301 return TYPE_UNSIGNED (type) ? udot_prod_optab : sdot_prod_optab;
303 case REDUC_MAX_EXPR:
304 return TYPE_UNSIGNED (type) ? reduc_umax_optab : reduc_smax_optab;
306 case REDUC_MIN_EXPR:
307 return TYPE_UNSIGNED (type) ? reduc_umin_optab : reduc_smin_optab;
309 case REDUC_PLUS_EXPR:
310 return TYPE_UNSIGNED (type) ? reduc_uplus_optab : reduc_splus_optab;
312 case VEC_LSHIFT_EXPR:
313 return vec_shl_optab;
315 case VEC_RSHIFT_EXPR:
316 return vec_shr_optab;
318 default:
319 break;
322 trapv = flag_trapv && INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type);
323 switch (code)
325 case PLUS_EXPR:
326 return trapv ? addv_optab : add_optab;
328 case MINUS_EXPR:
329 return trapv ? subv_optab : sub_optab;
331 case MULT_EXPR:
332 return trapv ? smulv_optab : smul_optab;
334 case NEGATE_EXPR:
335 return trapv ? negv_optab : neg_optab;
337 case ABS_EXPR:
338 return trapv ? absv_optab : abs_optab;
340 default:
341 return NULL;
346 /* Expand vector widening operations.
348 There are two different classes of operations handled here:
349 1) Operations whose result is wider than all the arguments to the operation.
350 Examples: VEC_UNPACK_HI/LO_EXPR, VEC_WIDEN_MULT_HI/LO_EXPR
351 In this case OP0 and optionally OP1 would be initialized,
352 but WIDE_OP wouldn't (not relevant for this case).
353 2) Operations whose result is of the same size as the last argument to the
354 operation, but wider than all the other arguments to the operation.
355 Examples: WIDEN_SUM_EXPR, VEC_DOT_PROD_EXPR.
356 In the case WIDE_OP, OP0 and optionally OP1 would be initialized.
358 E.g, when called to expand the following operations, this is how
359 the arguments will be initialized:
360 nops OP0 OP1 WIDE_OP
361 widening-sum 2 oprnd0 - oprnd1
362 widening-dot-product 3 oprnd0 oprnd1 oprnd2
363 widening-mult 2 oprnd0 oprnd1 -
364 type-promotion (vec-unpack) 1 oprnd0 - - */
367 expand_widen_pattern_expr (tree exp, rtx op0, rtx op1, rtx wide_op, rtx target,
368 int unsignedp)
370 tree oprnd0, oprnd1, oprnd2;
371 enum machine_mode wmode = 0, tmode0, tmode1 = 0;
372 optab widen_pattern_optab;
373 int icode;
374 enum machine_mode xmode0, xmode1 = 0, wxmode = 0;
375 rtx temp;
376 rtx pat;
377 rtx xop0, xop1, wxop;
378 int nops = TREE_CODE_LENGTH (TREE_CODE (exp));
380 oprnd0 = TREE_OPERAND (exp, 0);
381 tmode0 = TYPE_MODE (TREE_TYPE (oprnd0));
382 widen_pattern_optab =
383 optab_for_tree_code (TREE_CODE (exp), TREE_TYPE (oprnd0));
384 icode = (int) widen_pattern_optab->handlers[(int) tmode0].insn_code;
385 gcc_assert (icode != CODE_FOR_nothing);
386 xmode0 = insn_data[icode].operand[1].mode;
388 if (nops >= 2)
390 oprnd1 = TREE_OPERAND (exp, 1);
391 tmode1 = TYPE_MODE (TREE_TYPE (oprnd1));
392 xmode1 = insn_data[icode].operand[2].mode;
395 /* The last operand is of a wider mode than the rest of the operands. */
396 if (nops == 2)
398 wmode = tmode1;
399 wxmode = xmode1;
401 else if (nops == 3)
403 gcc_assert (tmode1 == tmode0);
404 gcc_assert (op1);
405 oprnd2 = TREE_OPERAND (exp, 2);
406 wmode = TYPE_MODE (TREE_TYPE (oprnd2));
407 wxmode = insn_data[icode].operand[3].mode;
410 if (!wide_op)
411 wmode = wxmode = insn_data[icode].operand[0].mode;
413 if (!target
414 || ! (*insn_data[icode].operand[0].predicate) (target, wmode))
415 temp = gen_reg_rtx (wmode);
416 else
417 temp = target;
419 xop0 = op0;
420 xop1 = op1;
421 wxop = wide_op;
423 /* In case the insn wants input operands in modes different from
424 those of the actual operands, convert the operands. It would
425 seem that we don't need to convert CONST_INTs, but we do, so
426 that they're properly zero-extended, sign-extended or truncated
427 for their mode. */
429 if (GET_MODE (op0) != xmode0 && xmode0 != VOIDmode)
430 xop0 = convert_modes (xmode0,
431 GET_MODE (op0) != VOIDmode
432 ? GET_MODE (op0)
433 : tmode0,
434 xop0, unsignedp);
436 if (op1)
437 if (GET_MODE (op1) != xmode1 && xmode1 != VOIDmode)
438 xop1 = convert_modes (xmode1,
439 GET_MODE (op1) != VOIDmode
440 ? GET_MODE (op1)
441 : tmode1,
442 xop1, unsignedp);
444 if (wide_op)
445 if (GET_MODE (wide_op) != wxmode && wxmode != VOIDmode)
446 wxop = convert_modes (wxmode,
447 GET_MODE (wide_op) != VOIDmode
448 ? GET_MODE (wide_op)
449 : wmode,
450 wxop, unsignedp);
452 /* Now, if insn's predicates don't allow our operands, put them into
453 pseudo regs. */
455 if (! (*insn_data[icode].operand[1].predicate) (xop0, xmode0)
456 && xmode0 != VOIDmode)
457 xop0 = copy_to_mode_reg (xmode0, xop0);
459 if (op1)
461 if (! (*insn_data[icode].operand[2].predicate) (xop1, xmode1)
462 && xmode1 != VOIDmode)
463 xop1 = copy_to_mode_reg (xmode1, xop1);
465 if (wide_op)
467 if (! (*insn_data[icode].operand[3].predicate) (wxop, wxmode)
468 && wxmode != VOIDmode)
469 wxop = copy_to_mode_reg (wxmode, wxop);
471 pat = GEN_FCN (icode) (temp, xop0, xop1, wxop);
473 else
474 pat = GEN_FCN (icode) (temp, xop0, xop1);
476 else
478 if (wide_op)
480 if (! (*insn_data[icode].operand[2].predicate) (wxop, wxmode)
481 && wxmode != VOIDmode)
482 wxop = copy_to_mode_reg (wxmode, wxop);
484 pat = GEN_FCN (icode) (temp, xop0, wxop);
486 else
487 pat = GEN_FCN (icode) (temp, xop0);
490 emit_insn (pat);
491 return temp;
494 /* Generate code to perform an operation specified by TERNARY_OPTAB
495 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
497 UNSIGNEDP is for the case where we have to widen the operands
498 to perform the operation. It says to use zero-extension.
500 If TARGET is nonzero, the value
501 is generated there, if it is convenient to do so.
502 In all cases an rtx is returned for the locus of the value;
503 this may or may not be TARGET. */
506 expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
507 rtx op1, rtx op2, rtx target, int unsignedp)
509 int icode = (int) ternary_optab->handlers[(int) mode].insn_code;
510 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
511 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
512 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
513 rtx temp;
514 rtx pat;
515 rtx xop0 = op0, xop1 = op1, xop2 = op2;
517 gcc_assert (ternary_optab->handlers[(int) mode].insn_code
518 != CODE_FOR_nothing);
520 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
521 temp = gen_reg_rtx (mode);
522 else
523 temp = target;
525 /* In case the insn wants input operands in modes different from
526 those of the actual operands, convert the operands. It would
527 seem that we don't need to convert CONST_INTs, but we do, so
528 that they're properly zero-extended, sign-extended or truncated
529 for their mode. */
531 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
532 xop0 = convert_modes (mode0,
533 GET_MODE (op0) != VOIDmode
534 ? GET_MODE (op0)
535 : mode,
536 xop0, unsignedp);
538 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
539 xop1 = convert_modes (mode1,
540 GET_MODE (op1) != VOIDmode
541 ? GET_MODE (op1)
542 : mode,
543 xop1, unsignedp);
545 if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
546 xop2 = convert_modes (mode2,
547 GET_MODE (op2) != VOIDmode
548 ? GET_MODE (op2)
549 : mode,
550 xop2, unsignedp);
552 /* Now, if insn's predicates don't allow our operands, put them into
553 pseudo regs. */
555 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
556 && mode0 != VOIDmode)
557 xop0 = copy_to_mode_reg (mode0, xop0);
559 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
560 && mode1 != VOIDmode)
561 xop1 = copy_to_mode_reg (mode1, xop1);
563 if (!insn_data[icode].operand[3].predicate (xop2, mode2)
564 && mode2 != VOIDmode)
565 xop2 = copy_to_mode_reg (mode2, xop2);
567 pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
569 emit_insn (pat);
570 return temp;
574 /* Like expand_binop, but return a constant rtx if the result can be
575 calculated at compile time. The arguments and return value are
576 otherwise the same as for expand_binop. */
578 static rtx
579 simplify_expand_binop (enum machine_mode mode, optab binoptab,
580 rtx op0, rtx op1, rtx target, int unsignedp,
581 enum optab_methods methods)
583 if (CONSTANT_P (op0) && CONSTANT_P (op1))
585 rtx x = simplify_binary_operation (binoptab->code, mode, op0, op1);
587 if (x)
588 return x;
591 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
594 /* Like simplify_expand_binop, but always put the result in TARGET.
595 Return true if the expansion succeeded. */
597 bool
598 force_expand_binop (enum machine_mode mode, optab binoptab,
599 rtx op0, rtx op1, rtx target, int unsignedp,
600 enum optab_methods methods)
602 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
603 target, unsignedp, methods);
604 if (x == 0)
605 return false;
606 if (x != target)
607 emit_move_insn (target, x);
608 return true;
611 /* Generate insns for VEC_LSHIFT_EXPR, VEC_RSHIFT_EXPR. */
614 expand_vec_shift_expr (tree vec_shift_expr, rtx target)
616 enum insn_code icode;
617 rtx rtx_op1, rtx_op2;
618 enum machine_mode mode1;
619 enum machine_mode mode2;
620 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_shift_expr));
621 tree vec_oprnd = TREE_OPERAND (vec_shift_expr, 0);
622 tree shift_oprnd = TREE_OPERAND (vec_shift_expr, 1);
623 optab shift_optab;
624 rtx pat;
626 switch (TREE_CODE (vec_shift_expr))
628 case VEC_RSHIFT_EXPR:
629 shift_optab = vec_shr_optab;
630 break;
631 case VEC_LSHIFT_EXPR:
632 shift_optab = vec_shl_optab;
633 break;
634 default:
635 gcc_unreachable ();
638 icode = (int) shift_optab->handlers[(int) mode].insn_code;
639 gcc_assert (icode != CODE_FOR_nothing);
641 mode1 = insn_data[icode].operand[1].mode;
642 mode2 = insn_data[icode].operand[2].mode;
644 rtx_op1 = expand_expr (vec_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
645 if (!(*insn_data[icode].operand[1].predicate) (rtx_op1, mode1)
646 && mode1 != VOIDmode)
647 rtx_op1 = force_reg (mode1, rtx_op1);
649 rtx_op2 = expand_expr (shift_oprnd, NULL_RTX, VOIDmode, EXPAND_NORMAL);
650 if (!(*insn_data[icode].operand[2].predicate) (rtx_op2, mode2)
651 && mode2 != VOIDmode)
652 rtx_op2 = force_reg (mode2, rtx_op2);
654 if (!target
655 || ! (*insn_data[icode].operand[0].predicate) (target, mode))
656 target = gen_reg_rtx (mode);
658 /* Emit instruction */
659 pat = GEN_FCN (icode) (target, rtx_op1, rtx_op2);
660 gcc_assert (pat);
661 emit_insn (pat);
663 return target;
666 /* This subroutine of expand_doubleword_shift handles the cases in which
667 the effective shift value is >= BITS_PER_WORD. The arguments and return
668 value are the same as for the parent routine, except that SUPERWORD_OP1
669 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
670 INTO_TARGET may be null if the caller has decided to calculate it. */
672 static bool
673 expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
674 rtx outof_target, rtx into_target,
675 int unsignedp, enum optab_methods methods)
677 if (into_target != 0)
678 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
679 into_target, unsignedp, methods))
680 return false;
682 if (outof_target != 0)
684 /* For a signed right shift, we must fill OUTOF_TARGET with copies
685 of the sign bit, otherwise we must fill it with zeros. */
686 if (binoptab != ashr_optab)
687 emit_move_insn (outof_target, CONST0_RTX (word_mode));
688 else
689 if (!force_expand_binop (word_mode, binoptab,
690 outof_input, GEN_INT (BITS_PER_WORD - 1),
691 outof_target, unsignedp, methods))
692 return false;
694 return true;
697 /* This subroutine of expand_doubleword_shift handles the cases in which
698 the effective shift value is < BITS_PER_WORD. The arguments and return
699 value are the same as for the parent routine. */
701 static bool
702 expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
703 rtx outof_input, rtx into_input, rtx op1,
704 rtx outof_target, rtx into_target,
705 int unsignedp, enum optab_methods methods,
706 unsigned HOST_WIDE_INT shift_mask)
708 optab reverse_unsigned_shift, unsigned_shift;
709 rtx tmp, carries;
711 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
712 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
714 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
715 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
716 the opposite direction to BINOPTAB. */
717 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
719 carries = outof_input;
720 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
721 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
722 0, true, methods);
724 else
726 /* We must avoid shifting by BITS_PER_WORD bits since that is either
727 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
728 has unknown behavior. Do a single shift first, then shift by the
729 remainder. It's OK to use ~OP1 as the remainder if shift counts
730 are truncated to the mode size. */
731 carries = expand_binop (word_mode, reverse_unsigned_shift,
732 outof_input, const1_rtx, 0, unsignedp, methods);
733 if (shift_mask == BITS_PER_WORD - 1)
735 tmp = immed_double_const (-1, -1, op1_mode);
736 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
737 0, true, methods);
739 else
741 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
742 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
743 0, true, methods);
746 if (tmp == 0 || carries == 0)
747 return false;
748 carries = expand_binop (word_mode, reverse_unsigned_shift,
749 carries, tmp, 0, unsignedp, methods);
750 if (carries == 0)
751 return false;
753 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
754 so the result can go directly into INTO_TARGET if convenient. */
755 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
756 into_target, unsignedp, methods);
757 if (tmp == 0)
758 return false;
760 /* Now OR in the bits carried over from OUTOF_INPUT. */
761 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
762 into_target, unsignedp, methods))
763 return false;
765 /* Use a standard word_mode shift for the out-of half. */
766 if (outof_target != 0)
767 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
768 outof_target, unsignedp, methods))
769 return false;
771 return true;
775 #ifdef HAVE_conditional_move
776 /* Try implementing expand_doubleword_shift using conditional moves.
777 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
778 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
779 are the shift counts to use in the former and latter case. All other
780 arguments are the same as the parent routine. */
782 static bool
783 expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
784 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
785 rtx outof_input, rtx into_input,
786 rtx subword_op1, rtx superword_op1,
787 rtx outof_target, rtx into_target,
788 int unsignedp, enum optab_methods methods,
789 unsigned HOST_WIDE_INT shift_mask)
791 rtx outof_superword, into_superword;
793 /* Put the superword version of the output into OUTOF_SUPERWORD and
794 INTO_SUPERWORD. */
795 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
796 if (outof_target != 0 && subword_op1 == superword_op1)
798 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
799 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
800 into_superword = outof_target;
801 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
802 outof_superword, 0, unsignedp, methods))
803 return false;
805 else
807 into_superword = gen_reg_rtx (word_mode);
808 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
809 outof_superword, into_superword,
810 unsignedp, methods))
811 return false;
814 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
815 if (!expand_subword_shift (op1_mode, binoptab,
816 outof_input, into_input, subword_op1,
817 outof_target, into_target,
818 unsignedp, methods, shift_mask))
819 return false;
821 /* Select between them. Do the INTO half first because INTO_SUPERWORD
822 might be the current value of OUTOF_TARGET. */
823 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
824 into_target, into_superword, word_mode, false))
825 return false;
827 if (outof_target != 0)
828 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
829 outof_target, outof_superword,
830 word_mode, false))
831 return false;
833 return true;
835 #endif
837 /* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
838 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
839 input operand; the shift moves bits in the direction OUTOF_INPUT->
840 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
841 of the target. OP1 is the shift count and OP1_MODE is its mode.
842 If OP1 is constant, it will have been truncated as appropriate
843 and is known to be nonzero.
845 If SHIFT_MASK is zero, the result of word shifts is undefined when the
846 shift count is outside the range [0, BITS_PER_WORD). This routine must
847 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
849 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
850 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
851 fill with zeros or sign bits as appropriate.
853 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
854 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
855 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
856 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
857 are undefined.
859 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
860 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
861 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
862 function wants to calculate it itself.
864 Return true if the shift could be successfully synthesized. */
866 static bool
867 expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
868 rtx outof_input, rtx into_input, rtx op1,
869 rtx outof_target, rtx into_target,
870 int unsignedp, enum optab_methods methods,
871 unsigned HOST_WIDE_INT shift_mask)
873 rtx superword_op1, tmp, cmp1, cmp2;
874 rtx subword_label, done_label;
875 enum rtx_code cmp_code;
877 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
878 fill the result with sign or zero bits as appropriate. If so, the value
879 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
880 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
881 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
883 This isn't worthwhile for constant shifts since the optimizers will
884 cope better with in-range shift counts. */
885 if (shift_mask >= BITS_PER_WORD
886 && outof_target != 0
887 && !CONSTANT_P (op1))
889 if (!expand_doubleword_shift (op1_mode, binoptab,
890 outof_input, into_input, op1,
891 0, into_target,
892 unsignedp, methods, shift_mask))
893 return false;
894 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
895 outof_target, unsignedp, methods))
896 return false;
897 return true;
900 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
901 is true when the effective shift value is less than BITS_PER_WORD.
902 Set SUPERWORD_OP1 to the shift count that should be used to shift
903 OUTOF_INPUT into INTO_TARGET when the condition is false. */
904 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
905 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
907 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
908 is a subword shift count. */
909 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
910 0, true, methods);
911 cmp2 = CONST0_RTX (op1_mode);
912 cmp_code = EQ;
913 superword_op1 = op1;
915 else
917 /* Set CMP1 to OP1 - BITS_PER_WORD. */
918 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
919 0, true, methods);
920 cmp2 = CONST0_RTX (op1_mode);
921 cmp_code = LT;
922 superword_op1 = cmp1;
924 if (cmp1 == 0)
925 return false;
927 /* If we can compute the condition at compile time, pick the
928 appropriate subroutine. */
929 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
930 if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
932 if (tmp == const0_rtx)
933 return expand_superword_shift (binoptab, outof_input, superword_op1,
934 outof_target, into_target,
935 unsignedp, methods);
936 else
937 return expand_subword_shift (op1_mode, binoptab,
938 outof_input, into_input, op1,
939 outof_target, into_target,
940 unsignedp, methods, shift_mask);
943 #ifdef HAVE_conditional_move
944 /* Try using conditional moves to generate straight-line code. */
946 rtx start = get_last_insn ();
947 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
948 cmp_code, cmp1, cmp2,
949 outof_input, into_input,
950 op1, superword_op1,
951 outof_target, into_target,
952 unsignedp, methods, shift_mask))
953 return true;
954 delete_insns_since (start);
956 #endif
958 /* As a last resort, use branches to select the correct alternative. */
959 subword_label = gen_label_rtx ();
960 done_label = gen_label_rtx ();
962 NO_DEFER_POP;
963 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
964 0, 0, subword_label);
965 OK_DEFER_POP;
967 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
968 outof_target, into_target,
969 unsignedp, methods))
970 return false;
972 emit_jump_insn (gen_jump (done_label));
973 emit_barrier ();
974 emit_label (subword_label);
976 if (!expand_subword_shift (op1_mode, binoptab,
977 outof_input, into_input, op1,
978 outof_target, into_target,
979 unsignedp, methods, shift_mask))
980 return false;
982 emit_label (done_label);
983 return true;
986 /* Subroutine of expand_binop. Perform a double word multiplication of
987 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
988 as the target's word_mode. This function return NULL_RTX if anything
989 goes wrong, in which case it may have already emitted instructions
990 which need to be deleted.
992 If we want to multiply two two-word values and have normal and widening
993 multiplies of single-word values, we can do this with three smaller
994 multiplications. Note that we do not make a REG_NO_CONFLICT block here
995 because we are not operating on one word at a time.
997 The multiplication proceeds as follows:
998 _______________________
999 [__op0_high_|__op0_low__]
1000 _______________________
1001 * [__op1_high_|__op1_low__]
1002 _______________________________________________
1003 _______________________
1004 (1) [__op0_low__*__op1_low__]
1005 _______________________
1006 (2a) [__op0_low__*__op1_high_]
1007 _______________________
1008 (2b) [__op0_high_*__op1_low__]
1009 _______________________
1010 (3) [__op0_high_*__op1_high_]
1013 This gives a 4-word result. Since we are only interested in the
1014 lower 2 words, partial result (3) and the upper words of (2a) and
1015 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1016 calculated using non-widening multiplication.
1018 (1), however, needs to be calculated with an unsigned widening
1019 multiplication. If this operation is not directly supported we
1020 try using a signed widening multiplication and adjust the result.
1021 This adjustment works as follows:
1023 If both operands are positive then no adjustment is needed.
1025 If the operands have different signs, for example op0_low < 0 and
1026 op1_low >= 0, the instruction treats the most significant bit of
1027 op0_low as a sign bit instead of a bit with significance
1028 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1029 with 2**BITS_PER_WORD - op0_low, and two's complements the
1030 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1031 the result.
1033 Similarly, if both operands are negative, we need to add
1034 (op0_low + op1_low) * 2**BITS_PER_WORD.
1036 We use a trick to adjust quickly. We logically shift op0_low right
1037 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1038 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1039 logical shift exists, we do an arithmetic right shift and subtract
1040 the 0 or -1. */
1042 static rtx
1043 expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
1044 bool umulp, enum optab_methods methods)
1046 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1047 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1048 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
1049 rtx product, adjust, product_high, temp;
1051 rtx op0_high = operand_subword_force (op0, high, mode);
1052 rtx op0_low = operand_subword_force (op0, low, mode);
1053 rtx op1_high = operand_subword_force (op1, high, mode);
1054 rtx op1_low = operand_subword_force (op1, low, mode);
1056 /* If we're using an unsigned multiply to directly compute the product
1057 of the low-order words of the operands and perform any required
1058 adjustments of the operands, we begin by trying two more multiplications
1059 and then computing the appropriate sum.
1061 We have checked above that the required addition is provided.
1062 Full-word addition will normally always succeed, especially if
1063 it is provided at all, so we don't worry about its failure. The
1064 multiplication may well fail, however, so we do handle that. */
1066 if (!umulp)
1068 /* ??? This could be done with emit_store_flag where available. */
1069 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1070 NULL_RTX, 1, methods);
1071 if (temp)
1072 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
1073 NULL_RTX, 0, OPTAB_DIRECT);
1074 else
1076 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1077 NULL_RTX, 0, methods);
1078 if (!temp)
1079 return NULL_RTX;
1080 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
1081 NULL_RTX, 0, OPTAB_DIRECT);
1084 if (!op0_high)
1085 return NULL_RTX;
1088 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
1089 NULL_RTX, 0, OPTAB_DIRECT);
1090 if (!adjust)
1091 return NULL_RTX;
1093 /* OP0_HIGH should now be dead. */
1095 if (!umulp)
1097 /* ??? This could be done with emit_store_flag where available. */
1098 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1099 NULL_RTX, 1, methods);
1100 if (temp)
1101 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
1102 NULL_RTX, 0, OPTAB_DIRECT);
1103 else
1105 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1106 NULL_RTX, 0, methods);
1107 if (!temp)
1108 return NULL_RTX;
1109 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
1110 NULL_RTX, 0, OPTAB_DIRECT);
1113 if (!op1_high)
1114 return NULL_RTX;
1117 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
1118 NULL_RTX, 0, OPTAB_DIRECT);
1119 if (!temp)
1120 return NULL_RTX;
1122 /* OP1_HIGH should now be dead. */
1124 adjust = expand_binop (word_mode, add_optab, adjust, temp,
1125 adjust, 0, OPTAB_DIRECT);
1127 if (target && !REG_P (target))
1128 target = NULL_RTX;
1130 if (umulp)
1131 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1132 target, 1, OPTAB_DIRECT);
1133 else
1134 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1135 target, 1, OPTAB_DIRECT);
1137 if (!product)
1138 return NULL_RTX;
1140 product_high = operand_subword (product, high, 1, mode);
1141 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
1142 REG_P (product_high) ? product_high : adjust,
1143 0, OPTAB_DIRECT);
1144 emit_move_insn (product_high, adjust);
1145 return product;
1148 /* Wrapper around expand_binop which takes an rtx code to specify
1149 the operation to perform, not an optab pointer. All other
1150 arguments are the same. */
1152 expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
1153 rtx op1, rtx target, int unsignedp,
1154 enum optab_methods methods)
1156 optab binop = code_to_optab[(int) code];
1157 gcc_assert (binop);
1159 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
1162 /* Return whether OP0 and OP1 should be swapped when expanding a commutative
1163 binop. Order them according to commutative_operand_precedence and, if
1164 possible, try to put TARGET or a pseudo first. */
1165 static bool
1166 swap_commutative_operands_with_target (rtx target, rtx op0, rtx op1)
1168 int op0_prec = commutative_operand_precedence (op0);
1169 int op1_prec = commutative_operand_precedence (op1);
1171 if (op0_prec < op1_prec)
1172 return true;
1174 if (op0_prec > op1_prec)
1175 return false;
1177 /* With equal precedence, both orders are ok, but it is better if the
1178 first operand is TARGET, or if both TARGET and OP0 are pseudos. */
1179 if (target == 0 || REG_P (target))
1180 return (REG_P (op1) && !REG_P (op0)) || target == op1;
1181 else
1182 return rtx_equal_p (op1, target);
1186 /* Generate code to perform an operation specified by BINOPTAB
1187 on operands OP0 and OP1, with result having machine-mode MODE.
1189 UNSIGNEDP is for the case where we have to widen the operands
1190 to perform the operation. It says to use zero-extension.
1192 If TARGET is nonzero, the value
1193 is generated there, if it is convenient to do so.
1194 In all cases an rtx is returned for the locus of the value;
1195 this may or may not be TARGET. */
1198 expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
1199 rtx target, int unsignedp, enum optab_methods methods)
1201 enum optab_methods next_methods
1202 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
1203 ? OPTAB_WIDEN : methods);
1204 enum mode_class class;
1205 enum machine_mode wider_mode;
1206 rtx temp;
1207 int commutative_op = 0;
1208 int shift_op = (binoptab->code == ASHIFT
1209 || binoptab->code == ASHIFTRT
1210 || binoptab->code == LSHIFTRT
1211 || binoptab->code == ROTATE
1212 || binoptab->code == ROTATERT);
1213 rtx entry_last = get_last_insn ();
1214 rtx last;
1215 bool first_pass_p = true;
1217 class = GET_MODE_CLASS (mode);
1219 /* If subtracting an integer constant, convert this into an addition of
1220 the negated constant. */
1222 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
1224 op1 = negate_rtx (mode, op1);
1225 binoptab = add_optab;
1228 /* If we are inside an appropriately-short loop and we are optimizing,
1229 force expensive constants into a register. */
1230 if (CONSTANT_P (op0) && optimize
1231 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1233 if (GET_MODE (op0) != VOIDmode)
1234 op0 = convert_modes (mode, VOIDmode, op0, unsignedp);
1235 op0 = force_reg (mode, op0);
1238 if (CONSTANT_P (op1) && optimize
1239 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1241 if (GET_MODE (op1) != VOIDmode)
1242 op1 = convert_modes (mode, VOIDmode, op1, unsignedp);
1243 op1 = force_reg (mode, op1);
1246 /* Record where to delete back to if we backtrack. */
1247 last = get_last_insn ();
1249 /* If operation is commutative,
1250 try to make the first operand a register.
1251 Even better, try to make it the same as the target.
1252 Also try to make the last operand a constant. */
1253 if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
1254 || binoptab == smul_widen_optab
1255 || binoptab == umul_widen_optab
1256 || binoptab == smul_highpart_optab
1257 || binoptab == umul_highpart_optab)
1259 commutative_op = 1;
1261 if (swap_commutative_operands_with_target (target, op0, op1))
1263 temp = op1;
1264 op1 = op0;
1265 op0 = temp;
1269 retry:
1271 /* If we can do it with a three-operand insn, do so. */
1273 if (methods != OPTAB_MUST_WIDEN
1274 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1276 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1277 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1278 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1279 rtx pat;
1280 rtx xop0 = op0, xop1 = op1;
1282 if (target)
1283 temp = target;
1284 else
1285 temp = gen_reg_rtx (mode);
1287 /* If it is a commutative operator and the modes would match
1288 if we would swap the operands, we can save the conversions. */
1289 if (commutative_op)
1291 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
1292 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
1294 rtx tmp;
1296 tmp = op0; op0 = op1; op1 = tmp;
1297 tmp = xop0; xop0 = xop1; xop1 = tmp;
1301 /* In case the insn wants input operands in modes different from
1302 those of the actual operands, convert the operands. It would
1303 seem that we don't need to convert CONST_INTs, but we do, so
1304 that they're properly zero-extended, sign-extended or truncated
1305 for their mode. */
1307 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
1308 xop0 = convert_modes (mode0,
1309 GET_MODE (op0) != VOIDmode
1310 ? GET_MODE (op0)
1311 : mode,
1312 xop0, unsignedp);
1314 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
1315 xop1 = convert_modes (mode1,
1316 GET_MODE (op1) != VOIDmode
1317 ? GET_MODE (op1)
1318 : mode,
1319 xop1, unsignedp);
1321 /* Now, if insn's predicates don't allow our operands, put them into
1322 pseudo regs. */
1324 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
1325 && mode0 != VOIDmode)
1326 xop0 = copy_to_mode_reg (mode0, xop0);
1328 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
1329 && mode1 != VOIDmode)
1330 xop1 = copy_to_mode_reg (mode1, xop1);
1332 if (!insn_data[icode].operand[0].predicate (temp, mode))
1333 temp = gen_reg_rtx (mode);
1335 pat = GEN_FCN (icode) (temp, xop0, xop1);
1336 if (pat)
1338 /* If PAT is composed of more than one insn, try to add an appropriate
1339 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1340 operand, call ourselves again, this time without a target. */
1341 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
1342 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1344 delete_insns_since (last);
1345 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1346 unsignedp, methods);
1349 emit_insn (pat);
1350 return temp;
1352 else
1353 delete_insns_since (last);
1356 /* If we were trying to rotate by a constant value, and that didn't
1357 work, try rotating the other direction before falling back to
1358 shifts and bitwise-or. */
1359 if (first_pass_p
1360 && (binoptab == rotl_optab || binoptab == rotr_optab)
1361 && class == MODE_INT
1362 && GET_CODE (op1) == CONST_INT
1363 && INTVAL (op1) > 0
1364 && (unsigned int) INTVAL (op1) < GET_MODE_BITSIZE (mode))
1366 first_pass_p = false;
1367 op1 = GEN_INT (GET_MODE_BITSIZE (mode) - INTVAL (op1));
1368 binoptab = binoptab == rotl_optab ? rotr_optab : rotl_optab;
1369 goto retry;
1372 /* If this is a multiply, see if we can do a widening operation that
1373 takes operands of this mode and makes a wider mode. */
1375 if (binoptab == smul_optab
1376 && GET_MODE_WIDER_MODE (mode) != VOIDmode
1377 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1378 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
1379 != CODE_FOR_nothing))
1381 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1382 unsignedp ? umul_widen_optab : smul_widen_optab,
1383 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
1385 if (temp != 0)
1387 if (GET_MODE_CLASS (mode) == MODE_INT
1388 && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1389 GET_MODE_BITSIZE (GET_MODE (temp))))
1390 return gen_lowpart (mode, temp);
1391 else
1392 return convert_to_mode (mode, temp, unsignedp);
1396 /* Look for a wider mode of the same class for which we think we
1397 can open-code the operation. Check for a widening multiply at the
1398 wider mode as well. */
1400 if (CLASS_HAS_WIDER_MODES_P (class)
1401 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
1402 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1403 wider_mode != VOIDmode;
1404 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1406 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
1407 || (binoptab == smul_optab
1408 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1409 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1410 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
1411 != CODE_FOR_nothing)))
1413 rtx xop0 = op0, xop1 = op1;
1414 int no_extend = 0;
1416 /* For certain integer operations, we need not actually extend
1417 the narrow operands, as long as we will truncate
1418 the results to the same narrowness. */
1420 if ((binoptab == ior_optab || binoptab == and_optab
1421 || binoptab == xor_optab
1422 || binoptab == add_optab || binoptab == sub_optab
1423 || binoptab == smul_optab || binoptab == ashl_optab)
1424 && class == MODE_INT)
1425 no_extend = 1;
1427 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
1429 /* The second operand of a shift must always be extended. */
1430 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1431 no_extend && binoptab != ashl_optab);
1433 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1434 unsignedp, OPTAB_DIRECT);
1435 if (temp)
1437 if (class != MODE_INT
1438 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1439 GET_MODE_BITSIZE (wider_mode)))
1441 if (target == 0)
1442 target = gen_reg_rtx (mode);
1443 convert_move (target, temp, 0);
1444 return target;
1446 else
1447 return gen_lowpart (mode, temp);
1449 else
1450 delete_insns_since (last);
1454 /* These can be done a word at a time. */
1455 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1456 && class == MODE_INT
1457 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1458 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1460 int i;
1461 rtx insns;
1462 rtx equiv_value;
1464 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1465 won't be accurate, so use a new target. */
1466 if (target == 0 || target == op0 || target == op1)
1467 target = gen_reg_rtx (mode);
1469 start_sequence ();
1471 /* Do the actual arithmetic. */
1472 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1474 rtx target_piece = operand_subword (target, i, 1, mode);
1475 rtx x = expand_binop (word_mode, binoptab,
1476 operand_subword_force (op0, i, mode),
1477 operand_subword_force (op1, i, mode),
1478 target_piece, unsignedp, next_methods);
1480 if (x == 0)
1481 break;
1483 if (target_piece != x)
1484 emit_move_insn (target_piece, x);
1487 insns = get_insns ();
1488 end_sequence ();
1490 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1492 if (binoptab->code != UNKNOWN)
1493 equiv_value
1494 = gen_rtx_fmt_ee (binoptab->code, mode,
1495 copy_rtx (op0), copy_rtx (op1));
1496 else
1497 equiv_value = 0;
1499 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1500 return target;
1504 /* Synthesize double word shifts from single word shifts. */
1505 if ((binoptab == lshr_optab || binoptab == ashl_optab
1506 || binoptab == ashr_optab)
1507 && class == MODE_INT
1508 && (GET_CODE (op1) == CONST_INT || !optimize_size)
1509 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1510 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1511 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1512 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1514 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1515 enum machine_mode op1_mode;
1517 double_shift_mask = targetm.shift_truncation_mask (mode);
1518 shift_mask = targetm.shift_truncation_mask (word_mode);
1519 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
1521 /* Apply the truncation to constant shifts. */
1522 if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1523 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
1525 if (op1 == CONST0_RTX (op1_mode))
1526 return op0;
1528 /* Make sure that this is a combination that expand_doubleword_shift
1529 can handle. See the comments there for details. */
1530 if (double_shift_mask == 0
1531 || (shift_mask == BITS_PER_WORD - 1
1532 && double_shift_mask == BITS_PER_WORD * 2 - 1))
1534 rtx insns, equiv_value;
1535 rtx into_target, outof_target;
1536 rtx into_input, outof_input;
1537 int left_shift, outof_word;
1539 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1540 won't be accurate, so use a new target. */
1541 if (target == 0 || target == op0 || target == op1)
1542 target = gen_reg_rtx (mode);
1544 start_sequence ();
1546 /* OUTOF_* is the word we are shifting bits away from, and
1547 INTO_* is the word that we are shifting bits towards, thus
1548 they differ depending on the direction of the shift and
1549 WORDS_BIG_ENDIAN. */
1551 left_shift = binoptab == ashl_optab;
1552 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1554 outof_target = operand_subword (target, outof_word, 1, mode);
1555 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1557 outof_input = operand_subword_force (op0, outof_word, mode);
1558 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1560 if (expand_doubleword_shift (op1_mode, binoptab,
1561 outof_input, into_input, op1,
1562 outof_target, into_target,
1563 unsignedp, next_methods, shift_mask))
1565 insns = get_insns ();
1566 end_sequence ();
1568 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1569 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1570 return target;
1572 end_sequence ();
1576 /* Synthesize double word rotates from single word shifts. */
1577 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1578 && class == MODE_INT
1579 && GET_CODE (op1) == CONST_INT
1580 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1581 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1582 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1584 rtx insns;
1585 rtx into_target, outof_target;
1586 rtx into_input, outof_input;
1587 rtx inter;
1588 int shift_count, left_shift, outof_word;
1590 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1591 won't be accurate, so use a new target. Do this also if target is not
1592 a REG, first because having a register instead may open optimization
1593 opportunities, and second because if target and op0 happen to be MEMs
1594 designating the same location, we would risk clobbering it too early
1595 in the code sequence we generate below. */
1596 if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
1597 target = gen_reg_rtx (mode);
1599 start_sequence ();
1601 shift_count = INTVAL (op1);
1603 /* OUTOF_* is the word we are shifting bits away from, and
1604 INTO_* is the word that we are shifting bits towards, thus
1605 they differ depending on the direction of the shift and
1606 WORDS_BIG_ENDIAN. */
1608 left_shift = (binoptab == rotl_optab);
1609 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1611 outof_target = operand_subword (target, outof_word, 1, mode);
1612 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1614 outof_input = operand_subword_force (op0, outof_word, mode);
1615 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1617 if (shift_count == BITS_PER_WORD)
1619 /* This is just a word swap. */
1620 emit_move_insn (outof_target, into_input);
1621 emit_move_insn (into_target, outof_input);
1622 inter = const0_rtx;
1624 else
1626 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1627 rtx first_shift_count, second_shift_count;
1628 optab reverse_unsigned_shift, unsigned_shift;
1630 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1631 ? lshr_optab : ashl_optab);
1633 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1634 ? ashl_optab : lshr_optab);
1636 if (shift_count > BITS_PER_WORD)
1638 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1639 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
1641 else
1643 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1644 second_shift_count = GEN_INT (shift_count);
1647 into_temp1 = expand_binop (word_mode, unsigned_shift,
1648 outof_input, first_shift_count,
1649 NULL_RTX, unsignedp, next_methods);
1650 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1651 into_input, second_shift_count,
1652 NULL_RTX, unsignedp, next_methods);
1654 if (into_temp1 != 0 && into_temp2 != 0)
1655 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1656 into_target, unsignedp, next_methods);
1657 else
1658 inter = 0;
1660 if (inter != 0 && inter != into_target)
1661 emit_move_insn (into_target, inter);
1663 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1664 into_input, first_shift_count,
1665 NULL_RTX, unsignedp, next_methods);
1666 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1667 outof_input, second_shift_count,
1668 NULL_RTX, unsignedp, next_methods);
1670 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1671 inter = expand_binop (word_mode, ior_optab,
1672 outof_temp1, outof_temp2,
1673 outof_target, unsignedp, next_methods);
1675 if (inter != 0 && inter != outof_target)
1676 emit_move_insn (outof_target, inter);
1679 insns = get_insns ();
1680 end_sequence ();
1682 if (inter != 0)
1684 /* One may be tempted to wrap the insns in a REG_NO_CONFLICT
1685 block to help the register allocator a bit. But a multi-word
1686 rotate will need all the input bits when setting the output
1687 bits, so there clearly is a conflict between the input and
1688 output registers. So we can't use a no-conflict block here. */
1689 emit_insn (insns);
1690 return target;
1694 /* These can be done a word at a time by propagating carries. */
1695 if ((binoptab == add_optab || binoptab == sub_optab)
1696 && class == MODE_INT
1697 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1698 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1700 unsigned int i;
1701 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1702 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1703 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1704 rtx xop0, xop1, xtarget;
1706 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1707 value is one of those, use it. Otherwise, use 1 since it is the
1708 one easiest to get. */
1709 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1710 int normalizep = STORE_FLAG_VALUE;
1711 #else
1712 int normalizep = 1;
1713 #endif
1715 /* Prepare the operands. */
1716 xop0 = force_reg (mode, op0);
1717 xop1 = force_reg (mode, op1);
1719 xtarget = gen_reg_rtx (mode);
1721 if (target == 0 || !REG_P (target))
1722 target = xtarget;
1724 /* Indicate for flow that the entire target reg is being set. */
1725 if (REG_P (target))
1726 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
1728 /* Do the actual arithmetic. */
1729 for (i = 0; i < nwords; i++)
1731 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1732 rtx target_piece = operand_subword (xtarget, index, 1, mode);
1733 rtx op0_piece = operand_subword_force (xop0, index, mode);
1734 rtx op1_piece = operand_subword_force (xop1, index, mode);
1735 rtx x;
1737 /* Main add/subtract of the input operands. */
1738 x = expand_binop (word_mode, binoptab,
1739 op0_piece, op1_piece,
1740 target_piece, unsignedp, next_methods);
1741 if (x == 0)
1742 break;
1744 if (i + 1 < nwords)
1746 /* Store carry from main add/subtract. */
1747 carry_out = gen_reg_rtx (word_mode);
1748 carry_out = emit_store_flag_force (carry_out,
1749 (binoptab == add_optab
1750 ? LT : GT),
1751 x, op0_piece,
1752 word_mode, 1, normalizep);
1755 if (i > 0)
1757 rtx newx;
1759 /* Add/subtract previous carry to main result. */
1760 newx = expand_binop (word_mode,
1761 normalizep == 1 ? binoptab : otheroptab,
1762 x, carry_in,
1763 NULL_RTX, 1, next_methods);
1765 if (i + 1 < nwords)
1767 /* Get out carry from adding/subtracting carry in. */
1768 rtx carry_tmp = gen_reg_rtx (word_mode);
1769 carry_tmp = emit_store_flag_force (carry_tmp,
1770 (binoptab == add_optab
1771 ? LT : GT),
1772 newx, x,
1773 word_mode, 1, normalizep);
1775 /* Logical-ior the two poss. carry together. */
1776 carry_out = expand_binop (word_mode, ior_optab,
1777 carry_out, carry_tmp,
1778 carry_out, 0, next_methods);
1779 if (carry_out == 0)
1780 break;
1782 emit_move_insn (target_piece, newx);
1784 else
1786 if (x != target_piece)
1787 emit_move_insn (target_piece, x);
1790 carry_in = carry_out;
1793 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
1795 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
1796 || ! rtx_equal_p (target, xtarget))
1798 rtx temp = emit_move_insn (target, xtarget);
1800 set_unique_reg_note (temp,
1801 REG_EQUAL,
1802 gen_rtx_fmt_ee (binoptab->code, mode,
1803 copy_rtx (xop0),
1804 copy_rtx (xop1)));
1806 else
1807 target = xtarget;
1809 return target;
1812 else
1813 delete_insns_since (last);
1816 /* Attempt to synthesize double word multiplies using a sequence of word
1817 mode multiplications. We first attempt to generate a sequence using a
1818 more efficient unsigned widening multiply, and if that fails we then
1819 try using a signed widening multiply. */
1821 if (binoptab == smul_optab
1822 && class == MODE_INT
1823 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1824 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1825 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1827 rtx product = NULL_RTX;
1829 if (umul_widen_optab->handlers[(int) mode].insn_code
1830 != CODE_FOR_nothing)
1832 product = expand_doubleword_mult (mode, op0, op1, target,
1833 true, methods);
1834 if (!product)
1835 delete_insns_since (last);
1838 if (product == NULL_RTX
1839 && smul_widen_optab->handlers[(int) mode].insn_code
1840 != CODE_FOR_nothing)
1842 product = expand_doubleword_mult (mode, op0, op1, target,
1843 false, methods);
1844 if (!product)
1845 delete_insns_since (last);
1848 if (product != NULL_RTX)
1850 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1852 temp = emit_move_insn (target ? target : product, product);
1853 set_unique_reg_note (temp,
1854 REG_EQUAL,
1855 gen_rtx_fmt_ee (MULT, mode,
1856 copy_rtx (op0),
1857 copy_rtx (op1)));
1859 return product;
1863 /* It can't be open-coded in this mode.
1864 Use a library call if one is available and caller says that's ok. */
1866 if (binoptab->handlers[(int) mode].libfunc
1867 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1869 rtx insns;
1870 rtx op1x = op1;
1871 enum machine_mode op1_mode = mode;
1872 rtx value;
1874 start_sequence ();
1876 if (shift_op)
1878 op1_mode = word_mode;
1879 /* Specify unsigned here,
1880 since negative shift counts are meaningless. */
1881 op1x = convert_to_mode (word_mode, op1, 1);
1884 if (GET_MODE (op0) != VOIDmode
1885 && GET_MODE (op0) != mode)
1886 op0 = convert_to_mode (mode, op0, unsignedp);
1888 /* Pass 1 for NO_QUEUE so we don't lose any increments
1889 if the libcall is cse'd or moved. */
1890 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1891 NULL_RTX, LCT_CONST, mode, 2,
1892 op0, mode, op1x, op1_mode);
1894 insns = get_insns ();
1895 end_sequence ();
1897 target = gen_reg_rtx (mode);
1898 emit_libcall_block (insns, target, value,
1899 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1901 return target;
1904 delete_insns_since (last);
1906 /* It can't be done in this mode. Can we do it in a wider mode? */
1908 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1909 || methods == OPTAB_MUST_WIDEN))
1911 /* Caller says, don't even try. */
1912 delete_insns_since (entry_last);
1913 return 0;
1916 /* Compute the value of METHODS to pass to recursive calls.
1917 Don't allow widening to be tried recursively. */
1919 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1921 /* Look for a wider mode of the same class for which it appears we can do
1922 the operation. */
1924 if (CLASS_HAS_WIDER_MODES_P (class))
1926 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1927 wider_mode != VOIDmode;
1928 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1930 if ((binoptab->handlers[(int) wider_mode].insn_code
1931 != CODE_FOR_nothing)
1932 || (methods == OPTAB_LIB
1933 && binoptab->handlers[(int) wider_mode].libfunc))
1935 rtx xop0 = op0, xop1 = op1;
1936 int no_extend = 0;
1938 /* For certain integer operations, we need not actually extend
1939 the narrow operands, as long as we will truncate
1940 the results to the same narrowness. */
1942 if ((binoptab == ior_optab || binoptab == and_optab
1943 || binoptab == xor_optab
1944 || binoptab == add_optab || binoptab == sub_optab
1945 || binoptab == smul_optab || binoptab == ashl_optab)
1946 && class == MODE_INT)
1947 no_extend = 1;
1949 xop0 = widen_operand (xop0, wider_mode, mode,
1950 unsignedp, no_extend);
1952 /* The second operand of a shift must always be extended. */
1953 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1954 no_extend && binoptab != ashl_optab);
1956 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1957 unsignedp, methods);
1958 if (temp)
1960 if (class != MODE_INT
1961 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
1962 GET_MODE_BITSIZE (wider_mode)))
1964 if (target == 0)
1965 target = gen_reg_rtx (mode);
1966 convert_move (target, temp, 0);
1967 return target;
1969 else
1970 return gen_lowpart (mode, temp);
1972 else
1973 delete_insns_since (last);
1978 delete_insns_since (entry_last);
1979 return 0;
1982 /* Expand a binary operator which has both signed and unsigned forms.
1983 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1984 signed operations.
1986 If we widen unsigned operands, we may use a signed wider operation instead
1987 of an unsigned wider operation, since the result would be the same. */
1990 sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
1991 rtx op0, rtx op1, rtx target, int unsignedp,
1992 enum optab_methods methods)
1994 rtx temp;
1995 optab direct_optab = unsignedp ? uoptab : soptab;
1996 struct optab wide_soptab;
1998 /* Do it without widening, if possible. */
1999 temp = expand_binop (mode, direct_optab, op0, op1, target,
2000 unsignedp, OPTAB_DIRECT);
2001 if (temp || methods == OPTAB_DIRECT)
2002 return temp;
2004 /* Try widening to a signed int. Make a fake signed optab that
2005 hides any signed insn for direct use. */
2006 wide_soptab = *soptab;
2007 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
2008 wide_soptab.handlers[(int) mode].libfunc = 0;
2010 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2011 unsignedp, OPTAB_WIDEN);
2013 /* For unsigned operands, try widening to an unsigned int. */
2014 if (temp == 0 && unsignedp)
2015 temp = expand_binop (mode, uoptab, op0, op1, target,
2016 unsignedp, OPTAB_WIDEN);
2017 if (temp || methods == OPTAB_WIDEN)
2018 return temp;
2020 /* Use the right width lib call if that exists. */
2021 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
2022 if (temp || methods == OPTAB_LIB)
2023 return temp;
2025 /* Must widen and use a lib call, use either signed or unsigned. */
2026 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
2027 unsignedp, methods);
2028 if (temp != 0)
2029 return temp;
2030 if (unsignedp)
2031 return expand_binop (mode, uoptab, op0, op1, target,
2032 unsignedp, methods);
2033 return 0;
2036 /* Generate code to perform an operation specified by UNOPPTAB
2037 on operand OP0, with two results to TARG0 and TARG1.
2038 We assume that the order of the operands for the instruction
2039 is TARG0, TARG1, OP0.
2041 Either TARG0 or TARG1 may be zero, but what that means is that
2042 the result is not actually wanted. We will generate it into
2043 a dummy pseudo-reg and discard it. They may not both be zero.
2045 Returns 1 if this operation can be performed; 0 if not. */
2048 expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
2049 int unsignedp)
2051 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2052 enum mode_class class;
2053 enum machine_mode wider_mode;
2054 rtx entry_last = get_last_insn ();
2055 rtx last;
2057 class = GET_MODE_CLASS (mode);
2059 if (!targ0)
2060 targ0 = gen_reg_rtx (mode);
2061 if (!targ1)
2062 targ1 = gen_reg_rtx (mode);
2064 /* Record where to go back to if we fail. */
2065 last = get_last_insn ();
2067 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2069 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2070 enum machine_mode mode0 = insn_data[icode].operand[2].mode;
2071 rtx pat;
2072 rtx xop0 = op0;
2074 if (GET_MODE (xop0) != VOIDmode
2075 && GET_MODE (xop0) != mode0)
2076 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2078 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2079 if (!insn_data[icode].operand[2].predicate (xop0, mode0))
2080 xop0 = copy_to_mode_reg (mode0, xop0);
2082 /* We could handle this, but we should always be called with a pseudo
2083 for our targets and all insns should take them as outputs. */
2084 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2085 gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
2087 pat = GEN_FCN (icode) (targ0, targ1, xop0);
2088 if (pat)
2090 emit_insn (pat);
2091 return 1;
2093 else
2094 delete_insns_since (last);
2097 /* It can't be done in this mode. Can we do it in a wider mode? */
2099 if (CLASS_HAS_WIDER_MODES_P (class))
2101 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2102 wider_mode != VOIDmode;
2103 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2105 if (unoptab->handlers[(int) wider_mode].insn_code
2106 != CODE_FOR_nothing)
2108 rtx t0 = gen_reg_rtx (wider_mode);
2109 rtx t1 = gen_reg_rtx (wider_mode);
2110 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2112 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
2114 convert_move (targ0, t0, unsignedp);
2115 convert_move (targ1, t1, unsignedp);
2116 return 1;
2118 else
2119 delete_insns_since (last);
2124 delete_insns_since (entry_last);
2125 return 0;
2128 /* Generate code to perform an operation specified by BINOPTAB
2129 on operands OP0 and OP1, with two results to TARG1 and TARG2.
2130 We assume that the order of the operands for the instruction
2131 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
2132 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
2134 Either TARG0 or TARG1 may be zero, but what that means is that
2135 the result is not actually wanted. We will generate it into
2136 a dummy pseudo-reg and discard it. They may not both be zero.
2138 Returns 1 if this operation can be performed; 0 if not. */
2141 expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
2142 int unsignedp)
2144 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
2145 enum mode_class class;
2146 enum machine_mode wider_mode;
2147 rtx entry_last = get_last_insn ();
2148 rtx last;
2150 class = GET_MODE_CLASS (mode);
2152 /* If we are inside an appropriately-short loop and we are optimizing,
2153 force expensive constants into a register. */
2154 if (CONSTANT_P (op0) && optimize
2155 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
2156 op0 = force_reg (mode, op0);
2158 if (CONSTANT_P (op1) && optimize
2159 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
2160 op1 = force_reg (mode, op1);
2162 if (!targ0)
2163 targ0 = gen_reg_rtx (mode);
2164 if (!targ1)
2165 targ1 = gen_reg_rtx (mode);
2167 /* Record where to go back to if we fail. */
2168 last = get_last_insn ();
2170 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2172 int icode = (int) binoptab->handlers[(int) mode].insn_code;
2173 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2174 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
2175 rtx pat;
2176 rtx xop0 = op0, xop1 = op1;
2178 /* In case the insn wants input operands in modes different from
2179 those of the actual operands, convert the operands. It would
2180 seem that we don't need to convert CONST_INTs, but we do, so
2181 that they're properly zero-extended, sign-extended or truncated
2182 for their mode. */
2184 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
2185 xop0 = convert_modes (mode0,
2186 GET_MODE (op0) != VOIDmode
2187 ? GET_MODE (op0)
2188 : mode,
2189 xop0, unsignedp);
2191 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
2192 xop1 = convert_modes (mode1,
2193 GET_MODE (op1) != VOIDmode
2194 ? GET_MODE (op1)
2195 : mode,
2196 xop1, unsignedp);
2198 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2199 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2200 xop0 = copy_to_mode_reg (mode0, xop0);
2202 if (!insn_data[icode].operand[2].predicate (xop1, mode1))
2203 xop1 = copy_to_mode_reg (mode1, xop1);
2205 /* We could handle this, but we should always be called with a pseudo
2206 for our targets and all insns should take them as outputs. */
2207 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
2208 gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
2210 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2211 if (pat)
2213 emit_insn (pat);
2214 return 1;
2216 else
2217 delete_insns_since (last);
2220 /* It can't be done in this mode. Can we do it in a wider mode? */
2222 if (CLASS_HAS_WIDER_MODES_P (class))
2224 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2225 wider_mode != VOIDmode;
2226 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2228 if (binoptab->handlers[(int) wider_mode].insn_code
2229 != CODE_FOR_nothing)
2231 rtx t0 = gen_reg_rtx (wider_mode);
2232 rtx t1 = gen_reg_rtx (wider_mode);
2233 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2234 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2236 if (expand_twoval_binop (binoptab, cop0, cop1,
2237 t0, t1, unsignedp))
2239 convert_move (targ0, t0, unsignedp);
2240 convert_move (targ1, t1, unsignedp);
2241 return 1;
2243 else
2244 delete_insns_since (last);
2249 delete_insns_since (entry_last);
2250 return 0;
2253 /* Expand the two-valued library call indicated by BINOPTAB, but
2254 preserve only one of the values. If TARG0 is non-NULL, the first
2255 value is placed into TARG0; otherwise the second value is placed
2256 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2257 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2258 This routine assumes that the value returned by the library call is
2259 as if the return value was of an integral mode twice as wide as the
2260 mode of OP0. Returns 1 if the call was successful. */
2262 bool
2263 expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
2264 rtx targ0, rtx targ1, enum rtx_code code)
2266 enum machine_mode mode;
2267 enum machine_mode libval_mode;
2268 rtx libval;
2269 rtx insns;
2271 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
2272 gcc_assert (!targ0 != !targ1);
2274 mode = GET_MODE (op0);
2275 if (!binoptab->handlers[(int) mode].libfunc)
2276 return false;
2278 /* The value returned by the library function will have twice as
2279 many bits as the nominal MODE. */
2280 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
2281 MODE_INT);
2282 start_sequence ();
2283 libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
2284 NULL_RTX, LCT_CONST,
2285 libval_mode, 2,
2286 op0, mode,
2287 op1, mode);
2288 /* Get the part of VAL containing the value that we want. */
2289 libval = simplify_gen_subreg (mode, libval, libval_mode,
2290 targ0 ? 0 : GET_MODE_SIZE (mode));
2291 insns = get_insns ();
2292 end_sequence ();
2293 /* Move the into the desired location. */
2294 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
2295 gen_rtx_fmt_ee (code, mode, op0, op1));
2297 return true;
2301 /* Wrapper around expand_unop which takes an rtx code to specify
2302 the operation to perform, not an optab pointer. All other
2303 arguments are the same. */
2305 expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2306 rtx target, int unsignedp)
2308 optab unop = code_to_optab[(int) code];
2309 gcc_assert (unop);
2311 return expand_unop (mode, unop, op0, target, unsignedp);
2314 /* Try calculating
2315 (clz:narrow x)
2317 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2318 static rtx
2319 widen_clz (enum machine_mode mode, rtx op0, rtx target)
2321 enum mode_class class = GET_MODE_CLASS (mode);
2322 if (CLASS_HAS_WIDER_MODES_P (class))
2324 enum machine_mode wider_mode;
2325 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2326 wider_mode != VOIDmode;
2327 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2329 if (clz_optab->handlers[(int) wider_mode].insn_code
2330 != CODE_FOR_nothing)
2332 rtx xop0, temp, last;
2334 last = get_last_insn ();
2336 if (target == 0)
2337 target = gen_reg_rtx (mode);
2338 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2339 temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2340 if (temp != 0)
2341 temp = expand_binop (wider_mode, sub_optab, temp,
2342 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2343 - GET_MODE_BITSIZE (mode)),
2344 target, true, OPTAB_DIRECT);
2345 if (temp == 0)
2346 delete_insns_since (last);
2348 return temp;
2352 return 0;
2355 /* Try calculating (parity x) as (and (popcount x) 1), where
2356 popcount can also be done in a wider mode. */
2357 static rtx
2358 expand_parity (enum machine_mode mode, rtx op0, rtx target)
2360 enum mode_class class = GET_MODE_CLASS (mode);
2361 if (CLASS_HAS_WIDER_MODES_P (class))
2363 enum machine_mode wider_mode;
2364 for (wider_mode = mode; wider_mode != VOIDmode;
2365 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2367 if (popcount_optab->handlers[(int) wider_mode].insn_code
2368 != CODE_FOR_nothing)
2370 rtx xop0, temp, last;
2372 last = get_last_insn ();
2374 if (target == 0)
2375 target = gen_reg_rtx (mode);
2376 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2377 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2378 true);
2379 if (temp != 0)
2380 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2381 target, true, OPTAB_DIRECT);
2382 if (temp == 0)
2383 delete_insns_since (last);
2385 return temp;
2389 return 0;
2392 /* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2393 conditions, VAL may already be a SUBREG against which we cannot generate
2394 a further SUBREG. In this case, we expect forcing the value into a
2395 register will work around the situation. */
2397 static rtx
2398 lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2399 enum machine_mode imode)
2401 rtx ret;
2402 ret = lowpart_subreg (omode, val, imode);
2403 if (ret == NULL)
2405 val = force_reg (imode, val);
2406 ret = lowpart_subreg (omode, val, imode);
2407 gcc_assert (ret != NULL);
2409 return ret;
2412 /* Expand a floating point absolute value or negation operation via a
2413 logical operation on the sign bit. */
2415 static rtx
2416 expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2417 rtx op0, rtx target)
2419 const struct real_format *fmt;
2420 int bitpos, word, nwords, i;
2421 enum machine_mode imode;
2422 HOST_WIDE_INT hi, lo;
2423 rtx temp, insns;
2425 /* The format has to have a simple sign bit. */
2426 fmt = REAL_MODE_FORMAT (mode);
2427 if (fmt == NULL)
2428 return NULL_RTX;
2430 bitpos = fmt->signbit_rw;
2431 if (bitpos < 0)
2432 return NULL_RTX;
2434 /* Don't create negative zeros if the format doesn't support them. */
2435 if (code == NEG && !fmt->has_signed_zero)
2436 return NULL_RTX;
2438 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2440 imode = int_mode_for_mode (mode);
2441 if (imode == BLKmode)
2442 return NULL_RTX;
2443 word = 0;
2444 nwords = 1;
2446 else
2448 imode = word_mode;
2450 if (FLOAT_WORDS_BIG_ENDIAN)
2451 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2452 else
2453 word = bitpos / BITS_PER_WORD;
2454 bitpos = bitpos % BITS_PER_WORD;
2455 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2458 if (bitpos < HOST_BITS_PER_WIDE_INT)
2460 hi = 0;
2461 lo = (HOST_WIDE_INT) 1 << bitpos;
2463 else
2465 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2466 lo = 0;
2468 if (code == ABS)
2469 lo = ~lo, hi = ~hi;
2471 if (target == 0 || target == op0)
2472 target = gen_reg_rtx (mode);
2474 if (nwords > 1)
2476 start_sequence ();
2478 for (i = 0; i < nwords; ++i)
2480 rtx targ_piece = operand_subword (target, i, 1, mode);
2481 rtx op0_piece = operand_subword_force (op0, i, mode);
2483 if (i == word)
2485 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2486 op0_piece,
2487 immed_double_const (lo, hi, imode),
2488 targ_piece, 1, OPTAB_LIB_WIDEN);
2489 if (temp != targ_piece)
2490 emit_move_insn (targ_piece, temp);
2492 else
2493 emit_move_insn (targ_piece, op0_piece);
2496 insns = get_insns ();
2497 end_sequence ();
2499 temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2500 emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2502 else
2504 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2505 gen_lowpart (imode, op0),
2506 immed_double_const (lo, hi, imode),
2507 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2508 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2510 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2511 gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2514 return target;
2517 /* Generate code to perform an operation specified by UNOPTAB
2518 on operand OP0, with result having machine-mode MODE.
2520 UNSIGNEDP is for the case where we have to widen the operands
2521 to perform the operation. It says to use zero-extension.
2523 If TARGET is nonzero, the value
2524 is generated there, if it is convenient to do so.
2525 In all cases an rtx is returned for the locus of the value;
2526 this may or may not be TARGET. */
2529 expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2530 int unsignedp)
2532 enum mode_class class;
2533 enum machine_mode wider_mode;
2534 rtx temp;
2535 rtx last = get_last_insn ();
2536 rtx pat;
2538 class = GET_MODE_CLASS (mode);
2540 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2542 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2543 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2544 rtx xop0 = op0;
2546 if (target)
2547 temp = target;
2548 else
2549 temp = gen_reg_rtx (mode);
2551 if (GET_MODE (xop0) != VOIDmode
2552 && GET_MODE (xop0) != mode0)
2553 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2555 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2557 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
2558 xop0 = copy_to_mode_reg (mode0, xop0);
2560 if (!insn_data[icode].operand[0].predicate (temp, mode))
2561 temp = gen_reg_rtx (mode);
2563 pat = GEN_FCN (icode) (temp, xop0);
2564 if (pat)
2566 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
2567 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2569 delete_insns_since (last);
2570 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2573 emit_insn (pat);
2575 return temp;
2577 else
2578 delete_insns_since (last);
2581 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2583 /* Widening clz needs special treatment. */
2584 if (unoptab == clz_optab)
2586 temp = widen_clz (mode, op0, target);
2587 if (temp)
2588 return temp;
2589 else
2590 goto try_libcall;
2593 /* We can't widen a bswap. */
2594 if (unoptab == bswap_optab)
2595 goto try_libcall;
2597 if (CLASS_HAS_WIDER_MODES_P (class))
2598 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2599 wider_mode != VOIDmode;
2600 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2602 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2604 rtx xop0 = op0;
2606 /* For certain operations, we need not actually extend
2607 the narrow operand, as long as we will truncate the
2608 results to the same narrowness. */
2610 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2611 (unoptab == neg_optab
2612 || unoptab == one_cmpl_optab)
2613 && class == MODE_INT);
2615 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2616 unsignedp);
2618 if (temp)
2620 if (class != MODE_INT
2621 || !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
2622 GET_MODE_BITSIZE (wider_mode)))
2624 if (target == 0)
2625 target = gen_reg_rtx (mode);
2626 convert_move (target, temp, 0);
2627 return target;
2629 else
2630 return gen_lowpart (mode, temp);
2632 else
2633 delete_insns_since (last);
2637 /* These can be done a word at a time. */
2638 if (unoptab == one_cmpl_optab
2639 && class == MODE_INT
2640 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2641 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2643 int i;
2644 rtx insns;
2646 if (target == 0 || target == op0)
2647 target = gen_reg_rtx (mode);
2649 start_sequence ();
2651 /* Do the actual arithmetic. */
2652 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2654 rtx target_piece = operand_subword (target, i, 1, mode);
2655 rtx x = expand_unop (word_mode, unoptab,
2656 operand_subword_force (op0, i, mode),
2657 target_piece, unsignedp);
2659 if (target_piece != x)
2660 emit_move_insn (target_piece, x);
2663 insns = get_insns ();
2664 end_sequence ();
2666 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2667 gen_rtx_fmt_e (unoptab->code, mode,
2668 copy_rtx (op0)));
2669 return target;
2672 if (unoptab->code == NEG)
2674 /* Try negating floating point values by flipping the sign bit. */
2675 if (SCALAR_FLOAT_MODE_P (mode))
2677 temp = expand_absneg_bit (NEG, mode, op0, target);
2678 if (temp)
2679 return temp;
2682 /* If there is no negation pattern, and we have no negative zero,
2683 try subtracting from zero. */
2684 if (!HONOR_SIGNED_ZEROS (mode))
2686 temp = expand_binop (mode, (unoptab == negv_optab
2687 ? subv_optab : sub_optab),
2688 CONST0_RTX (mode), op0, target,
2689 unsignedp, OPTAB_DIRECT);
2690 if (temp)
2691 return temp;
2695 /* Try calculating parity (x) as popcount (x) % 2. */
2696 if (unoptab == parity_optab)
2698 temp = expand_parity (mode, op0, target);
2699 if (temp)
2700 return temp;
2703 try_libcall:
2704 /* Now try a library call in this mode. */
2705 if (unoptab->handlers[(int) mode].libfunc)
2707 rtx insns;
2708 rtx value;
2709 enum machine_mode outmode = mode;
2711 /* All of these functions return small values. Thus we choose to
2712 have them return something that isn't a double-word. */
2713 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2714 || unoptab == popcount_optab || unoptab == parity_optab)
2715 outmode
2716 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
2718 start_sequence ();
2720 /* Pass 1 for NO_QUEUE so we don't lose any increments
2721 if the libcall is cse'd or moved. */
2722 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2723 NULL_RTX, LCT_CONST, outmode,
2724 1, op0, mode);
2725 insns = get_insns ();
2726 end_sequence ();
2728 target = gen_reg_rtx (outmode);
2729 emit_libcall_block (insns, target, value,
2730 gen_rtx_fmt_e (unoptab->code, outmode, op0));
2732 return target;
2735 /* It can't be done in this mode. Can we do it in a wider mode? */
2737 if (CLASS_HAS_WIDER_MODES_P (class))
2739 for (wider_mode = GET_MODE_WIDER_MODE (mode);
2740 wider_mode != VOIDmode;
2741 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2743 if ((unoptab->handlers[(int) wider_mode].insn_code
2744 != CODE_FOR_nothing)
2745 || unoptab->handlers[(int) wider_mode].libfunc)
2747 rtx xop0 = op0;
2749 /* For certain operations, we need not actually extend
2750 the narrow operand, as long as we will truncate the
2751 results to the same narrowness. */
2753 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2754 (unoptab == neg_optab
2755 || unoptab == one_cmpl_optab)
2756 && class == MODE_INT);
2758 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2759 unsignedp);
2761 /* If we are generating clz using wider mode, adjust the
2762 result. */
2763 if (unoptab == clz_optab && temp != 0)
2764 temp = expand_binop (wider_mode, sub_optab, temp,
2765 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2766 - GET_MODE_BITSIZE (mode)),
2767 target, true, OPTAB_DIRECT);
2769 if (temp)
2771 if (class != MODE_INT)
2773 if (target == 0)
2774 target = gen_reg_rtx (mode);
2775 convert_move (target, temp, 0);
2776 return target;
2778 else
2779 return gen_lowpart (mode, temp);
2781 else
2782 delete_insns_since (last);
2787 /* One final attempt at implementing negation via subtraction,
2788 this time allowing widening of the operand. */
2789 if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
2791 rtx temp;
2792 temp = expand_binop (mode,
2793 unoptab == negv_optab ? subv_optab : sub_optab,
2794 CONST0_RTX (mode), op0,
2795 target, unsignedp, OPTAB_LIB_WIDEN);
2796 if (temp)
2797 return temp;
2800 return 0;
2803 /* Emit code to compute the absolute value of OP0, with result to
2804 TARGET if convenient. (TARGET may be 0.) The return value says
2805 where the result actually is to be found.
2807 MODE is the mode of the operand; the mode of the result is
2808 different but can be deduced from MODE.
2813 expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2814 int result_unsignedp)
2816 rtx temp;
2818 if (! flag_trapv)
2819 result_unsignedp = 1;
2821 /* First try to do it with a special abs instruction. */
2822 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2823 op0, target, 0);
2824 if (temp != 0)
2825 return temp;
2827 /* For floating point modes, try clearing the sign bit. */
2828 if (SCALAR_FLOAT_MODE_P (mode))
2830 temp = expand_absneg_bit (ABS, mode, op0, target);
2831 if (temp)
2832 return temp;
2835 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2836 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
2837 && !HONOR_SIGNED_ZEROS (mode))
2839 rtx last = get_last_insn ();
2841 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2842 if (temp != 0)
2843 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2844 OPTAB_WIDEN);
2846 if (temp != 0)
2847 return temp;
2849 delete_insns_since (last);
2852 /* If this machine has expensive jumps, we can do integer absolute
2853 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2854 where W is the width of MODE. */
2856 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2858 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2859 size_int (GET_MODE_BITSIZE (mode) - 1),
2860 NULL_RTX, 0);
2862 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2863 OPTAB_LIB_WIDEN);
2864 if (temp != 0)
2865 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2866 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2868 if (temp != 0)
2869 return temp;
2872 return NULL_RTX;
2876 expand_abs (enum machine_mode mode, rtx op0, rtx target,
2877 int result_unsignedp, int safe)
2879 rtx temp, op1;
2881 if (! flag_trapv)
2882 result_unsignedp = 1;
2884 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2885 if (temp != 0)
2886 return temp;
2888 /* If that does not win, use conditional jump and negate. */
2890 /* It is safe to use the target if it is the same
2891 as the source if this is also a pseudo register */
2892 if (op0 == target && REG_P (op0)
2893 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2894 safe = 1;
2896 op1 = gen_label_rtx ();
2897 if (target == 0 || ! safe
2898 || GET_MODE (target) != mode
2899 || (MEM_P (target) && MEM_VOLATILE_P (target))
2900 || (REG_P (target)
2901 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2902 target = gen_reg_rtx (mode);
2904 emit_move_insn (target, op0);
2905 NO_DEFER_POP;
2907 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2908 NULL_RTX, NULL_RTX, op1);
2910 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2911 target, target, 0);
2912 if (op0 != target)
2913 emit_move_insn (target, op0);
2914 emit_label (op1);
2915 OK_DEFER_POP;
2916 return target;
2919 /* A subroutine of expand_copysign, perform the copysign operation using the
2920 abs and neg primitives advertised to exist on the target. The assumption
2921 is that we have a split register file, and leaving op0 in fp registers,
2922 and not playing with subregs so much, will help the register allocator. */
2924 static rtx
2925 expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2926 int bitpos, bool op0_is_abs)
2928 enum machine_mode imode;
2929 HOST_WIDE_INT hi, lo;
2930 int word;
2931 rtx label;
2933 if (target == op1)
2934 target = NULL_RTX;
2936 if (!op0_is_abs)
2938 op0 = expand_unop (mode, abs_optab, op0, target, 0);
2939 if (op0 == NULL)
2940 return NULL_RTX;
2941 target = op0;
2943 else
2945 if (target == NULL_RTX)
2946 target = copy_to_reg (op0);
2947 else
2948 emit_move_insn (target, op0);
2951 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2953 imode = int_mode_for_mode (mode);
2954 if (imode == BLKmode)
2955 return NULL_RTX;
2956 op1 = gen_lowpart (imode, op1);
2958 else
2960 imode = word_mode;
2961 if (FLOAT_WORDS_BIG_ENDIAN)
2962 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2963 else
2964 word = bitpos / BITS_PER_WORD;
2965 bitpos = bitpos % BITS_PER_WORD;
2966 op1 = operand_subword_force (op1, word, mode);
2969 if (bitpos < HOST_BITS_PER_WIDE_INT)
2971 hi = 0;
2972 lo = (HOST_WIDE_INT) 1 << bitpos;
2974 else
2976 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2977 lo = 0;
2980 op1 = expand_binop (imode, and_optab, op1,
2981 immed_double_const (lo, hi, imode),
2982 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2984 label = gen_label_rtx ();
2985 emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label);
2987 if (GET_CODE (op0) == CONST_DOUBLE)
2988 op0 = simplify_unary_operation (NEG, mode, op0, mode);
2989 else
2990 op0 = expand_unop (mode, neg_optab, op0, target, 0);
2991 if (op0 != target)
2992 emit_move_insn (target, op0);
2994 emit_label (label);
2996 return target;
3000 /* A subroutine of expand_copysign, perform the entire copysign operation
3001 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
3002 is true if op0 is known to have its sign bit clear. */
3004 static rtx
3005 expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
3006 int bitpos, bool op0_is_abs)
3008 enum machine_mode imode;
3009 HOST_WIDE_INT hi, lo;
3010 int word, nwords, i;
3011 rtx temp, insns;
3013 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
3015 imode = int_mode_for_mode (mode);
3016 if (imode == BLKmode)
3017 return NULL_RTX;
3018 word = 0;
3019 nwords = 1;
3021 else
3023 imode = word_mode;
3025 if (FLOAT_WORDS_BIG_ENDIAN)
3026 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
3027 else
3028 word = bitpos / BITS_PER_WORD;
3029 bitpos = bitpos % BITS_PER_WORD;
3030 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
3033 if (bitpos < HOST_BITS_PER_WIDE_INT)
3035 hi = 0;
3036 lo = (HOST_WIDE_INT) 1 << bitpos;
3038 else
3040 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
3041 lo = 0;
3044 if (target == 0 || target == op0 || target == op1)
3045 target = gen_reg_rtx (mode);
3047 if (nwords > 1)
3049 start_sequence ();
3051 for (i = 0; i < nwords; ++i)
3053 rtx targ_piece = operand_subword (target, i, 1, mode);
3054 rtx op0_piece = operand_subword_force (op0, i, mode);
3056 if (i == word)
3058 if (!op0_is_abs)
3059 op0_piece = expand_binop (imode, and_optab, op0_piece,
3060 immed_double_const (~lo, ~hi, imode),
3061 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3063 op1 = expand_binop (imode, and_optab,
3064 operand_subword_force (op1, i, mode),
3065 immed_double_const (lo, hi, imode),
3066 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3068 temp = expand_binop (imode, ior_optab, op0_piece, op1,
3069 targ_piece, 1, OPTAB_LIB_WIDEN);
3070 if (temp != targ_piece)
3071 emit_move_insn (targ_piece, temp);
3073 else
3074 emit_move_insn (targ_piece, op0_piece);
3077 insns = get_insns ();
3078 end_sequence ();
3080 emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
3082 else
3084 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
3085 immed_double_const (lo, hi, imode),
3086 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3088 op0 = gen_lowpart (imode, op0);
3089 if (!op0_is_abs)
3090 op0 = expand_binop (imode, and_optab, op0,
3091 immed_double_const (~lo, ~hi, imode),
3092 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3094 temp = expand_binop (imode, ior_optab, op0, op1,
3095 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
3096 target = lowpart_subreg_maybe_copy (mode, temp, imode);
3099 return target;
3102 /* Expand the C99 copysign operation. OP0 and OP1 must be the same
3103 scalar floating point mode. Return NULL if we do not know how to
3104 expand the operation inline. */
3107 expand_copysign (rtx op0, rtx op1, rtx target)
3109 enum machine_mode mode = GET_MODE (op0);
3110 const struct real_format *fmt;
3111 bool op0_is_abs;
3112 rtx temp;
3114 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3115 gcc_assert (GET_MODE (op1) == mode);
3117 /* First try to do it with a special instruction. */
3118 temp = expand_binop (mode, copysign_optab, op0, op1,
3119 target, 0, OPTAB_DIRECT);
3120 if (temp)
3121 return temp;
3123 fmt = REAL_MODE_FORMAT (mode);
3124 if (fmt == NULL || !fmt->has_signed_zero)
3125 return NULL_RTX;
3127 op0_is_abs = false;
3128 if (GET_CODE (op0) == CONST_DOUBLE)
3130 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
3131 op0 = simplify_unary_operation (ABS, mode, op0, mode);
3132 op0_is_abs = true;
3135 if (fmt->signbit_ro >= 0
3136 && (GET_CODE (op0) == CONST_DOUBLE
3137 || (neg_optab->handlers[mode].insn_code != CODE_FOR_nothing
3138 && abs_optab->handlers[mode].insn_code != CODE_FOR_nothing)))
3140 temp = expand_copysign_absneg (mode, op0, op1, target,
3141 fmt->signbit_ro, op0_is_abs);
3142 if (temp)
3143 return temp;
3146 if (fmt->signbit_rw < 0)
3147 return NULL_RTX;
3148 return expand_copysign_bit (mode, op0, op1, target,
3149 fmt->signbit_rw, op0_is_abs);
3152 /* Generate an instruction whose insn-code is INSN_CODE,
3153 with two operands: an output TARGET and an input OP0.
3154 TARGET *must* be nonzero, and the output is always stored there.
3155 CODE is an rtx code such that (CODE OP0) is an rtx that describes
3156 the value that is stored into TARGET. */
3158 void
3159 emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
3161 rtx temp;
3162 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
3163 rtx pat;
3165 temp = target;
3167 /* Now, if insn does not accept our operands, put them into pseudos. */
3169 if (!insn_data[icode].operand[1].predicate (op0, mode0))
3170 op0 = copy_to_mode_reg (mode0, op0);
3172 if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp)))
3173 temp = gen_reg_rtx (GET_MODE (temp));
3175 pat = GEN_FCN (icode) (temp, op0);
3177 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
3178 add_equal_note (pat, temp, code, op0, NULL_RTX);
3180 emit_insn (pat);
3182 if (temp != target)
3183 emit_move_insn (target, temp);
3186 struct no_conflict_data
3188 rtx target, first, insn;
3189 bool must_stay;
3192 /* Called via note_stores by emit_no_conflict_block and emit_libcall_block.
3193 Set P->must_stay if the currently examined clobber / store has to stay
3194 in the list of insns that constitute the actual no_conflict block /
3195 libcall block. */
3196 static void
3197 no_conflict_move_test (rtx dest, rtx set, void *p0)
3199 struct no_conflict_data *p= p0;
3201 /* If this inns directly contributes to setting the target, it must stay. */
3202 if (reg_overlap_mentioned_p (p->target, dest))
3203 p->must_stay = true;
3204 /* If we haven't committed to keeping any other insns in the list yet,
3205 there is nothing more to check. */
3206 else if (p->insn == p->first)
3207 return;
3208 /* If this insn sets / clobbers a register that feeds one of the insns
3209 already in the list, this insn has to stay too. */
3210 else if (reg_overlap_mentioned_p (dest, PATTERN (p->first))
3211 || (CALL_P (p->first) && (find_reg_fusage (p->first, USE, dest)))
3212 || reg_used_between_p (dest, p->first, p->insn)
3213 /* Likewise if this insn depends on a register set by a previous
3214 insn in the list, or if it sets a result (presumably a hard
3215 register) that is set or clobbered by a previous insn.
3216 N.B. the modified_*_p (SET_DEST...) tests applied to a MEM
3217 SET_DEST perform the former check on the address, and the latter
3218 check on the MEM. */
3219 || (GET_CODE (set) == SET
3220 && (modified_in_p (SET_SRC (set), p->first)
3221 || modified_in_p (SET_DEST (set), p->first)
3222 || modified_between_p (SET_SRC (set), p->first, p->insn)
3223 || modified_between_p (SET_DEST (set), p->first, p->insn))))
3224 p->must_stay = true;
3227 /* Encapsulate the block starting at FIRST and ending with LAST, which is
3228 logically equivalent to EQUIV, so it gets manipulated as a unit if it
3229 is possible to do so. */
3231 static void
3232 maybe_encapsulate_block (rtx first, rtx last, rtx equiv)
3234 if (!flag_non_call_exceptions || !may_trap_p (equiv))
3236 /* We can't attach the REG_LIBCALL and REG_RETVAL notes when the
3237 encapsulated region would not be in one basic block, i.e. when
3238 there is a control_flow_insn_p insn between FIRST and LAST. */
3239 bool attach_libcall_retval_notes = true;
3240 rtx insn, next = NEXT_INSN (last);
3242 for (insn = first; insn != next; insn = NEXT_INSN (insn))
3243 if (control_flow_insn_p (insn))
3245 attach_libcall_retval_notes = false;
3246 break;
3249 if (attach_libcall_retval_notes)
3251 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3252 REG_NOTES (first));
3253 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3254 REG_NOTES (last));
3259 /* Emit code to perform a series of operations on a multi-word quantity, one
3260 word at a time.
3262 Such a block is preceded by a CLOBBER of the output, consists of multiple
3263 insns, each setting one word of the output, and followed by a SET copying
3264 the output to itself.
3266 Each of the insns setting words of the output receives a REG_NO_CONFLICT
3267 note indicating that it doesn't conflict with the (also multi-word)
3268 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
3269 notes.
3271 INSNS is a block of code generated to perform the operation, not including
3272 the CLOBBER and final copy. All insns that compute intermediate values
3273 are first emitted, followed by the block as described above.
3275 TARGET, OP0, and OP1 are the output and inputs of the operations,
3276 respectively. OP1 may be zero for a unary operation.
3278 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
3279 on the last insn.
3281 If TARGET is not a register, INSNS is simply emitted with no special
3282 processing. Likewise if anything in INSNS is not an INSN or if
3283 there is a libcall block inside INSNS.
3285 The final insn emitted is returned. */
3288 emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
3290 rtx prev, next, first, last, insn;
3292 if (!REG_P (target) || reload_in_progress)
3293 return emit_insn (insns);
3294 else
3295 for (insn = insns; insn; insn = NEXT_INSN (insn))
3296 if (!NONJUMP_INSN_P (insn)
3297 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
3298 return emit_insn (insns);
3300 /* First emit all insns that do not store into words of the output and remove
3301 these from the list. */
3302 for (insn = insns; insn; insn = next)
3304 rtx note;
3305 struct no_conflict_data data;
3307 next = NEXT_INSN (insn);
3309 /* Some ports (cris) create a libcall regions at their own. We must
3310 avoid any potential nesting of LIBCALLs. */
3311 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3312 remove_note (insn, note);
3313 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3314 remove_note (insn, note);
3316 data.target = target;
3317 data.first = insns;
3318 data.insn = insn;
3319 data.must_stay = 0;
3320 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3321 if (! data.must_stay)
3323 if (PREV_INSN (insn))
3324 NEXT_INSN (PREV_INSN (insn)) = next;
3325 else
3326 insns = next;
3328 if (next)
3329 PREV_INSN (next) = PREV_INSN (insn);
3331 add_insn (insn);
3335 prev = get_last_insn ();
3337 /* Now write the CLOBBER of the output, followed by the setting of each
3338 of the words, followed by the final copy. */
3339 if (target != op0 && target != op1)
3340 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
3342 for (insn = insns; insn; insn = next)
3344 next = NEXT_INSN (insn);
3345 add_insn (insn);
3347 if (op1 && REG_P (op1))
3348 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3349 REG_NOTES (insn));
3351 if (op0 && REG_P (op0))
3352 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3353 REG_NOTES (insn));
3356 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3357 != CODE_FOR_nothing)
3359 last = emit_move_insn (target, target);
3360 if (equiv)
3361 set_unique_reg_note (last, REG_EQUAL, equiv);
3363 else
3365 last = get_last_insn ();
3367 /* Remove any existing REG_EQUAL note from "last", or else it will
3368 be mistaken for a note referring to the full contents of the
3369 alleged libcall value when found together with the REG_RETVAL
3370 note added below. An existing note can come from an insn
3371 expansion at "last". */
3372 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3375 if (prev == 0)
3376 first = get_insns ();
3377 else
3378 first = NEXT_INSN (prev);
3380 maybe_encapsulate_block (first, last, equiv);
3382 return last;
3385 /* Emit code to make a call to a constant function or a library call.
3387 INSNS is a list containing all insns emitted in the call.
3388 These insns leave the result in RESULT. Our block is to copy RESULT
3389 to TARGET, which is logically equivalent to EQUIV.
3391 We first emit any insns that set a pseudo on the assumption that these are
3392 loading constants into registers; doing so allows them to be safely cse'ed
3393 between blocks. Then we emit all the other insns in the block, followed by
3394 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3395 note with an operand of EQUIV.
3397 Moving assignments to pseudos outside of the block is done to improve
3398 the generated code, but is not required to generate correct code,
3399 hence being unable to move an assignment is not grounds for not making
3400 a libcall block. There are two reasons why it is safe to leave these
3401 insns inside the block: First, we know that these pseudos cannot be
3402 used in generated RTL outside the block since they are created for
3403 temporary purposes within the block. Second, CSE will not record the
3404 values of anything set inside a libcall block, so we know they must
3405 be dead at the end of the block.
3407 Except for the first group of insns (the ones setting pseudos), the
3408 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3410 void
3411 emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
3413 rtx final_dest = target;
3414 rtx prev, next, first, last, insn;
3416 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3417 into a MEM later. Protect the libcall block from this change. */
3418 if (! REG_P (target) || REG_USERVAR_P (target))
3419 target = gen_reg_rtx (GET_MODE (target));
3421 /* If we're using non-call exceptions, a libcall corresponding to an
3422 operation that may trap may also trap. */
3423 if (flag_non_call_exceptions && may_trap_p (equiv))
3425 for (insn = insns; insn; insn = NEXT_INSN (insn))
3426 if (CALL_P (insn))
3428 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3430 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3431 remove_note (insn, note);
3434 else
3435 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
3436 reg note to indicate that this call cannot throw or execute a nonlocal
3437 goto (unless there is already a REG_EH_REGION note, in which case
3438 we update it). */
3439 for (insn = insns; insn; insn = NEXT_INSN (insn))
3440 if (CALL_P (insn))
3442 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
3444 if (note != 0)
3445 XEXP (note, 0) = constm1_rtx;
3446 else
3447 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
3448 REG_NOTES (insn));
3451 /* First emit all insns that set pseudos. Remove them from the list as
3452 we go. Avoid insns that set pseudos which were referenced in previous
3453 insns. These can be generated by move_by_pieces, for example,
3454 to update an address. Similarly, avoid insns that reference things
3455 set in previous insns. */
3457 for (insn = insns; insn; insn = next)
3459 rtx set = single_set (insn);
3460 rtx note;
3462 /* Some ports (cris) create a libcall regions at their own. We must
3463 avoid any potential nesting of LIBCALLs. */
3464 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3465 remove_note (insn, note);
3466 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3467 remove_note (insn, note);
3469 next = NEXT_INSN (insn);
3471 if (set != 0 && REG_P (SET_DEST (set))
3472 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
3474 struct no_conflict_data data;
3476 data.target = const0_rtx;
3477 data.first = insns;
3478 data.insn = insn;
3479 data.must_stay = 0;
3480 note_stores (PATTERN (insn), no_conflict_move_test, &data);
3481 if (! data.must_stay)
3483 if (PREV_INSN (insn))
3484 NEXT_INSN (PREV_INSN (insn)) = next;
3485 else
3486 insns = next;
3488 if (next)
3489 PREV_INSN (next) = PREV_INSN (insn);
3491 add_insn (insn);
3495 /* Some ports use a loop to copy large arguments onto the stack.
3496 Don't move anything outside such a loop. */
3497 if (LABEL_P (insn))
3498 break;
3501 prev = get_last_insn ();
3503 /* Write the remaining insns followed by the final copy. */
3505 for (insn = insns; insn; insn = next)
3507 next = NEXT_INSN (insn);
3509 add_insn (insn);
3512 last = emit_move_insn (target, result);
3513 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3514 != CODE_FOR_nothing)
3515 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
3516 else
3518 /* Remove any existing REG_EQUAL note from "last", or else it will
3519 be mistaken for a note referring to the full contents of the
3520 libcall value when found together with the REG_RETVAL note added
3521 below. An existing note can come from an insn expansion at
3522 "last". */
3523 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3526 if (final_dest != target)
3527 emit_move_insn (final_dest, target);
3529 if (prev == 0)
3530 first = get_insns ();
3531 else
3532 first = NEXT_INSN (prev);
3534 maybe_encapsulate_block (first, last, equiv);
3537 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
3538 PURPOSE describes how this comparison will be used. CODE is the rtx
3539 comparison code we will be using.
3541 ??? Actually, CODE is slightly weaker than that. A target is still
3542 required to implement all of the normal bcc operations, but not
3543 required to implement all (or any) of the unordered bcc operations. */
3546 can_compare_p (enum rtx_code code, enum machine_mode mode,
3547 enum can_compare_purpose purpose)
3551 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3553 if (purpose == ccp_jump)
3554 return bcc_gen_fctn[(int) code] != NULL;
3555 else if (purpose == ccp_store_flag)
3556 return setcc_gen_code[(int) code] != CODE_FOR_nothing;
3557 else
3558 /* There's only one cmov entry point, and it's allowed to fail. */
3559 return 1;
3561 if (purpose == ccp_jump
3562 && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3563 return 1;
3564 if (purpose == ccp_cmov
3565 && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3566 return 1;
3567 if (purpose == ccp_store_flag
3568 && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
3569 return 1;
3570 mode = GET_MODE_WIDER_MODE (mode);
3572 while (mode != VOIDmode);
3574 return 0;
3577 /* This function is called when we are going to emit a compare instruction that
3578 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3580 *PMODE is the mode of the inputs (in case they are const_int).
3581 *PUNSIGNEDP nonzero says that the operands are unsigned;
3582 this matters if they need to be widened.
3584 If they have mode BLKmode, then SIZE specifies the size of both operands.
3586 This function performs all the setup necessary so that the caller only has
3587 to emit a single comparison insn. This setup can involve doing a BLKmode
3588 comparison or emitting a library call to perform the comparison if no insn
3589 is available to handle it.
3590 The values which are passed in through pointers can be modified; the caller
3591 should perform the comparison on the modified values. Constant
3592 comparisons must have already been folded. */
3594 static void
3595 prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3596 enum machine_mode *pmode, int *punsignedp,
3597 enum can_compare_purpose purpose)
3599 enum machine_mode mode = *pmode;
3600 rtx x = *px, y = *py;
3601 int unsignedp = *punsignedp;
3603 /* If we are inside an appropriately-short loop and we are optimizing,
3604 force expensive constants into a register. */
3605 if (CONSTANT_P (x) && optimize
3606 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3607 x = force_reg (mode, x);
3609 if (CONSTANT_P (y) && optimize
3610 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3611 y = force_reg (mode, y);
3613 #ifdef HAVE_cc0
3614 /* Make sure if we have a canonical comparison. The RTL
3615 documentation states that canonical comparisons are required only
3616 for targets which have cc0. */
3617 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
3618 #endif
3620 /* Don't let both operands fail to indicate the mode. */
3621 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3622 x = force_reg (mode, x);
3624 /* Handle all BLKmode compares. */
3626 if (mode == BLKmode)
3628 enum machine_mode cmp_mode, result_mode;
3629 enum insn_code cmp_code;
3630 tree length_type;
3631 rtx libfunc;
3632 rtx result;
3633 rtx opalign
3634 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3636 gcc_assert (size);
3638 /* Try to use a memory block compare insn - either cmpstr
3639 or cmpmem will do. */
3640 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3641 cmp_mode != VOIDmode;
3642 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
3644 cmp_code = cmpmem_optab[cmp_mode];
3645 if (cmp_code == CODE_FOR_nothing)
3646 cmp_code = cmpstr_optab[cmp_mode];
3647 if (cmp_code == CODE_FOR_nothing)
3648 cmp_code = cmpstrn_optab[cmp_mode];
3649 if (cmp_code == CODE_FOR_nothing)
3650 continue;
3652 /* Must make sure the size fits the insn's mode. */
3653 if ((GET_CODE (size) == CONST_INT
3654 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3655 || (GET_MODE_BITSIZE (GET_MODE (size))
3656 > GET_MODE_BITSIZE (cmp_mode)))
3657 continue;
3659 result_mode = insn_data[cmp_code].operand[0].mode;
3660 result = gen_reg_rtx (result_mode);
3661 size = convert_to_mode (cmp_mode, size, 1);
3662 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3664 *px = result;
3665 *py = const0_rtx;
3666 *pmode = result_mode;
3667 return;
3670 /* Otherwise call a library function, memcmp. */
3671 libfunc = memcmp_libfunc;
3672 length_type = sizetype;
3673 result_mode = TYPE_MODE (integer_type_node);
3674 cmp_mode = TYPE_MODE (length_type);
3675 size = convert_to_mode (TYPE_MODE (length_type), size,
3676 TYPE_UNSIGNED (length_type));
3678 result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3679 result_mode, 3,
3680 XEXP (x, 0), Pmode,
3681 XEXP (y, 0), Pmode,
3682 size, cmp_mode);
3683 *px = result;
3684 *py = const0_rtx;
3685 *pmode = result_mode;
3686 return;
3689 /* Don't allow operands to the compare to trap, as that can put the
3690 compare and branch in different basic blocks. */
3691 if (flag_non_call_exceptions)
3693 if (may_trap_p (x))
3694 x = force_reg (mode, x);
3695 if (may_trap_p (y))
3696 y = force_reg (mode, y);
3699 *px = x;
3700 *py = y;
3701 if (can_compare_p (*pcomparison, mode, purpose))
3702 return;
3704 /* Handle a lib call just for the mode we are using. */
3706 if (cmp_optab->handlers[(int) mode].libfunc && !SCALAR_FLOAT_MODE_P (mode))
3708 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3709 rtx result;
3711 /* If we want unsigned, and this mode has a distinct unsigned
3712 comparison routine, use that. */
3713 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3714 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3716 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3717 word_mode, 2, x, mode, y, mode);
3719 /* There are two kinds of comparison routines. Biased routines
3720 return 0/1/2, and unbiased routines return -1/0/1. Other parts
3721 of gcc expect that the comparison operation is equivalent
3722 to the modified comparison. For signed comparisons compare the
3723 result against 1 in the biased case, and zero in the unbiased
3724 case. For unsigned comparisons always compare against 1 after
3725 biasing the unbiased result by adding 1. This gives us a way to
3726 represent LTU. */
3727 *px = result;
3728 *pmode = word_mode;
3729 *py = const1_rtx;
3731 if (!TARGET_LIB_INT_CMP_BIASED)
3733 if (*punsignedp)
3734 *px = plus_constant (result, 1);
3735 else
3736 *py = const0_rtx;
3738 return;
3741 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
3742 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3745 /* Before emitting an insn with code ICODE, make sure that X, which is going
3746 to be used for operand OPNUM of the insn, is converted from mode MODE to
3747 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3748 that it is accepted by the operand predicate. Return the new value. */
3750 static rtx
3751 prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3752 enum machine_mode wider_mode, int unsignedp)
3754 if (mode != wider_mode)
3755 x = convert_modes (wider_mode, mode, x, unsignedp);
3757 if (!insn_data[icode].operand[opnum].predicate
3758 (x, insn_data[icode].operand[opnum].mode))
3760 if (no_new_pseudos)
3761 return NULL_RTX;
3762 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3765 return x;
3768 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3769 we can do the comparison.
3770 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3771 be NULL_RTX which indicates that only a comparison is to be generated. */
3773 static void
3774 emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3775 enum rtx_code comparison, int unsignedp, rtx label)
3777 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3778 enum mode_class class = GET_MODE_CLASS (mode);
3779 enum machine_mode wider_mode = mode;
3781 /* Try combined insns first. */
3784 enum insn_code icode;
3785 PUT_MODE (test, wider_mode);
3787 if (label)
3789 icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
3791 if (icode != CODE_FOR_nothing
3792 && insn_data[icode].operand[0].predicate (test, wider_mode))
3794 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3795 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3796 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3797 return;
3801 /* Handle some compares against zero. */
3802 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3803 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3805 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3806 emit_insn (GEN_FCN (icode) (x));
3807 if (label)
3808 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3809 return;
3812 /* Handle compares for which there is a directly suitable insn. */
3814 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3815 if (icode != CODE_FOR_nothing)
3817 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3818 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3819 emit_insn (GEN_FCN (icode) (x, y));
3820 if (label)
3821 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
3822 return;
3825 if (!CLASS_HAS_WIDER_MODES_P (class))
3826 break;
3828 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3830 while (wider_mode != VOIDmode);
3832 gcc_unreachable ();
3835 /* Generate code to compare X with Y so that the condition codes are
3836 set and to jump to LABEL if the condition is true. If X is a
3837 constant and Y is not a constant, then the comparison is swapped to
3838 ensure that the comparison RTL has the canonical form.
3840 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3841 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3842 the proper branch condition code.
3844 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3846 MODE is the mode of the inputs (in case they are const_int).
3848 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3849 be passed unchanged to emit_cmp_insn, then potentially converted into an
3850 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3852 void
3853 emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3854 enum machine_mode mode, int unsignedp, rtx label)
3856 rtx op0 = x, op1 = y;
3858 /* Swap operands and condition to ensure canonical RTL. */
3859 if (swap_commutative_operands_p (x, y))
3861 /* If we're not emitting a branch, this means some caller
3862 is out of sync. */
3863 gcc_assert (label);
3865 op0 = y, op1 = x;
3866 comparison = swap_condition (comparison);
3869 #ifdef HAVE_cc0
3870 /* If OP0 is still a constant, then both X and Y must be constants.
3871 Force X into a register to create canonical RTL. */
3872 if (CONSTANT_P (op0))
3873 op0 = force_reg (mode, op0);
3874 #endif
3876 if (unsignedp)
3877 comparison = unsigned_condition (comparison);
3879 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3880 ccp_jump);
3881 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3884 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3886 void
3887 emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3888 enum machine_mode mode, int unsignedp)
3890 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3893 /* Emit a library call comparison between floating point X and Y.
3894 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3896 static void
3897 prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3898 enum machine_mode *pmode, int *punsignedp)
3900 enum rtx_code comparison = *pcomparison;
3901 enum rtx_code swapped = swap_condition (comparison);
3902 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
3903 rtx x = *px;
3904 rtx y = *py;
3905 enum machine_mode orig_mode = GET_MODE (x);
3906 enum machine_mode mode;
3907 rtx value, target, insns, equiv;
3908 rtx libfunc = 0;
3909 bool reversed_p = false;
3911 for (mode = orig_mode;
3912 mode != VOIDmode;
3913 mode = GET_MODE_WIDER_MODE (mode))
3915 if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3916 break;
3918 if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
3920 rtx tmp;
3921 tmp = x; x = y; y = tmp;
3922 comparison = swapped;
3923 break;
3926 if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
3927 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
3929 comparison = reversed;
3930 reversed_p = true;
3931 break;
3935 gcc_assert (mode != VOIDmode);
3937 if (mode != orig_mode)
3939 x = convert_to_mode (mode, x, 0);
3940 y = convert_to_mode (mode, y, 0);
3943 /* Attach a REG_EQUAL note describing the semantics of the libcall to
3944 the RTL. The allows the RTL optimizers to delete the libcall if the
3945 condition can be determined at compile-time. */
3946 if (comparison == UNORDERED)
3948 rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
3949 equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
3950 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3951 temp, const_true_rtx, equiv);
3953 else
3955 equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
3956 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3958 rtx true_rtx, false_rtx;
3960 switch (comparison)
3962 case EQ:
3963 true_rtx = const0_rtx;
3964 false_rtx = const_true_rtx;
3965 break;
3967 case NE:
3968 true_rtx = const_true_rtx;
3969 false_rtx = const0_rtx;
3970 break;
3972 case GT:
3973 true_rtx = const1_rtx;
3974 false_rtx = const0_rtx;
3975 break;
3977 case GE:
3978 true_rtx = const0_rtx;
3979 false_rtx = constm1_rtx;
3980 break;
3982 case LT:
3983 true_rtx = constm1_rtx;
3984 false_rtx = const0_rtx;
3985 break;
3987 case LE:
3988 true_rtx = const0_rtx;
3989 false_rtx = const1_rtx;
3990 break;
3992 default:
3993 gcc_unreachable ();
3995 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3996 equiv, true_rtx, false_rtx);
4000 start_sequence ();
4001 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4002 word_mode, 2, x, mode, y, mode);
4003 insns = get_insns ();
4004 end_sequence ();
4006 target = gen_reg_rtx (word_mode);
4007 emit_libcall_block (insns, target, value, equiv);
4009 if (comparison == UNORDERED
4010 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
4011 comparison = reversed_p ? EQ : NE;
4013 *px = target;
4014 *py = const0_rtx;
4015 *pmode = word_mode;
4016 *pcomparison = comparison;
4017 *punsignedp = 0;
4020 /* Generate code to indirectly jump to a location given in the rtx LOC. */
4022 void
4023 emit_indirect_jump (rtx loc)
4025 if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
4026 (loc, Pmode))
4027 loc = copy_to_mode_reg (Pmode, loc);
4029 emit_jump_insn (gen_indirect_jump (loc));
4030 emit_barrier ();
4033 #ifdef HAVE_conditional_move
4035 /* Emit a conditional move instruction if the machine supports one for that
4036 condition and machine mode.
4038 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4039 the mode to use should they be constants. If it is VOIDmode, they cannot
4040 both be constants.
4042 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
4043 should be stored there. MODE is the mode to use should they be constants.
4044 If it is VOIDmode, they cannot both be constants.
4046 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4047 is not supported. */
4050 emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
4051 enum machine_mode cmode, rtx op2, rtx op3,
4052 enum machine_mode mode, int unsignedp)
4054 rtx tem, subtarget, comparison, insn;
4055 enum insn_code icode;
4056 enum rtx_code reversed;
4058 /* If one operand is constant, make it the second one. Only do this
4059 if the other operand is not constant as well. */
4061 if (swap_commutative_operands_p (op0, op1))
4063 tem = op0;
4064 op0 = op1;
4065 op1 = tem;
4066 code = swap_condition (code);
4069 /* get_condition will prefer to generate LT and GT even if the old
4070 comparison was against zero, so undo that canonicalization here since
4071 comparisons against zero are cheaper. */
4072 if (code == LT && op1 == const1_rtx)
4073 code = LE, op1 = const0_rtx;
4074 else if (code == GT && op1 == constm1_rtx)
4075 code = GE, op1 = const0_rtx;
4077 if (cmode == VOIDmode)
4078 cmode = GET_MODE (op0);
4080 if (swap_commutative_operands_p (op2, op3)
4081 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4082 != UNKNOWN))
4084 tem = op2;
4085 op2 = op3;
4086 op3 = tem;
4087 code = reversed;
4090 if (mode == VOIDmode)
4091 mode = GET_MODE (op2);
4093 icode = movcc_gen_code[mode];
4095 if (icode == CODE_FOR_nothing)
4096 return 0;
4098 if (!target)
4099 target = gen_reg_rtx (mode);
4101 subtarget = target;
4103 /* If the insn doesn't accept these operands, put them in pseudos. */
4105 if (!insn_data[icode].operand[0].predicate
4106 (subtarget, insn_data[icode].operand[0].mode))
4107 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4109 if (!insn_data[icode].operand[2].predicate
4110 (op2, insn_data[icode].operand[2].mode))
4111 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4113 if (!insn_data[icode].operand[3].predicate
4114 (op3, insn_data[icode].operand[3].mode))
4115 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4117 /* Everything should now be in the suitable form, so emit the compare insn
4118 and then the conditional move. */
4120 comparison
4121 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4123 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4124 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4125 return NULL and let the caller figure out how best to deal with this
4126 situation. */
4127 if (GET_CODE (comparison) != code)
4128 return NULL_RTX;
4130 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4132 /* If that failed, then give up. */
4133 if (insn == 0)
4134 return 0;
4136 emit_insn (insn);
4138 if (subtarget != target)
4139 convert_move (target, subtarget, 0);
4141 return target;
4144 /* Return nonzero if a conditional move of mode MODE is supported.
4146 This function is for combine so it can tell whether an insn that looks
4147 like a conditional move is actually supported by the hardware. If we
4148 guess wrong we lose a bit on optimization, but that's it. */
4149 /* ??? sparc64 supports conditionally moving integers values based on fp
4150 comparisons, and vice versa. How do we handle them? */
4153 can_conditionally_move_p (enum machine_mode mode)
4155 if (movcc_gen_code[mode] != CODE_FOR_nothing)
4156 return 1;
4158 return 0;
4161 #endif /* HAVE_conditional_move */
4163 /* Emit a conditional addition instruction if the machine supports one for that
4164 condition and machine mode.
4166 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
4167 the mode to use should they be constants. If it is VOIDmode, they cannot
4168 both be constants.
4170 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
4171 should be stored there. MODE is the mode to use should they be constants.
4172 If it is VOIDmode, they cannot both be constants.
4174 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
4175 is not supported. */
4178 emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
4179 enum machine_mode cmode, rtx op2, rtx op3,
4180 enum machine_mode mode, int unsignedp)
4182 rtx tem, subtarget, comparison, insn;
4183 enum insn_code icode;
4184 enum rtx_code reversed;
4186 /* If one operand is constant, make it the second one. Only do this
4187 if the other operand is not constant as well. */
4189 if (swap_commutative_operands_p (op0, op1))
4191 tem = op0;
4192 op0 = op1;
4193 op1 = tem;
4194 code = swap_condition (code);
4197 /* get_condition will prefer to generate LT and GT even if the old
4198 comparison was against zero, so undo that canonicalization here since
4199 comparisons against zero are cheaper. */
4200 if (code == LT && op1 == const1_rtx)
4201 code = LE, op1 = const0_rtx;
4202 else if (code == GT && op1 == constm1_rtx)
4203 code = GE, op1 = const0_rtx;
4205 if (cmode == VOIDmode)
4206 cmode = GET_MODE (op0);
4208 if (swap_commutative_operands_p (op2, op3)
4209 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
4210 != UNKNOWN))
4212 tem = op2;
4213 op2 = op3;
4214 op3 = tem;
4215 code = reversed;
4218 if (mode == VOIDmode)
4219 mode = GET_MODE (op2);
4221 icode = addcc_optab->handlers[(int) mode].insn_code;
4223 if (icode == CODE_FOR_nothing)
4224 return 0;
4226 if (!target)
4227 target = gen_reg_rtx (mode);
4229 /* If the insn doesn't accept these operands, put them in pseudos. */
4231 if (!insn_data[icode].operand[0].predicate
4232 (target, insn_data[icode].operand[0].mode))
4233 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
4234 else
4235 subtarget = target;
4237 if (!insn_data[icode].operand[2].predicate
4238 (op2, insn_data[icode].operand[2].mode))
4239 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
4241 if (!insn_data[icode].operand[3].predicate
4242 (op3, insn_data[icode].operand[3].mode))
4243 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
4245 /* Everything should now be in the suitable form, so emit the compare insn
4246 and then the conditional move. */
4248 comparison
4249 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
4251 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
4252 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
4253 return NULL and let the caller figure out how best to deal with this
4254 situation. */
4255 if (GET_CODE (comparison) != code)
4256 return NULL_RTX;
4258 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4260 /* If that failed, then give up. */
4261 if (insn == 0)
4262 return 0;
4264 emit_insn (insn);
4266 if (subtarget != target)
4267 convert_move (target, subtarget, 0);
4269 return target;
4272 /* These functions attempt to generate an insn body, rather than
4273 emitting the insn, but if the gen function already emits them, we
4274 make no attempt to turn them back into naked patterns. */
4276 /* Generate and return an insn body to add Y to X. */
4279 gen_add2_insn (rtx x, rtx y)
4281 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4283 gcc_assert (insn_data[icode].operand[0].predicate
4284 (x, insn_data[icode].operand[0].mode));
4285 gcc_assert (insn_data[icode].operand[1].predicate
4286 (x, insn_data[icode].operand[1].mode));
4287 gcc_assert (insn_data[icode].operand[2].predicate
4288 (y, insn_data[icode].operand[2].mode));
4290 return GEN_FCN (icode) (x, x, y);
4293 /* Generate and return an insn body to add r1 and c,
4294 storing the result in r0. */
4296 gen_add3_insn (rtx r0, rtx r1, rtx c)
4298 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4300 if (icode == CODE_FOR_nothing
4301 || !(insn_data[icode].operand[0].predicate
4302 (r0, insn_data[icode].operand[0].mode))
4303 || !(insn_data[icode].operand[1].predicate
4304 (r1, insn_data[icode].operand[1].mode))
4305 || !(insn_data[icode].operand[2].predicate
4306 (c, insn_data[icode].operand[2].mode)))
4307 return NULL_RTX;
4309 return GEN_FCN (icode) (r0, r1, c);
4313 have_add2_insn (rtx x, rtx y)
4315 int icode;
4317 gcc_assert (GET_MODE (x) != VOIDmode);
4319 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
4321 if (icode == CODE_FOR_nothing)
4322 return 0;
4324 if (!(insn_data[icode].operand[0].predicate
4325 (x, insn_data[icode].operand[0].mode))
4326 || !(insn_data[icode].operand[1].predicate
4327 (x, insn_data[icode].operand[1].mode))
4328 || !(insn_data[icode].operand[2].predicate
4329 (y, insn_data[icode].operand[2].mode)))
4330 return 0;
4332 return 1;
4335 /* Generate and return an insn body to subtract Y from X. */
4338 gen_sub2_insn (rtx x, rtx y)
4340 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4342 gcc_assert (insn_data[icode].operand[0].predicate
4343 (x, insn_data[icode].operand[0].mode));
4344 gcc_assert (insn_data[icode].operand[1].predicate
4345 (x, insn_data[icode].operand[1].mode));
4346 gcc_assert (insn_data[icode].operand[2].predicate
4347 (y, insn_data[icode].operand[2].mode));
4349 return GEN_FCN (icode) (x, x, y);
4352 /* Generate and return an insn body to subtract r1 and c,
4353 storing the result in r0. */
4355 gen_sub3_insn (rtx r0, rtx r1, rtx c)
4357 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4359 if (icode == CODE_FOR_nothing
4360 || !(insn_data[icode].operand[0].predicate
4361 (r0, insn_data[icode].operand[0].mode))
4362 || !(insn_data[icode].operand[1].predicate
4363 (r1, insn_data[icode].operand[1].mode))
4364 || !(insn_data[icode].operand[2].predicate
4365 (c, insn_data[icode].operand[2].mode)))
4366 return NULL_RTX;
4368 return GEN_FCN (icode) (r0, r1, c);
4372 have_sub2_insn (rtx x, rtx y)
4374 int icode;
4376 gcc_assert (GET_MODE (x) != VOIDmode);
4378 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4380 if (icode == CODE_FOR_nothing)
4381 return 0;
4383 if (!(insn_data[icode].operand[0].predicate
4384 (x, insn_data[icode].operand[0].mode))
4385 || !(insn_data[icode].operand[1].predicate
4386 (x, insn_data[icode].operand[1].mode))
4387 || !(insn_data[icode].operand[2].predicate
4388 (y, insn_data[icode].operand[2].mode)))
4389 return 0;
4391 return 1;
4394 /* Generate the body of an instruction to copy Y into X.
4395 It may be a list of insns, if one insn isn't enough. */
4398 gen_move_insn (rtx x, rtx y)
4400 rtx seq;
4402 start_sequence ();
4403 emit_move_insn_1 (x, y);
4404 seq = get_insns ();
4405 end_sequence ();
4406 return seq;
4409 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4410 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4411 no such operation exists, CODE_FOR_nothing will be returned. */
4413 enum insn_code
4414 can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4415 int unsignedp)
4417 convert_optab tab;
4418 #ifdef HAVE_ptr_extend
4419 if (unsignedp < 0)
4420 return CODE_FOR_ptr_extend;
4421 #endif
4423 tab = unsignedp ? zext_optab : sext_optab;
4424 return tab->handlers[to_mode][from_mode].insn_code;
4427 /* Generate the body of an insn to extend Y (with mode MFROM)
4428 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4431 gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4432 enum machine_mode mfrom, int unsignedp)
4434 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4435 return GEN_FCN (icode) (x, y);
4438 /* can_fix_p and can_float_p say whether the target machine
4439 can directly convert a given fixed point type to
4440 a given floating point type, or vice versa.
4441 The returned value is the CODE_FOR_... value to use,
4442 or CODE_FOR_nothing if these modes cannot be directly converted.
4444 *TRUNCP_PTR is set to 1 if it is necessary to output
4445 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4447 static enum insn_code
4448 can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4449 int unsignedp, int *truncp_ptr)
4451 convert_optab tab;
4452 enum insn_code icode;
4454 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4455 icode = tab->handlers[fixmode][fltmode].insn_code;
4456 if (icode != CODE_FOR_nothing)
4458 *truncp_ptr = 0;
4459 return icode;
4462 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4463 for this to work. We need to rework the fix* and ftrunc* patterns
4464 and documentation. */
4465 tab = unsignedp ? ufix_optab : sfix_optab;
4466 icode = tab->handlers[fixmode][fltmode].insn_code;
4467 if (icode != CODE_FOR_nothing
4468 && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
4470 *truncp_ptr = 1;
4471 return icode;
4474 *truncp_ptr = 0;
4475 return CODE_FOR_nothing;
4478 static enum insn_code
4479 can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4480 int unsignedp)
4482 convert_optab tab;
4484 tab = unsignedp ? ufloat_optab : sfloat_optab;
4485 return tab->handlers[fltmode][fixmode].insn_code;
4488 /* Generate code to convert FROM to floating point
4489 and store in TO. FROM must be fixed point and not VOIDmode.
4490 UNSIGNEDP nonzero means regard FROM as unsigned.
4491 Normally this is done by correcting the final value
4492 if it is negative. */
4494 void
4495 expand_float (rtx to, rtx from, int unsignedp)
4497 enum insn_code icode;
4498 rtx target = to;
4499 enum machine_mode fmode, imode;
4500 bool can_do_signed = false;
4502 /* Crash now, because we won't be able to decide which mode to use. */
4503 gcc_assert (GET_MODE (from) != VOIDmode);
4505 /* Look for an insn to do the conversion. Do it in the specified
4506 modes if possible; otherwise convert either input, output or both to
4507 wider mode. If the integer mode is wider than the mode of FROM,
4508 we can do the conversion signed even if the input is unsigned. */
4510 for (fmode = GET_MODE (to); fmode != VOIDmode;
4511 fmode = GET_MODE_WIDER_MODE (fmode))
4512 for (imode = GET_MODE (from); imode != VOIDmode;
4513 imode = GET_MODE_WIDER_MODE (imode))
4515 int doing_unsigned = unsignedp;
4517 if (fmode != GET_MODE (to)
4518 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4519 continue;
4521 icode = can_float_p (fmode, imode, unsignedp);
4522 if (icode == CODE_FOR_nothing && unsignedp)
4524 enum insn_code scode = can_float_p (fmode, imode, 0);
4525 if (scode != CODE_FOR_nothing)
4526 can_do_signed = true;
4527 if (imode != GET_MODE (from))
4528 icode = scode, doing_unsigned = 0;
4531 if (icode != CODE_FOR_nothing)
4533 if (imode != GET_MODE (from))
4534 from = convert_to_mode (imode, from, unsignedp);
4536 if (fmode != GET_MODE (to))
4537 target = gen_reg_rtx (fmode);
4539 emit_unop_insn (icode, target, from,
4540 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4542 if (target != to)
4543 convert_move (to, target, 0);
4544 return;
4548 /* Unsigned integer, and no way to convert directly. For binary
4549 floating point modes, convert as signed, then conditionally adjust
4550 the result. */
4551 if (unsignedp && can_do_signed && !DECIMAL_FLOAT_MODE_P (GET_MODE (to)))
4553 rtx label = gen_label_rtx ();
4554 rtx temp;
4555 REAL_VALUE_TYPE offset;
4557 /* Look for a usable floating mode FMODE wider than the source and at
4558 least as wide as the target. Using FMODE will avoid rounding woes
4559 with unsigned values greater than the signed maximum value. */
4561 for (fmode = GET_MODE (to); fmode != VOIDmode;
4562 fmode = GET_MODE_WIDER_MODE (fmode))
4563 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4564 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4565 break;
4567 if (fmode == VOIDmode)
4569 /* There is no such mode. Pretend the target is wide enough. */
4570 fmode = GET_MODE (to);
4572 /* Avoid double-rounding when TO is narrower than FROM. */
4573 if ((significand_size (fmode) + 1)
4574 < GET_MODE_BITSIZE (GET_MODE (from)))
4576 rtx temp1;
4577 rtx neglabel = gen_label_rtx ();
4579 /* Don't use TARGET if it isn't a register, is a hard register,
4580 or is the wrong mode. */
4581 if (!REG_P (target)
4582 || REGNO (target) < FIRST_PSEUDO_REGISTER
4583 || GET_MODE (target) != fmode)
4584 target = gen_reg_rtx (fmode);
4586 imode = GET_MODE (from);
4587 do_pending_stack_adjust ();
4589 /* Test whether the sign bit is set. */
4590 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4591 0, neglabel);
4593 /* The sign bit is not set. Convert as signed. */
4594 expand_float (target, from, 0);
4595 emit_jump_insn (gen_jump (label));
4596 emit_barrier ();
4598 /* The sign bit is set.
4599 Convert to a usable (positive signed) value by shifting right
4600 one bit, while remembering if a nonzero bit was shifted
4601 out; i.e., compute (from & 1) | (from >> 1). */
4603 emit_label (neglabel);
4604 temp = expand_binop (imode, and_optab, from, const1_rtx,
4605 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4606 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4607 NULL_RTX, 1);
4608 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4609 OPTAB_LIB_WIDEN);
4610 expand_float (target, temp, 0);
4612 /* Multiply by 2 to undo the shift above. */
4613 temp = expand_binop (fmode, add_optab, target, target,
4614 target, 0, OPTAB_LIB_WIDEN);
4615 if (temp != target)
4616 emit_move_insn (target, temp);
4618 do_pending_stack_adjust ();
4619 emit_label (label);
4620 goto done;
4624 /* If we are about to do some arithmetic to correct for an
4625 unsigned operand, do it in a pseudo-register. */
4627 if (GET_MODE (to) != fmode
4628 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
4629 target = gen_reg_rtx (fmode);
4631 /* Convert as signed integer to floating. */
4632 expand_float (target, from, 0);
4634 /* If FROM is negative (and therefore TO is negative),
4635 correct its value by 2**bitwidth. */
4637 do_pending_stack_adjust ();
4638 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4639 0, label);
4642 real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
4643 temp = expand_binop (fmode, add_optab, target,
4644 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4645 target, 0, OPTAB_LIB_WIDEN);
4646 if (temp != target)
4647 emit_move_insn (target, temp);
4649 do_pending_stack_adjust ();
4650 emit_label (label);
4651 goto done;
4654 /* No hardware instruction available; call a library routine. */
4656 rtx libfunc;
4657 rtx insns;
4658 rtx value;
4659 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
4661 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4662 from = convert_to_mode (SImode, from, unsignedp);
4664 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4665 gcc_assert (libfunc);
4667 start_sequence ();
4669 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4670 GET_MODE (to), 1, from,
4671 GET_MODE (from));
4672 insns = get_insns ();
4673 end_sequence ();
4675 emit_libcall_block (insns, target, value,
4676 gen_rtx_FLOAT (GET_MODE (to), from));
4679 done:
4681 /* Copy result to requested destination
4682 if we have been computing in a temp location. */
4684 if (target != to)
4686 if (GET_MODE (target) == GET_MODE (to))
4687 emit_move_insn (to, target);
4688 else
4689 convert_move (to, target, 0);
4693 /* Generate code to convert FROM to fixed point and store in TO. FROM
4694 must be floating point. */
4696 void
4697 expand_fix (rtx to, rtx from, int unsignedp)
4699 enum insn_code icode;
4700 rtx target = to;
4701 enum machine_mode fmode, imode;
4702 int must_trunc = 0;
4704 /* We first try to find a pair of modes, one real and one integer, at
4705 least as wide as FROM and TO, respectively, in which we can open-code
4706 this conversion. If the integer mode is wider than the mode of TO,
4707 we can do the conversion either signed or unsigned. */
4709 for (fmode = GET_MODE (from); fmode != VOIDmode;
4710 fmode = GET_MODE_WIDER_MODE (fmode))
4711 for (imode = GET_MODE (to); imode != VOIDmode;
4712 imode = GET_MODE_WIDER_MODE (imode))
4714 int doing_unsigned = unsignedp;
4716 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4717 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4718 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4720 if (icode != CODE_FOR_nothing)
4722 if (fmode != GET_MODE (from))
4723 from = convert_to_mode (fmode, from, 0);
4725 if (must_trunc)
4727 rtx temp = gen_reg_rtx (GET_MODE (from));
4728 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4729 temp, 0);
4732 if (imode != GET_MODE (to))
4733 target = gen_reg_rtx (imode);
4735 emit_unop_insn (icode, target, from,
4736 doing_unsigned ? UNSIGNED_FIX : FIX);
4737 if (target != to)
4738 convert_move (to, target, unsignedp);
4739 return;
4743 /* For an unsigned conversion, there is one more way to do it.
4744 If we have a signed conversion, we generate code that compares
4745 the real value to the largest representable positive number. If if
4746 is smaller, the conversion is done normally. Otherwise, subtract
4747 one plus the highest signed number, convert, and add it back.
4749 We only need to check all real modes, since we know we didn't find
4750 anything with a wider integer mode.
4752 This code used to extend FP value into mode wider than the destination.
4753 This is not needed. Consider, for instance conversion from SFmode
4754 into DImode.
4756 The hot path through the code is dealing with inputs smaller than 2^63
4757 and doing just the conversion, so there is no bits to lose.
4759 In the other path we know the value is positive in the range 2^63..2^64-1
4760 inclusive. (as for other imput overflow happens and result is undefined)
4761 So we know that the most important bit set in mantissa corresponds to
4762 2^63. The subtraction of 2^63 should not generate any rounding as it
4763 simply clears out that bit. The rest is trivial. */
4765 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4766 for (fmode = GET_MODE (from); fmode != VOIDmode;
4767 fmode = GET_MODE_WIDER_MODE (fmode))
4768 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4769 &must_trunc))
4771 int bitsize;
4772 REAL_VALUE_TYPE offset;
4773 rtx limit, lab1, lab2, insn;
4775 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4776 real_2expN (&offset, bitsize - 1);
4777 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4778 lab1 = gen_label_rtx ();
4779 lab2 = gen_label_rtx ();
4781 if (fmode != GET_MODE (from))
4782 from = convert_to_mode (fmode, from, 0);
4784 /* See if we need to do the subtraction. */
4785 do_pending_stack_adjust ();
4786 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4787 0, lab1);
4789 /* If not, do the signed "fix" and branch around fixup code. */
4790 expand_fix (to, from, 0);
4791 emit_jump_insn (gen_jump (lab2));
4792 emit_barrier ();
4794 /* Otherwise, subtract 2**(N-1), convert to signed number,
4795 then add 2**(N-1). Do the addition using XOR since this
4796 will often generate better code. */
4797 emit_label (lab1);
4798 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4799 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4800 expand_fix (to, target, 0);
4801 target = expand_binop (GET_MODE (to), xor_optab, to,
4802 gen_int_mode
4803 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4804 GET_MODE (to)),
4805 to, 1, OPTAB_LIB_WIDEN);
4807 if (target != to)
4808 emit_move_insn (to, target);
4810 emit_label (lab2);
4812 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4813 != CODE_FOR_nothing)
4815 /* Make a place for a REG_NOTE and add it. */
4816 insn = emit_move_insn (to, to);
4817 set_unique_reg_note (insn,
4818 REG_EQUAL,
4819 gen_rtx_fmt_e (UNSIGNED_FIX,
4820 GET_MODE (to),
4821 copy_rtx (from)));
4824 return;
4827 /* We can't do it with an insn, so use a library call. But first ensure
4828 that the mode of TO is at least as wide as SImode, since those are the
4829 only library calls we know about. */
4831 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4833 target = gen_reg_rtx (SImode);
4835 expand_fix (target, from, unsignedp);
4837 else
4839 rtx insns;
4840 rtx value;
4841 rtx libfunc;
4843 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4844 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
4845 gcc_assert (libfunc);
4847 start_sequence ();
4849 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
4850 GET_MODE (to), 1, from,
4851 GET_MODE (from));
4852 insns = get_insns ();
4853 end_sequence ();
4855 emit_libcall_block (insns, target, value,
4856 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4857 GET_MODE (to), from));
4860 if (target != to)
4862 if (GET_MODE (to) == GET_MODE (target))
4863 emit_move_insn (to, target);
4864 else
4865 convert_move (to, target, 0);
4869 /* Generate code to convert FROM to fixed point and store in TO. FROM
4870 must be floating point, TO must be signed. Use the conversion optab
4871 TAB to do the conversion. */
4873 bool
4874 expand_sfix_optab (rtx to, rtx from, convert_optab tab)
4876 enum insn_code icode;
4877 rtx target = to;
4878 enum machine_mode fmode, imode;
4880 /* We first try to find a pair of modes, one real and one integer, at
4881 least as wide as FROM and TO, respectively, in which we can open-code
4882 this conversion. If the integer mode is wider than the mode of TO,
4883 we can do the conversion either signed or unsigned. */
4885 for (fmode = GET_MODE (from); fmode != VOIDmode;
4886 fmode = GET_MODE_WIDER_MODE (fmode))
4887 for (imode = GET_MODE (to); imode != VOIDmode;
4888 imode = GET_MODE_WIDER_MODE (imode))
4890 icode = tab->handlers[imode][fmode].insn_code;
4891 if (icode != CODE_FOR_nothing)
4893 if (fmode != GET_MODE (from))
4894 from = convert_to_mode (fmode, from, 0);
4896 if (imode != GET_MODE (to))
4897 target = gen_reg_rtx (imode);
4899 emit_unop_insn (icode, target, from, UNKNOWN);
4900 if (target != to)
4901 convert_move (to, target, 0);
4902 return true;
4906 return false;
4909 /* Report whether we have an instruction to perform the operation
4910 specified by CODE on operands of mode MODE. */
4912 have_insn_for (enum rtx_code code, enum machine_mode mode)
4914 return (code_to_optab[(int) code] != 0
4915 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4916 != CODE_FOR_nothing));
4919 /* Create a blank optab. */
4920 static optab
4921 new_optab (void)
4923 int i;
4924 optab op = ggc_alloc (sizeof (struct optab));
4925 for (i = 0; i < NUM_MACHINE_MODES; i++)
4927 op->handlers[i].insn_code = CODE_FOR_nothing;
4928 op->handlers[i].libfunc = 0;
4931 return op;
4934 static convert_optab
4935 new_convert_optab (void)
4937 int i, j;
4938 convert_optab op = ggc_alloc (sizeof (struct convert_optab));
4939 for (i = 0; i < NUM_MACHINE_MODES; i++)
4940 for (j = 0; j < NUM_MACHINE_MODES; j++)
4942 op->handlers[i][j].insn_code = CODE_FOR_nothing;
4943 op->handlers[i][j].libfunc = 0;
4945 return op;
4948 /* Same, but fill in its code as CODE, and write it into the
4949 code_to_optab table. */
4950 static inline optab
4951 init_optab (enum rtx_code code)
4953 optab op = new_optab ();
4954 op->code = code;
4955 code_to_optab[(int) code] = op;
4956 return op;
4959 /* Same, but fill in its code as CODE, and do _not_ write it into
4960 the code_to_optab table. */
4961 static inline optab
4962 init_optabv (enum rtx_code code)
4964 optab op = new_optab ();
4965 op->code = code;
4966 return op;
4969 /* Conversion optabs never go in the code_to_optab table. */
4970 static inline convert_optab
4971 init_convert_optab (enum rtx_code code)
4973 convert_optab op = new_convert_optab ();
4974 op->code = code;
4975 return op;
4978 /* Initialize the libfunc fields of an entire group of entries in some
4979 optab. Each entry is set equal to a string consisting of a leading
4980 pair of underscores followed by a generic operation name followed by
4981 a mode name (downshifted to lowercase) followed by a single character
4982 representing the number of operands for the given operation (which is
4983 usually one of the characters '2', '3', or '4').
4985 OPTABLE is the table in which libfunc fields are to be initialized.
4986 FIRST_MODE is the first machine mode index in the given optab to
4987 initialize.
4988 LAST_MODE is the last machine mode index in the given optab to
4989 initialize.
4990 OPNAME is the generic (string) name of the operation.
4991 SUFFIX is the character which specifies the number of operands for
4992 the given generic operation.
4995 static void
4996 init_libfuncs (optab optable, int first_mode, int last_mode,
4997 const char *opname, int suffix)
4999 int mode;
5000 unsigned opname_len = strlen (opname);
5002 for (mode = first_mode; (int) mode <= (int) last_mode;
5003 mode = (enum machine_mode) ((int) mode + 1))
5005 const char *mname = GET_MODE_NAME (mode);
5006 unsigned mname_len = strlen (mname);
5007 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
5008 char *p;
5009 const char *q;
5011 p = libfunc_name;
5012 *p++ = '_';
5013 *p++ = '_';
5014 for (q = opname; *q; )
5015 *p++ = *q++;
5016 for (q = mname; *q; q++)
5017 *p++ = TOLOWER (*q);
5018 *p++ = suffix;
5019 *p = '\0';
5021 optable->handlers[(int) mode].libfunc
5022 = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
5026 /* Initialize the libfunc fields of an entire group of entries in some
5027 optab which correspond to all integer mode operations. The parameters
5028 have the same meaning as similarly named ones for the `init_libfuncs'
5029 routine. (See above). */
5031 static void
5032 init_integral_libfuncs (optab optable, const char *opname, int suffix)
5034 int maxsize = 2*BITS_PER_WORD;
5035 if (maxsize < LONG_LONG_TYPE_SIZE)
5036 maxsize = LONG_LONG_TYPE_SIZE;
5037 init_libfuncs (optable, word_mode,
5038 mode_for_size (maxsize, MODE_INT, 0),
5039 opname, suffix);
5042 /* Initialize the libfunc fields of an entire group of entries in some
5043 optab which correspond to all real mode operations. The parameters
5044 have the same meaning as similarly named ones for the `init_libfuncs'
5045 routine. (See above). */
5047 static void
5048 init_floating_libfuncs (optab optable, const char *opname, int suffix)
5050 init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
5051 init_libfuncs (optable, MIN_MODE_DECIMAL_FLOAT, MAX_MODE_DECIMAL_FLOAT,
5052 opname, suffix);
5055 /* Initialize the libfunc fields of an entire group of entries of an
5056 inter-mode-class conversion optab. The string formation rules are
5057 similar to the ones for init_libfuncs, above, but instead of having
5058 a mode name and an operand count these functions have two mode names
5059 and no operand count. */
5060 static void
5061 init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
5062 enum mode_class from_class,
5063 enum mode_class to_class)
5065 enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
5066 enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
5067 size_t opname_len = strlen (opname);
5068 size_t max_mname_len = 0;
5070 enum machine_mode fmode, tmode;
5071 const char *fname, *tname;
5072 const char *q;
5073 char *libfunc_name, *suffix;
5074 char *p;
5076 for (fmode = first_from_mode;
5077 fmode != VOIDmode;
5078 fmode = GET_MODE_WIDER_MODE (fmode))
5079 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
5081 for (tmode = first_to_mode;
5082 tmode != VOIDmode;
5083 tmode = GET_MODE_WIDER_MODE (tmode))
5084 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
5086 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5087 libfunc_name[0] = '_';
5088 libfunc_name[1] = '_';
5089 memcpy (&libfunc_name[2], opname, opname_len);
5090 suffix = libfunc_name + opname_len + 2;
5092 for (fmode = first_from_mode; fmode != VOIDmode;
5093 fmode = GET_MODE_WIDER_MODE (fmode))
5094 for (tmode = first_to_mode; tmode != VOIDmode;
5095 tmode = GET_MODE_WIDER_MODE (tmode))
5097 fname = GET_MODE_NAME (fmode);
5098 tname = GET_MODE_NAME (tmode);
5100 p = suffix;
5101 for (q = fname; *q; p++, q++)
5102 *p = TOLOWER (*q);
5103 for (q = tname; *q; p++, q++)
5104 *p = TOLOWER (*q);
5106 *p = '\0';
5108 tab->handlers[tmode][fmode].libfunc
5109 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5110 p - libfunc_name));
5114 /* Initialize the libfunc fields of an entire group of entries of an
5115 intra-mode-class conversion optab. The string formation rules are
5116 similar to the ones for init_libfunc, above. WIDENING says whether
5117 the optab goes from narrow to wide modes or vice versa. These functions
5118 have two mode names _and_ an operand count. */
5119 static void
5120 init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
5121 enum mode_class class, bool widening)
5123 enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
5124 size_t opname_len = strlen (opname);
5125 size_t max_mname_len = 0;
5127 enum machine_mode nmode, wmode;
5128 const char *nname, *wname;
5129 const char *q;
5130 char *libfunc_name, *suffix;
5131 char *p;
5133 for (nmode = first_mode; nmode != VOIDmode;
5134 nmode = GET_MODE_WIDER_MODE (nmode))
5135 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
5137 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
5138 libfunc_name[0] = '_';
5139 libfunc_name[1] = '_';
5140 memcpy (&libfunc_name[2], opname, opname_len);
5141 suffix = libfunc_name + opname_len + 2;
5143 for (nmode = first_mode; nmode != VOIDmode;
5144 nmode = GET_MODE_WIDER_MODE (nmode))
5145 for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
5146 wmode = GET_MODE_WIDER_MODE (wmode))
5148 nname = GET_MODE_NAME (nmode);
5149 wname = GET_MODE_NAME (wmode);
5151 p = suffix;
5152 for (q = widening ? nname : wname; *q; p++, q++)
5153 *p = TOLOWER (*q);
5154 for (q = widening ? wname : nname; *q; p++, q++)
5155 *p = TOLOWER (*q);
5157 *p++ = '2';
5158 *p = '\0';
5160 tab->handlers[widening ? wmode : nmode]
5161 [widening ? nmode : wmode].libfunc
5162 = init_one_libfunc (ggc_alloc_string (libfunc_name,
5163 p - libfunc_name));
5169 init_one_libfunc (const char *name)
5171 rtx symbol;
5173 /* Create a FUNCTION_DECL that can be passed to
5174 targetm.encode_section_info. */
5175 /* ??? We don't have any type information except for this is
5176 a function. Pretend this is "int foo()". */
5177 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
5178 build_function_type (integer_type_node, NULL_TREE));
5179 DECL_ARTIFICIAL (decl) = 1;
5180 DECL_EXTERNAL (decl) = 1;
5181 TREE_PUBLIC (decl) = 1;
5183 symbol = XEXP (DECL_RTL (decl), 0);
5185 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
5186 are the flags assigned by targetm.encode_section_info. */
5187 SET_SYMBOL_REF_DECL (symbol, 0);
5189 return symbol;
5192 /* Call this to reset the function entry for one optab (OPTABLE) in mode
5193 MODE to NAME, which should be either 0 or a string constant. */
5194 void
5195 set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
5197 if (name)
5198 optable->handlers[mode].libfunc = init_one_libfunc (name);
5199 else
5200 optable->handlers[mode].libfunc = 0;
5203 /* Call this to reset the function entry for one conversion optab
5204 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
5205 either 0 or a string constant. */
5206 void
5207 set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
5208 enum machine_mode fmode, const char *name)
5210 if (name)
5211 optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
5212 else
5213 optable->handlers[tmode][fmode].libfunc = 0;
5216 /* Call this once to initialize the contents of the optabs
5217 appropriately for the current target machine. */
5219 void
5220 init_optabs (void)
5222 unsigned int i;
5224 /* Start by initializing all tables to contain CODE_FOR_nothing. */
5226 for (i = 0; i < NUM_RTX_CODE; i++)
5227 setcc_gen_code[i] = CODE_FOR_nothing;
5229 #ifdef HAVE_conditional_move
5230 for (i = 0; i < NUM_MACHINE_MODES; i++)
5231 movcc_gen_code[i] = CODE_FOR_nothing;
5232 #endif
5234 for (i = 0; i < NUM_MACHINE_MODES; i++)
5236 vcond_gen_code[i] = CODE_FOR_nothing;
5237 vcondu_gen_code[i] = CODE_FOR_nothing;
5240 add_optab = init_optab (PLUS);
5241 addv_optab = init_optabv (PLUS);
5242 sub_optab = init_optab (MINUS);
5243 subv_optab = init_optabv (MINUS);
5244 smul_optab = init_optab (MULT);
5245 smulv_optab = init_optabv (MULT);
5246 smul_highpart_optab = init_optab (UNKNOWN);
5247 umul_highpart_optab = init_optab (UNKNOWN);
5248 smul_widen_optab = init_optab (UNKNOWN);
5249 umul_widen_optab = init_optab (UNKNOWN);
5250 usmul_widen_optab = init_optab (UNKNOWN);
5251 sdiv_optab = init_optab (DIV);
5252 sdivv_optab = init_optabv (DIV);
5253 sdivmod_optab = init_optab (UNKNOWN);
5254 udiv_optab = init_optab (UDIV);
5255 udivmod_optab = init_optab (UNKNOWN);
5256 smod_optab = init_optab (MOD);
5257 umod_optab = init_optab (UMOD);
5258 fmod_optab = init_optab (UNKNOWN);
5259 remainder_optab = init_optab (UNKNOWN);
5260 ftrunc_optab = init_optab (UNKNOWN);
5261 and_optab = init_optab (AND);
5262 ior_optab = init_optab (IOR);
5263 xor_optab = init_optab (XOR);
5264 ashl_optab = init_optab (ASHIFT);
5265 ashr_optab = init_optab (ASHIFTRT);
5266 lshr_optab = init_optab (LSHIFTRT);
5267 rotl_optab = init_optab (ROTATE);
5268 rotr_optab = init_optab (ROTATERT);
5269 smin_optab = init_optab (SMIN);
5270 smax_optab = init_optab (SMAX);
5271 umin_optab = init_optab (UMIN);
5272 umax_optab = init_optab (UMAX);
5273 pow_optab = init_optab (UNKNOWN);
5274 atan2_optab = init_optab (UNKNOWN);
5276 /* These three have codes assigned exclusively for the sake of
5277 have_insn_for. */
5278 mov_optab = init_optab (SET);
5279 movstrict_optab = init_optab (STRICT_LOW_PART);
5280 cmp_optab = init_optab (COMPARE);
5282 ucmp_optab = init_optab (UNKNOWN);
5283 tst_optab = init_optab (UNKNOWN);
5285 eq_optab = init_optab (EQ);
5286 ne_optab = init_optab (NE);
5287 gt_optab = init_optab (GT);
5288 ge_optab = init_optab (GE);
5289 lt_optab = init_optab (LT);
5290 le_optab = init_optab (LE);
5291 unord_optab = init_optab (UNORDERED);
5293 neg_optab = init_optab (NEG);
5294 negv_optab = init_optabv (NEG);
5295 abs_optab = init_optab (ABS);
5296 absv_optab = init_optabv (ABS);
5297 addcc_optab = init_optab (UNKNOWN);
5298 one_cmpl_optab = init_optab (NOT);
5299 bswap_optab = init_optab (BSWAP);
5300 ffs_optab = init_optab (FFS);
5301 clz_optab = init_optab (CLZ);
5302 ctz_optab = init_optab (CTZ);
5303 popcount_optab = init_optab (POPCOUNT);
5304 parity_optab = init_optab (PARITY);
5305 sqrt_optab = init_optab (SQRT);
5306 floor_optab = init_optab (UNKNOWN);
5307 ceil_optab = init_optab (UNKNOWN);
5308 round_optab = init_optab (UNKNOWN);
5309 btrunc_optab = init_optab (UNKNOWN);
5310 nearbyint_optab = init_optab (UNKNOWN);
5311 rint_optab = init_optab (UNKNOWN);
5312 sincos_optab = init_optab (UNKNOWN);
5313 sin_optab = init_optab (UNKNOWN);
5314 asin_optab = init_optab (UNKNOWN);
5315 cos_optab = init_optab (UNKNOWN);
5316 acos_optab = init_optab (UNKNOWN);
5317 exp_optab = init_optab (UNKNOWN);
5318 exp10_optab = init_optab (UNKNOWN);
5319 exp2_optab = init_optab (UNKNOWN);
5320 expm1_optab = init_optab (UNKNOWN);
5321 ldexp_optab = init_optab (UNKNOWN);
5322 logb_optab = init_optab (UNKNOWN);
5323 ilogb_optab = init_optab (UNKNOWN);
5324 log_optab = init_optab (UNKNOWN);
5325 log10_optab = init_optab (UNKNOWN);
5326 log2_optab = init_optab (UNKNOWN);
5327 log1p_optab = init_optab (UNKNOWN);
5328 tan_optab = init_optab (UNKNOWN);
5329 atan_optab = init_optab (UNKNOWN);
5330 copysign_optab = init_optab (UNKNOWN);
5332 strlen_optab = init_optab (UNKNOWN);
5333 cbranch_optab = init_optab (UNKNOWN);
5334 cmov_optab = init_optab (UNKNOWN);
5335 cstore_optab = init_optab (UNKNOWN);
5336 push_optab = init_optab (UNKNOWN);
5338 reduc_smax_optab = init_optab (UNKNOWN);
5339 reduc_umax_optab = init_optab (UNKNOWN);
5340 reduc_smin_optab = init_optab (UNKNOWN);
5341 reduc_umin_optab = init_optab (UNKNOWN);
5342 reduc_splus_optab = init_optab (UNKNOWN);
5343 reduc_uplus_optab = init_optab (UNKNOWN);
5345 ssum_widen_optab = init_optab (UNKNOWN);
5346 usum_widen_optab = init_optab (UNKNOWN);
5347 sdot_prod_optab = init_optab (UNKNOWN);
5348 udot_prod_optab = init_optab (UNKNOWN);
5350 vec_extract_optab = init_optab (UNKNOWN);
5351 vec_set_optab = init_optab (UNKNOWN);
5352 vec_init_optab = init_optab (UNKNOWN);
5353 vec_shl_optab = init_optab (UNKNOWN);
5354 vec_shr_optab = init_optab (UNKNOWN);
5355 vec_realign_load_optab = init_optab (UNKNOWN);
5356 movmisalign_optab = init_optab (UNKNOWN);
5358 powi_optab = init_optab (UNKNOWN);
5360 /* Conversions. */
5361 sext_optab = init_convert_optab (SIGN_EXTEND);
5362 zext_optab = init_convert_optab (ZERO_EXTEND);
5363 trunc_optab = init_convert_optab (TRUNCATE);
5364 sfix_optab = init_convert_optab (FIX);
5365 ufix_optab = init_convert_optab (UNSIGNED_FIX);
5366 sfixtrunc_optab = init_convert_optab (UNKNOWN);
5367 ufixtrunc_optab = init_convert_optab (UNKNOWN);
5368 sfloat_optab = init_convert_optab (FLOAT);
5369 ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5370 lrint_optab = init_convert_optab (UNKNOWN);
5371 lround_optab = init_convert_optab (UNKNOWN);
5372 lfloor_optab = init_convert_optab (UNKNOWN);
5373 lceil_optab = init_convert_optab (UNKNOWN);
5375 for (i = 0; i < NUM_MACHINE_MODES; i++)
5377 movmem_optab[i] = CODE_FOR_nothing;
5378 cmpstr_optab[i] = CODE_FOR_nothing;
5379 cmpstrn_optab[i] = CODE_FOR_nothing;
5380 cmpmem_optab[i] = CODE_FOR_nothing;
5381 setmem_optab[i] = CODE_FOR_nothing;
5383 sync_add_optab[i] = CODE_FOR_nothing;
5384 sync_sub_optab[i] = CODE_FOR_nothing;
5385 sync_ior_optab[i] = CODE_FOR_nothing;
5386 sync_and_optab[i] = CODE_FOR_nothing;
5387 sync_xor_optab[i] = CODE_FOR_nothing;
5388 sync_nand_optab[i] = CODE_FOR_nothing;
5389 sync_old_add_optab[i] = CODE_FOR_nothing;
5390 sync_old_sub_optab[i] = CODE_FOR_nothing;
5391 sync_old_ior_optab[i] = CODE_FOR_nothing;
5392 sync_old_and_optab[i] = CODE_FOR_nothing;
5393 sync_old_xor_optab[i] = CODE_FOR_nothing;
5394 sync_old_nand_optab[i] = CODE_FOR_nothing;
5395 sync_new_add_optab[i] = CODE_FOR_nothing;
5396 sync_new_sub_optab[i] = CODE_FOR_nothing;
5397 sync_new_ior_optab[i] = CODE_FOR_nothing;
5398 sync_new_and_optab[i] = CODE_FOR_nothing;
5399 sync_new_xor_optab[i] = CODE_FOR_nothing;
5400 sync_new_nand_optab[i] = CODE_FOR_nothing;
5401 sync_compare_and_swap[i] = CODE_FOR_nothing;
5402 sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5403 sync_lock_test_and_set[i] = CODE_FOR_nothing;
5404 sync_lock_release[i] = CODE_FOR_nothing;
5406 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
5409 /* Fill in the optabs with the insns we support. */
5410 init_all_optabs ();
5412 /* Initialize the optabs with the names of the library functions. */
5413 init_integral_libfuncs (add_optab, "add", '3');
5414 init_floating_libfuncs (add_optab, "add", '3');
5415 init_integral_libfuncs (addv_optab, "addv", '3');
5416 init_floating_libfuncs (addv_optab, "add", '3');
5417 init_integral_libfuncs (sub_optab, "sub", '3');
5418 init_floating_libfuncs (sub_optab, "sub", '3');
5419 init_integral_libfuncs (subv_optab, "subv", '3');
5420 init_floating_libfuncs (subv_optab, "sub", '3');
5421 init_integral_libfuncs (smul_optab, "mul", '3');
5422 init_floating_libfuncs (smul_optab, "mul", '3');
5423 init_integral_libfuncs (smulv_optab, "mulv", '3');
5424 init_floating_libfuncs (smulv_optab, "mul", '3');
5425 init_integral_libfuncs (sdiv_optab, "div", '3');
5426 init_floating_libfuncs (sdiv_optab, "div", '3');
5427 init_integral_libfuncs (sdivv_optab, "divv", '3');
5428 init_integral_libfuncs (udiv_optab, "udiv", '3');
5429 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5430 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5431 init_integral_libfuncs (smod_optab, "mod", '3');
5432 init_integral_libfuncs (umod_optab, "umod", '3');
5433 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5434 init_integral_libfuncs (and_optab, "and", '3');
5435 init_integral_libfuncs (ior_optab, "ior", '3');
5436 init_integral_libfuncs (xor_optab, "xor", '3');
5437 init_integral_libfuncs (ashl_optab, "ashl", '3');
5438 init_integral_libfuncs (ashr_optab, "ashr", '3');
5439 init_integral_libfuncs (lshr_optab, "lshr", '3');
5440 init_integral_libfuncs (smin_optab, "min", '3');
5441 init_floating_libfuncs (smin_optab, "min", '3');
5442 init_integral_libfuncs (smax_optab, "max", '3');
5443 init_floating_libfuncs (smax_optab, "max", '3');
5444 init_integral_libfuncs (umin_optab, "umin", '3');
5445 init_integral_libfuncs (umax_optab, "umax", '3');
5446 init_integral_libfuncs (neg_optab, "neg", '2');
5447 init_floating_libfuncs (neg_optab, "neg", '2');
5448 init_integral_libfuncs (negv_optab, "negv", '2');
5449 init_floating_libfuncs (negv_optab, "neg", '2');
5450 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5451 init_integral_libfuncs (ffs_optab, "ffs", '2');
5452 init_integral_libfuncs (clz_optab, "clz", '2');
5453 init_integral_libfuncs (ctz_optab, "ctz", '2');
5454 init_integral_libfuncs (popcount_optab, "popcount", '2');
5455 init_integral_libfuncs (parity_optab, "parity", '2');
5457 /* Comparison libcalls for integers MUST come in pairs,
5458 signed/unsigned. */
5459 init_integral_libfuncs (cmp_optab, "cmp", '2');
5460 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5461 init_floating_libfuncs (cmp_optab, "cmp", '2');
5463 /* EQ etc are floating point only. */
5464 init_floating_libfuncs (eq_optab, "eq", '2');
5465 init_floating_libfuncs (ne_optab, "ne", '2');
5466 init_floating_libfuncs (gt_optab, "gt", '2');
5467 init_floating_libfuncs (ge_optab, "ge", '2');
5468 init_floating_libfuncs (lt_optab, "lt", '2');
5469 init_floating_libfuncs (le_optab, "le", '2');
5470 init_floating_libfuncs (unord_optab, "unord", '2');
5472 init_floating_libfuncs (powi_optab, "powi", '2');
5474 /* Conversions. */
5475 init_interclass_conv_libfuncs (sfloat_optab, "float",
5476 MODE_INT, MODE_FLOAT);
5477 init_interclass_conv_libfuncs (sfloat_optab, "float",
5478 MODE_INT, MODE_DECIMAL_FLOAT);
5479 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5480 MODE_INT, MODE_FLOAT);
5481 init_interclass_conv_libfuncs (ufloat_optab, "floatun",
5482 MODE_INT, MODE_DECIMAL_FLOAT);
5483 init_interclass_conv_libfuncs (sfix_optab, "fix",
5484 MODE_FLOAT, MODE_INT);
5485 init_interclass_conv_libfuncs (sfix_optab, "fix",
5486 MODE_DECIMAL_FLOAT, MODE_INT);
5487 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5488 MODE_FLOAT, MODE_INT);
5489 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
5490 MODE_DECIMAL_FLOAT, MODE_INT);
5491 init_interclass_conv_libfuncs (ufloat_optab, "floatuns",
5492 MODE_INT, MODE_DECIMAL_FLOAT);
5493 init_interclass_conv_libfuncs (lrint_optab, "lrint",
5494 MODE_INT, MODE_FLOAT);
5495 init_interclass_conv_libfuncs (lround_optab, "lround",
5496 MODE_INT, MODE_FLOAT);
5497 init_interclass_conv_libfuncs (lfloor_optab, "lfloor",
5498 MODE_INT, MODE_FLOAT);
5499 init_interclass_conv_libfuncs (lceil_optab, "lceil",
5500 MODE_INT, MODE_FLOAT);
5502 /* sext_optab is also used for FLOAT_EXTEND. */
5503 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5504 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, true);
5505 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5506 init_interclass_conv_libfuncs (sext_optab, "extend", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5507 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
5508 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, false);
5509 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, MODE_DECIMAL_FLOAT);
5510 init_interclass_conv_libfuncs (trunc_optab, "trunc", MODE_DECIMAL_FLOAT, MODE_FLOAT);
5512 /* Explicitly initialize the bswap libfuncs since we need them to be
5513 valid for things other than word_mode. */
5514 set_optab_libfunc (bswap_optab, SImode, "__bswapsi2");
5515 set_optab_libfunc (bswap_optab, DImode, "__bswapdi2");
5517 /* Use cabs for double complex abs, since systems generally have cabs.
5518 Don't define any libcall for float complex, so that cabs will be used. */
5519 if (complex_double_type_node)
5520 abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5521 = init_one_libfunc ("cabs");
5523 /* The ffs function operates on `int'. */
5524 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5525 = init_one_libfunc ("ffs");
5527 abort_libfunc = init_one_libfunc ("abort");
5528 memcpy_libfunc = init_one_libfunc ("memcpy");
5529 memmove_libfunc = init_one_libfunc ("memmove");
5530 memcmp_libfunc = init_one_libfunc ("memcmp");
5531 memset_libfunc = init_one_libfunc ("memset");
5532 setbits_libfunc = init_one_libfunc ("__setbits");
5534 #ifndef DONT_USE_BUILTIN_SETJMP
5535 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5536 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5537 #else
5538 setjmp_libfunc = init_one_libfunc ("setjmp");
5539 longjmp_libfunc = init_one_libfunc ("longjmp");
5540 #endif
5541 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5542 unwind_sjlj_unregister_libfunc
5543 = init_one_libfunc ("_Unwind_SjLj_Unregister");
5545 /* For function entry/exit instrumentation. */
5546 profile_function_entry_libfunc
5547 = init_one_libfunc ("__cyg_profile_func_enter");
5548 profile_function_exit_libfunc
5549 = init_one_libfunc ("__cyg_profile_func_exit");
5551 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
5553 if (HAVE_conditional_trap)
5554 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5556 /* Allow the target to add more libcalls or rename some, etc. */
5557 targetm.init_libfuncs ();
5560 #ifdef DEBUG
5562 /* Print information about the current contents of the optabs on
5563 STDERR. */
5565 static void
5566 debug_optab_libfuncs (void)
5568 int i;
5569 int j;
5570 int k;
5572 /* Dump the arithmetic optabs. */
5573 for (i = 0; i != (int) OTI_MAX; i++)
5574 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5576 optab o;
5577 struct optab_handlers *h;
5579 o = optab_table[i];
5580 h = &o->handlers[j];
5581 if (h->libfunc)
5583 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5584 fprintf (stderr, "%s\t%s:\t%s\n",
5585 GET_RTX_NAME (o->code),
5586 GET_MODE_NAME (j),
5587 XSTR (h->libfunc, 0));
5591 /* Dump the conversion optabs. */
5592 for (i = 0; i < (int) COI_MAX; ++i)
5593 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5594 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5596 convert_optab o;
5597 struct optab_handlers *h;
5599 o = &convert_optab_table[i];
5600 h = &o->handlers[j][k];
5601 if (h->libfunc)
5603 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5604 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
5605 GET_RTX_NAME (o->code),
5606 GET_MODE_NAME (j),
5607 GET_MODE_NAME (k),
5608 XSTR (h->libfunc, 0));
5613 #endif /* DEBUG */
5616 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5617 CODE. Return 0 on failure. */
5620 gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5621 rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
5623 enum machine_mode mode = GET_MODE (op1);
5624 enum insn_code icode;
5625 rtx insn;
5627 if (!HAVE_conditional_trap)
5628 return 0;
5630 if (mode == VOIDmode)
5631 return 0;
5633 icode = cmp_optab->handlers[(int) mode].insn_code;
5634 if (icode == CODE_FOR_nothing)
5635 return 0;
5637 start_sequence ();
5638 op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
5639 op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
5640 if (!op1 || !op2)
5642 end_sequence ();
5643 return 0;
5645 emit_insn (GEN_FCN (icode) (op1, op2));
5647 PUT_CODE (trap_rtx, code);
5648 gcc_assert (HAVE_conditional_trap);
5649 insn = gen_conditional_trap (trap_rtx, tcode);
5650 if (insn)
5652 emit_insn (insn);
5653 insn = get_insns ();
5655 end_sequence ();
5657 return insn;
5660 /* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5661 or unsigned operation code. */
5663 static enum rtx_code
5664 get_rtx_code (enum tree_code tcode, bool unsignedp)
5666 enum rtx_code code;
5667 switch (tcode)
5669 case EQ_EXPR:
5670 code = EQ;
5671 break;
5672 case NE_EXPR:
5673 code = NE;
5674 break;
5675 case LT_EXPR:
5676 code = unsignedp ? LTU : LT;
5677 break;
5678 case LE_EXPR:
5679 code = unsignedp ? LEU : LE;
5680 break;
5681 case GT_EXPR:
5682 code = unsignedp ? GTU : GT;
5683 break;
5684 case GE_EXPR:
5685 code = unsignedp ? GEU : GE;
5686 break;
5688 case UNORDERED_EXPR:
5689 code = UNORDERED;
5690 break;
5691 case ORDERED_EXPR:
5692 code = ORDERED;
5693 break;
5694 case UNLT_EXPR:
5695 code = UNLT;
5696 break;
5697 case UNLE_EXPR:
5698 code = UNLE;
5699 break;
5700 case UNGT_EXPR:
5701 code = UNGT;
5702 break;
5703 case UNGE_EXPR:
5704 code = UNGE;
5705 break;
5706 case UNEQ_EXPR:
5707 code = UNEQ;
5708 break;
5709 case LTGT_EXPR:
5710 code = LTGT;
5711 break;
5713 default:
5714 gcc_unreachable ();
5716 return code;
5719 /* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5720 unsigned operators. Do not generate compare instruction. */
5722 static rtx
5723 vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
5725 enum rtx_code rcode;
5726 tree t_op0, t_op1;
5727 rtx rtx_op0, rtx_op1;
5729 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
5730 ensures that condition is a relational operation. */
5731 gcc_assert (COMPARISON_CLASS_P (cond));
5733 rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
5734 t_op0 = TREE_OPERAND (cond, 0);
5735 t_op1 = TREE_OPERAND (cond, 1);
5737 /* Expand operands. */
5738 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)), 1);
5739 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)), 1);
5741 if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
5742 && GET_MODE (rtx_op0) != VOIDmode)
5743 rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
5745 if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
5746 && GET_MODE (rtx_op1) != VOIDmode)
5747 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5749 return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
5752 /* Return insn code for VEC_COND_EXPR EXPR. */
5754 static inline enum insn_code
5755 get_vcond_icode (tree expr, enum machine_mode mode)
5757 enum insn_code icode = CODE_FOR_nothing;
5759 if (TYPE_UNSIGNED (TREE_TYPE (expr)))
5760 icode = vcondu_gen_code[mode];
5761 else
5762 icode = vcond_gen_code[mode];
5763 return icode;
5766 /* Return TRUE iff, appropriate vector insns are available
5767 for vector cond expr expr in VMODE mode. */
5769 bool
5770 expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
5772 if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
5773 return false;
5774 return true;
5777 /* Generate insns for VEC_COND_EXPR. */
5780 expand_vec_cond_expr (tree vec_cond_expr, rtx target)
5782 enum insn_code icode;
5783 rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
5784 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
5785 bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
5787 icode = get_vcond_icode (vec_cond_expr, mode);
5788 if (icode == CODE_FOR_nothing)
5789 return 0;
5791 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5792 target = gen_reg_rtx (mode);
5794 /* Get comparison rtx. First expand both cond expr operands. */
5795 comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
5796 unsignedp, icode);
5797 cc_op0 = XEXP (comparison, 0);
5798 cc_op1 = XEXP (comparison, 1);
5799 /* Expand both operands and force them in reg, if required. */
5800 rtx_op1 = expand_expr (TREE_OPERAND (vec_cond_expr, 1),
5801 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5802 if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
5803 && mode != VOIDmode)
5804 rtx_op1 = force_reg (mode, rtx_op1);
5806 rtx_op2 = expand_expr (TREE_OPERAND (vec_cond_expr, 2),
5807 NULL_RTX, VOIDmode, EXPAND_NORMAL);
5808 if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
5809 && mode != VOIDmode)
5810 rtx_op2 = force_reg (mode, rtx_op2);
5812 /* Emit instruction! */
5813 emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
5814 comparison, cc_op0, cc_op1));
5816 return target;
5820 /* This is an internal subroutine of the other compare_and_swap expanders.
5821 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
5822 operation. TARGET is an optional place to store the value result of
5823 the operation. ICODE is the particular instruction to expand. Return
5824 the result of the operation. */
5826 static rtx
5827 expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
5828 rtx target, enum insn_code icode)
5830 enum machine_mode mode = GET_MODE (mem);
5831 rtx insn;
5833 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5834 target = gen_reg_rtx (mode);
5836 if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
5837 old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
5838 if (!insn_data[icode].operand[2].predicate (old_val, mode))
5839 old_val = force_reg (mode, old_val);
5841 if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
5842 new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
5843 if (!insn_data[icode].operand[3].predicate (new_val, mode))
5844 new_val = force_reg (mode, new_val);
5846 insn = GEN_FCN (icode) (target, mem, old_val, new_val);
5847 if (insn == NULL_RTX)
5848 return NULL_RTX;
5849 emit_insn (insn);
5851 return target;
5854 /* Expand a compare-and-swap operation and return its value. */
5857 expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5859 enum machine_mode mode = GET_MODE (mem);
5860 enum insn_code icode = sync_compare_and_swap[mode];
5862 if (icode == CODE_FOR_nothing)
5863 return NULL_RTX;
5865 return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
5868 /* Expand a compare-and-swap operation and store true into the result if
5869 the operation was successful and false otherwise. Return the result.
5870 Unlike other routines, TARGET is not optional. */
5873 expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5875 enum machine_mode mode = GET_MODE (mem);
5876 enum insn_code icode;
5877 rtx subtarget, label0, label1;
5879 /* If the target supports a compare-and-swap pattern that simultaneously
5880 sets some flag for success, then use it. Otherwise use the regular
5881 compare-and-swap and follow that immediately with a compare insn. */
5882 icode = sync_compare_and_swap_cc[mode];
5883 switch (icode)
5885 default:
5886 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5887 NULL_RTX, icode);
5888 if (subtarget != NULL_RTX)
5889 break;
5891 /* FALLTHRU */
5892 case CODE_FOR_nothing:
5893 icode = sync_compare_and_swap[mode];
5894 if (icode == CODE_FOR_nothing)
5895 return NULL_RTX;
5897 /* Ensure that if old_val == mem, that we're not comparing
5898 against an old value. */
5899 if (MEM_P (old_val))
5900 old_val = force_reg (mode, old_val);
5902 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5903 NULL_RTX, icode);
5904 if (subtarget == NULL_RTX)
5905 return NULL_RTX;
5907 emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
5910 /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
5911 setcc instruction from the beginning. We don't work too hard here,
5912 but it's nice to not be stupid about initial code gen either. */
5913 if (STORE_FLAG_VALUE == 1)
5915 icode = setcc_gen_code[EQ];
5916 if (icode != CODE_FOR_nothing)
5918 enum machine_mode cmode = insn_data[icode].operand[0].mode;
5919 rtx insn;
5921 subtarget = target;
5922 if (!insn_data[icode].operand[0].predicate (target, cmode))
5923 subtarget = gen_reg_rtx (cmode);
5925 insn = GEN_FCN (icode) (subtarget);
5926 if (insn)
5928 emit_insn (insn);
5929 if (GET_MODE (target) != GET_MODE (subtarget))
5931 convert_move (target, subtarget, 1);
5932 subtarget = target;
5934 return subtarget;
5939 /* Without an appropriate setcc instruction, use a set of branches to
5940 get 1 and 0 stored into target. Presumably if the target has a
5941 STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt. */
5943 label0 = gen_label_rtx ();
5944 label1 = gen_label_rtx ();
5946 emit_jump_insn (bcc_gen_fctn[EQ] (label0));
5947 emit_move_insn (target, const0_rtx);
5948 emit_jump_insn (gen_jump (label1));
5949 emit_barrier ();
5950 emit_label (label0);
5951 emit_move_insn (target, const1_rtx);
5952 emit_label (label1);
5954 return target;
5957 /* This is a helper function for the other atomic operations. This function
5958 emits a loop that contains SEQ that iterates until a compare-and-swap
5959 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5960 a set of instructions that takes a value from OLD_REG as an input and
5961 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5962 set to the current contents of MEM. After SEQ, a compare-and-swap will
5963 attempt to update MEM with NEW_REG. The function returns true when the
5964 loop was generated successfully. */
5966 static bool
5967 expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5969 enum machine_mode mode = GET_MODE (mem);
5970 enum insn_code icode;
5971 rtx label, cmp_reg, subtarget;
5973 /* The loop we want to generate looks like
5975 cmp_reg = mem;
5976 label:
5977 old_reg = cmp_reg;
5978 seq;
5979 cmp_reg = compare-and-swap(mem, old_reg, new_reg)
5980 if (cmp_reg != old_reg)
5981 goto label;
5983 Note that we only do the plain load from memory once. Subsequent
5984 iterations use the value loaded by the compare-and-swap pattern. */
5986 label = gen_label_rtx ();
5987 cmp_reg = gen_reg_rtx (mode);
5989 emit_move_insn (cmp_reg, mem);
5990 emit_label (label);
5991 emit_move_insn (old_reg, cmp_reg);
5992 if (seq)
5993 emit_insn (seq);
5995 /* If the target supports a compare-and-swap pattern that simultaneously
5996 sets some flag for success, then use it. Otherwise use the regular
5997 compare-and-swap and follow that immediately with a compare insn. */
5998 icode = sync_compare_and_swap_cc[mode];
5999 switch (icode)
6001 default:
6002 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6003 cmp_reg, icode);
6004 if (subtarget != NULL_RTX)
6006 gcc_assert (subtarget == cmp_reg);
6007 break;
6010 /* FALLTHRU */
6011 case CODE_FOR_nothing:
6012 icode = sync_compare_and_swap[mode];
6013 if (icode == CODE_FOR_nothing)
6014 return false;
6016 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
6017 cmp_reg, icode);
6018 if (subtarget == NULL_RTX)
6019 return false;
6020 if (subtarget != cmp_reg)
6021 emit_move_insn (cmp_reg, subtarget);
6023 emit_cmp_insn (cmp_reg, old_reg, EQ, const0_rtx, mode, true);
6026 /* ??? Mark this jump predicted not taken? */
6027 emit_jump_insn (bcc_gen_fctn[NE] (label));
6029 return true;
6032 /* This function generates the atomic operation MEM CODE= VAL. In this
6033 case, we do not care about any resulting value. Returns NULL if we
6034 cannot generate the operation. */
6037 expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
6039 enum machine_mode mode = GET_MODE (mem);
6040 enum insn_code icode;
6041 rtx insn;
6043 /* Look to see if the target supports the operation directly. */
6044 switch (code)
6046 case PLUS:
6047 icode = sync_add_optab[mode];
6048 break;
6049 case IOR:
6050 icode = sync_ior_optab[mode];
6051 break;
6052 case XOR:
6053 icode = sync_xor_optab[mode];
6054 break;
6055 case AND:
6056 icode = sync_and_optab[mode];
6057 break;
6058 case NOT:
6059 icode = sync_nand_optab[mode];
6060 break;
6062 case MINUS:
6063 icode = sync_sub_optab[mode];
6064 if (icode == CODE_FOR_nothing)
6066 icode = sync_add_optab[mode];
6067 if (icode != CODE_FOR_nothing)
6069 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6070 code = PLUS;
6073 break;
6075 default:
6076 gcc_unreachable ();
6079 /* Generate the direct operation, if present. */
6080 if (icode != CODE_FOR_nothing)
6082 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6083 val = convert_modes (mode, GET_MODE (val), val, 1);
6084 if (!insn_data[icode].operand[1].predicate (val, mode))
6085 val = force_reg (mode, val);
6087 insn = GEN_FCN (icode) (mem, val);
6088 if (insn)
6090 emit_insn (insn);
6091 return const0_rtx;
6095 /* Failing that, generate a compare-and-swap loop in which we perform the
6096 operation with normal arithmetic instructions. */
6097 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6099 rtx t0 = gen_reg_rtx (mode), t1;
6101 start_sequence ();
6103 t1 = t0;
6104 if (code == NOT)
6106 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6107 code = AND;
6109 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6110 true, OPTAB_LIB_WIDEN);
6112 insn = get_insns ();
6113 end_sequence ();
6115 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6116 return const0_rtx;
6119 return NULL_RTX;
6122 /* This function generates the atomic operation MEM CODE= VAL. In this
6123 case, we do care about the resulting value: if AFTER is true then
6124 return the value MEM holds after the operation, if AFTER is false
6125 then return the value MEM holds before the operation. TARGET is an
6126 optional place for the result value to be stored. */
6129 expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
6130 bool after, rtx target)
6132 enum machine_mode mode = GET_MODE (mem);
6133 enum insn_code old_code, new_code, icode;
6134 bool compensate;
6135 rtx insn;
6137 /* Look to see if the target supports the operation directly. */
6138 switch (code)
6140 case PLUS:
6141 old_code = sync_old_add_optab[mode];
6142 new_code = sync_new_add_optab[mode];
6143 break;
6144 case IOR:
6145 old_code = sync_old_ior_optab[mode];
6146 new_code = sync_new_ior_optab[mode];
6147 break;
6148 case XOR:
6149 old_code = sync_old_xor_optab[mode];
6150 new_code = sync_new_xor_optab[mode];
6151 break;
6152 case AND:
6153 old_code = sync_old_and_optab[mode];
6154 new_code = sync_new_and_optab[mode];
6155 break;
6156 case NOT:
6157 old_code = sync_old_nand_optab[mode];
6158 new_code = sync_new_nand_optab[mode];
6159 break;
6161 case MINUS:
6162 old_code = sync_old_sub_optab[mode];
6163 new_code = sync_new_sub_optab[mode];
6164 if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
6166 old_code = sync_old_add_optab[mode];
6167 new_code = sync_new_add_optab[mode];
6168 if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
6170 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
6171 code = PLUS;
6174 break;
6176 default:
6177 gcc_unreachable ();
6180 /* If the target does supports the proper new/old operation, great. But
6181 if we only support the opposite old/new operation, check to see if we
6182 can compensate. In the case in which the old value is supported, then
6183 we can always perform the operation again with normal arithmetic. In
6184 the case in which the new value is supported, then we can only handle
6185 this in the case the operation is reversible. */
6186 compensate = false;
6187 if (after)
6189 icode = new_code;
6190 if (icode == CODE_FOR_nothing)
6192 icode = old_code;
6193 if (icode != CODE_FOR_nothing)
6194 compensate = true;
6197 else
6199 icode = old_code;
6200 if (icode == CODE_FOR_nothing
6201 && (code == PLUS || code == MINUS || code == XOR))
6203 icode = new_code;
6204 if (icode != CODE_FOR_nothing)
6205 compensate = true;
6209 /* If we found something supported, great. */
6210 if (icode != CODE_FOR_nothing)
6212 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6213 target = gen_reg_rtx (mode);
6215 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6216 val = convert_modes (mode, GET_MODE (val), val, 1);
6217 if (!insn_data[icode].operand[2].predicate (val, mode))
6218 val = force_reg (mode, val);
6220 insn = GEN_FCN (icode) (target, mem, val);
6221 if (insn)
6223 emit_insn (insn);
6225 /* If we need to compensate for using an operation with the
6226 wrong return value, do so now. */
6227 if (compensate)
6229 if (!after)
6231 if (code == PLUS)
6232 code = MINUS;
6233 else if (code == MINUS)
6234 code = PLUS;
6237 if (code == NOT)
6238 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
6239 target = expand_simple_binop (mode, code, target, val, NULL_RTX,
6240 true, OPTAB_LIB_WIDEN);
6243 return target;
6247 /* Failing that, generate a compare-and-swap loop in which we perform the
6248 operation with normal arithmetic instructions. */
6249 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6251 rtx t0 = gen_reg_rtx (mode), t1;
6253 if (!target || !register_operand (target, mode))
6254 target = gen_reg_rtx (mode);
6256 start_sequence ();
6258 if (!after)
6259 emit_move_insn (target, t0);
6260 t1 = t0;
6261 if (code == NOT)
6263 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
6264 code = AND;
6266 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
6267 true, OPTAB_LIB_WIDEN);
6268 if (after)
6269 emit_move_insn (target, t1);
6271 insn = get_insns ();
6272 end_sequence ();
6274 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
6275 return target;
6278 return NULL_RTX;
6281 /* This function expands a test-and-set operation. Ideally we atomically
6282 store VAL in MEM and return the previous value in MEM. Some targets
6283 may not support this operation and only support VAL with the constant 1;
6284 in this case while the return value will be 0/1, but the exact value
6285 stored in MEM is target defined. TARGET is an option place to stick
6286 the return value. */
6289 expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
6291 enum machine_mode mode = GET_MODE (mem);
6292 enum insn_code icode;
6293 rtx insn;
6295 /* If the target supports the test-and-set directly, great. */
6296 icode = sync_lock_test_and_set[mode];
6297 if (icode != CODE_FOR_nothing)
6299 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
6300 target = gen_reg_rtx (mode);
6302 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6303 val = convert_modes (mode, GET_MODE (val), val, 1);
6304 if (!insn_data[icode].operand[2].predicate (val, mode))
6305 val = force_reg (mode, val);
6307 insn = GEN_FCN (icode) (target, mem, val);
6308 if (insn)
6310 emit_insn (insn);
6311 return target;
6315 /* Otherwise, use a compare-and-swap loop for the exchange. */
6316 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
6318 if (!target || !register_operand (target, mode))
6319 target = gen_reg_rtx (mode);
6320 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
6321 val = convert_modes (mode, GET_MODE (val), val, 1);
6322 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
6323 return target;
6326 return NULL_RTX;
6329 #include "gt-optabs.h"