]> gcc.gnu.org Git - gcc.git/blame - gcc/optabs.c
vect-85.c: Don't xfail on alpha.
[gcc.git] / gcc / optabs.c
CommitLineData
77c9c6c2 1/* Expand the basic unary and binary arithmetic operations, for GNU compiler.
d050d723 2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
c5c367ac 3 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
77c9c6c2 4
1322177d 5This file is part of GCC.
77c9c6c2 6
1322177d
LB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
77c9c6c2 11
1322177d
LB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
77c9c6c2
RK
16
17You should have received a copy of the GNU General Public License
1322177d
LB
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
77c9c6c2
RK
21
22
23#include "config.h"
670ee920 24#include "system.h"
4977bab6
ZW
25#include "coretypes.h"
26#include "tm.h"
01198c2f 27#include "toplev.h"
dff01034
KG
28
29/* Include insn-config.h before expr.h so that HAVE_conditional_move
dc297297 30 is properly defined. */
dff01034 31#include "insn-config.h"
77c9c6c2
RK
32#include "rtl.h"
33#include "tree.h"
6baf1cc8 34#include "tm_p.h"
77c9c6c2 35#include "flags.h"
49ad7cfa 36#include "function.h"
52a11cbf 37#include "except.h"
77c9c6c2 38#include "expr.h"
e78d8e51
ZW
39#include "optabs.h"
40#include "libfuncs.h"
77c9c6c2 41#include "recog.h"
2829c155 42#include "reload.h"
87ff9c8e 43#include "ggc.h"
7bdb32b9 44#include "real.h"
4a69cf79 45#include "basic-block.h"
c15c90bb 46#include "target.h"
77c9c6c2
RK
47
48/* Each optab contains info on how this target machine
49 can perform a particular operation
50 for all sizes and kinds of operands.
51
52 The operation to be performed is often specified
53 by passing one of these optabs as an argument.
54
55 See expr.h for documentation of these optabs. */
56
34220a12
BS
57optab optab_table[OTI_MAX];
58
59rtx libfunc_table[LTI_MAX];
19c3fc24 60
85363ca0
ZW
61/* Tables of patterns for converting one mode to another. */
62convert_optab convert_optab_table[CTI_MAX];
5d81dc5b 63
377017c4
RK
64/* Contains the optab used for each rtx code. */
65optab code_to_optab[NUM_RTX_CODE + 1];
66
77c9c6c2
RK
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. */
69
70rtxfun bcc_gen_fctn[NUM_RTX_CODE];
71
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. */
75
76enum insn_code setcc_gen_code[NUM_RTX_CODE];
77
49c4584c
DE
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). */
83
84enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
85#endif
86
7ce67fbe
DP
87/* Indexed by the machine mode, gives the insn code for vector conditional
88 operation. */
89
90enum insn_code vcond_gen_code[NUM_MACHINE_MODES];
91enum insn_code vcondu_gen_code[NUM_MACHINE_MODES];
92
842a431a
DM
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. */
96static GTY(()) rtx trap_rtx;
97
0c20a65f
AJ
98static int add_equal_note (rtx, rtx, enum rtx_code, rtx, rtx);
99static rtx widen_operand (rtx, enum machine_mode, enum machine_mode, int,
100 int);
0c20a65f
AJ
101static void prepare_cmp_insn (rtx *, rtx *, enum rtx_code *, rtx,
102 enum machine_mode *, int *,
103 enum can_compare_purpose);
104static enum insn_code can_fix_p (enum machine_mode, enum machine_mode, int,
105 int *);
106static enum insn_code can_float_p (enum machine_mode, enum machine_mode, int);
0c20a65f 107static optab new_optab (void);
85363ca0 108static convert_optab new_convert_optab (void);
0c20a65f
AJ
109static inline optab init_optab (enum rtx_code);
110static inline optab init_optabv (enum rtx_code);
85363ca0 111static inline convert_optab init_convert_optab (enum rtx_code);
0c20a65f
AJ
112static void init_libfuncs (optab, int, int, const char *, int);
113static void init_integral_libfuncs (optab, const char *, int);
114static void init_floating_libfuncs (optab, const char *, int);
85363ca0
ZW
115static void init_interclass_conv_libfuncs (convert_optab, const char *,
116 enum mode_class, enum mode_class);
117static void init_intraclass_conv_libfuncs (convert_optab, const char *,
118 enum mode_class, bool);
0c20a65f
AJ
119static void emit_cmp_and_jump_insn_1 (rtx, rtx, enum machine_mode,
120 enum rtx_code, int, rtx);
121static void prepare_float_lib_cmp (rtx *, rtx *, enum rtx_code *,
122 enum machine_mode *, int *);
0c20a65f
AJ
123static rtx widen_clz (enum machine_mode, rtx, rtx);
124static rtx expand_parity (enum machine_mode, rtx, rtx);
7ce67fbe
DP
125static enum rtx_code get_rtx_code (enum tree_code, bool);
126static rtx vector_compare_rtx (tree, bool, enum insn_code);
842a431a
DM
127
128#ifndef HAVE_conditional_trap
129#define HAVE_conditional_trap 0
de3eb46f 130#define gen_conditional_trap(a,b) (gcc_unreachable (), NULL_RTX)
842a431a 131#endif
77c9c6c2 132\f
2f937369 133/* Add a REG_EQUAL note to the last insn in INSNS. TARGET is being set to
77c9c6c2
RK
134 the result of operation CODE applied to OP0 (and OP1 if it is a binary
135 operation).
136
137 If the last insn does not set TARGET, don't do anything, but return 1.
138
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. */
142
143static int
0c20a65f 144add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
77c9c6c2 145{
2f937369 146 rtx last_insn, insn, set;
77c9c6c2
RK
147 rtx note;
148
e3feb571 149 gcc_assert (insns && INSN_P (insns) && NEXT_INSN (insns));
2f937369 150
ec8e098d
PB
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)
2f937369
DM
156 return 1;
157
158 if (GET_CODE (target) == ZERO_EXTRACT)
159 return 1;
160
161 for (last_insn = insns;
162 NEXT_INSN (last_insn) != NULL_RTX;
163 last_insn = NEXT_INSN (last_insn))
164 ;
165
166 set = single_set (last_insn);
167 if (set == NULL_RTX)
168 return 1;
169
170 if (! rtx_equal_p (SET_DEST (set), target)
f9d36a92 171 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside it. */
2f937369 172 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
f9d36a92 173 || ! rtx_equal_p (XEXP (SET_DEST (set), 0), target)))
77c9c6c2
RK
174 return 1;
175
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)))
2f937369
DM
180 {
181 insn = PREV_INSN (last_insn);
182 while (insn != NULL_RTX)
183 {
184 if (reg_set_p (target, insn))
185 return 0;
186
187 insn = PREV_INSN (insn);
188 }
189 }
77c9c6c2 190
ec8e098d 191 if (GET_RTX_CLASS (code) == RTX_UNARY)
9e6a5703 192 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
77c9c6c2 193 else
9e6a5703 194 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
77c9c6c2 195
2f937369 196 set_unique_reg_note (last_insn, REG_EQUAL, note);
77c9c6c2
RK
197
198 return 1;
199}
200\f
835532b8
RK
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
0c20a65f 203 not actually do a sign-extend or zero-extend, but can leave the
835532b8
RK
204 higher-order bits of the result rtx undefined, for example, in the case
205 of logical operations, but not right shifts. */
206
207static rtx
0c20a65f
AJ
208widen_operand (rtx op, enum machine_mode mode, enum machine_mode oldmode,
209 int unsignedp, int no_extend)
835532b8
RK
210{
211 rtx result;
212
8041889f
RK
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;
216
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. */
835532b8 220 if (! no_extend
cb8f73be
RK
221 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
222 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
0661a3de 223 return convert_modes (mode, oldmode, op, unsignedp);
835532b8
RK
224
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)
9e6a5703 228 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
835532b8
RK
229
230 /* Otherwise, get an object of MODE, clobber it, and set the low-order
231 part to OP. */
232
233 result = gen_reg_rtx (mode);
9e6a5703 234 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
835532b8
RK
235 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
236 return result;
237}
238\f
26277d41
PB
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. */
244optab
245optab_for_tree_code (enum tree_code code, tree type)
246{
247 bool trapv;
248 switch (code)
249 {
250 case BIT_AND_EXPR:
251 return and_optab;
252
253 case BIT_IOR_EXPR:
254 return ior_optab;
255
256 case BIT_NOT_EXPR:
257 return one_cmpl_optab;
258
259 case BIT_XOR_EXPR:
260 return xor_optab;
261
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;
267
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;
275
276 case LSHIFT_EXPR:
277 return ashl_optab;
278
279 case RSHIFT_EXPR:
280 return TYPE_UNSIGNED (type) ? lshr_optab : ashr_optab;
281
282 case LROTATE_EXPR:
283 return rotl_optab;
284
285 case RROTATE_EXPR:
286 return rotr_optab;
287
288 case MAX_EXPR:
289 return TYPE_UNSIGNED (type) ? umax_optab : smax_optab;
290
291 case MIN_EXPR:
292 return TYPE_UNSIGNED (type) ? umin_optab : smin_optab;
293
7ccf35ed
DN
294 case REALIGN_LOAD_EXPR:
295 return vec_realign_load_optab;
296
26277d41
PB
297 default:
298 break;
299 }
300
301 trapv = flag_trapv && INTEGRAL_TYPE_P (type) && !TYPE_UNSIGNED (type);
302 switch (code)
303 {
304 case PLUS_EXPR:
305 return trapv ? addv_optab : add_optab;
306
307 case MINUS_EXPR:
308 return trapv ? subv_optab : sub_optab;
309
310 case MULT_EXPR:
311 return trapv ? smulv_optab : smul_optab;
312
313 case NEGATE_EXPR:
314 return trapv ? negv_optab : neg_optab;
315
316 case ABS_EXPR:
317 return trapv ? absv_optab : abs_optab;
318
319 default:
320 return NULL;
321 }
322}
273a2526 323\f
7ccf35ed
DN
324
325/* Generate code to perform an operation specified by TERNARY_OPTAB
326 on operands OP0, OP1 and OP2, with result having machine-mode MODE.
327
328 UNSIGNEDP is for the case where we have to widen the operands
329 to perform the operation. It says to use zero-extension.
330
331 If TARGET is nonzero, the value
332 is generated there, if it is convenient to do so.
333 In all cases an rtx is returned for the locus of the value;
334 this may or may not be TARGET. */
335
336rtx
337expand_ternary_op (enum machine_mode mode, optab ternary_optab, rtx op0,
338 rtx op1, rtx op2, rtx target, int unsignedp)
339{
340 int icode = (int) ternary_optab->handlers[(int) mode].insn_code;
341 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
342 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
343 enum machine_mode mode2 = insn_data[icode].operand[3].mode;
344 rtx temp;
345 rtx pat;
346 rtx xop0 = op0, xop1 = op1, xop2 = op2;
347
e3feb571
NS
348 gcc_assert (ternary_optab->handlers[(int) mode].insn_code
349 != CODE_FOR_nothing);
7ccf35ed 350
e3feb571 351 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
7ccf35ed
DN
352 temp = gen_reg_rtx (mode);
353 else
354 temp = target;
355
356 /* In case the insn wants input operands in modes different from
357 those of the actual operands, convert the operands. It would
358 seem that we don't need to convert CONST_INTs, but we do, so
359 that they're properly zero-extended, sign-extended or truncated
360 for their mode. */
361
362 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
363 xop0 = convert_modes (mode0,
364 GET_MODE (op0) != VOIDmode
365 ? GET_MODE (op0)
366 : mode,
367 xop0, unsignedp);
368
369 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
370 xop1 = convert_modes (mode1,
371 GET_MODE (op1) != VOIDmode
372 ? GET_MODE (op1)
373 : mode,
374 xop1, unsignedp);
375
376 if (GET_MODE (op2) != mode2 && mode2 != VOIDmode)
377 xop2 = convert_modes (mode2,
378 GET_MODE (op2) != VOIDmode
379 ? GET_MODE (op2)
380 : mode,
381 xop2, unsignedp);
382
383 /* Now, if insn's predicates don't allow our operands, put them into
384 pseudo regs. */
385
e3feb571 386 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
7ccf35ed
DN
387 && mode0 != VOIDmode)
388 xop0 = copy_to_mode_reg (mode0, xop0);
389
e3feb571 390 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
7ccf35ed
DN
391 && mode1 != VOIDmode)
392 xop1 = copy_to_mode_reg (mode1, xop1);
393
e3feb571 394 if (!insn_data[icode].operand[3].predicate (xop2, mode2)
7ccf35ed
DN
395 && mode2 != VOIDmode)
396 xop2 = copy_to_mode_reg (mode2, xop2);
397
398 pat = GEN_FCN (icode) (temp, xop0, xop1, xop2);
399
400 emit_insn (pat);
401 return temp;
402}
403
404
273a2526
RS
405/* Like expand_binop, but return a constant rtx if the result can be
406 calculated at compile time. The arguments and return value are
407 otherwise the same as for expand_binop. */
408
409static rtx
410simplify_expand_binop (enum machine_mode mode, optab binoptab,
411 rtx op0, rtx op1, rtx target, int unsignedp,
412 enum optab_methods methods)
413{
414 if (CONSTANT_P (op0) && CONSTANT_P (op1))
415 return simplify_gen_binary (binoptab->code, mode, op0, op1);
416 else
417 return expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods);
418}
419
420/* Like simplify_expand_binop, but always put the result in TARGET.
421 Return true if the expansion succeeded. */
422
bef5d8b6 423bool
273a2526
RS
424force_expand_binop (enum machine_mode mode, optab binoptab,
425 rtx op0, rtx op1, rtx target, int unsignedp,
426 enum optab_methods methods)
427{
428 rtx x = simplify_expand_binop (mode, binoptab, op0, op1,
429 target, unsignedp, methods);
430 if (x == 0)
431 return false;
432 if (x != target)
433 emit_move_insn (target, x);
434 return true;
435}
436
437/* This subroutine of expand_doubleword_shift handles the cases in which
438 the effective shift value is >= BITS_PER_WORD. The arguments and return
439 value are the same as for the parent routine, except that SUPERWORD_OP1
440 is the shift count to use when shifting OUTOF_INPUT into INTO_TARGET.
441 INTO_TARGET may be null if the caller has decided to calculate it. */
442
443static bool
444expand_superword_shift (optab binoptab, rtx outof_input, rtx superword_op1,
445 rtx outof_target, rtx into_target,
446 int unsignedp, enum optab_methods methods)
447{
448 if (into_target != 0)
449 if (!force_expand_binop (word_mode, binoptab, outof_input, superword_op1,
450 into_target, unsignedp, methods))
451 return false;
452
453 if (outof_target != 0)
454 {
455 /* For a signed right shift, we must fill OUTOF_TARGET with copies
456 of the sign bit, otherwise we must fill it with zeros. */
457 if (binoptab != ashr_optab)
458 emit_move_insn (outof_target, CONST0_RTX (word_mode));
459 else
460 if (!force_expand_binop (word_mode, binoptab,
461 outof_input, GEN_INT (BITS_PER_WORD - 1),
462 outof_target, unsignedp, methods))
463 return false;
464 }
465 return true;
466}
467
468/* This subroutine of expand_doubleword_shift handles the cases in which
469 the effective shift value is < BITS_PER_WORD. The arguments and return
470 value are the same as for the parent routine. */
471
472static bool
473expand_subword_shift (enum machine_mode op1_mode, optab binoptab,
474 rtx outof_input, rtx into_input, rtx op1,
475 rtx outof_target, rtx into_target,
476 int unsignedp, enum optab_methods methods,
477 unsigned HOST_WIDE_INT shift_mask)
478{
479 optab reverse_unsigned_shift, unsigned_shift;
480 rtx tmp, carries;
481
482 reverse_unsigned_shift = (binoptab == ashl_optab ? lshr_optab : ashl_optab);
483 unsigned_shift = (binoptab == ashl_optab ? ashl_optab : lshr_optab);
484
485 /* The low OP1 bits of INTO_TARGET come from the high bits of OUTOF_INPUT.
486 We therefore need to shift OUTOF_INPUT by (BITS_PER_WORD - OP1) bits in
487 the opposite direction to BINOPTAB. */
488 if (CONSTANT_P (op1) || shift_mask >= BITS_PER_WORD)
489 {
490 carries = outof_input;
491 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
492 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
493 0, true, methods);
494 }
495 else
496 {
497 /* We must avoid shifting by BITS_PER_WORD bits since that is either
498 the same as a zero shift (if shift_mask == BITS_PER_WORD - 1) or
b01d837f 499 has unknown behavior. Do a single shift first, then shift by the
273a2526
RS
500 remainder. It's OK to use ~OP1 as the remainder if shift counts
501 are truncated to the mode size. */
502 carries = expand_binop (word_mode, reverse_unsigned_shift,
503 outof_input, const1_rtx, 0, unsignedp, methods);
504 if (shift_mask == BITS_PER_WORD - 1)
505 {
506 tmp = immed_double_const (-1, -1, op1_mode);
507 tmp = simplify_expand_binop (op1_mode, xor_optab, op1, tmp,
508 0, true, methods);
509 }
510 else
511 {
512 tmp = immed_double_const (BITS_PER_WORD - 1, 0, op1_mode);
513 tmp = simplify_expand_binop (op1_mode, sub_optab, tmp, op1,
514 0, true, methods);
515 }
516 }
517 if (tmp == 0 || carries == 0)
518 return false;
519 carries = expand_binop (word_mode, reverse_unsigned_shift,
520 carries, tmp, 0, unsignedp, methods);
521 if (carries == 0)
522 return false;
523
524 /* Shift INTO_INPUT logically by OP1. This is the last use of INTO_INPUT
525 so the result can go directly into INTO_TARGET if convenient. */
526 tmp = expand_binop (word_mode, unsigned_shift, into_input, op1,
527 into_target, unsignedp, methods);
528 if (tmp == 0)
529 return false;
530
531 /* Now OR in the bits carried over from OUTOF_INPUT. */
532 if (!force_expand_binop (word_mode, ior_optab, tmp, carries,
533 into_target, unsignedp, methods))
534 return false;
535
536 /* Use a standard word_mode shift for the out-of half. */
537 if (outof_target != 0)
538 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
539 outof_target, unsignedp, methods))
540 return false;
541
542 return true;
543}
544
545
546#ifdef HAVE_conditional_move
547/* Try implementing expand_doubleword_shift using conditional moves.
548 The shift is by < BITS_PER_WORD if (CMP_CODE CMP1 CMP2) is true,
549 otherwise it is by >= BITS_PER_WORD. SUBWORD_OP1 and SUPERWORD_OP1
550 are the shift counts to use in the former and latter case. All other
551 arguments are the same as the parent routine. */
552
553static bool
554expand_doubleword_shift_condmove (enum machine_mode op1_mode, optab binoptab,
555 enum rtx_code cmp_code, rtx cmp1, rtx cmp2,
556 rtx outof_input, rtx into_input,
557 rtx subword_op1, rtx superword_op1,
558 rtx outof_target, rtx into_target,
559 int unsignedp, enum optab_methods methods,
560 unsigned HOST_WIDE_INT shift_mask)
561{
562 rtx outof_superword, into_superword;
563
564 /* Put the superword version of the output into OUTOF_SUPERWORD and
565 INTO_SUPERWORD. */
566 outof_superword = outof_target != 0 ? gen_reg_rtx (word_mode) : 0;
567 if (outof_target != 0 && subword_op1 == superword_op1)
568 {
569 /* The value INTO_TARGET >> SUBWORD_OP1, which we later store in
570 OUTOF_TARGET, is the same as the value of INTO_SUPERWORD. */
571 into_superword = outof_target;
572 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
573 outof_superword, 0, unsignedp, methods))
574 return false;
575 }
576 else
577 {
578 into_superword = gen_reg_rtx (word_mode);
579 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
580 outof_superword, into_superword,
581 unsignedp, methods))
582 return false;
583 }
26277d41 584
273a2526
RS
585 /* Put the subword version directly in OUTOF_TARGET and INTO_TARGET. */
586 if (!expand_subword_shift (op1_mode, binoptab,
587 outof_input, into_input, subword_op1,
588 outof_target, into_target,
589 unsignedp, methods, shift_mask))
590 return false;
591
592 /* Select between them. Do the INTO half first because INTO_SUPERWORD
593 might be the current value of OUTOF_TARGET. */
594 if (!emit_conditional_move (into_target, cmp_code, cmp1, cmp2, op1_mode,
595 into_target, into_superword, word_mode, false))
596 return false;
597
598 if (outof_target != 0)
599 if (!emit_conditional_move (outof_target, cmp_code, cmp1, cmp2, op1_mode,
600 outof_target, outof_superword,
601 word_mode, false))
602 return false;
603
604 return true;
605}
606#endif
607
608/* Expand a doubleword shift (ashl, ashr or lshr) using word-mode shifts.
609 OUTOF_INPUT and INTO_INPUT are the two word-sized halves of the first
610 input operand; the shift moves bits in the direction OUTOF_INPUT->
611 INTO_TARGET. OUTOF_TARGET and INTO_TARGET are the equivalent words
612 of the target. OP1 is the shift count and OP1_MODE is its mode.
613 If OP1 is constant, it will have been truncated as appropriate
614 and is known to be nonzero.
615
616 If SHIFT_MASK is zero, the result of word shifts is undefined when the
617 shift count is outside the range [0, BITS_PER_WORD). This routine must
618 avoid generating such shifts for OP1s in the range [0, BITS_PER_WORD * 2).
619
620 If SHIFT_MASK is nonzero, all word-mode shift counts are effectively
621 masked by it and shifts in the range [BITS_PER_WORD, SHIFT_MASK) will
622 fill with zeros or sign bits as appropriate.
623
2a7e31df 624 If SHIFT_MASK is BITS_PER_WORD - 1, this routine will synthesize
273a2526
RS
625 a doubleword shift whose equivalent mask is BITS_PER_WORD * 2 - 1.
626 Doing this preserves semantics required by SHIFT_COUNT_TRUNCATED.
627 In all other cases, shifts by values outside [0, BITS_PER_UNIT * 2)
628 are undefined.
629
630 BINOPTAB, UNSIGNEDP and METHODS are as for expand_binop. This function
631 may not use INTO_INPUT after modifying INTO_TARGET, and similarly for
632 OUTOF_INPUT and OUTOF_TARGET. OUTOF_TARGET can be null if the parent
633 function wants to calculate it itself.
634
635 Return true if the shift could be successfully synthesized. */
636
637static bool
638expand_doubleword_shift (enum machine_mode op1_mode, optab binoptab,
639 rtx outof_input, rtx into_input, rtx op1,
640 rtx outof_target, rtx into_target,
641 int unsignedp, enum optab_methods methods,
642 unsigned HOST_WIDE_INT shift_mask)
643{
644 rtx superword_op1, tmp, cmp1, cmp2;
645 rtx subword_label, done_label;
646 enum rtx_code cmp_code;
647
648 /* See if word-mode shifts by BITS_PER_WORD...BITS_PER_WORD * 2 - 1 will
649 fill the result with sign or zero bits as appropriate. If so, the value
650 of OUTOF_TARGET will always be (SHIFT OUTOF_INPUT OP1). Recursively call
651 this routine to calculate INTO_TARGET (which depends on both OUTOF_INPUT
652 and INTO_INPUT), then emit code to set up OUTOF_TARGET.
653
654 This isn't worthwhile for constant shifts since the optimizers will
655 cope better with in-range shift counts. */
656 if (shift_mask >= BITS_PER_WORD
657 && outof_target != 0
658 && !CONSTANT_P (op1))
659 {
660 if (!expand_doubleword_shift (op1_mode, binoptab,
661 outof_input, into_input, op1,
662 0, into_target,
663 unsignedp, methods, shift_mask))
664 return false;
665 if (!force_expand_binop (word_mode, binoptab, outof_input, op1,
666 outof_target, unsignedp, methods))
667 return false;
668 return true;
669 }
670
671 /* Set CMP_CODE, CMP1 and CMP2 so that the rtx (CMP_CODE CMP1 CMP2)
672 is true when the effective shift value is less than BITS_PER_WORD.
673 Set SUPERWORD_OP1 to the shift count that should be used to shift
674 OUTOF_INPUT into INTO_TARGET when the condition is false. */
675 tmp = immed_double_const (BITS_PER_WORD, 0, op1_mode);
676 if (!CONSTANT_P (op1) && shift_mask == BITS_PER_WORD - 1)
677 {
678 /* Set CMP1 to OP1 & BITS_PER_WORD. The result is zero iff OP1
679 is a subword shift count. */
680 cmp1 = simplify_expand_binop (op1_mode, and_optab, op1, tmp,
681 0, true, methods);
682 cmp2 = CONST0_RTX (op1_mode);
683 cmp_code = EQ;
684 superword_op1 = op1;
685 }
686 else
687 {
688 /* Set CMP1 to OP1 - BITS_PER_WORD. */
689 cmp1 = simplify_expand_binop (op1_mode, sub_optab, op1, tmp,
690 0, true, methods);
691 cmp2 = CONST0_RTX (op1_mode);
692 cmp_code = LT;
693 superword_op1 = cmp1;
694 }
695 if (cmp1 == 0)
696 return false;
697
698 /* If we can compute the condition at compile time, pick the
699 appropriate subroutine. */
700 tmp = simplify_relational_operation (cmp_code, SImode, op1_mode, cmp1, cmp2);
701 if (tmp != 0 && GET_CODE (tmp) == CONST_INT)
702 {
703 if (tmp == const0_rtx)
704 return expand_superword_shift (binoptab, outof_input, superword_op1,
705 outof_target, into_target,
706 unsignedp, methods);
707 else
708 return expand_subword_shift (op1_mode, binoptab,
709 outof_input, into_input, op1,
710 outof_target, into_target,
711 unsignedp, methods, shift_mask);
712 }
713
714#ifdef HAVE_conditional_move
715 /* Try using conditional moves to generate straight-line code. */
716 {
717 rtx start = get_last_insn ();
718 if (expand_doubleword_shift_condmove (op1_mode, binoptab,
719 cmp_code, cmp1, cmp2,
720 outof_input, into_input,
721 op1, superword_op1,
722 outof_target, into_target,
723 unsignedp, methods, shift_mask))
724 return true;
725 delete_insns_since (start);
726 }
727#endif
728
729 /* As a last resort, use branches to select the correct alternative. */
730 subword_label = gen_label_rtx ();
731 done_label = gen_label_rtx ();
732
733 do_compare_rtx_and_jump (cmp1, cmp2, cmp_code, false, op1_mode,
734 0, 0, subword_label);
735
736 if (!expand_superword_shift (binoptab, outof_input, superword_op1,
737 outof_target, into_target,
738 unsignedp, methods))
739 return false;
740
741 emit_jump_insn (gen_jump (done_label));
742 emit_barrier ();
743 emit_label (subword_label);
744
745 if (!expand_subword_shift (op1_mode, binoptab,
746 outof_input, into_input, op1,
747 outof_target, into_target,
748 unsignedp, methods, shift_mask))
749 return false;
750
751 emit_label (done_label);
752 return true;
753}
c64f913e 754\f
f927760b
RS
755/* Subroutine of expand_binop. Perform a double word multiplication of
756 operands OP0 and OP1 both of mode MODE, which is exactly twice as wide
757 as the target's word_mode. This function return NULL_RTX if anything
758 goes wrong, in which case it may have already emitted instructions
759 which need to be deleted.
760
761 If we want to multiply two two-word values and have normal and widening
762 multiplies of single-word values, we can do this with three smaller
763 multiplications. Note that we do not make a REG_NO_CONFLICT block here
764 because we are not operating on one word at a time.
765
766 The multiplication proceeds as follows:
767 _______________________
768 [__op0_high_|__op0_low__]
769 _______________________
770 * [__op1_high_|__op1_low__]
771 _______________________________________________
772 _______________________
773 (1) [__op0_low__*__op1_low__]
774 _______________________
775 (2a) [__op0_low__*__op1_high_]
776 _______________________
777 (2b) [__op0_high_*__op1_low__]
778 _______________________
779 (3) [__op0_high_*__op1_high_]
780
781
782 This gives a 4-word result. Since we are only interested in the
783 lower 2 words, partial result (3) and the upper words of (2a) and
784 (2b) don't need to be calculated. Hence (2a) and (2b) can be
785 calculated using non-widening multiplication.
786
787 (1), however, needs to be calculated with an unsigned widening
788 multiplication. If this operation is not directly supported we
789 try using a signed widening multiplication and adjust the result.
790 This adjustment works as follows:
791
792 If both operands are positive then no adjustment is needed.
793
794 If the operands have different signs, for example op0_low < 0 and
795 op1_low >= 0, the instruction treats the most significant bit of
796 op0_low as a sign bit instead of a bit with significance
797 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
798 with 2**BITS_PER_WORD - op0_low, and two's complements the
799 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
800 the result.
801
802 Similarly, if both operands are negative, we need to add
803 (op0_low + op1_low) * 2**BITS_PER_WORD.
804
805 We use a trick to adjust quickly. We logically shift op0_low right
806 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
807 op0_high (op1_high) before it is used to calculate 2b (2a). If no
808 logical shift exists, we do an arithmetic right shift and subtract
809 the 0 or -1. */
810
811static rtx
812expand_doubleword_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target,
813 bool umulp, enum optab_methods methods)
814{
815 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
816 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
817 rtx wordm1 = umulp ? NULL_RTX : GEN_INT (BITS_PER_WORD - 1);
818 rtx product, adjust, product_high, temp;
819
820 rtx op0_high = operand_subword_force (op0, high, mode);
821 rtx op0_low = operand_subword_force (op0, low, mode);
822 rtx op1_high = operand_subword_force (op1, high, mode);
823 rtx op1_low = operand_subword_force (op1, low, mode);
824
825 /* If we're using an unsigned multiply to directly compute the product
826 of the low-order words of the operands and perform any required
827 adjustments of the operands, we begin by trying two more multiplications
828 and then computing the appropriate sum.
829
830 We have checked above that the required addition is provided.
831 Full-word addition will normally always succeed, especially if
832 it is provided at all, so we don't worry about its failure. The
833 multiplication may well fail, however, so we do handle that. */
834
835 if (!umulp)
836 {
837 /* ??? This could be done with emit_store_flag where available. */
838 temp = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
839 NULL_RTX, 1, methods);
840 if (temp)
841 op0_high = expand_binop (word_mode, add_optab, op0_high, temp,
69f39b11 842 NULL_RTX, 0, OPTAB_DIRECT);
f927760b
RS
843 else
844 {
845 temp = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
846 NULL_RTX, 0, methods);
847 if (!temp)
848 return NULL_RTX;
849 op0_high = expand_binop (word_mode, sub_optab, op0_high, temp,
69f39b11 850 NULL_RTX, 0, OPTAB_DIRECT);
f927760b
RS
851 }
852
853 if (!op0_high)
854 return NULL_RTX;
855 }
856
857 adjust = expand_binop (word_mode, smul_optab, op0_high, op1_low,
858 NULL_RTX, 0, OPTAB_DIRECT);
859 if (!adjust)
860 return NULL_RTX;
861
862 /* OP0_HIGH should now be dead. */
863
864 if (!umulp)
865 {
866 /* ??? This could be done with emit_store_flag where available. */
867 temp = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
868 NULL_RTX, 1, methods);
869 if (temp)
870 op1_high = expand_binop (word_mode, add_optab, op1_high, temp,
69f39b11 871 NULL_RTX, 0, OPTAB_DIRECT);
f927760b
RS
872 else
873 {
874 temp = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
875 NULL_RTX, 0, methods);
876 if (!temp)
877 return NULL_RTX;
878 op1_high = expand_binop (word_mode, sub_optab, op1_high, temp,
69f39b11 879 NULL_RTX, 0, OPTAB_DIRECT);
f927760b
RS
880 }
881
882 if (!op1_high)
883 return NULL_RTX;
884 }
885
886 temp = expand_binop (word_mode, smul_optab, op1_high, op0_low,
887 NULL_RTX, 0, OPTAB_DIRECT);
888 if (!temp)
889 return NULL_RTX;
890
891 /* OP1_HIGH should now be dead. */
892
893 adjust = expand_binop (word_mode, add_optab, adjust, temp,
894 adjust, 0, OPTAB_DIRECT);
895
896 if (target && !REG_P (target))
897 target = NULL_RTX;
898
899 if (umulp)
900 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
901 target, 1, OPTAB_DIRECT);
902 else
903 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
904 target, 1, OPTAB_DIRECT);
905
906 if (!product)
907 return NULL_RTX;
908
909 product_high = operand_subword (product, high, 1, mode);
910 adjust = expand_binop (word_mode, add_optab, product_high, adjust,
911 REG_P (product_high) ? product_high : adjust,
912 0, OPTAB_DIRECT);
913 emit_move_insn (product_high, adjust);
914 return product;
915}
916\f
ef89d648
ZW
917/* Wrapper around expand_binop which takes an rtx code to specify
918 the operation to perform, not an optab pointer. All other
919 arguments are the same. */
920rtx
0c20a65f
AJ
921expand_simple_binop (enum machine_mode mode, enum rtx_code code, rtx op0,
922 rtx op1, rtx target, int unsignedp,
923 enum optab_methods methods)
ef89d648 924{
7e1a450d 925 optab binop = code_to_optab[(int) code];
e3feb571 926 gcc_assert (binop);
ef89d648
ZW
927
928 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
929}
930
77c9c6c2
RK
931/* Generate code to perform an operation specified by BINOPTAB
932 on operands OP0 and OP1, with result having machine-mode MODE.
933
934 UNSIGNEDP is for the case where we have to widen the operands
935 to perform the operation. It says to use zero-extension.
936
937 If TARGET is nonzero, the value
938 is generated there, if it is convenient to do so.
939 In all cases an rtx is returned for the locus of the value;
940 this may or may not be TARGET. */
941
942rtx
0c20a65f
AJ
943expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1,
944 rtx target, int unsignedp, enum optab_methods methods)
77c9c6c2 945{
70864443
RK
946 enum optab_methods next_methods
947 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
948 ? OPTAB_WIDEN : methods);
77c9c6c2
RK
949 enum mode_class class;
950 enum machine_mode wider_mode;
b3694847 951 rtx temp;
77c9c6c2 952 int commutative_op = 0;
7e1a450d 953 int shift_op = (binoptab->code == ASHIFT
77c9c6c2 954 || binoptab->code == ASHIFTRT
77c9c6c2
RK
955 || binoptab->code == LSHIFTRT
956 || binoptab->code == ROTATE
957 || binoptab->code == ROTATERT);
abd418d3 958 rtx entry_last = get_last_insn ();
77c9c6c2
RK
959 rtx last;
960
961 class = GET_MODE_CLASS (mode);
962
77c9c6c2
RK
963 if (flag_force_mem)
964 {
894207cf
RS
965 /* Load duplicate non-volatile operands once. */
966 if (rtx_equal_p (op0, op1) && ! volatile_refs_p (op0))
967 {
968 op0 = force_not_mem (op0);
969 op1 = op0;
970 }
971 else
972 {
973 op0 = force_not_mem (op0);
974 op1 = force_not_mem (op1);
975 }
77c9c6c2
RK
976 }
977
8aecce0a
RK
978 /* If subtracting an integer constant, convert this into an addition of
979 the negated constant. */
980
981 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
982 {
983 op1 = negate_rtx (mode, op1);
984 binoptab = add_optab;
985 }
986
7c27e184
PB
987 /* If we are inside an appropriately-short loop and we are optimizing,
988 force expensive constants into a register. */
989 if (CONSTANT_P (op0) && optimize
b437f1a7 990 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
b0b324b0
RH
991 {
992 if (GET_MODE (op0) != VOIDmode)
993 op0 = convert_modes (mode, VOIDmode, op0, unsignedp);
994 op0 = force_reg (mode, op0);
995 }
77c9c6c2 996
7c27e184 997 if (CONSTANT_P (op1) && optimize
b437f1a7 998 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
b0b324b0
RH
999 {
1000 if (GET_MODE (op1) != VOIDmode)
1001 op1 = convert_modes (mode, VOIDmode, op1, unsignedp);
1002 op1 = force_reg (mode, op1);
1003 }
77c9c6c2 1004
77c9c6c2
RK
1005 /* Record where to delete back to if we backtrack. */
1006 last = get_last_insn ();
1007
1008 /* If operation is commutative,
1009 try to make the first operand a register.
1010 Even better, try to make it the same as the target.
1011 Also try to make the last operand a constant. */
ec8e098d 1012 if (GET_RTX_CLASS (binoptab->code) == RTX_COMM_ARITH
77c9c6c2 1013 || binoptab == smul_widen_optab
5035bbfe
TG
1014 || binoptab == umul_widen_optab
1015 || binoptab == smul_highpart_optab
1016 || binoptab == umul_highpart_optab)
77c9c6c2
RK
1017 {
1018 commutative_op = 1;
1019
f8cfc6aa
JQ
1020 if (((target == 0 || REG_P (target))
1021 ? ((REG_P (op1)
1022 && !REG_P (op0))
77c9c6c2
RK
1023 || target == op1)
1024 : rtx_equal_p (op1, target))
1025 || GET_CODE (op0) == CONST_INT)
1026 {
1027 temp = op1;
1028 op1 = op0;
1029 op0 = temp;
1030 }
1031 }
1032
1033 /* If we can do it with a three-operand insn, do so. */
1034
1035 if (methods != OPTAB_MUST_WIDEN
1036 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1037 {
1038 int icode = (int) binoptab->handlers[(int) mode].insn_code;
a995e389
RH
1039 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1040 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
77c9c6c2
RK
1041 rtx pat;
1042 rtx xop0 = op0, xop1 = op1;
1043
1044 if (target)
1045 temp = target;
1046 else
1047 temp = gen_reg_rtx (mode);
1048
1049 /* If it is a commutative operator and the modes would match
0f41302f 1050 if we would swap the operands, we can save the conversions. */
77c9c6c2
RK
1051 if (commutative_op)
1052 {
1053 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
1054 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
1055 {
b3694847 1056 rtx tmp;
77c9c6c2
RK
1057
1058 tmp = op0; op0 = op1; op1 = tmp;
1059 tmp = xop0; xop0 = xop1; xop1 = tmp;
1060 }
1061 }
1062
1063 /* In case the insn wants input operands in modes different from
29984e05
EB
1064 those of the actual operands, convert the operands. It would
1065 seem that we don't need to convert CONST_INTs, but we do, so
35f1c975
EB
1066 that they're properly zero-extended, sign-extended or truncated
1067 for their mode. */
77c9c6c2 1068
874f6a6d 1069 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
69107307
AO
1070 xop0 = convert_modes (mode0,
1071 GET_MODE (op0) != VOIDmode
1072 ? GET_MODE (op0)
29984e05 1073 : mode,
69107307 1074 xop0, unsignedp);
77c9c6c2 1075
874f6a6d 1076 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
69107307
AO
1077 xop1 = convert_modes (mode1,
1078 GET_MODE (op1) != VOIDmode
1079 ? GET_MODE (op1)
35f1c975 1080 : mode,
69107307 1081 xop1, unsignedp);
77c9c6c2
RK
1082
1083 /* Now, if insn's predicates don't allow our operands, put them into
1084 pseudo regs. */
1085
e3feb571 1086 if (!insn_data[icode].operand[1].predicate (xop0, mode0)
4074220e 1087 && mode0 != VOIDmode)
77c9c6c2
RK
1088 xop0 = copy_to_mode_reg (mode0, xop0);
1089
e3feb571 1090 if (!insn_data[icode].operand[2].predicate (xop1, mode1)
4074220e 1091 && mode1 != VOIDmode)
77c9c6c2
RK
1092 xop1 = copy_to_mode_reg (mode1, xop1);
1093
e3feb571 1094 if (!insn_data[icode].operand[0].predicate (temp, mode))
77c9c6c2
RK
1095 temp = gen_reg_rtx (mode);
1096
1097 pat = GEN_FCN (icode) (temp, xop0, xop1);
1098 if (pat)
1099 {
2f937369 1100 /* If PAT is composed of more than one insn, try to add an appropriate
77c9c6c2
RK
1101 REG_EQUAL note to it. If we can't because TEMP conflicts with an
1102 operand, call ourselves again, this time without a target. */
2f937369 1103 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
77c9c6c2
RK
1104 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
1105 {
1106 delete_insns_since (last);
b1ec3c92
CH
1107 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
1108 unsignedp, methods);
77c9c6c2
RK
1109 }
1110
1111 emit_insn (pat);
1112 return temp;
1113 }
1114 else
1115 delete_insns_since (last);
1116 }
1117
5a5064dc
RK
1118 /* If this is a multiply, see if we can do a widening operation that
1119 takes operands of this mode and makes a wider mode. */
1120
1121 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
1122 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1123 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
1124 != CODE_FOR_nothing))
1125 {
1126 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
1127 unsignedp ? umul_widen_optab : smul_widen_optab,
73d9a835 1128 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
5a5064dc 1129
70864443
RK
1130 if (temp != 0)
1131 {
1132 if (GET_MODE_CLASS (mode) == MODE_INT)
1133 return gen_lowpart (mode, temp);
1134 else
1135 return convert_to_mode (mode, temp, unsignedp);
1136 }
5a5064dc
RK
1137 }
1138
9a856ec7 1139 /* Look for a wider mode of the same class for which we think we
5a5064dc
RK
1140 can open-code the operation. Check for a widening multiply at the
1141 wider mode as well. */
9a856ec7
RK
1142
1143 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
6f43c157 1144 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
9a856ec7
RK
1145 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1146 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1147 {
5a5064dc
RK
1148 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
1149 || (binoptab == smul_optab
1150 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
1151 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
1152 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
1153 != CODE_FOR_nothing)))
9a856ec7
RK
1154 {
1155 rtx xop0 = op0, xop1 = op1;
1156 int no_extend = 0;
1157
1158 /* For certain integer operations, we need not actually extend
1159 the narrow operands, as long as we will truncate
6d2f8887 1160 the results to the same narrowness. */
9a856ec7
RK
1161
1162 if ((binoptab == ior_optab || binoptab == and_optab
1163 || binoptab == xor_optab
1164 || binoptab == add_optab || binoptab == sub_optab
e5df894b 1165 || binoptab == smul_optab || binoptab == ashl_optab)
835532b8 1166 && class == MODE_INT)
9a856ec7
RK
1167 no_extend = 1;
1168
0661a3de 1169 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
943cc242
RK
1170
1171 /* The second operand of a shift must always be extended. */
0661a3de 1172 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
e5df894b 1173 no_extend && binoptab != ashl_optab);
943cc242 1174
b1ec3c92 1175 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
9a856ec7
RK
1176 unsignedp, OPTAB_DIRECT);
1177 if (temp)
1178 {
1179 if (class != MODE_INT)
1180 {
1181 if (target == 0)
1182 target = gen_reg_rtx (mode);
1183 convert_move (target, temp, 0);
1184 return target;
1185 }
1186 else
1187 return gen_lowpart (mode, temp);
1188 }
1189 else
1190 delete_insns_since (last);
1191 }
1192 }
1193
77c9c6c2
RK
1194 /* These can be done a word at a time. */
1195 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
1196 && class == MODE_INT
1197 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
34e56753 1198 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2 1199 {
bb93b973 1200 int i;
77c9c6c2
RK
1201 rtx insns;
1202 rtx equiv_value;
1203
1204 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1205 won't be accurate, so use a new target. */
1206 if (target == 0 || target == op0 || target == op1)
1207 target = gen_reg_rtx (mode);
1208
1209 start_sequence ();
1210
1211 /* Do the actual arithmetic. */
1212 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1213 {
1214 rtx target_piece = operand_subword (target, i, 1, mode);
34e56753 1215 rtx x = expand_binop (word_mode, binoptab,
77c9c6c2
RK
1216 operand_subword_force (op0, i, mode),
1217 operand_subword_force (op1, i, mode),
70864443
RK
1218 target_piece, unsignedp, next_methods);
1219
1220 if (x == 0)
1221 break;
1222
77c9c6c2
RK
1223 if (target_piece != x)
1224 emit_move_insn (target_piece, x);
1225 }
1226
1227 insns = get_insns ();
1228 end_sequence ();
1229
70864443
RK
1230 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1231 {
1232 if (binoptab->code != UNKNOWN)
1233 equiv_value
9e6a5703
JC
1234 = gen_rtx_fmt_ee (binoptab->code, mode,
1235 copy_rtx (op0), copy_rtx (op1));
70864443
RK
1236 else
1237 equiv_value = 0;
77c9c6c2 1238
70864443
RK
1239 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1240 return target;
1241 }
77c9c6c2
RK
1242 }
1243
8c597270 1244 /* Synthesize double word shifts from single word shifts. */
e5df894b
RK
1245 if ((binoptab == lshr_optab || binoptab == ashl_optab
1246 || binoptab == ashr_optab)
8c597270 1247 && class == MODE_INT
273a2526 1248 && (GET_CODE (op1) == CONST_INT || !optimize_size)
8c597270
JW
1249 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1250 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1251 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1252 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1253 {
273a2526
RS
1254 unsigned HOST_WIDE_INT shift_mask, double_shift_mask;
1255 enum machine_mode op1_mode;
8c597270 1256
273a2526
RS
1257 double_shift_mask = targetm.shift_truncation_mask (mode);
1258 shift_mask = targetm.shift_truncation_mask (word_mode);
1259 op1_mode = GET_MODE (op1) != VOIDmode ? GET_MODE (op1) : word_mode;
8c597270 1260
273a2526
RS
1261 /* Apply the truncation to constant shifts. */
1262 if (double_shift_mask > 0 && GET_CODE (op1) == CONST_INT)
1263 op1 = GEN_INT (INTVAL (op1) & double_shift_mask);
8c597270 1264
273a2526
RS
1265 if (op1 == CONST0_RTX (op1_mode))
1266 return op0;
8c597270 1267
273a2526
RS
1268 /* Make sure that this is a combination that expand_doubleword_shift
1269 can handle. See the comments there for details. */
1270 if (double_shift_mask == 0
1271 || (shift_mask == BITS_PER_WORD - 1
1272 && double_shift_mask == BITS_PER_WORD * 2 - 1))
8c597270 1273 {
273a2526
RS
1274 rtx insns, equiv_value;
1275 rtx into_target, outof_target;
1276 rtx into_input, outof_input;
1277 int left_shift, outof_word;
8c597270 1278
273a2526
RS
1279 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1280 won't be accurate, so use a new target. */
1281 if (target == 0 || target == op0 || target == op1)
1282 target = gen_reg_rtx (mode);
8c597270 1283
273a2526 1284 start_sequence ();
8c597270 1285
273a2526
RS
1286 /* OUTOF_* is the word we are shifting bits away from, and
1287 INTO_* is the word that we are shifting bits towards, thus
1288 they differ depending on the direction of the shift and
1289 WORDS_BIG_ENDIAN. */
70864443 1290
273a2526
RS
1291 left_shift = binoptab == ashl_optab;
1292 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
70864443 1293
273a2526
RS
1294 outof_target = operand_subword (target, outof_word, 1, mode);
1295 into_target = operand_subword (target, 1 - outof_word, 1, mode);
cf2f7113 1296
273a2526
RS
1297 outof_input = operand_subword_force (op0, outof_word, mode);
1298 into_input = operand_subword_force (op0, 1 - outof_word, mode);
0c20a65f 1299
273a2526
RS
1300 if (expand_doubleword_shift (op1_mode, binoptab,
1301 outof_input, into_input, op1,
1302 outof_target, into_target,
1303 unsignedp, methods, shift_mask))
1304 {
1305 insns = get_insns ();
1306 end_sequence ();
8c597270 1307
273a2526
RS
1308 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1309 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1310 return target;
1311 }
1312 end_sequence ();
70864443 1313 }
8c597270
JW
1314 }
1315
1316 /* Synthesize double word rotates from single word shifts. */
1317 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1318 && class == MODE_INT
1319 && GET_CODE (op1) == CONST_INT
1320 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1321 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1322 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1323 {
1324 rtx insns, equiv_value;
1325 rtx into_target, outof_target;
1326 rtx into_input, outof_input;
70864443 1327 rtx inter;
8c597270
JW
1328 int shift_count, left_shift, outof_word;
1329
1330 /* If TARGET is the same as one of the operands, the REG_EQUAL note
0c0ab0f1
OH
1331 won't be accurate, so use a new target. Do this also if target is not
1332 a REG, first because having a register instead may open optimization
1ae58c30 1333 opportunities, and second because if target and op0 happen to be MEMs
0c0ab0f1
OH
1334 designating the same location, we would risk clobbering it too early
1335 in the code sequence we generate below. */
1336 if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
8c597270
JW
1337 target = gen_reg_rtx (mode);
1338
1339 start_sequence ();
1340
1341 shift_count = INTVAL (op1);
1342
1343 /* OUTOF_* is the word we are shifting bits away from, and
1344 INTO_* is the word that we are shifting bits towards, thus
1345 they differ depending on the direction of the shift and
1346 WORDS_BIG_ENDIAN. */
1347
1348 left_shift = (binoptab == rotl_optab);
1349 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1350
1351 outof_target = operand_subword (target, outof_word, 1, mode);
1352 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1353
1354 outof_input = operand_subword_force (op0, outof_word, mode);
1355 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1356
1357 if (shift_count == BITS_PER_WORD)
1358 {
1359 /* This is just a word swap. */
1360 emit_move_insn (outof_target, into_input);
1361 emit_move_insn (into_target, outof_input);
70864443 1362 inter = const0_rtx;
8c597270
JW
1363 }
1364 else
1365 {
1366 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1367 rtx first_shift_count, second_shift_count;
1368 optab reverse_unsigned_shift, unsigned_shift;
1369
1370 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1371 ? lshr_optab : ashl_optab);
1372
1373 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1374 ? ashl_optab : lshr_optab);
1375
1376 if (shift_count > BITS_PER_WORD)
1377 {
1378 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
7e1a450d 1379 second_shift_count = GEN_INT (2 * BITS_PER_WORD - shift_count);
8c597270
JW
1380 }
1381 else
1382 {
1383 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1384 second_shift_count = GEN_INT (shift_count);
1385 }
1386
1387 into_temp1 = expand_binop (word_mode, unsigned_shift,
1388 outof_input, first_shift_count,
70864443 1389 NULL_RTX, unsignedp, next_methods);
8c597270
JW
1390 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1391 into_input, second_shift_count,
5be5c8d4 1392 NULL_RTX, unsignedp, next_methods);
70864443
RK
1393
1394 if (into_temp1 != 0 && into_temp2 != 0)
1395 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1396 into_target, unsignedp, next_methods);
1397 else
1398 inter = 0;
1399
cb5b00cf 1400 if (inter != 0 && inter != into_target)
70864443 1401 emit_move_insn (into_target, inter);
8c597270
JW
1402
1403 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1404 into_input, first_shift_count,
70864443 1405 NULL_RTX, unsignedp, next_methods);
8c597270
JW
1406 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1407 outof_input, second_shift_count,
5be5c8d4 1408 NULL_RTX, unsignedp, next_methods);
70864443
RK
1409
1410 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1411 inter = expand_binop (word_mode, ior_optab,
1412 outof_temp1, outof_temp2,
1413 outof_target, unsignedp, next_methods);
1414
cb5b00cf 1415 if (inter != 0 && inter != outof_target)
70864443 1416 emit_move_insn (outof_target, inter);
8c597270
JW
1417 }
1418
1419 insns = get_insns ();
1420 end_sequence ();
1421
70864443
RK
1422 if (inter != 0)
1423 {
1424 if (binoptab->code != UNKNOWN)
9e6a5703 1425 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
70864443
RK
1426 else
1427 equiv_value = 0;
8c597270 1428
70864443
RK
1429 /* We can't make this a no conflict block if this is a word swap,
1430 because the word swap case fails if the input and output values
1431 are in the same register. */
1432 if (shift_count != BITS_PER_WORD)
1433 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1434 else
2f937369 1435 emit_insn (insns);
70864443
RK
1436
1437
1438 return target;
1439 }
8c597270
JW
1440 }
1441
77c9c6c2
RK
1442 /* These can be done a word at a time by propagating carries. */
1443 if ((binoptab == add_optab || binoptab == sub_optab)
1444 && class == MODE_INT
1445 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
34e56753 1446 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2 1447 {
e2500fed 1448 unsigned int i;
77c9c6c2 1449 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
a4b5414c 1450 const unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
07444f1d 1451 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
64de6c0a 1452 rtx xop0, xop1, xtarget;
77c9c6c2
RK
1453
1454 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1455 value is one of those, use it. Otherwise, use 1 since it is the
1456 one easiest to get. */
1457#if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1458 int normalizep = STORE_FLAG_VALUE;
1459#else
1460 int normalizep = 1;
1461#endif
1462
1463 /* Prepare the operands. */
cee85023
RS
1464 xop0 = force_reg (mode, op0);
1465 xop1 = force_reg (mode, op1);
77c9c6c2 1466
64de6c0a
DE
1467 xtarget = gen_reg_rtx (mode);
1468
f8cfc6aa 1469 if (target == 0 || !REG_P (target))
64de6c0a 1470 target = xtarget;
77c9c6c2 1471
af2cc4dd 1472 /* Indicate for flow that the entire target reg is being set. */
f8cfc6aa 1473 if (REG_P (target))
64de6c0a 1474 emit_insn (gen_rtx_CLOBBER (VOIDmode, xtarget));
af2cc4dd 1475
77c9c6c2
RK
1476 /* Do the actual arithmetic. */
1477 for (i = 0; i < nwords; i++)
1478 {
1479 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
64de6c0a 1480 rtx target_piece = operand_subword (xtarget, index, 1, mode);
cee85023
RS
1481 rtx op0_piece = operand_subword_force (xop0, index, mode);
1482 rtx op1_piece = operand_subword_force (xop1, index, mode);
77c9c6c2
RK
1483 rtx x;
1484
1485 /* Main add/subtract of the input operands. */
34e56753 1486 x = expand_binop (word_mode, binoptab,
77c9c6c2 1487 op0_piece, op1_piece,
70864443 1488 target_piece, unsignedp, next_methods);
77c9c6c2
RK
1489 if (x == 0)
1490 break;
1491
1492 if (i + 1 < nwords)
1493 {
1494 /* Store carry from main add/subtract. */
34e56753 1495 carry_out = gen_reg_rtx (word_mode);
23357404
TG
1496 carry_out = emit_store_flag_force (carry_out,
1497 (binoptab == add_optab
b30f05db 1498 ? LT : GT),
23357404
TG
1499 x, op0_piece,
1500 word_mode, 1, normalizep);
77c9c6c2
RK
1501 }
1502
1503 if (i > 0)
1504 {
859cb4d8 1505 rtx newx;
0c20a65f 1506
77c9c6c2 1507 /* Add/subtract previous carry to main result. */
859cb4d8
GK
1508 newx = expand_binop (word_mode,
1509 normalizep == 1 ? binoptab : otheroptab,
1510 x, carry_in,
1511 NULL_RTX, 1, next_methods);
77c9c6c2
RK
1512
1513 if (i + 1 < nwords)
1514 {
77c9c6c2 1515 /* Get out carry from adding/subtracting carry in. */
859cb4d8 1516 rtx carry_tmp = gen_reg_rtx (word_mode);
23357404 1517 carry_tmp = emit_store_flag_force (carry_tmp,
859cb4d8
GK
1518 (binoptab == add_optab
1519 ? LT : GT),
1520 newx, x,
23357404 1521 word_mode, 1, normalizep);
70864443 1522
77c9c6c2 1523 /* Logical-ior the two poss. carry together. */
34e56753 1524 carry_out = expand_binop (word_mode, ior_optab,
77c9c6c2 1525 carry_out, carry_tmp,
70864443
RK
1526 carry_out, 0, next_methods);
1527 if (carry_out == 0)
77c9c6c2
RK
1528 break;
1529 }
859cb4d8 1530 emit_move_insn (target_piece, newx);
77c9c6c2 1531 }
06cd9d72
DD
1532 else
1533 {
1534 if (x != target_piece)
1535 emit_move_insn (target_piece, x);
1536 }
77c9c6c2
RK
1537
1538 carry_in = carry_out;
0c20a65f 1539 }
77c9c6c2 1540
e2500fed 1541 if (i == GET_MODE_BITSIZE (mode) / (unsigned) BITS_PER_WORD)
77c9c6c2 1542 {
d0ccc658
RK
1543 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
1544 || ! rtx_equal_p (target, xtarget))
02214a5c 1545 {
64de6c0a 1546 rtx temp = emit_move_insn (target, xtarget);
70864443 1547
5fa671cf 1548 set_unique_reg_note (temp,
0c20a65f 1549 REG_EQUAL,
5fa671cf
AM
1550 gen_rtx_fmt_ee (binoptab->code, mode,
1551 copy_rtx (xop0),
1552 copy_rtx (xop1)));
02214a5c 1553 }
2cd622c3
AO
1554 else
1555 target = xtarget;
c5c76735 1556
77c9c6c2
RK
1557 return target;
1558 }
c5c76735 1559
77c9c6c2
RK
1560 else
1561 delete_insns_since (last);
1562 }
1563
f927760b
RS
1564 /* Attempt to synthesize double word multiplies using a sequence of word
1565 mode multiplications. We first attempt to generate a sequence using a
1566 more efficient unsigned widening multiply, and if that fails we then
1567 try using a signed widening multiply. */
77c9c6c2
RK
1568
1569 if (binoptab == smul_optab
1570 && class == MODE_INT
1571 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
34e56753 1572 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
f927760b 1573 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2 1574 {
f927760b 1575 rtx product = NULL_RTX;
77c9c6c2 1576
f927760b
RS
1577 if (umul_widen_optab->handlers[(int) mode].insn_code
1578 != CODE_FOR_nothing)
1579 {
1580 product = expand_doubleword_mult (mode, op0, op1, target,
1581 true, methods);
1582 if (!product)
77c9c6c2 1583 delete_insns_since (last);
77c9c6c2
RK
1584 }
1585
f927760b 1586 if (product == NULL_RTX
77c9c6c2 1587 && smul_widen_optab->handlers[(int) mode].insn_code
f927760b 1588 != CODE_FOR_nothing)
77c9c6c2 1589 {
f927760b
RS
1590 product = expand_doubleword_mult (mode, op0, op1, target,
1591 false, methods);
1592 if (!product)
1593 delete_insns_since (last);
77c9c6c2
RK
1594 }
1595
f927760b 1596 if (product != NULL_RTX)
77c9c6c2 1597 {
f927760b 1598 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
70864443 1599 {
f927760b
RS
1600 temp = emit_move_insn (target ? target : product, product);
1601 set_unique_reg_note (temp,
1602 REG_EQUAL,
1603 gen_rtx_fmt_ee (MULT, mode,
1604 copy_rtx (op0),
1605 copy_rtx (op1)));
77c9c6c2 1606 }
f927760b 1607 return product;
77c9c6c2 1608 }
77c9c6c2
RK
1609 }
1610
1611 /* It can't be open-coded in this mode.
1612 Use a library call if one is available and caller says that's ok. */
1613
1614 if (binoptab->handlers[(int) mode].libfunc
1615 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1616 {
1617 rtx insns;
0bbb7f4d
RS
1618 rtx op1x = op1;
1619 enum machine_mode op1_mode = mode;
9a7f678c 1620 rtx value;
77c9c6c2
RK
1621
1622 start_sequence ();
1623
0bbb7f4d
RS
1624 if (shift_op)
1625 {
1626 op1_mode = word_mode;
1627 /* Specify unsigned here,
1628 since negative shift counts are meaningless. */
1629 op1x = convert_to_mode (word_mode, op1, 1);
1630 }
1631
82f0e2cc
RK
1632 if (GET_MODE (op0) != VOIDmode
1633 && GET_MODE (op0) != mode)
5035bbfe
TG
1634 op0 = convert_to_mode (mode, op0, unsignedp);
1635
77c9c6c2
RK
1636 /* Pass 1 for NO_QUEUE so we don't lose any increments
1637 if the libcall is cse'd or moved. */
9a7f678c 1638 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
ebb1b59a 1639 NULL_RTX, LCT_CONST, mode, 2,
9a7f678c 1640 op0, mode, op1x, op1_mode);
77c9c6c2
RK
1641
1642 insns = get_insns ();
1643 end_sequence ();
1644
1645 target = gen_reg_rtx (mode);
9a7f678c 1646 emit_libcall_block (insns, target, value,
9e6a5703 1647 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
77c9c6c2
RK
1648
1649 return target;
1650 }
1651
1652 delete_insns_since (last);
1653
1654 /* It can't be done in this mode. Can we do it in a wider mode? */
1655
1656 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1657 || methods == OPTAB_MUST_WIDEN))
abd418d3
RS
1658 {
1659 /* Caller says, don't even try. */
1660 delete_insns_since (entry_last);
1661 return 0;
1662 }
77c9c6c2
RK
1663
1664 /* Compute the value of METHODS to pass to recursive calls.
1665 Don't allow widening to be tried recursively. */
1666
1667 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1668
34e56753
RS
1669 /* Look for a wider mode of the same class for which it appears we can do
1670 the operation. */
77c9c6c2
RK
1671
1672 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1673 {
34e56753 1674 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1675 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1676 {
1677 if ((binoptab->handlers[(int) wider_mode].insn_code
1678 != CODE_FOR_nothing)
1679 || (methods == OPTAB_LIB
1680 && binoptab->handlers[(int) wider_mode].libfunc))
1681 {
1682 rtx xop0 = op0, xop1 = op1;
1683 int no_extend = 0;
1684
34e56753 1685 /* For certain integer operations, we need not actually extend
77c9c6c2 1686 the narrow operands, as long as we will truncate
835532b8 1687 the results to the same narrowness. */
77c9c6c2 1688
34e56753
RS
1689 if ((binoptab == ior_optab || binoptab == and_optab
1690 || binoptab == xor_optab
1691 || binoptab == add_optab || binoptab == sub_optab
e5df894b 1692 || binoptab == smul_optab || binoptab == ashl_optab)
835532b8 1693 && class == MODE_INT)
77c9c6c2
RK
1694 no_extend = 1;
1695
0661a3de
RS
1696 xop0 = widen_operand (xop0, wider_mode, mode,
1697 unsignedp, no_extend);
943cc242
RK
1698
1699 /* The second operand of a shift must always be extended. */
0661a3de 1700 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
e5df894b 1701 no_extend && binoptab != ashl_optab);
77c9c6c2 1702
b1ec3c92 1703 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
77c9c6c2
RK
1704 unsignedp, methods);
1705 if (temp)
1706 {
34e56753 1707 if (class != MODE_INT)
77c9c6c2
RK
1708 {
1709 if (target == 0)
1710 target = gen_reg_rtx (mode);
1711 convert_move (target, temp, 0);
1712 return target;
1713 }
1714 else
1715 return gen_lowpart (mode, temp);
1716 }
1717 else
1718 delete_insns_since (last);
1719 }
1720 }
1721 }
1722
abd418d3 1723 delete_insns_since (entry_last);
77c9c6c2
RK
1724 return 0;
1725}
1726\f
1727/* Expand a binary operator which has both signed and unsigned forms.
1728 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1729 signed operations.
1730
1731 If we widen unsigned operands, we may use a signed wider operation instead
1732 of an unsigned wider operation, since the result would be the same. */
1733
1734rtx
0c20a65f
AJ
1735sign_expand_binop (enum machine_mode mode, optab uoptab, optab soptab,
1736 rtx op0, rtx op1, rtx target, int unsignedp,
1737 enum optab_methods methods)
77c9c6c2 1738{
b3694847 1739 rtx temp;
77c9c6c2
RK
1740 optab direct_optab = unsignedp ? uoptab : soptab;
1741 struct optab wide_soptab;
1742
1743 /* Do it without widening, if possible. */
1744 temp = expand_binop (mode, direct_optab, op0, op1, target,
1745 unsignedp, OPTAB_DIRECT);
1746 if (temp || methods == OPTAB_DIRECT)
1747 return temp;
1748
1749 /* Try widening to a signed int. Make a fake signed optab that
1750 hides any signed insn for direct use. */
1751 wide_soptab = *soptab;
1752 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1753 wide_soptab.handlers[(int) mode].libfunc = 0;
1754
1755 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1756 unsignedp, OPTAB_WIDEN);
1757
1758 /* For unsigned operands, try widening to an unsigned int. */
1759 if (temp == 0 && unsignedp)
1760 temp = expand_binop (mode, uoptab, op0, op1, target,
1761 unsignedp, OPTAB_WIDEN);
1762 if (temp || methods == OPTAB_WIDEN)
1763 return temp;
1764
1765 /* Use the right width lib call if that exists. */
1766 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1767 if (temp || methods == OPTAB_LIB)
1768 return temp;
1769
1770 /* Must widen and use a lib call, use either signed or unsigned. */
1771 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1772 unsignedp, methods);
1773 if (temp != 0)
1774 return temp;
1775 if (unsignedp)
1776 return expand_binop (mode, uoptab, op0, op1, target,
1777 unsignedp, methods);
1778 return 0;
1779}
1780\f
6c7cf1f0
UB
1781/* Generate code to perform an operation specified by UNOPPTAB
1782 on operand OP0, with two results to TARG0 and TARG1.
1783 We assume that the order of the operands for the instruction
1784 is TARG0, TARG1, OP0.
1785
1786 Either TARG0 or TARG1 may be zero, but what that means is that
1787 the result is not actually wanted. We will generate it into
1788 a dummy pseudo-reg and discard it. They may not both be zero.
1789
1790 Returns 1 if this operation can be performed; 0 if not. */
1791
1792int
a072d43b 1793expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
6c7cf1f0
UB
1794 int unsignedp)
1795{
1796 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1797 enum mode_class class;
1798 enum machine_mode wider_mode;
1799 rtx entry_last = get_last_insn ();
1800 rtx last;
1801
1802 class = GET_MODE_CLASS (mode);
1803
6c7cf1f0 1804 if (flag_force_mem)
ad76cef8 1805 op0 = force_not_mem (op0);
6c7cf1f0 1806
ad76cef8 1807 if (!targ0)
6c7cf1f0 1808 targ0 = gen_reg_rtx (mode);
ad76cef8 1809 if (!targ1)
6c7cf1f0
UB
1810 targ1 = gen_reg_rtx (mode);
1811
1812 /* Record where to go back to if we fail. */
1813 last = get_last_insn ();
1814
1815 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1816 {
1817 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1818 enum machine_mode mode0 = insn_data[icode].operand[2].mode;
1819 rtx pat;
1820 rtx xop0 = op0;
1821
1822 if (GET_MODE (xop0) != VOIDmode
1823 && GET_MODE (xop0) != mode0)
1824 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1825
1826 /* Now, if insn doesn't accept these operands, put them into pseudos. */
e3feb571 1827 if (!insn_data[icode].operand[2].predicate (xop0, mode0))
6c7cf1f0
UB
1828 xop0 = copy_to_mode_reg (mode0, xop0);
1829
1830 /* We could handle this, but we should always be called with a pseudo
1831 for our targets and all insns should take them as outputs. */
e3feb571
NS
1832 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
1833 gcc_assert (insn_data[icode].operand[1].predicate (targ1, mode));
6c7cf1f0
UB
1834
1835 pat = GEN_FCN (icode) (targ0, targ1, xop0);
1836 if (pat)
1837 {
1838 emit_insn (pat);
1839 return 1;
1840 }
1841 else
1842 delete_insns_since (last);
1843 }
1844
1845 /* It can't be done in this mode. Can we do it in a wider mode? */
1846
1847 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1848 {
1849 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1850 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1851 {
1852 if (unoptab->handlers[(int) wider_mode].insn_code
1853 != CODE_FOR_nothing)
1854 {
1855 rtx t0 = gen_reg_rtx (wider_mode);
1856 rtx t1 = gen_reg_rtx (wider_mode);
1857 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1858
a072d43b 1859 if (expand_twoval_unop (unoptab, cop0, t0, t1, unsignedp))
6c7cf1f0
UB
1860 {
1861 convert_move (targ0, t0, unsignedp);
1862 convert_move (targ1, t1, unsignedp);
1863 return 1;
1864 }
1865 else
1866 delete_insns_since (last);
1867 }
1868 }
1869 }
1870
1871 delete_insns_since (entry_last);
1872 return 0;
1873}
1874\f
77c9c6c2
RK
1875/* Generate code to perform an operation specified by BINOPTAB
1876 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1877 We assume that the order of the operands for the instruction
1878 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1879 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1880
1881 Either TARG0 or TARG1 may be zero, but what that means is that
38e01259 1882 the result is not actually wanted. We will generate it into
77c9c6c2
RK
1883 a dummy pseudo-reg and discard it. They may not both be zero.
1884
1885 Returns 1 if this operation can be performed; 0 if not. */
1886
1887int
0c20a65f
AJ
1888expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
1889 int unsignedp)
77c9c6c2
RK
1890{
1891 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1892 enum mode_class class;
1893 enum machine_mode wider_mode;
abd418d3 1894 rtx entry_last = get_last_insn ();
77c9c6c2
RK
1895 rtx last;
1896
1897 class = GET_MODE_CLASS (mode);
1898
77c9c6c2
RK
1899 if (flag_force_mem)
1900 {
1901 op0 = force_not_mem (op0);
1902 op1 = force_not_mem (op1);
1903 }
1904
7c27e184
PB
1905 /* If we are inside an appropriately-short loop and we are optimizing,
1906 force expensive constants into a register. */
1907 if (CONSTANT_P (op0) && optimize
b437f1a7 1908 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
77c9c6c2
RK
1909 op0 = force_reg (mode, op0);
1910
7c27e184 1911 if (CONSTANT_P (op1) && optimize
b437f1a7 1912 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
77c9c6c2
RK
1913 op1 = force_reg (mode, op1);
1914
ad76cef8 1915 if (!targ0)
77c9c6c2 1916 targ0 = gen_reg_rtx (mode);
ad76cef8 1917 if (!targ1)
77c9c6c2
RK
1918 targ1 = gen_reg_rtx (mode);
1919
1920 /* Record where to go back to if we fail. */
1921 last = get_last_insn ();
1922
1923 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1924 {
1925 int icode = (int) binoptab->handlers[(int) mode].insn_code;
a995e389
RH
1926 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1927 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
77c9c6c2
RK
1928 rtx pat;
1929 rtx xop0 = op0, xop1 = op1;
1930
874f6a6d
EB
1931 /* In case the insn wants input operands in modes different from
1932 those of the actual operands, convert the operands. It would
1933 seem that we don't need to convert CONST_INTs, but we do, so
35f1c975
EB
1934 that they're properly zero-extended, sign-extended or truncated
1935 for their mode. */
77c9c6c2 1936
874f6a6d
EB
1937 if (GET_MODE (op0) != mode0 && mode0 != VOIDmode)
1938 xop0 = convert_modes (mode0,
1939 GET_MODE (op0) != VOIDmode
1940 ? GET_MODE (op0)
1941 : mode,
1942 xop0, unsignedp);
1943
1944 if (GET_MODE (op1) != mode1 && mode1 != VOIDmode)
1945 xop1 = convert_modes (mode1,
1946 GET_MODE (op1) != VOIDmode
1947 ? GET_MODE (op1)
1948 : mode,
1949 xop1, unsignedp);
77c9c6c2
RK
1950
1951 /* Now, if insn doesn't accept these operands, put them into pseudos. */
e3feb571 1952 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
77c9c6c2
RK
1953 xop0 = copy_to_mode_reg (mode0, xop0);
1954
e3feb571 1955 if (!insn_data[icode].operand[2].predicate (xop1, mode1))
77c9c6c2
RK
1956 xop1 = copy_to_mode_reg (mode1, xop1);
1957
1958 /* We could handle this, but we should always be called with a pseudo
1959 for our targets and all insns should take them as outputs. */
e3feb571
NS
1960 gcc_assert (insn_data[icode].operand[0].predicate (targ0, mode));
1961 gcc_assert (insn_data[icode].operand[3].predicate (targ1, mode));
0c20a65f 1962
77c9c6c2
RK
1963 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1964 if (pat)
1965 {
1966 emit_insn (pat);
1967 return 1;
1968 }
1969 else
1970 delete_insns_since (last);
1971 }
1972
1973 /* It can't be done in this mode. Can we do it in a wider mode? */
1974
1975 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1976 {
34e56753 1977 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
1978 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1979 {
1980 if (binoptab->handlers[(int) wider_mode].insn_code
1981 != CODE_FOR_nothing)
1982 {
b3694847
SS
1983 rtx t0 = gen_reg_rtx (wider_mode);
1984 rtx t1 = gen_reg_rtx (wider_mode);
76791f3d
JH
1985 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
1986 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
77c9c6c2 1987
76791f3d 1988 if (expand_twoval_binop (binoptab, cop0, cop1,
77c9c6c2
RK
1989 t0, t1, unsignedp))
1990 {
1991 convert_move (targ0, t0, unsignedp);
1992 convert_move (targ1, t1, unsignedp);
1993 return 1;
1994 }
1995 else
1996 delete_insns_since (last);
1997 }
1998 }
1999 }
2000
abd418d3 2001 delete_insns_since (entry_last);
77c9c6c2
RK
2002 return 0;
2003}
b3f8d95d
MM
2004
2005/* Expand the two-valued library call indicated by BINOPTAB, but
2006 preserve only one of the values. If TARG0 is non-NULL, the first
2007 value is placed into TARG0; otherwise the second value is placed
2008 into TARG1. Exactly one of TARG0 and TARG1 must be non-NULL. The
2009 value stored into TARG0 or TARG1 is equivalent to (CODE OP0 OP1).
2010 This routine assumes that the value returned by the library call is
2011 as if the return value was of an integral mode twice as wide as the
2012 mode of OP0. Returns 1 if the call was successful. */
2013
2014bool
5906d013 2015expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
b3f8d95d
MM
2016 rtx targ0, rtx targ1, enum rtx_code code)
2017{
2018 enum machine_mode mode;
2019 enum machine_mode libval_mode;
2020 rtx libval;
2021 rtx insns;
5906d013 2022
b3f8d95d 2023 /* Exactly one of TARG0 or TARG1 should be non-NULL. */
e3feb571 2024 gcc_assert (!targ0 != !targ1);
b3f8d95d
MM
2025
2026 mode = GET_MODE (op0);
2027 if (!binoptab->handlers[(int) mode].libfunc)
2028 return false;
2029
2030 /* The value returned by the library function will have twice as
2031 many bits as the nominal MODE. */
5906d013 2032 libval_mode = smallest_mode_for_size (2 * GET_MODE_BITSIZE (mode),
b3f8d95d
MM
2033 MODE_INT);
2034 start_sequence ();
2035 libval = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
5906d013 2036 NULL_RTX, LCT_CONST,
b3f8d95d 2037 libval_mode, 2,
5906d013 2038 op0, mode,
b3f8d95d
MM
2039 op1, mode);
2040 /* Get the part of VAL containing the value that we want. */
2041 libval = simplify_gen_subreg (mode, libval, libval_mode,
2042 targ0 ? 0 : GET_MODE_SIZE (mode));
2043 insns = get_insns ();
2044 end_sequence ();
2045 /* Move the into the desired location. */
5906d013 2046 emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
b3f8d95d 2047 gen_rtx_fmt_ee (code, mode, op0, op1));
5906d013 2048
b3f8d95d
MM
2049 return true;
2050}
2051
77c9c6c2 2052\f
ef89d648
ZW
2053/* Wrapper around expand_unop which takes an rtx code to specify
2054 the operation to perform, not an optab pointer. All other
2055 arguments are the same. */
2056rtx
0c20a65f
AJ
2057expand_simple_unop (enum machine_mode mode, enum rtx_code code, rtx op0,
2058 rtx target, int unsignedp)
ef89d648 2059{
7e1a450d 2060 optab unop = code_to_optab[(int) code];
e3feb571 2061 gcc_assert (unop);
ef89d648
ZW
2062
2063 return expand_unop (mode, unop, op0, target, unsignedp);
2064}
2065
2928cd7a
RH
2066/* Try calculating
2067 (clz:narrow x)
2068 as
2069 (clz:wide (zero_extend:wide x)) - ((width wide) - (width narrow)). */
2070static rtx
0c20a65f 2071widen_clz (enum machine_mode mode, rtx op0, rtx target)
2928cd7a
RH
2072{
2073 enum mode_class class = GET_MODE_CLASS (mode);
2074 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2075 {
2076 enum machine_mode wider_mode;
2077 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2078 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2079 {
2080 if (clz_optab->handlers[(int) wider_mode].insn_code
2081 != CODE_FOR_nothing)
2082 {
2083 rtx xop0, temp, last;
2084
2085 last = get_last_insn ();
2086
2087 if (target == 0)
2088 target = gen_reg_rtx (mode);
2089 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2090 temp = expand_unop (wider_mode, clz_optab, xop0, NULL_RTX, true);
2091 if (temp != 0)
2092 temp = expand_binop (wider_mode, sub_optab, temp,
2093 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2094 - GET_MODE_BITSIZE (mode)),
2095 target, true, OPTAB_DIRECT);
2096 if (temp == 0)
2097 delete_insns_since (last);
2098
2099 return temp;
2100 }
2101 }
2102 }
2103 return 0;
2104}
2105
2106/* Try calculating (parity x) as (and (popcount x) 1), where
2107 popcount can also be done in a wider mode. */
2108static rtx
0c20a65f 2109expand_parity (enum machine_mode mode, rtx op0, rtx target)
2928cd7a
RH
2110{
2111 enum mode_class class = GET_MODE_CLASS (mode);
2112 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2113 {
2114 enum machine_mode wider_mode;
2115 for (wider_mode = mode; wider_mode != VOIDmode;
2116 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2117 {
2118 if (popcount_optab->handlers[(int) wider_mode].insn_code
2119 != CODE_FOR_nothing)
2120 {
2121 rtx xop0, temp, last;
2122
2123 last = get_last_insn ();
2124
2125 if (target == 0)
2126 target = gen_reg_rtx (mode);
2127 xop0 = widen_operand (op0, wider_mode, mode, true, false);
2128 temp = expand_unop (wider_mode, popcount_optab, xop0, NULL_RTX,
2129 true);
2130 if (temp != 0)
60c81c89 2131 temp = expand_binop (wider_mode, and_optab, temp, const1_rtx,
2928cd7a
RH
2132 target, true, OPTAB_DIRECT);
2133 if (temp == 0)
2134 delete_insns_since (last);
2135
2136 return temp;
2137 }
2138 }
2139 }
2140 return 0;
2141}
2142
6b132673
RH
2143/* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
2144 conditions, VAL may already be a SUBREG against which we cannot generate
2145 a further SUBREG. In this case, we expect forcing the value into a
2146 register will work around the situation. */
2147
2148static rtx
2149lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
2150 enum machine_mode imode)
2151{
2152 rtx ret;
2153 ret = lowpart_subreg (omode, val, imode);
2154 if (ret == NULL)
2155 {
2156 val = force_reg (imode, val);
2157 ret = lowpart_subreg (omode, val, imode);
2158 gcc_assert (ret != NULL);
2159 }
2160 return ret;
2161}
2162
8c55a142
RH
2163/* Expand a floating point absolute value or negation operation via a
2164 logical operation on the sign bit. */
2165
2166static rtx
2167expand_absneg_bit (enum rtx_code code, enum machine_mode mode,
2168 rtx op0, rtx target)
2169{
2170 const struct real_format *fmt;
2171 int bitpos, word, nwords, i;
2172 enum machine_mode imode;
2173 HOST_WIDE_INT hi, lo;
2174 rtx temp, insns;
2175
2176 /* The format has to have a simple sign bit. */
2177 fmt = REAL_MODE_FORMAT (mode);
2178 if (fmt == NULL)
2179 return NULL_RTX;
2180
b87a0206 2181 bitpos = fmt->signbit_rw;
8c55a142
RH
2182 if (bitpos < 0)
2183 return NULL_RTX;
2184
2185 /* Don't create negative zeros if the format doesn't support them. */
2186 if (code == NEG && !fmt->has_signed_zero)
2187 return NULL_RTX;
2188
2189 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2190 {
2191 imode = int_mode_for_mode (mode);
2192 if (imode == BLKmode)
2193 return NULL_RTX;
2194 word = 0;
2195 nwords = 1;
2196 }
2197 else
2198 {
2199 imode = word_mode;
2200
2201 if (FLOAT_WORDS_BIG_ENDIAN)
2202 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2203 else
2204 word = bitpos / BITS_PER_WORD;
2205 bitpos = bitpos % BITS_PER_WORD;
2206 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
2207 }
2208
2209 if (bitpos < HOST_BITS_PER_WIDE_INT)
2210 {
2211 hi = 0;
2212 lo = (HOST_WIDE_INT) 1 << bitpos;
2213 }
2214 else
2215 {
2216 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2217 lo = 0;
2218 }
2219 if (code == ABS)
2220 lo = ~lo, hi = ~hi;
2221
2222 if (target == 0 || target == op0)
2223 target = gen_reg_rtx (mode);
2224
2225 if (nwords > 1)
2226 {
2227 start_sequence ();
2228
2229 for (i = 0; i < nwords; ++i)
2230 {
2231 rtx targ_piece = operand_subword (target, i, 1, mode);
2232 rtx op0_piece = operand_subword_force (op0, i, mode);
2233
2234 if (i == word)
2235 {
2236 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2237 op0_piece,
2238 immed_double_const (lo, hi, imode),
2239 targ_piece, 1, OPTAB_LIB_WIDEN);
2240 if (temp != targ_piece)
2241 emit_move_insn (targ_piece, temp);
2242 }
2243 else
2244 emit_move_insn (targ_piece, op0_piece);
2245 }
2246
2247 insns = get_insns ();
2248 end_sequence ();
2249
2250 temp = gen_rtx_fmt_e (code, mode, copy_rtx (op0));
2251 emit_no_conflict_block (insns, target, op0, NULL_RTX, temp);
2252 }
2253 else
2254 {
2255 temp = expand_binop (imode, code == ABS ? and_optab : xor_optab,
2256 gen_lowpart (imode, op0),
2257 immed_double_const (lo, hi, imode),
2258 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2259 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2260
2261 set_unique_reg_note (get_last_insn (), REG_EQUAL,
2262 gen_rtx_fmt_e (code, mode, copy_rtx (op0)));
2263 }
2264
2265 return target;
2266}
2267
77c9c6c2
RK
2268/* Generate code to perform an operation specified by UNOPTAB
2269 on operand OP0, with result having machine-mode MODE.
2270
2271 UNSIGNEDP is for the case where we have to widen the operands
2272 to perform the operation. It says to use zero-extension.
2273
2274 If TARGET is nonzero, the value
2275 is generated there, if it is convenient to do so.
2276 In all cases an rtx is returned for the locus of the value;
2277 this may or may not be TARGET. */
2278
2279rtx
0c20a65f
AJ
2280expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
2281 int unsignedp)
77c9c6c2
RK
2282{
2283 enum mode_class class;
2284 enum machine_mode wider_mode;
b3694847 2285 rtx temp;
77c9c6c2
RK
2286 rtx last = get_last_insn ();
2287 rtx pat;
2288
2289 class = GET_MODE_CLASS (mode);
2290
77c9c6c2 2291 if (flag_force_mem)
ad76cef8 2292 op0 = force_not_mem (op0);
77c9c6c2
RK
2293
2294 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2295 {
2296 int icode = (int) unoptab->handlers[(int) mode].insn_code;
a995e389 2297 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
77c9c6c2
RK
2298 rtx xop0 = op0;
2299
2300 if (target)
2301 temp = target;
2302 else
2303 temp = gen_reg_rtx (mode);
2304
2305 if (GET_MODE (xop0) != VOIDmode
2306 && GET_MODE (xop0) != mode0)
2307 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2308
2309 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2310
e3feb571 2311 if (!insn_data[icode].operand[1].predicate (xop0, mode0))
77c9c6c2
RK
2312 xop0 = copy_to_mode_reg (mode0, xop0);
2313
e3feb571 2314 if (!insn_data[icode].operand[0].predicate (temp, mode))
77c9c6c2
RK
2315 temp = gen_reg_rtx (mode);
2316
2317 pat = GEN_FCN (icode) (temp, xop0);
2318 if (pat)
2319 {
2f937369 2320 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX
b1ec3c92 2321 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
77c9c6c2
RK
2322 {
2323 delete_insns_since (last);
b1ec3c92 2324 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
77c9c6c2
RK
2325 }
2326
2327 emit_insn (pat);
0c20a65f 2328
77c9c6c2
RK
2329 return temp;
2330 }
2331 else
2332 delete_insns_since (last);
2333 }
2334
9a856ec7
RK
2335 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2336
2928cd7a
RH
2337 /* Widening clz needs special treatment. */
2338 if (unoptab == clz_optab)
2339 {
2340 temp = widen_clz (mode, op0, target);
2341 if (temp)
2342 return temp;
2343 else
2344 goto try_libcall;
2345 }
2346
9a856ec7
RK
2347 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2348 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2349 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2350 {
2351 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2352 {
2353 rtx xop0 = op0;
2354
2355 /* For certain operations, we need not actually extend
2356 the narrow operand, as long as we will truncate the
835532b8
RK
2357 results to the same narrowness. */
2358
0661a3de 2359 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
835532b8
RK
2360 (unoptab == neg_optab
2361 || unoptab == one_cmpl_optab)
2362 && class == MODE_INT);
0c20a65f 2363
b1ec3c92
CH
2364 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2365 unsignedp);
9a856ec7
RK
2366
2367 if (temp)
2368 {
2369 if (class != MODE_INT)
2370 {
2371 if (target == 0)
2372 target = gen_reg_rtx (mode);
2373 convert_move (target, temp, 0);
2374 return target;
2375 }
2376 else
2377 return gen_lowpart (mode, temp);
2378 }
2379 else
2380 delete_insns_since (last);
2381 }
2382 }
2383
77c9c6c2
RK
2384 /* These can be done a word at a time. */
2385 if (unoptab == one_cmpl_optab
2386 && class == MODE_INT
2387 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
34e56753 2388 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
77c9c6c2 2389 {
bb93b973 2390 int i;
77c9c6c2
RK
2391 rtx insns;
2392
2393 if (target == 0 || target == op0)
2394 target = gen_reg_rtx (mode);
2395
2396 start_sequence ();
2397
2398 /* Do the actual arithmetic. */
2399 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2400 {
2401 rtx target_piece = operand_subword (target, i, 1, mode);
34e56753 2402 rtx x = expand_unop (word_mode, unoptab,
77c9c6c2
RK
2403 operand_subword_force (op0, i, mode),
2404 target_piece, unsignedp);
bb93b973 2405
77c9c6c2
RK
2406 if (target_piece != x)
2407 emit_move_insn (target_piece, x);
2408 }
2409
2410 insns = get_insns ();
2411 end_sequence ();
2412
b1ec3c92 2413 emit_no_conflict_block (insns, target, op0, NULL_RTX,
9e6a5703
JC
2414 gen_rtx_fmt_e (unoptab->code, mode,
2415 copy_rtx (op0)));
77c9c6c2
RK
2416 return target;
2417 }
2418
8c55a142 2419 if (unoptab->code == NEG)
4977bab6 2420 {
8c55a142
RH
2421 /* Try negating floating point values by flipping the sign bit. */
2422 if (class == MODE_FLOAT)
4977bab6 2423 {
8c55a142
RH
2424 temp = expand_absneg_bit (NEG, mode, op0, target);
2425 if (temp)
2426 return temp;
2427 }
9ee0a442 2428
8c55a142
RH
2429 /* If there is no negation pattern, and we have no negative zero,
2430 try subtracting from zero. */
2431 if (!HONOR_SIGNED_ZEROS (mode))
2432 {
2433 temp = expand_binop (mode, (unoptab == negv_optab
2434 ? subv_optab : sub_optab),
2435 CONST0_RTX (mode), op0, target,
2436 unsignedp, OPTAB_DIRECT);
2437 if (temp)
2438 return temp;
2439 }
4977bab6
ZW
2440 }
2441
2928cd7a
RH
2442 /* Try calculating parity (x) as popcount (x) % 2. */
2443 if (unoptab == parity_optab)
2444 {
2445 temp = expand_parity (mode, op0, target);
2446 if (temp)
2447 return temp;
2448 }
2449
2450 try_libcall:
139e5e08 2451 /* Now try a library call in this mode. */
77c9c6c2
RK
2452 if (unoptab->handlers[(int) mode].libfunc)
2453 {
2454 rtx insns;
9a7f678c 2455 rtx value;
2928cd7a
RH
2456 enum machine_mode outmode = mode;
2457
2458 /* All of these functions return small values. Thus we choose to
2459 have them return something that isn't a double-word. */
2460 if (unoptab == ffs_optab || unoptab == clz_optab || unoptab == ctz_optab
2461 || unoptab == popcount_optab || unoptab == parity_optab)
cd2ac05b
FH
2462 outmode
2463 = GET_MODE (hard_libcall_value (TYPE_MODE (integer_type_node)));
77c9c6c2
RK
2464
2465 start_sequence ();
2466
2467 /* Pass 1 for NO_QUEUE so we don't lose any increments
2468 if the libcall is cse'd or moved. */
9a7f678c 2469 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2928cd7a
RH
2470 NULL_RTX, LCT_CONST, outmode,
2471 1, op0, mode);
77c9c6c2
RK
2472 insns = get_insns ();
2473 end_sequence ();
2474
2928cd7a 2475 target = gen_reg_rtx (outmode);
9a7f678c 2476 emit_libcall_block (insns, target, value,
9e6a5703 2477 gen_rtx_fmt_e (unoptab->code, mode, op0));
77c9c6c2
RK
2478
2479 return target;
2480 }
2481
2482 /* It can't be done in this mode. Can we do it in a wider mode? */
2483
2484 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2485 {
34e56753 2486 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
77c9c6c2
RK
2487 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2488 {
2489 if ((unoptab->handlers[(int) wider_mode].insn_code
2490 != CODE_FOR_nothing)
2491 || unoptab->handlers[(int) wider_mode].libfunc)
2492 {
34e56753
RS
2493 rtx xop0 = op0;
2494
2495 /* For certain operations, we need not actually extend
2496 the narrow operand, as long as we will truncate the
2497 results to the same narrowness. */
2498
0661a3de 2499 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
835532b8
RK
2500 (unoptab == neg_optab
2501 || unoptab == one_cmpl_optab)
2502 && class == MODE_INT);
0c20a65f 2503
b1ec3c92
CH
2504 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2505 unsignedp);
34e56753 2506
c117dddc
KH
2507 /* If we are generating clz using wider mode, adjust the
2508 result. */
2509 if (unoptab == clz_optab && temp != 0)
2510 temp = expand_binop (wider_mode, sub_optab, temp,
2511 GEN_INT (GET_MODE_BITSIZE (wider_mode)
2512 - GET_MODE_BITSIZE (mode)),
2513 target, true, OPTAB_DIRECT);
2514
34e56753 2515 if (temp)
77c9c6c2 2516 {
34e56753
RS
2517 if (class != MODE_INT)
2518 {
2519 if (target == 0)
2520 target = gen_reg_rtx (mode);
2521 convert_move (target, temp, 0);
2522 return target;
2523 }
2524 else
2525 return gen_lowpart (mode, temp);
77c9c6c2
RK
2526 }
2527 else
34e56753 2528 delete_insns_since (last);
77c9c6c2
RK
2529 }
2530 }
2531 }
2532
8c55a142
RH
2533 /* One final attempt at implementing negation via subtraction,
2534 this time allowing widening of the operand. */
2535 if (unoptab->code == NEG && !HONOR_SIGNED_ZEROS (mode))
0c20a65f 2536 {
b82b6eea 2537 rtx temp;
91ce572a
CC
2538 temp = expand_binop (mode,
2539 unoptab == negv_optab ? subv_optab : sub_optab,
2540 CONST0_RTX (mode), op0,
2541 target, unsignedp, OPTAB_LIB_WIDEN);
b82b6eea 2542 if (temp)
8c55a142 2543 return temp;
b82b6eea 2544 }
0c20a65f 2545
77c9c6c2
RK
2546 return 0;
2547}
2548\f
decdfa82
RS
2549/* Emit code to compute the absolute value of OP0, with result to
2550 TARGET if convenient. (TARGET may be 0.) The return value says
2551 where the result actually is to be found.
2552
2553 MODE is the mode of the operand; the mode of the result is
2554 different but can be deduced from MODE.
2555
91813b28 2556 */
7fd01431
RK
2557
2558rtx
0c20a65f
AJ
2559expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
2560 int result_unsignedp)
7fd01431 2561{
2ef0a555 2562 rtx temp;
7fd01431 2563
91ce572a
CC
2564 if (! flag_trapv)
2565 result_unsignedp = 1;
2566
7fd01431 2567 /* First try to do it with a special abs instruction. */
91ce572a
CC
2568 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2569 op0, target, 0);
7fd01431
RK
2570 if (temp != 0)
2571 return temp;
2572
4977bab6 2573 /* For floating point modes, try clearing the sign bit. */
8c55a142 2574 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
4977bab6 2575 {
8c55a142
RH
2576 temp = expand_absneg_bit (ABS, mode, op0, target);
2577 if (temp)
2578 return temp;
4977bab6
ZW
2579 }
2580
14a774a9 2581 /* If we have a MAX insn, we can do this as MAX (x, -x). */
8c55a142
RH
2582 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing
2583 && !HONOR_SIGNED_ZEROS (mode))
14a774a9
RK
2584 {
2585 rtx last = get_last_insn ();
2586
2587 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2588 if (temp != 0)
2589 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2590 OPTAB_WIDEN);
2591
2592 if (temp != 0)
2593 return temp;
2594
2595 delete_insns_since (last);
2596 }
2597
7fd01431
RK
2598 /* If this machine has expensive jumps, we can do integer absolute
2599 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
e1078cfc 2600 where W is the width of MODE. */
7fd01431
RK
2601
2602 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2603 {
2604 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2605 size_int (GET_MODE_BITSIZE (mode) - 1),
2606 NULL_RTX, 0);
2607
2608 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2609 OPTAB_LIB_WIDEN);
2610 if (temp != 0)
91ce572a
CC
2611 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2612 temp, extended, target, 0, OPTAB_LIB_WIDEN);
7fd01431
RK
2613
2614 if (temp != 0)
2615 return temp;
2616 }
2617
2ef0a555
RH
2618 return NULL_RTX;
2619}
2620
2621rtx
0c20a65f
AJ
2622expand_abs (enum machine_mode mode, rtx op0, rtx target,
2623 int result_unsignedp, int safe)
2ef0a555
RH
2624{
2625 rtx temp, op1;
2626
77173bbe
KH
2627 if (! flag_trapv)
2628 result_unsignedp = 1;
2629
2ef0a555
RH
2630 temp = expand_abs_nojump (mode, op0, target, result_unsignedp);
2631 if (temp != 0)
2632 return temp;
2633
7fd01431 2634 /* If that does not win, use conditional jump and negate. */
5c0bf747
RK
2635
2636 /* It is safe to use the target if it is the same
2637 as the source if this is also a pseudo register */
f8cfc6aa 2638 if (op0 == target && REG_P (op0)
5c0bf747
RK
2639 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2640 safe = 1;
2641
7fd01431
RK
2642 op1 = gen_label_rtx ();
2643 if (target == 0 || ! safe
2644 || GET_MODE (target) != mode
3c0cb5de 2645 || (MEM_P (target) && MEM_VOLATILE_P (target))
f8cfc6aa 2646 || (REG_P (target)
7fd01431
RK
2647 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2648 target = gen_reg_rtx (mode);
2649
2650 emit_move_insn (target, op0);
2651 NO_DEFER_POP;
2652
2653 /* If this mode is an integer too wide to compare properly,
2654 compare word by word. Rely on CSE to optimize constant cases. */
1eb8759b
RH
2655 if (GET_MODE_CLASS (mode) == MODE_INT
2656 && ! can_compare_p (GE, mode, ccp_jump))
0c20a65f 2657 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
7fd01431
RK
2658 NULL_RTX, op1);
2659 else
b30f05db 2660 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
a06ef755 2661 NULL_RTX, NULL_RTX, op1);
7fd01431 2662
91ce572a
CC
2663 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2664 target, target, 0);
7fd01431
RK
2665 if (op0 != target)
2666 emit_move_insn (target, op0);
2667 emit_label (op1);
2668 OK_DEFER_POP;
2669 return target;
2670}
046625fa 2671
ae394659
RH
2672/* A subroutine of expand_copysign, perform the copysign operation using the
2673 abs and neg primitives advertised to exist on the target. The assumption
2674 is that we have a split register file, and leaving op0 in fp registers,
2675 and not playing with subregs so much, will help the register allocator. */
046625fa 2676
9abd1955 2677static rtx
ae394659
RH
2678expand_copysign_absneg (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2679 int bitpos, bool op0_is_abs)
046625fa 2680{
046625fa 2681 enum machine_mode imode;
046625fa 2682 HOST_WIDE_INT hi, lo;
ae394659
RH
2683 int word;
2684 rtx label;
046625fa 2685
ae394659
RH
2686 if (target == op1)
2687 target = NULL_RTX;
046625fa 2688
ae394659
RH
2689 if (!op0_is_abs)
2690 {
2691 op0 = expand_unop (mode, abs_optab, op0, target, 0);
2692 if (op0 == NULL)
2693 return NULL_RTX;
2694 target = op0;
2695 }
2696 else
2697 {
2698 if (target == NULL_RTX)
2699 target = copy_to_reg (op0);
2700 else
2701 emit_move_insn (target, op0);
2702 }
046625fa 2703
ae394659
RH
2704 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
2705 {
2706 imode = int_mode_for_mode (mode);
2707 if (imode == BLKmode)
2708 return NULL_RTX;
2709 op1 = gen_lowpart (imode, op1);
2710 }
2711 else
2712 {
2713 imode = word_mode;
2714 if (FLOAT_WORDS_BIG_ENDIAN)
2715 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2716 else
2717 word = bitpos / BITS_PER_WORD;
2718 bitpos = bitpos % BITS_PER_WORD;
2719 op1 = operand_subword_force (op1, word, mode);
2720 }
046625fa 2721
ae394659 2722 if (bitpos < HOST_BITS_PER_WIDE_INT)
8c55a142 2723 {
ae394659
RH
2724 hi = 0;
2725 lo = (HOST_WIDE_INT) 1 << bitpos;
8c55a142 2726 }
ae394659
RH
2727 else
2728 {
2729 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2730 lo = 0;
2731 }
2732
2733 op1 = expand_binop (imode, and_optab, op1,
2734 immed_double_const (lo, hi, imode),
2735 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2736
2737 label = gen_label_rtx ();
2738 emit_cmp_and_jump_insns (op1, const0_rtx, EQ, NULL_RTX, imode, 1, label);
2739
2740 if (GET_CODE (op0) == CONST_DOUBLE)
2741 op0 = simplify_unary_operation (NEG, mode, op0, mode);
2742 else
2743 op0 = expand_unop (mode, neg_optab, op0, target, 0);
2744 if (op0 != target)
2745 emit_move_insn (target, op0);
2746
2747 emit_label (label);
2748
2749 return target;
2750}
2751
2752
2753/* A subroutine of expand_copysign, perform the entire copysign operation
2754 with integer bitmasks. BITPOS is the position of the sign bit; OP0_IS_ABS
2755 is true if op0 is known to have its sign bit clear. */
2756
2757static rtx
2758expand_copysign_bit (enum machine_mode mode, rtx op0, rtx op1, rtx target,
2759 int bitpos, bool op0_is_abs)
2760{
2761 enum machine_mode imode;
2762 HOST_WIDE_INT hi, lo;
2763 int word, nwords, i;
2764 rtx temp, insns;
046625fa 2765
8c55a142 2766 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
046625fa 2767 {
8c55a142
RH
2768 imode = int_mode_for_mode (mode);
2769 if (imode == BLKmode)
2770 return NULL_RTX;
2771 word = 0;
2772 nwords = 1;
2773 }
2774 else
2775 {
2776 imode = word_mode;
2777
2778 if (FLOAT_WORDS_BIG_ENDIAN)
2779 word = (GET_MODE_BITSIZE (mode) - bitpos) / BITS_PER_WORD;
2780 else
2781 word = bitpos / BITS_PER_WORD;
2782 bitpos = bitpos % BITS_PER_WORD;
2783 nwords = (GET_MODE_BITSIZE (mode) + BITS_PER_WORD - 1) / BITS_PER_WORD;
046625fa
RH
2784 }
2785
2786 if (bitpos < HOST_BITS_PER_WIDE_INT)
2787 {
2788 hi = 0;
2789 lo = (HOST_WIDE_INT) 1 << bitpos;
2790 }
2791 else
2792 {
2793 hi = (HOST_WIDE_INT) 1 << (bitpos - HOST_BITS_PER_WIDE_INT);
2794 lo = 0;
2795 }
2796
8c55a142
RH
2797 if (target == 0 || target == op0 || target == op1)
2798 target = gen_reg_rtx (mode);
2799
2800 if (nwords > 1)
046625fa 2801 {
8c55a142
RH
2802 start_sequence ();
2803
2804 for (i = 0; i < nwords; ++i)
046625fa 2805 {
8c55a142
RH
2806 rtx targ_piece = operand_subword (target, i, 1, mode);
2807 rtx op0_piece = operand_subword_force (op0, i, mode);
2808
2809 if (i == word)
2810 {
ae394659 2811 if (!op0_is_abs)
8c55a142
RH
2812 op0_piece = expand_binop (imode, and_optab, op0_piece,
2813 immed_double_const (~lo, ~hi, imode),
2814 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2815
2816 op1 = expand_binop (imode, and_optab,
2817 operand_subword_force (op1, i, mode),
2818 immed_double_const (lo, hi, imode),
2819 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2820
2821 temp = expand_binop (imode, ior_optab, op0_piece, op1,
2822 targ_piece, 1, OPTAB_LIB_WIDEN);
2823 if (temp != targ_piece)
2824 emit_move_insn (targ_piece, temp);
2825 }
2826 else
2827 emit_move_insn (targ_piece, op0_piece);
046625fa 2828 }
8c55a142
RH
2829
2830 insns = get_insns ();
2831 end_sequence ();
2832
2833 emit_no_conflict_block (insns, target, op0, op1, NULL_RTX);
046625fa
RH
2834 }
2835 else
8c55a142
RH
2836 {
2837 op1 = expand_binop (imode, and_optab, gen_lowpart (imode, op1),
2838 immed_double_const (lo, hi, imode),
2839 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2840
2841 op0 = gen_lowpart (imode, op0);
ae394659 2842 if (!op0_is_abs)
8c55a142
RH
2843 op0 = expand_binop (imode, and_optab, op0,
2844 immed_double_const (~lo, ~hi, imode),
2845 NULL_RTX, 1, OPTAB_LIB_WIDEN);
2846
2847 temp = expand_binop (imode, ior_optab, op0, op1,
2848 gen_lowpart (imode, target), 1, OPTAB_LIB_WIDEN);
2849 target = lowpart_subreg_maybe_copy (mode, temp, imode);
2850 }
046625fa
RH
2851
2852 return target;
2853}
ae394659
RH
2854
2855/* Expand the C99 copysign operation. OP0 and OP1 must be the same
2856 scalar floating point mode. Return NULL if we do not know how to
2857 expand the operation inline. */
2858
2859rtx
2860expand_copysign (rtx op0, rtx op1, rtx target)
2861{
2862 enum machine_mode mode = GET_MODE (op0);
2863 const struct real_format *fmt;
ae394659
RH
2864 bool op0_is_abs;
2865 rtx temp;
2866
2867 gcc_assert (SCALAR_FLOAT_MODE_P (mode));
2868 gcc_assert (GET_MODE (op1) == mode);
2869
2870 /* First try to do it with a special instruction. */
2871 temp = expand_binop (mode, copysign_optab, op0, op1,
2872 target, 0, OPTAB_DIRECT);
2873 if (temp)
2874 return temp;
2875
2876 fmt = REAL_MODE_FORMAT (mode);
2877 if (fmt == NULL || !fmt->has_signed_zero)
2878 return NULL_RTX;
2879
ae394659
RH
2880 op0_is_abs = false;
2881 if (GET_CODE (op0) == CONST_DOUBLE)
2882 {
2883 if (real_isneg (CONST_DOUBLE_REAL_VALUE (op0)))
2884 op0 = simplify_unary_operation (ABS, mode, op0, mode);
2885 op0_is_abs = true;
2886 }
2887
c064fde5
RS
2888 if (fmt->signbit_ro >= 0
2889 && (GET_CODE (op0) == CONST_DOUBLE
2890 || (neg_optab->handlers[mode].insn_code != CODE_FOR_nothing
2891 && abs_optab->handlers[mode].insn_code != CODE_FOR_nothing)))
ae394659
RH
2892 {
2893 temp = expand_copysign_absneg (mode, op0, op1, target,
c064fde5 2894 fmt->signbit_ro, op0_is_abs);
ae394659
RH
2895 if (temp)
2896 return temp;
2897 }
2898
c064fde5
RS
2899 if (fmt->signbit_rw < 0)
2900 return NULL_RTX;
2901 return expand_copysign_bit (mode, op0, op1, target,
2902 fmt->signbit_rw, op0_is_abs);
ae394659 2903}
7fd01431 2904\f
77c9c6c2
RK
2905/* Generate an instruction whose insn-code is INSN_CODE,
2906 with two operands: an output TARGET and an input OP0.
2907 TARGET *must* be nonzero, and the output is always stored there.
2908 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2909 the value that is stored into TARGET. */
2910
2911void
0c20a65f 2912emit_unop_insn (int icode, rtx target, rtx op0, enum rtx_code code)
77c9c6c2 2913{
b3694847 2914 rtx temp;
a995e389 2915 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
77c9c6c2
RK
2916 rtx pat;
2917
ad76cef8 2918 temp = target;
77c9c6c2 2919
bd8c4b14
ILT
2920 /* Sign and zero extension from memory is often done specially on
2921 RISC machines, so forcing into a register here can pessimize
2922 code. */
2923 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
77c9c6c2
RK
2924 op0 = force_not_mem (op0);
2925
2926 /* Now, if insn does not accept our operands, put them into pseudos. */
2927
e3feb571 2928 if (!insn_data[icode].operand[1].predicate (op0, mode0))
77c9c6c2
RK
2929 op0 = copy_to_mode_reg (mode0, op0);
2930
e3feb571 2931 if (!insn_data[icode].operand[0].predicate (temp, GET_MODE (temp))
3c0cb5de 2932 || (flag_force_mem && MEM_P (temp)))
77c9c6c2
RK
2933 temp = gen_reg_rtx (GET_MODE (temp));
2934
2935 pat = GEN_FCN (icode) (temp, op0);
2936
2f937369 2937 if (INSN_P (pat) && NEXT_INSN (pat) != NULL_RTX && code != UNKNOWN)
b1ec3c92 2938 add_equal_note (pat, temp, code, op0, NULL_RTX);
0c20a65f 2939
77c9c6c2
RK
2940 emit_insn (pat);
2941
2942 if (temp != target)
2943 emit_move_insn (target, temp);
2944}
2945\f
2946/* Emit code to perform a series of operations on a multi-word quantity, one
2947 word at a time.
2948
d45cf215 2949 Such a block is preceded by a CLOBBER of the output, consists of multiple
77c9c6c2
RK
2950 insns, each setting one word of the output, and followed by a SET copying
2951 the output to itself.
2952
2953 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2954 note indicating that it doesn't conflict with the (also multi-word)
2955 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2956 notes.
2957
2958 INSNS is a block of code generated to perform the operation, not including
2959 the CLOBBER and final copy. All insns that compute intermediate values
0c20a65f 2960 are first emitted, followed by the block as described above.
77c9c6c2
RK
2961
2962 TARGET, OP0, and OP1 are the output and inputs of the operations,
2963 respectively. OP1 may be zero for a unary operation.
2964
40f03658 2965 EQUIV, if nonzero, is an expression to be placed into a REG_EQUAL note
77c9c6c2
RK
2966 on the last insn.
2967
2968 If TARGET is not a register, INSNS is simply emitted with no special
dce39da6
RK
2969 processing. Likewise if anything in INSNS is not an INSN or if
2970 there is a libcall block inside INSNS.
77c9c6c2
RK
2971
2972 The final insn emitted is returned. */
2973
2974rtx
0c20a65f 2975emit_no_conflict_block (rtx insns, rtx target, rtx op0, rtx op1, rtx equiv)
77c9c6c2
RK
2976{
2977 rtx prev, next, first, last, insn;
2978
f8cfc6aa 2979 if (!REG_P (target) || reload_in_progress)
2f937369 2980 return emit_insn (insns);
dce39da6
RK
2981 else
2982 for (insn = insns; insn; insn = NEXT_INSN (insn))
4b4bf941 2983 if (!NONJUMP_INSN_P (insn)
dce39da6 2984 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2f937369 2985 return emit_insn (insns);
77c9c6c2
RK
2986
2987 /* First emit all insns that do not store into words of the output and remove
2988 these from the list. */
2989 for (insn = insns; insn; insn = next)
2990 {
218aa620 2991 rtx set = 0, note;
77c9c6c2
RK
2992 int i;
2993
2994 next = NEXT_INSN (insn);
2995
dcc24678 2996 /* Some ports (cris) create a libcall regions at their own. We must
218aa620
JH
2997 avoid any potential nesting of LIBCALLs. */
2998 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
2999 remove_note (insn, note);
3000 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3001 remove_note (insn, note);
3002
c5c76735
JL
3003 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
3004 || GET_CODE (PATTERN (insn)) == CLOBBER)
77c9c6c2
RK
3005 set = PATTERN (insn);
3006 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
3007 {
3008 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
3009 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
3010 {
3011 set = XVECEXP (PATTERN (insn), 0, i);
3012 break;
3013 }
3014 }
3015
e3feb571 3016 gcc_assert (set);
77c9c6c2
RK
3017
3018 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
3019 {
3020 if (PREV_INSN (insn))
3021 NEXT_INSN (PREV_INSN (insn)) = next;
3022 else
3023 insns = next;
3024
3025 if (next)
3026 PREV_INSN (next) = PREV_INSN (insn);
3027
3028 add_insn (insn);
3029 }
3030 }
3031
3032 prev = get_last_insn ();
3033
3034 /* Now write the CLOBBER of the output, followed by the setting of each
3035 of the words, followed by the final copy. */
3036 if (target != op0 && target != op1)
9e6a5703 3037 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
77c9c6c2
RK
3038
3039 for (insn = insns; insn; insn = next)
3040 {
3041 next = NEXT_INSN (insn);
3042 add_insn (insn);
3043
f8cfc6aa 3044 if (op1 && REG_P (op1))
9e6a5703
JC
3045 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
3046 REG_NOTES (insn));
77c9c6c2 3047
f8cfc6aa 3048 if (op0 && REG_P (op0))
9e6a5703
JC
3049 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
3050 REG_NOTES (insn));
77c9c6c2
RK
3051 }
3052
54e7b5e6
RS
3053 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3054 != CODE_FOR_nothing)
3055 {
3056 last = emit_move_insn (target, target);
3057 if (equiv)
5fa671cf 3058 set_unique_reg_note (last, REG_EQUAL, equiv);
54e7b5e6
RS
3059 }
3060 else
07edd4c5
HPN
3061 {
3062 last = get_last_insn ();
3063
3064 /* Remove any existing REG_EQUAL note from "last", or else it will
3065 be mistaken for a note referring to the full contents of the
3066 alleged libcall value when found together with the REG_RETVAL
3067 note added below. An existing note can come from an insn
3068 expansion at "last". */
3069 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3070 }
77c9c6c2
RK
3071
3072 if (prev == 0)
3073 first = get_insns ();
3074 else
3075 first = NEXT_INSN (prev);
3076
3077 /* Encapsulate the block so it gets manipulated as a unit. */
9e6a5703
JC
3078 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3079 REG_NOTES (first));
3080 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
77c9c6c2
RK
3081
3082 return last;
3083}
3084\f
3085/* Emit code to make a call to a constant function or a library call.
3086
3087 INSNS is a list containing all insns emitted in the call.
3088 These insns leave the result in RESULT. Our block is to copy RESULT
3089 to TARGET, which is logically equivalent to EQUIV.
3090
3091 We first emit any insns that set a pseudo on the assumption that these are
3092 loading constants into registers; doing so allows them to be safely cse'ed
3093 between blocks. Then we emit all the other insns in the block, followed by
3094 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
3095 note with an operand of EQUIV.
3096
29ebe69a
RK
3097 Moving assignments to pseudos outside of the block is done to improve
3098 the generated code, but is not required to generate correct code,
3099 hence being unable to move an assignment is not grounds for not making
3100 a libcall block. There are two reasons why it is safe to leave these
3101 insns inside the block: First, we know that these pseudos cannot be
3102 used in generated RTL outside the block since they are created for
3103 temporary purposes within the block. Second, CSE will not record the
3104 values of anything set inside a libcall block, so we know they must
3105 be dead at the end of the block.
3106
77c9c6c2
RK
3107 Except for the first group of insns (the ones setting pseudos), the
3108 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
3109
3110void
0c20a65f 3111emit_libcall_block (rtx insns, rtx target, rtx result, rtx equiv)
77c9c6c2 3112{
aff2c2d3 3113 rtx final_dest = target;
77c9c6c2
RK
3114 rtx prev, next, first, last, insn;
3115
aff2c2d3
BS
3116 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
3117 into a MEM later. Protect the libcall block from this change. */
3118 if (! REG_P (target) || REG_USERVAR_P (target))
3119 target = gen_reg_rtx (GET_MODE (target));
0c20a65f 3120
5154e79a
AH
3121 /* If we're using non-call exceptions, a libcall corresponding to an
3122 operation that may trap may also trap. */
3123 if (flag_non_call_exceptions && may_trap_p (equiv))
3124 {
3125 for (insn = insns; insn; insn = NEXT_INSN (insn))
4b4bf941 3126 if (CALL_P (insn))
5154e79a
AH
3127 {
3128 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
0c20a65f 3129
5154e79a
AH
3130 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
3131 remove_note (insn, note);
3132 }
3133 }
3134 else
b472794d 3135 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
c29ea88a 3136 reg note to indicate that this call cannot throw or execute a nonlocal
cf67d231 3137 goto (unless there is already a REG_EH_REGION note, in which case
897aa57f 3138 we update it). */
5154e79a 3139 for (insn = insns; insn; insn = NEXT_INSN (insn))
4b4bf941 3140 if (CALL_P (insn))
5154e79a
AH
3141 {
3142 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
0c20a65f 3143
5154e79a 3144 if (note != 0)
60c81c89 3145 XEXP (note, 0) = constm1_rtx;
5154e79a 3146 else
60c81c89 3147 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, constm1_rtx,
5154e79a
AH
3148 REG_NOTES (insn));
3149 }
b472794d 3150
77c9c6c2 3151 /* First emit all insns that set pseudos. Remove them from the list as
ccf5f342 3152 we go. Avoid insns that set pseudos which were referenced in previous
29ebe69a 3153 insns. These can be generated by move_by_pieces, for example,
ccf5f342
RK
3154 to update an address. Similarly, avoid insns that reference things
3155 set in previous insns. */
77c9c6c2
RK
3156
3157 for (insn = insns; insn; insn = next)
3158 {
3159 rtx set = single_set (insn);
218aa620
JH
3160 rtx note;
3161
dcc24678 3162 /* Some ports (cris) create a libcall regions at their own. We must
218aa620
JH
3163 avoid any potential nesting of LIBCALLs. */
3164 if ((note = find_reg_note (insn, REG_LIBCALL, NULL)) != NULL)
3165 remove_note (insn, note);
3166 if ((note = find_reg_note (insn, REG_RETVAL, NULL)) != NULL)
3167 remove_note (insn, note);
77c9c6c2
RK
3168
3169 next = NEXT_INSN (insn);
3170
f8cfc6aa 3171 if (set != 0 && REG_P (SET_DEST (set))
29ebe69a 3172 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
8d9e73cc 3173 && (insn == insns
9485c46e
DM
3174 || ((! INSN_P(insns)
3175 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
ccf5f342
RK
3176 && ! reg_used_between_p (SET_DEST (set), insns, insn)
3177 && ! modified_in_p (SET_SRC (set), insns)
3178 && ! modified_between_p (SET_SRC (set), insns, insn))))
77c9c6c2
RK
3179 {
3180 if (PREV_INSN (insn))
3181 NEXT_INSN (PREV_INSN (insn)) = next;
3182 else
3183 insns = next;
3184
3185 if (next)
3186 PREV_INSN (next) = PREV_INSN (insn);
3187
3188 add_insn (insn);
3189 }
695a94b3
RS
3190
3191 /* Some ports use a loop to copy large arguments onto the stack.
3192 Don't move anything outside such a loop. */
4b4bf941 3193 if (LABEL_P (insn))
695a94b3 3194 break;
77c9c6c2
RK
3195 }
3196
3197 prev = get_last_insn ();
3198
3199 /* Write the remaining insns followed by the final copy. */
3200
3201 for (insn = insns; insn; insn = next)
3202 {
3203 next = NEXT_INSN (insn);
3204
3205 add_insn (insn);
3206 }
3207
3208 last = emit_move_insn (target, result);
02214a5c
RK
3209 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
3210 != CODE_FOR_nothing)
5fa671cf 3211 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
07edd4c5
HPN
3212 else
3213 {
3214 /* Remove any existing REG_EQUAL note from "last", or else it will
3215 be mistaken for a note referring to the full contents of the
3216 libcall value when found together with the REG_RETVAL note added
3217 below. An existing note can come from an insn expansion at
3218 "last". */
3219 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
3220 }
77c9c6c2 3221
e85427f9
BS
3222 if (final_dest != target)
3223 emit_move_insn (final_dest, target);
aff2c2d3 3224
77c9c6c2
RK
3225 if (prev == 0)
3226 first = get_insns ();
3227 else
3228 first = NEXT_INSN (prev);
3229
3230 /* Encapsulate the block so it gets manipulated as a unit. */
11e9ecc5
HB
3231 if (!flag_non_call_exceptions || !may_trap_p (equiv))
3232 {
4a69cf79
JZ
3233 /* We can't attach the REG_LIBCALL and REG_RETVAL notes
3234 when the encapsulated region would not be in one basic block,
3235 i.e. when there is a control_flow_insn_p insn between FIRST and LAST.
3236 */
3237 bool attach_libcall_retval_notes = true;
3238 next = NEXT_INSN (last);
3239 for (insn = first; insn != next; insn = NEXT_INSN (insn))
3240 if (control_flow_insn_p (insn))
3241 {
3242 attach_libcall_retval_notes = false;
3243 break;
3244 }
3245
3246 if (attach_libcall_retval_notes)
3247 {
3248 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
3249 REG_NOTES (first));
3250 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
3251 REG_NOTES (last));
3252 }
11e9ecc5 3253 }
77c9c6c2
RK
3254}
3255\f
1c0290ea 3256/* Nonzero if we can perform a comparison of mode MODE straightforwardly.
1eb8759b
RH
3257 PURPOSE describes how this comparison will be used. CODE is the rtx
3258 comparison code we will be using.
3259
3260 ??? Actually, CODE is slightly weaker than that. A target is still
0c20a65f 3261 required to implement all of the normal bcc operations, but not
1eb8759b 3262 required to implement all (or any) of the unordered bcc operations. */
0c20a65f 3263
1c0290ea 3264int
0c20a65f
AJ
3265can_compare_p (enum rtx_code code, enum machine_mode mode,
3266 enum can_compare_purpose purpose)
b30f05db
BS
3267{
3268 do
3269 {
7e1a450d 3270 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1eb8759b
RH
3271 {
3272 if (purpose == ccp_jump)
7e1a450d 3273 return bcc_gen_fctn[(int) code] != NULL;
1eb8759b 3274 else if (purpose == ccp_store_flag)
7e1a450d 3275 return setcc_gen_code[(int) code] != CODE_FOR_nothing;
1eb8759b
RH
3276 else
3277 /* There's only one cmov entry point, and it's allowed to fail. */
3278 return 1;
3279 }
1c0290ea 3280 if (purpose == ccp_jump
7e1a450d 3281 && cbranch_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1c0290ea
BS
3282 return 1;
3283 if (purpose == ccp_cmov
7e1a450d 3284 && cmov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1c0290ea
BS
3285 return 1;
3286 if (purpose == ccp_store_flag
7e1a450d 3287 && cstore_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1c0290ea 3288 return 1;
b30f05db 3289 mode = GET_MODE_WIDER_MODE (mode);
1c0290ea
BS
3290 }
3291 while (mode != VOIDmode);
b30f05db
BS
3292
3293 return 0;
3294}
3295
3296/* This function is called when we are going to emit a compare instruction that
3297 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3298
3299 *PMODE is the mode of the inputs (in case they are const_int).
3300 *PUNSIGNEDP nonzero says that the operands are unsigned;
77c9c6c2
RK
3301 this matters if they need to be widened.
3302
a06ef755 3303 If they have mode BLKmode, then SIZE specifies the size of both operands.
77c9c6c2 3304
b30f05db
BS
3305 This function performs all the setup necessary so that the caller only has
3306 to emit a single comparison insn. This setup can involve doing a BLKmode
3307 comparison or emitting a library call to perform the comparison if no insn
3308 is available to handle it.
3309 The values which are passed in through pointers can be modified; the caller
3310 should perform the comparison on the modified values. */
77c9c6c2 3311
a06ef755 3312static void
0c20a65f
AJ
3313prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size,
3314 enum machine_mode *pmode, int *punsignedp,
3315 enum can_compare_purpose purpose)
77c9c6c2 3316{
b30f05db
BS
3317 enum machine_mode mode = *pmode;
3318 rtx x = *px, y = *py;
3319 int unsignedp = *punsignedp;
77c9c6c2 3320 enum mode_class class;
77c9c6c2
RK
3321
3322 class = GET_MODE_CLASS (mode);
3323
3324 /* They could both be VOIDmode if both args are immediate constants,
3325 but we should fold that at an earlier stage.
8127d0e0 3326 With no special code here, this will call abort,
77c9c6c2
RK
3327 reminding the programmer to implement such folding. */
3328
3329 if (mode != BLKmode && flag_force_mem)
3330 {
894207cf
RS
3331 /* Load duplicate non-volatile operands once. */
3332 if (rtx_equal_p (x, y) && ! volatile_refs_p (x))
3333 {
3334 x = force_not_mem (x);
3335 y = x;
3336 }
3337 else
3338 {
3339 x = force_not_mem (x);
3340 y = force_not_mem (y);
3341 }
77c9c6c2
RK
3342 }
3343
7c27e184
PB
3344 /* If we are inside an appropriately-short loop and we are optimizing,
3345 force expensive constants into a register. */
3346 if (CONSTANT_P (x) && optimize
b437f1a7 3347 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
77c9c6c2
RK
3348 x = force_reg (mode, x);
3349
7c27e184 3350 if (CONSTANT_P (y) && optimize
b437f1a7 3351 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
77c9c6c2
RK
3352 y = force_reg (mode, y);
3353
362cc3d4 3354#ifdef HAVE_cc0
8127d0e0 3355 /* Abort if we have a non-canonical comparison. The RTL documentation
362cc3d4
MH
3356 states that canonical comparisons are required only for targets which
3357 have cc0. */
e3feb571 3358 gcc_assert (!CONSTANT_P (x) || CONSTANT_P (y));
362cc3d4
MH
3359#endif
3360
77c9c6c2
RK
3361 /* Don't let both operands fail to indicate the mode. */
3362 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3363 x = force_reg (mode, x);
3364
3365 /* Handle all BLKmode compares. */
3366
3367 if (mode == BLKmode)
3368 {
118355a0
ZW
3369 enum machine_mode cmp_mode, result_mode;
3370 enum insn_code cmp_code;
3371 tree length_type;
3372 rtx libfunc;
b30f05db 3373 rtx result;
118355a0 3374 rtx opalign
f4dc10d1 3375 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
b30f05db 3376
e3feb571 3377 gcc_assert (size);
118355a0 3378
118355a0
ZW
3379 /* Try to use a memory block compare insn - either cmpstr
3380 or cmpmem will do. */
3381 for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
3382 cmp_mode != VOIDmode;
3383 cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
358b8f01 3384 {
118355a0
ZW
3385 cmp_code = cmpmem_optab[cmp_mode];
3386 if (cmp_code == CODE_FOR_nothing)
3387 cmp_code = cmpstr_optab[cmp_mode];
3388 if (cmp_code == CODE_FOR_nothing)
3389 continue;
3390
3391 /* Must make sure the size fits the insn's mode. */
3392 if ((GET_CODE (size) == CONST_INT
3393 && INTVAL (size) >= (1 << GET_MODE_BITSIZE (cmp_mode)))
3394 || (GET_MODE_BITSIZE (GET_MODE (size))
3395 > GET_MODE_BITSIZE (cmp_mode)))
3396 continue;
3397
3398 result_mode = insn_data[cmp_code].operand[0].mode;
358b8f01 3399 result = gen_reg_rtx (result_mode);
118355a0
ZW
3400 size = convert_to_mode (cmp_mode, size, 1);
3401 emit_insn (GEN_FCN (cmp_code) (result, x, y, size, opalign));
3402
3403 *px = result;
3404 *py = const0_rtx;
3405 *pmode = result_mode;
3406 return;
77c9c6c2 3407 }
118355a0 3408
8f99553f 3409 /* Otherwise call a library function, memcmp. */
118355a0
ZW
3410 libfunc = memcmp_libfunc;
3411 length_type = sizetype;
118355a0
ZW
3412 result_mode = TYPE_MODE (integer_type_node);
3413 cmp_mode = TYPE_MODE (length_type);
3414 size = convert_to_mode (TYPE_MODE (length_type), size,
8df83eae 3415 TYPE_UNSIGNED (length_type));
118355a0
ZW
3416
3417 result = emit_library_call_value (libfunc, 0, LCT_PURE_MAKE_BLOCK,
3418 result_mode, 3,
3419 XEXP (x, 0), Pmode,
3420 XEXP (y, 0), Pmode,
3421 size, cmp_mode);
b30f05db
BS
3422 *px = result;
3423 *py = const0_rtx;
3424 *pmode = result_mode;
77c9c6c2
RK
3425 return;
3426 }
3427
27ab3e91
RH
3428 /* Don't allow operands to the compare to trap, as that can put the
3429 compare and branch in different basic blocks. */
3430 if (flag_non_call_exceptions)
3431 {
3432 if (may_trap_p (x))
3433 x = force_reg (mode, x);
3434 if (may_trap_p (y))
3435 y = force_reg (mode, y);
3436 }
3437
b30f05db
BS
3438 *px = x;
3439 *py = y;
1eb8759b 3440 if (can_compare_p (*pcomparison, mode, purpose))
b30f05db 3441 return;
77c9c6c2
RK
3442
3443 /* Handle a lib call just for the mode we are using. */
3444
b30f05db 3445 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
77c9c6c2
RK
3446 {
3447 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
9725066d
JL
3448 rtx result;
3449
77c9c6c2
RK
3450 /* If we want unsigned, and this mode has a distinct unsigned
3451 comparison routine, use that. */
3452 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3453 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3454
24491a09
KH
3455 result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
3456 word_mode, 2, x, mode, y, mode);
9725066d 3457
b30f05db 3458 *px = result;
b30f05db 3459 *pmode = word_mode;
b3f8d95d
MM
3460 if (TARGET_LIB_INT_CMP_BIASED)
3461 /* Integer comparison returns a result that must be compared
3462 against 1, so that even if we do an unsigned compare
3463 afterward, there is still a value that can represent the
3464 result "less than". */
3465 *py = const1_rtx;
3466 else
3467 {
3468 *py = const0_rtx;
3469 *punsignedp = 1;
3470 }
77c9c6c2
RK
3471 return;
3472 }
3473
e3feb571
NS
3474 gcc_assert (class == MODE_FLOAT);
3475 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
77c9c6c2
RK
3476}
3477
b30f05db
BS
3478/* Before emitting an insn with code ICODE, make sure that X, which is going
3479 to be used for operand OPNUM of the insn, is converted from mode MODE to
4fe9b91c 3480 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
b30f05db 3481 that it is accepted by the operand predicate. Return the new value. */
749a2da1 3482
6db0fb0e 3483static rtx
0c20a65f
AJ
3484prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
3485 enum machine_mode wider_mode, int unsignedp)
b30f05db 3486{
b30f05db
BS
3487 if (mode != wider_mode)
3488 x = convert_modes (wider_mode, mode, x, unsignedp);
3489
e3feb571 3490 if (!insn_data[icode].operand[opnum].predicate
a995e389 3491 (x, insn_data[icode].operand[opnum].mode))
d893ccde
RH
3492 {
3493 if (no_new_pseudos)
3494 return NULL_RTX;
3495 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3496 }
3497
b30f05db
BS
3498 return x;
3499}
3500
3501/* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3502 we can do the comparison.
3503 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3504 be NULL_RTX which indicates that only a comparison is to be generated. */
3505
3506static void
0c20a65f
AJ
3507emit_cmp_and_jump_insn_1 (rtx x, rtx y, enum machine_mode mode,
3508 enum rtx_code comparison, int unsignedp, rtx label)
b30f05db
BS
3509{
3510 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3511 enum mode_class class = GET_MODE_CLASS (mode);
3512 enum machine_mode wider_mode = mode;
3513
3514 /* Try combined insns first. */
8127d0e0 3515 do
b30f05db
BS
3516 {
3517 enum insn_code icode;
3518 PUT_MODE (test, wider_mode);
3519
1c0290ea 3520 if (label)
0c20a65f 3521 {
7e1a450d 3522 icode = cbranch_optab->handlers[(int) wider_mode].insn_code;
0c20a65f 3523
1c0290ea 3524 if (icode != CODE_FOR_nothing
e3feb571 3525 && insn_data[icode].operand[0].predicate (test, wider_mode))
1c0290ea
BS
3526 {
3527 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3528 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3529 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3530 return;
3531 }
3532 }
3533
b30f05db
BS
3534 /* Handle some compares against zero. */
3535 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3536 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3537 {
3538 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3539 emit_insn (GEN_FCN (icode) (x));
3540 if (label)
e3feb571 3541 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
b30f05db
BS
3542 return;
3543 }
3544
3545 /* Handle compares for which there is a directly suitable insn. */
3546
3547 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3548 if (icode != CODE_FOR_nothing)
3549 {
3550 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3551 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3552 emit_insn (GEN_FCN (icode) (x, y));
3553 if (label)
e3feb571 3554 emit_jump_insn (bcc_gen_fctn[(int) comparison] (label));
b30f05db
BS
3555 return;
3556 }
3557
8127d0e0
NS
3558 if (class != MODE_INT && class != MODE_FLOAT
3559 && class != MODE_COMPLEX_FLOAT)
3560 break;
b30f05db
BS
3561
3562 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
7e1a450d 3563 }
8127d0e0
NS
3564 while (wider_mode != VOIDmode);
3565
e3feb571 3566 gcc_unreachable ();
b30f05db
BS
3567}
3568
362cc3d4
MH
3569/* Generate code to compare X with Y so that the condition codes are
3570 set and to jump to LABEL if the condition is true. If X is a
3571 constant and Y is not a constant, then the comparison is swapped to
3572 ensure that the comparison RTL has the canonical form.
3573
c5d5d461
JL
3574 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3575 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3576 the proper branch condition code.
362cc3d4 3577
a06ef755 3578 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
362cc3d4 3579
c5d5d461
JL
3580 MODE is the mode of the inputs (in case they are const_int).
3581
3582 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3583 be passed unchanged to emit_cmp_insn, then potentially converted into an
3584 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
362cc3d4
MH
3585
3586void
0c20a65f
AJ
3587emit_cmp_and_jump_insns (rtx x, rtx y, enum rtx_code comparison, rtx size,
3588 enum machine_mode mode, int unsignedp, rtx label)
362cc3d4 3589{
8c9864f3
JH
3590 rtx op0 = x, op1 = y;
3591
3592 /* Swap operands and condition to ensure canonical RTL. */
3593 if (swap_commutative_operands_p (x, y))
362cc3d4 3594 {
8c9864f3
JH
3595 /* If we're not emitting a branch, this means some caller
3596 is out of sync. */
e3feb571 3597 gcc_assert (label);
8c9864f3
JH
3598
3599 op0 = y, op1 = x;
3600 comparison = swap_condition (comparison);
362cc3d4 3601 }
0ca40216
JL
3602
3603#ifdef HAVE_cc0
3604 /* If OP0 is still a constant, then both X and Y must be constants. Force
3605 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3606 RTL. */
3607 if (CONSTANT_P (op0))
3608 op0 = force_reg (mode, op0);
3609#endif
3610
c5d5d461
JL
3611 if (unsignedp)
3612 comparison = unsigned_condition (comparison);
a06ef755
RK
3613
3614 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
1c0290ea 3615 ccp_jump);
b30f05db
BS
3616 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3617}
3618
3619/* Like emit_cmp_and_jump_insns, but generate only the comparison. */
19caa751 3620
b30f05db 3621void
0c20a65f
AJ
3622emit_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
3623 enum machine_mode mode, int unsignedp)
b30f05db 3624{
a06ef755 3625 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
362cc3d4 3626}
77c9c6c2
RK
3627\f
3628/* Emit a library call comparison between floating point X and Y.
3629 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3630
c5c60e15 3631static void
0c20a65f
AJ
3632prepare_float_lib_cmp (rtx *px, rtx *py, enum rtx_code *pcomparison,
3633 enum machine_mode *pmode, int *punsignedp)
77c9c6c2 3634{
c5c60e15 3635 enum rtx_code comparison = *pcomparison;
c9034561 3636 enum rtx_code swapped = swap_condition (comparison);
b3f8d95d 3637 enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
ad76cef8
PB
3638 rtx x = *px;
3639 rtx y = *py;
c9034561
ZW
3640 enum machine_mode orig_mode = GET_MODE (x);
3641 enum machine_mode mode;
37bf20ee 3642 rtx value, target, insns, equiv;
0a300065 3643 rtx libfunc = 0;
b3f8d95d 3644 bool reversed_p = false;
77c9c6c2 3645
c9034561 3646 for (mode = orig_mode; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
77c9c6c2 3647 {
c9034561
ZW
3648 if ((libfunc = code_to_optab[comparison]->handlers[mode].libfunc))
3649 break;
77c9c6c2 3650
c9034561 3651 if ((libfunc = code_to_optab[swapped]->handlers[mode].libfunc))
77c9c6c2 3652 {
c9034561
ZW
3653 rtx tmp;
3654 tmp = x; x = y; y = tmp;
3655 comparison = swapped;
3656 break;
77c9c6c2 3657 }
77c9c6c2 3658
b3f8d95d
MM
3659 if ((libfunc = code_to_optab[reversed]->handlers[mode].libfunc)
3660 && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
3661 {
3662 comparison = reversed;
3663 reversed_p = true;
3664 break;
3665 }
3666 }
5906d013 3667
e3feb571 3668 gcc_assert (mode != VOIDmode);
0a300065 3669
c9034561
ZW
3670 if (mode != orig_mode)
3671 {
3672 x = convert_to_mode (mode, x, 0);
3673 y = convert_to_mode (mode, y, 0);
3674 }
3675
17796a89
RS
3676 /* Attach a REG_EQUAL note describing the semantics of the libcall to
3677 the RTL. The allows the RTL optimizers to delete the libcall if the
3678 condition can be determined at compile-time. */
3679 if (comparison == UNORDERED)
3680 {
3681 rtx temp = simplify_gen_relational (NE, word_mode, mode, x, x);
3682 equiv = simplify_gen_relational (NE, word_mode, mode, y, y);
3683 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3684 temp, const_true_rtx, equiv);
3685 }
3686 else
3687 {
3688 equiv = simplify_gen_relational (comparison, word_mode, mode, x, y);
3689 if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
bd831d5c 3690 {
17796a89 3691 rtx true_rtx, false_rtx;
37bf20ee 3692
17796a89
RS
3693 switch (comparison)
3694 {
3695 case EQ:
3696 true_rtx = const0_rtx;
3697 false_rtx = const_true_rtx;
3698 break;
3699
3700 case NE:
3701 true_rtx = const_true_rtx;
3702 false_rtx = const0_rtx;
3703 break;
3704
3705 case GT:
3706 true_rtx = const1_rtx;
3707 false_rtx = const0_rtx;
3708 break;
3709
3710 case GE:
3711 true_rtx = const0_rtx;
3712 false_rtx = constm1_rtx;
3713 break;
3714
3715 case LT:
3716 true_rtx = constm1_rtx;
3717 false_rtx = const0_rtx;
3718 break;
3719
3720 case LE:
3721 true_rtx = const0_rtx;
3722 false_rtx = const1_rtx;
3723 break;
3724
3725 default:
e3feb571 3726 gcc_unreachable ();
bd831d5c 3727 }
17796a89
RS
3728 equiv = simplify_gen_ternary (IF_THEN_ELSE, word_mode, word_mode,
3729 equiv, true_rtx, false_rtx);
bd831d5c
RS
3730 }
3731 }
37bf20ee
RS
3732
3733 start_sequence ();
3734 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
3735 word_mode, 2, x, mode, y, mode);
3736 insns = get_insns ();
3737 end_sequence ();
3738
3739 target = gen_reg_rtx (word_mode);
3740 emit_libcall_block (insns, target, value, equiv);
3741
c9034561
ZW
3742 if (comparison == UNORDERED
3743 || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
b3f8d95d 3744 comparison = reversed_p ? EQ : NE;
c9034561 3745
37bf20ee 3746 *px = target;
b30f05db
BS
3747 *py = const0_rtx;
3748 *pmode = word_mode;
c9034561 3749 *pcomparison = comparison;
b30f05db 3750 *punsignedp = 0;
77c9c6c2
RK
3751}
3752\f
3753/* Generate code to indirectly jump to a location given in the rtx LOC. */
3754
3755void
0c20a65f 3756emit_indirect_jump (rtx loc)
77c9c6c2 3757{
e3feb571
NS
3758 if (!insn_data[(int) CODE_FOR_indirect_jump].operand[0].predicate
3759 (loc, Pmode))
f2de2775 3760 loc = copy_to_mode_reg (Pmode, loc);
77c9c6c2
RK
3761
3762 emit_jump_insn (gen_indirect_jump (loc));
9649fb4d 3763 emit_barrier ();
77c9c6c2
RK
3764}
3765\f
49c4584c
DE
3766#ifdef HAVE_conditional_move
3767
3768/* Emit a conditional move instruction if the machine supports one for that
3769 condition and machine mode.
3770
3771 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3772 the mode to use should they be constants. If it is VOIDmode, they cannot
3773 both be constants.
3774
3775 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3776 should be stored there. MODE is the mode to use should they be constants.
3777 If it is VOIDmode, they cannot both be constants.
3778
3779 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3780 is not supported. */
3781
3782rtx
0c20a65f
AJ
3783emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
3784 enum machine_mode cmode, rtx op2, rtx op3,
3785 enum machine_mode mode, int unsignedp)
49c4584c
DE
3786{
3787 rtx tem, subtarget, comparison, insn;
3788 enum insn_code icode;
e5c56fd9 3789 enum rtx_code reversed;
49c4584c
DE
3790
3791 /* If one operand is constant, make it the second one. Only do this
3792 if the other operand is not constant as well. */
3793
e5c56fd9 3794 if (swap_commutative_operands_p (op0, op1))
49c4584c
DE
3795 {
3796 tem = op0;
3797 op0 = op1;
3798 op1 = tem;
3799 code = swap_condition (code);
3800 }
3801
c5c76735
JL
3802 /* get_condition will prefer to generate LT and GT even if the old
3803 comparison was against zero, so undo that canonicalization here since
3804 comparisons against zero are cheaper. */
87d9741e 3805 if (code == LT && op1 == const1_rtx)
c5c76735 3806 code = LE, op1 = const0_rtx;
87d9741e 3807 else if (code == GT && op1 == constm1_rtx)
c5c76735
JL
3808 code = GE, op1 = const0_rtx;
3809
49c4584c
DE
3810 if (cmode == VOIDmode)
3811 cmode = GET_MODE (op0);
3812
e5c56fd9
JH
3813 if (swap_commutative_operands_p (op2, op3)
3814 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
3815 != UNKNOWN))
49c4584c
DE
3816 {
3817 tem = op2;
3818 op2 = op3;
3819 op3 = tem;
e5c56fd9 3820 code = reversed;
49c4584c
DE
3821 }
3822
3823 if (mode == VOIDmode)
3824 mode = GET_MODE (op2);
3825
3826 icode = movcc_gen_code[mode];
3827
3828 if (icode == CODE_FOR_nothing)
3829 return 0;
3830
3831 if (flag_force_mem)
3832 {
3833 op2 = force_not_mem (op2);
3834 op3 = force_not_mem (op3);
3835 }
3836
ad76cef8 3837 if (!target)
49c4584c
DE
3838 target = gen_reg_rtx (mode);
3839
3840 subtarget = target;
3841
49c4584c
DE
3842 /* If the insn doesn't accept these operands, put them in pseudos. */
3843
e3feb571 3844 if (!insn_data[icode].operand[0].predicate
a995e389
RH
3845 (subtarget, insn_data[icode].operand[0].mode))
3846 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
49c4584c 3847
e3feb571 3848 if (!insn_data[icode].operand[2].predicate
a995e389
RH
3849 (op2, insn_data[icode].operand[2].mode))
3850 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
49c4584c 3851
e3feb571 3852 if (!insn_data[icode].operand[3].predicate
a995e389
RH
3853 (op3, insn_data[icode].operand[3].mode))
3854 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
49c4584c
DE
3855
3856 /* Everything should now be in the suitable form, so emit the compare insn
3857 and then the conditional move. */
3858
0c20a65f 3859 comparison
a06ef755 3860 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
49c4584c
DE
3861
3862 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
144a5f9d
JL
3863 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3864 return NULL and let the caller figure out how best to deal with this
3865 situation. */
49c4584c 3866 if (GET_CODE (comparison) != code)
144a5f9d 3867 return NULL_RTX;
0c20a65f 3868
49c4584c
DE
3869 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3870
3871 /* If that failed, then give up. */
3872 if (insn == 0)
3873 return 0;
3874
3875 emit_insn (insn);
3876
3877 if (subtarget != target)
3878 convert_move (target, subtarget, 0);
3879
3880 return target;
3881}
3882
40f03658 3883/* Return nonzero if a conditional move of mode MODE is supported.
49c4584c
DE
3884
3885 This function is for combine so it can tell whether an insn that looks
3886 like a conditional move is actually supported by the hardware. If we
3887 guess wrong we lose a bit on optimization, but that's it. */
3888/* ??? sparc64 supports conditionally moving integers values based on fp
3889 comparisons, and vice versa. How do we handle them? */
3890
3891int
0c20a65f 3892can_conditionally_move_p (enum machine_mode mode)
49c4584c
DE
3893{
3894 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3895 return 1;
3896
3897 return 0;
3898}
3899
3900#endif /* HAVE_conditional_move */
068f5dea
JH
3901
3902/* Emit a conditional addition instruction if the machine supports one for that
3903 condition and machine mode.
3904
3905 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3906 the mode to use should they be constants. If it is VOIDmode, they cannot
3907 both be constants.
3908
3909 OP2 should be stored in TARGET if the comparison is true, otherwise OP2+OP3
3910 should be stored there. MODE is the mode to use should they be constants.
3911 If it is VOIDmode, they cannot both be constants.
3912
3913 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3914 is not supported. */
3915
3916rtx
0c20a65f
AJ
3917emit_conditional_add (rtx target, enum rtx_code code, rtx op0, rtx op1,
3918 enum machine_mode cmode, rtx op2, rtx op3,
3919 enum machine_mode mode, int unsignedp)
068f5dea
JH
3920{
3921 rtx tem, subtarget, comparison, insn;
3922 enum insn_code icode;
3923 enum rtx_code reversed;
3924
3925 /* If one operand is constant, make it the second one. Only do this
3926 if the other operand is not constant as well. */
3927
3928 if (swap_commutative_operands_p (op0, op1))
3929 {
3930 tem = op0;
3931 op0 = op1;
3932 op1 = tem;
3933 code = swap_condition (code);
3934 }
3935
3936 /* get_condition will prefer to generate LT and GT even if the old
3937 comparison was against zero, so undo that canonicalization here since
3938 comparisons against zero are cheaper. */
87d9741e 3939 if (code == LT && op1 == const1_rtx)
068f5dea 3940 code = LE, op1 = const0_rtx;
87d9741e 3941 else if (code == GT && op1 == constm1_rtx)
068f5dea
JH
3942 code = GE, op1 = const0_rtx;
3943
3944 if (cmode == VOIDmode)
3945 cmode = GET_MODE (op0);
3946
3947 if (swap_commutative_operands_p (op2, op3)
3948 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
3949 != UNKNOWN))
3950 {
3951 tem = op2;
3952 op2 = op3;
3953 op3 = tem;
3954 code = reversed;
3955 }
3956
3957 if (mode == VOIDmode)
3958 mode = GET_MODE (op2);
3959
3960 icode = addcc_optab->handlers[(int) mode].insn_code;
3961
3962 if (icode == CODE_FOR_nothing)
3963 return 0;
3964
3965 if (flag_force_mem)
3966 {
3967 op2 = force_not_mem (op2);
3968 op3 = force_not_mem (op3);
3969 }
3970
ad76cef8 3971 if (!target)
068f5dea
JH
3972 target = gen_reg_rtx (mode);
3973
068f5dea
JH
3974 /* If the insn doesn't accept these operands, put them in pseudos. */
3975
e3feb571 3976 if (!insn_data[icode].operand[0].predicate
ad76cef8 3977 (target, insn_data[icode].operand[0].mode))
068f5dea 3978 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
ad76cef8
PB
3979 else
3980 subtarget = target;
068f5dea 3981
e3feb571 3982 if (!insn_data[icode].operand[2].predicate
068f5dea
JH
3983 (op2, insn_data[icode].operand[2].mode))
3984 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3985
e3feb571 3986 if (!insn_data[icode].operand[3].predicate
068f5dea
JH
3987 (op3, insn_data[icode].operand[3].mode))
3988 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3989
3990 /* Everything should now be in the suitable form, so emit the compare insn
3991 and then the conditional move. */
3992
0c20a65f 3993 comparison
068f5dea
JH
3994 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
3995
3996 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3997 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3998 return NULL and let the caller figure out how best to deal with this
3999 situation. */
4000 if (GET_CODE (comparison) != code)
4001 return NULL_RTX;
0c20a65f 4002
068f5dea
JH
4003 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
4004
4005 /* If that failed, then give up. */
4006 if (insn == 0)
4007 return 0;
4008
4009 emit_insn (insn);
4010
4011 if (subtarget != target)
4012 convert_move (target, subtarget, 0);
4013
4014 return target;
4015}
49c4584c 4016\f
0913e4b4
AO
4017/* These functions attempt to generate an insn body, rather than
4018 emitting the insn, but if the gen function already emits them, we
ad76cef8 4019 make no attempt to turn them back into naked patterns. */
77c9c6c2
RK
4020
4021/* Generate and return an insn body to add Y to X. */
4022
4023rtx
0c20a65f 4024gen_add2_insn (rtx x, rtx y)
77c9c6c2 4025{
0c20a65f 4026 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
77c9c6c2 4027
e3feb571
NS
4028 gcc_assert (insn_data[icode].operand[0].predicate
4029 (x, insn_data[icode].operand[0].mode));
4030 gcc_assert (insn_data[icode].operand[1].predicate
4031 (x, insn_data[icode].operand[1].mode));
4032 gcc_assert (insn_data[icode].operand[2].predicate
4033 (y, insn_data[icode].operand[2].mode));
77c9c6c2 4034
e3feb571 4035 return GEN_FCN (icode) (x, x, y);
77c9c6c2
RK
4036}
4037
e78d8e51
ZW
4038/* Generate and return an insn body to add r1 and c,
4039 storing the result in r0. */
4040rtx
0c20a65f 4041gen_add3_insn (rtx r0, rtx r1, rtx c)
e78d8e51
ZW
4042{
4043 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
4044
7e1a450d 4045 if (icode == CODE_FOR_nothing
e3feb571
NS
4046 || !(insn_data[icode].operand[0].predicate
4047 (r0, insn_data[icode].operand[0].mode))
4048 || !(insn_data[icode].operand[1].predicate
4049 (r1, insn_data[icode].operand[1].mode))
4050 || !(insn_data[icode].operand[2].predicate
4051 (c, insn_data[icode].operand[2].mode)))
e78d8e51
ZW
4052 return NULL_RTX;
4053
e3feb571 4054 return GEN_FCN (icode) (r0, r1, c);
e78d8e51
ZW
4055}
4056
77c9c6c2 4057int
0c20a65f 4058have_add2_insn (rtx x, rtx y)
77c9c6c2 4059{
fb7e77d7
TM
4060 int icode;
4061
e3feb571 4062 gcc_assert (GET_MODE (x) != VOIDmode);
fb7e77d7 4063
0c20a65f 4064 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
fb7e77d7
TM
4065
4066 if (icode == CODE_FOR_nothing)
4067 return 0;
4068
e3feb571
NS
4069 if (!(insn_data[icode].operand[0].predicate
4070 (x, insn_data[icode].operand[0].mode))
4071 || !(insn_data[icode].operand[1].predicate
4072 (x, insn_data[icode].operand[1].mode))
4073 || !(insn_data[icode].operand[2].predicate
4074 (y, insn_data[icode].operand[2].mode)))
fb7e77d7
TM
4075 return 0;
4076
4077 return 1;
77c9c6c2
RK
4078}
4079
4080/* Generate and return an insn body to subtract Y from X. */
4081
4082rtx
0c20a65f 4083gen_sub2_insn (rtx x, rtx y)
77c9c6c2 4084{
0c20a65f 4085 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
77c9c6c2 4086
e3feb571
NS
4087 gcc_assert (insn_data[icode].operand[0].predicate
4088 (x, insn_data[icode].operand[0].mode));
4089 gcc_assert (insn_data[icode].operand[1].predicate
4090 (x, insn_data[icode].operand[1].mode));
4091 gcc_assert (insn_data[icode].operand[2].predicate
4092 (y, insn_data[icode].operand[2].mode));
77c9c6c2 4093
e3feb571 4094 return GEN_FCN (icode) (x, x, y);
77c9c6c2
RK
4095}
4096
ef89d648
ZW
4097/* Generate and return an insn body to subtract r1 and c,
4098 storing the result in r0. */
4099rtx
0c20a65f 4100gen_sub3_insn (rtx r0, rtx r1, rtx c)
ef89d648
ZW
4101{
4102 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4103
7e1a450d 4104 if (icode == CODE_FOR_nothing
e3feb571
NS
4105 || !(insn_data[icode].operand[0].predicate
4106 (r0, insn_data[icode].operand[0].mode))
4107 || !(insn_data[icode].operand[1].predicate
4108 (r1, insn_data[icode].operand[1].mode))
4109 || !(insn_data[icode].operand[2].predicate
4110 (c, insn_data[icode].operand[2].mode)))
ef89d648
ZW
4111 return NULL_RTX;
4112
e3feb571 4113 return GEN_FCN (icode) (r0, r1, c);
ef89d648
ZW
4114}
4115
77c9c6c2 4116int
0c20a65f 4117have_sub2_insn (rtx x, rtx y)
77c9c6c2 4118{
fb7e77d7
TM
4119 int icode;
4120
e3feb571 4121 gcc_assert (GET_MODE (x) != VOIDmode);
fb7e77d7 4122
0c20a65f 4123 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
fb7e77d7
TM
4124
4125 if (icode == CODE_FOR_nothing)
4126 return 0;
4127
e3feb571
NS
4128 if (!(insn_data[icode].operand[0].predicate
4129 (x, insn_data[icode].operand[0].mode))
4130 || !(insn_data[icode].operand[1].predicate
4131 (x, insn_data[icode].operand[1].mode))
4132 || !(insn_data[icode].operand[2].predicate
4133 (y, insn_data[icode].operand[2].mode)))
fb7e77d7
TM
4134 return 0;
4135
4136 return 1;
77c9c6c2
RK
4137}
4138
e3654226 4139/* Generate the body of an instruction to copy Y into X.
2f937369 4140 It may be a list of insns, if one insn isn't enough. */
77c9c6c2
RK
4141
4142rtx
0c20a65f 4143gen_move_insn (rtx x, rtx y)
77c9c6c2 4144{
e3654226 4145 rtx seq;
77c9c6c2 4146
e3654226
RS
4147 start_sequence ();
4148 emit_move_insn_1 (x, y);
2f937369 4149 seq = get_insns ();
e3654226
RS
4150 end_sequence ();
4151 return seq;
77c9c6c2
RK
4152}
4153\f
34e56753
RS
4154/* Return the insn code used to extend FROM_MODE to TO_MODE.
4155 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4156 no such operation exists, CODE_FOR_nothing will be returned. */
77c9c6c2 4157
34e56753 4158enum insn_code
0c20a65f
AJ
4159can_extend_p (enum machine_mode to_mode, enum machine_mode from_mode,
4160 int unsignedp)
77c9c6c2 4161{
85363ca0 4162 convert_optab tab;
6dd12198
SE
4163#ifdef HAVE_ptr_extend
4164 if (unsignedp < 0)
4165 return CODE_FOR_ptr_extend;
6dd12198 4166#endif
85363ca0
ZW
4167
4168 tab = unsignedp ? zext_optab : sext_optab;
4169 return tab->handlers[to_mode][from_mode].insn_code;
77c9c6c2
RK
4170}
4171
4172/* Generate the body of an insn to extend Y (with mode MFROM)
4173 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4174
4175rtx
0c20a65f
AJ
4176gen_extend_insn (rtx x, rtx y, enum machine_mode mto,
4177 enum machine_mode mfrom, int unsignedp)
77c9c6c2 4178{
85363ca0
ZW
4179 enum insn_code icode = can_extend_p (mto, mfrom, unsignedp);
4180 return GEN_FCN (icode) (x, y);
77c9c6c2 4181}
77c9c6c2
RK
4182\f
4183/* can_fix_p and can_float_p say whether the target machine
4184 can directly convert a given fixed point type to
4185 a given floating point type, or vice versa.
4186 The returned value is the CODE_FOR_... value to use,
5d81dc5b 4187 or CODE_FOR_nothing if these modes cannot be directly converted.
77c9c6c2 4188
5d81dc5b 4189 *TRUNCP_PTR is set to 1 if it is necessary to output
77c9c6c2
RK
4190 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4191
4192static enum insn_code
0c20a65f
AJ
4193can_fix_p (enum machine_mode fixmode, enum machine_mode fltmode,
4194 int unsignedp, int *truncp_ptr)
77c9c6c2 4195{
85363ca0
ZW
4196 convert_optab tab;
4197 enum insn_code icode;
4198
4199 tab = unsignedp ? ufixtrunc_optab : sfixtrunc_optab;
4200 icode = tab->handlers[fixmode][fltmode].insn_code;
4201 if (icode != CODE_FOR_nothing)
4202 {
4203 *truncp_ptr = 0;
4204 return icode;
4205 }
77c9c6c2 4206
0e1d7f32
AH
4207 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
4208 for this to work. We need to rework the fix* and ftrunc* patterns
4209 and documentation. */
85363ca0
ZW
4210 tab = unsignedp ? ufix_optab : sfix_optab;
4211 icode = tab->handlers[fixmode][fltmode].insn_code;
4212 if (icode != CODE_FOR_nothing
4213 && ftrunc_optab->handlers[fltmode].insn_code != CODE_FOR_nothing)
77c9c6c2
RK
4214 {
4215 *truncp_ptr = 1;
85363ca0 4216 return icode;
77c9c6c2 4217 }
85363ca0
ZW
4218
4219 *truncp_ptr = 0;
77c9c6c2
RK
4220 return CODE_FOR_nothing;
4221}
4222
4223static enum insn_code
0c20a65f
AJ
4224can_float_p (enum machine_mode fltmode, enum machine_mode fixmode,
4225 int unsignedp)
77c9c6c2 4226{
85363ca0
ZW
4227 convert_optab tab;
4228
4229 tab = unsignedp ? ufloat_optab : sfloat_optab;
4230 return tab->handlers[fltmode][fixmode].insn_code;
77c9c6c2 4231}
77c9c6c2
RK
4232\f
4233/* Generate code to convert FROM to floating point
34e56753 4234 and store in TO. FROM must be fixed point and not VOIDmode.
77c9c6c2
RK
4235 UNSIGNEDP nonzero means regard FROM as unsigned.
4236 Normally this is done by correcting the final value
4237 if it is negative. */
4238
4239void
0c20a65f 4240expand_float (rtx to, rtx from, int unsignedp)
77c9c6c2
RK
4241{
4242 enum insn_code icode;
b3694847 4243 rtx target = to;
77c9c6c2
RK
4244 enum machine_mode fmode, imode;
4245
34e56753 4246 /* Crash now, because we won't be able to decide which mode to use. */
e3feb571 4247 gcc_assert (GET_MODE (from) != VOIDmode);
34e56753 4248
77c9c6c2
RK
4249 /* Look for an insn to do the conversion. Do it in the specified
4250 modes if possible; otherwise convert either input, output or both to
4251 wider mode. If the integer mode is wider than the mode of FROM,
4252 we can do the conversion signed even if the input is unsigned. */
4253
7bf0a593
AP
4254 for (fmode = GET_MODE (to); fmode != VOIDmode;
4255 fmode = GET_MODE_WIDER_MODE (fmode))
4256 for (imode = GET_MODE (from); imode != VOIDmode;
4257 imode = GET_MODE_WIDER_MODE (imode))
77c9c6c2
RK
4258 {
4259 int doing_unsigned = unsignedp;
4260
5ba02ca6
GK
4261 if (fmode != GET_MODE (to)
4262 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4263 continue;
4264
77c9c6c2
RK
4265 icode = can_float_p (fmode, imode, unsignedp);
4266 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4267 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4268
4269 if (icode != CODE_FOR_nothing)
4270 {
77c9c6c2
RK
4271 if (imode != GET_MODE (from))
4272 from = convert_to_mode (imode, from, unsignedp);
77c9c6c2
RK
4273
4274 if (fmode != GET_MODE (to))
4275 target = gen_reg_rtx (fmode);
4276
4277 emit_unop_insn (icode, target, from,
4278 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4279
4280 if (target != to)
4281 convert_move (to, target, 0);
4282 return;
4283 }
7e1a450d 4284 }
77c9c6c2 4285
77c9c6c2
RK
4286 /* Unsigned integer, and no way to convert directly.
4287 Convert as signed, then conditionally adjust the result. */
4288 if (unsignedp)
4289 {
4290 rtx label = gen_label_rtx ();
4291 rtx temp;
4292 REAL_VALUE_TYPE offset;
4293
77c9c6c2
RK
4294 if (flag_force_mem)
4295 from = force_not_mem (from);
4296
c95c47f3
PE
4297 /* Look for a usable floating mode FMODE wider than the source and at
4298 least as wide as the target. Using FMODE will avoid rounding woes
4299 with unsigned values greater than the signed maximum value. */
70864443 4300
c95c47f3
PE
4301 for (fmode = GET_MODE (to); fmode != VOIDmode;
4302 fmode = GET_MODE_WIDER_MODE (fmode))
4303 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4304 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4305 break;
a48fb61b 4306
c95c47f3
PE
4307 if (fmode == VOIDmode)
4308 {
a48fb61b 4309 /* There is no such mode. Pretend the target is wide enough. */
c95c47f3 4310 fmode = GET_MODE (to);
a48fb61b 4311
0f41302f 4312 /* Avoid double-rounding when TO is narrower than FROM. */
a48fb61b
RK
4313 if ((significand_size (fmode) + 1)
4314 < GET_MODE_BITSIZE (GET_MODE (from)))
4315 {
4316 rtx temp1;
4317 rtx neglabel = gen_label_rtx ();
4318
0c20a65f 4319 /* Don't use TARGET if it isn't a register, is a hard register,
70864443 4320 or is the wrong mode. */
f8cfc6aa 4321 if (!REG_P (target)
70864443
RK
4322 || REGNO (target) < FIRST_PSEUDO_REGISTER
4323 || GET_MODE (target) != fmode)
44f51d4a
RK
4324 target = gen_reg_rtx (fmode);
4325
a48fb61b
RK
4326 imode = GET_MODE (from);
4327 do_pending_stack_adjust ();
4328
4329 /* Test whether the sign bit is set. */
1c0290ea 4330 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
a06ef755 4331 0, neglabel);
a48fb61b
RK
4332
4333 /* The sign bit is not set. Convert as signed. */
4334 expand_float (target, from, 0);
4335 emit_jump_insn (gen_jump (label));
2ad79487 4336 emit_barrier ();
a48fb61b
RK
4337
4338 /* The sign bit is set.
4339 Convert to a usable (positive signed) value by shifting right
4340 one bit, while remembering if a nonzero bit was shifted
4341 out; i.e., compute (from & 1) | (from >> 1). */
4342
4343 emit_label (neglabel);
4344 temp = expand_binop (imode, and_optab, from, const1_rtx,
70864443 4345 NULL_RTX, 1, OPTAB_LIB_WIDEN);
73d9a835
RK
4346 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4347 NULL_RTX, 1);
0c20a65f 4348 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
70864443 4349 OPTAB_LIB_WIDEN);
a48fb61b
RK
4350 expand_float (target, temp, 0);
4351
4352 /* Multiply by 2 to undo the shift above. */
a93738eb 4353 temp = expand_binop (fmode, add_optab, target, target,
7e1a450d 4354 target, 0, OPTAB_LIB_WIDEN);
a93738eb
RK
4355 if (temp != target)
4356 emit_move_insn (target, temp);
4357
a48fb61b
RK
4358 do_pending_stack_adjust ();
4359 emit_label (label);
4360 goto done;
4361 }
c95c47f3
PE
4362 }
4363
77c9c6c2
RK
4364 /* If we are about to do some arithmetic to correct for an
4365 unsigned operand, do it in a pseudo-register. */
4366
c95c47f3 4367 if (GET_MODE (to) != fmode
f8cfc6aa 4368 || !REG_P (to) || REGNO (to) < FIRST_PSEUDO_REGISTER)
c95c47f3 4369 target = gen_reg_rtx (fmode);
77c9c6c2
RK
4370
4371 /* Convert as signed integer to floating. */
4372 expand_float (target, from, 0);
4373
4374 /* If FROM is negative (and therefore TO is negative),
4375 correct its value by 2**bitwidth. */
4376
4377 do_pending_stack_adjust ();
c5d5d461 4378 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
a06ef755 4379 0, label);
70864443 4380
0c20a65f 4381
efdc7e19 4382 real_2expN (&offset, GET_MODE_BITSIZE (GET_MODE (from)));
c95c47f3 4383 temp = expand_binop (fmode, add_optab, target,
30d88916 4384 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
77c9c6c2
RK
4385 target, 0, OPTAB_LIB_WIDEN);
4386 if (temp != target)
4387 emit_move_insn (target, temp);
a48fb61b 4388
77c9c6c2
RK
4389 do_pending_stack_adjust ();
4390 emit_label (label);
70864443 4391 goto done;
77c9c6c2 4392 }
77c9c6c2 4393
85363ca0 4394 /* No hardware instruction available; call a library routine. */
77c9c6c2 4395 {
85363ca0 4396 rtx libfunc;
77c9c6c2 4397 rtx insns;
9a7f678c 4398 rtx value;
85363ca0 4399 convert_optab tab = unsignedp ? ufloat_optab : sfloat_optab;
77c9c6c2 4400
77c9c6c2
RK
4401 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4402 from = convert_to_mode (SImode, from, unsignedp);
77c9c6c2
RK
4403
4404 if (flag_force_mem)
4405 from = force_not_mem (from);
4406
85363ca0 4407 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
e3feb571 4408 gcc_assert (libfunc);
77c9c6c2
RK
4409
4410 start_sequence ();
4411
85363ca0 4412 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
ebb1b59a
BS
4413 GET_MODE (to), 1, from,
4414 GET_MODE (from));
77c9c6c2
RK
4415 insns = get_insns ();
4416 end_sequence ();
4417
9a7f678c 4418 emit_libcall_block (insns, target, value,
9e6a5703 4419 gen_rtx_FLOAT (GET_MODE (to), from));
77c9c6c2
RK
4420 }
4421
a48fb61b
RK
4422 done:
4423
77c9c6c2
RK
4424 /* Copy result to requested destination
4425 if we have been computing in a temp location. */
4426
4427 if (target != to)
4428 {
4429 if (GET_MODE (target) == GET_MODE (to))
4430 emit_move_insn (to, target);
4431 else
4432 convert_move (to, target, 0);
4433 }
4434}
4435\f
0e1d7f32
AH
4436/* Generate code to convert FROM to fixed point and store in TO. FROM
4437 must be floating point. */
77c9c6c2
RK
4438
4439void
0c20a65f 4440expand_fix (rtx to, rtx from, int unsignedp)
77c9c6c2
RK
4441{
4442 enum insn_code icode;
b3694847 4443 rtx target = to;
77c9c6c2
RK
4444 enum machine_mode fmode, imode;
4445 int must_trunc = 0;
77c9c6c2
RK
4446
4447 /* We first try to find a pair of modes, one real and one integer, at
4448 least as wide as FROM and TO, respectively, in which we can open-code
4449 this conversion. If the integer mode is wider than the mode of TO,
4450 we can do the conversion either signed or unsigned. */
4451
3987b9db
JH
4452 for (fmode = GET_MODE (from); fmode != VOIDmode;
4453 fmode = GET_MODE_WIDER_MODE (fmode))
4454 for (imode = GET_MODE (to); imode != VOIDmode;
4455 imode = GET_MODE_WIDER_MODE (imode))
77c9c6c2
RK
4456 {
4457 int doing_unsigned = unsignedp;
4458
4459 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4460 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4461 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4462
4463 if (icode != CODE_FOR_nothing)
4464 {
77c9c6c2
RK
4465 if (fmode != GET_MODE (from))
4466 from = convert_to_mode (fmode, from, 0);
77c9c6c2
RK
4467
4468 if (must_trunc)
0e1d7f32
AH
4469 {
4470 rtx temp = gen_reg_rtx (GET_MODE (from));
4471 from = expand_unop (GET_MODE (from), ftrunc_optab, from,
4472 temp, 0);
4473 }
77c9c6c2
RK
4474
4475 if (imode != GET_MODE (to))
4476 target = gen_reg_rtx (imode);
4477
4478 emit_unop_insn (icode, target, from,
4479 doing_unsigned ? UNSIGNED_FIX : FIX);
4480 if (target != to)
4481 convert_move (to, target, unsignedp);
4482 return;
4483 }
4484 }
4485
77c9c6c2
RK
4486 /* For an unsigned conversion, there is one more way to do it.
4487 If we have a signed conversion, we generate code that compares
4488 the real value to the largest representable positive number. If if
4489 is smaller, the conversion is done normally. Otherwise, subtract
4490 one plus the highest signed number, convert, and add it back.
4491
4492 We only need to check all real modes, since we know we didn't find
0c20a65f 4493 anything with a wider integer mode.
0d446150
JH
4494
4495 This code used to extend FP value into mode wider than the destination.
4496 This is not needed. Consider, for instance conversion from SFmode
4497 into DImode.
4498
4499 The hot path trought the code is dealing with inputs smaller than 2^63
4500 and doing just the conversion, so there is no bits to lose.
4501
4502 In the other path we know the value is positive in the range 2^63..2^64-1
4503 inclusive. (as for other imput overflow happens and result is undefined)
e0bb17a8 4504 So we know that the most important bit set in mantissa corresponds to
0d446150
JH
4505 2^63. The subtraction of 2^63 should not generate any rounding as it
4506 simply clears out that bit. The rest is trivial. */
77c9c6c2 4507
b1ec3c92 4508 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
77c9c6c2
RK
4509 for (fmode = GET_MODE (from); fmode != VOIDmode;
4510 fmode = GET_MODE_WIDER_MODE (fmode))
0d446150
JH
4511 if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4512 &must_trunc))
77c9c6c2 4513 {
e9f7ae44
RS
4514 int bitsize;
4515 REAL_VALUE_TYPE offset;
4516 rtx limit, lab1, lab2, insn;
4517
4518 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
efdc7e19 4519 real_2expN (&offset, bitsize - 1);
30d88916 4520 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
e9f7ae44
RS
4521 lab1 = gen_label_rtx ();
4522 lab2 = gen_label_rtx ();
77c9c6c2 4523
77c9c6c2
RK
4524 if (flag_force_mem)
4525 from = force_not_mem (from);
4526
4527 if (fmode != GET_MODE (from))
4528 from = convert_to_mode (fmode, from, 0);
4529
4530 /* See if we need to do the subtraction. */
4531 do_pending_stack_adjust ();
c5d5d461 4532 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
a06ef755 4533 0, lab1);
77c9c6c2
RK
4534
4535 /* If not, do the signed "fix" and branch around fixup code. */
4536 expand_fix (to, from, 0);
4537 emit_jump_insn (gen_jump (lab2));
4538 emit_barrier ();
4539
4540 /* Otherwise, subtract 2**(N-1), convert to signed number,
4541 then add 2**(N-1). Do the addition using XOR since this
4542 will often generate better code. */
4543 emit_label (lab1);
4544 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
b1ec3c92 4545 NULL_RTX, 0, OPTAB_LIB_WIDEN);
77c9c6c2
RK
4546 expand_fix (to, target, 0);
4547 target = expand_binop (GET_MODE (to), xor_optab, to,
2496c7bd
LB
4548 gen_int_mode
4549 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4550 GET_MODE (to)),
77c9c6c2
RK
4551 to, 1, OPTAB_LIB_WIDEN);
4552
4553 if (target != to)
4554 emit_move_insn (to, target);
4555
4556 emit_label (lab2);
4557
02214a5c
RK
4558 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4559 != CODE_FOR_nothing)
4560 {
4561 /* Make a place for a REG_NOTE and add it. */
4562 insn = emit_move_insn (to, to);
5fa671cf
AM
4563 set_unique_reg_note (insn,
4564 REG_EQUAL,
4565 gen_rtx_fmt_e (UNSIGNED_FIX,
4566 GET_MODE (to),
4567 copy_rtx (from)));
02214a5c 4568 }
c5c76735 4569
77c9c6c2
RK
4570 return;
4571 }
77c9c6c2
RK
4572
4573 /* We can't do it with an insn, so use a library call. But first ensure
4574 that the mode of TO is at least as wide as SImode, since those are the
4575 only library calls we know about. */
4576
4577 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4578 {
4579 target = gen_reg_rtx (SImode);
4580
4581 expand_fix (target, from, unsignedp);
4582 }
77c9c6c2 4583 else
77c9c6c2
RK
4584 {
4585 rtx insns;
560f3f8a 4586 rtx value;
85363ca0 4587 rtx libfunc;
5906d013 4588
85363ca0
ZW
4589 convert_optab tab = unsignedp ? ufix_optab : sfix_optab;
4590 libfunc = tab->handlers[GET_MODE (to)][GET_MODE (from)].libfunc;
e3feb571 4591 gcc_assert (libfunc);
77c9c6c2 4592
77c9c6c2
RK
4593 if (flag_force_mem)
4594 from = force_not_mem (from);
4595
4596 start_sequence ();
4597
85363ca0 4598 value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
ebb1b59a
BS
4599 GET_MODE (to), 1, from,
4600 GET_MODE (from));
77c9c6c2
RK
4601 insns = get_insns ();
4602 end_sequence ();
4603
560f3f8a 4604 emit_libcall_block (insns, target, value,
9e6a5703
JC
4605 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4606 GET_MODE (to), from));
77c9c6c2 4607 }
0c20a65f 4608
3e53ea48
RK
4609 if (target != to)
4610 {
4611 if (GET_MODE (to) == GET_MODE (target))
4612 emit_move_insn (to, target);
4613 else
4614 convert_move (to, target, 0);
4615 }
77c9c6c2
RK
4616}
4617\f
ef89d648
ZW
4618/* Report whether we have an instruction to perform the operation
4619 specified by CODE on operands of mode MODE. */
4620int
0c20a65f 4621have_insn_for (enum rtx_code code, enum machine_mode mode)
ef89d648
ZW
4622{
4623 return (code_to_optab[(int) code] != 0
4624 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4625 != CODE_FOR_nothing));
4626}
4627
4628/* Create a blank optab. */
4629static optab
0c20a65f 4630new_optab (void)
77c9c6c2
RK
4631{
4632 int i;
703ad42b 4633 optab op = ggc_alloc (sizeof (struct optab));
77c9c6c2
RK
4634 for (i = 0; i < NUM_MACHINE_MODES; i++)
4635 {
4636 op->handlers[i].insn_code = CODE_FOR_nothing;
4637 op->handlers[i].libfunc = 0;
4638 }
377017c4 4639
ef89d648
ZW
4640 return op;
4641}
377017c4 4642
85363ca0
ZW
4643static convert_optab
4644new_convert_optab (void)
4645{
4646 int i, j;
4647 convert_optab op = ggc_alloc (sizeof (struct convert_optab));
4648 for (i = 0; i < NUM_MACHINE_MODES; i++)
4649 for (j = 0; j < NUM_MACHINE_MODES; j++)
4650 {
4651 op->handlers[i][j].insn_code = CODE_FOR_nothing;
4652 op->handlers[i][j].libfunc = 0;
4653 }
4654 return op;
4655}
4656
ef89d648
ZW
4657/* Same, but fill in its code as CODE, and write it into the
4658 code_to_optab table. */
4659static inline optab
0c20a65f 4660init_optab (enum rtx_code code)
ef89d648
ZW
4661{
4662 optab op = new_optab ();
4663 op->code = code;
4664 code_to_optab[(int) code] = op;
4665 return op;
4666}
4667
4668/* Same, but fill in its code as CODE, and do _not_ write it into
4669 the code_to_optab table. */
4670static inline optab
0c20a65f 4671init_optabv (enum rtx_code code)
ef89d648
ZW
4672{
4673 optab op = new_optab ();
4674 op->code = code;
77c9c6c2
RK
4675 return op;
4676}
4677
85363ca0
ZW
4678/* Conversion optabs never go in the code_to_optab table. */
4679static inline convert_optab
4680init_convert_optab (enum rtx_code code)
4681{
4682 convert_optab op = new_convert_optab ();
4683 op->code = code;
4684 return op;
4685}
4686
b092b471
JW
4687/* Initialize the libfunc fields of an entire group of entries in some
4688 optab. Each entry is set equal to a string consisting of a leading
4689 pair of underscores followed by a generic operation name followed by
7ef0daad 4690 a mode name (downshifted to lowercase) followed by a single character
b092b471
JW
4691 representing the number of operands for the given operation (which is
4692 usually one of the characters '2', '3', or '4').
4693
4694 OPTABLE is the table in which libfunc fields are to be initialized.
4695 FIRST_MODE is the first machine mode index in the given optab to
4696 initialize.
4697 LAST_MODE is the last machine mode index in the given optab to
4698 initialize.
4699 OPNAME is the generic (string) name of the operation.
4700 SUFFIX is the character which specifies the number of operands for
4701 the given generic operation.
4702*/
4703
4704static void
0c20a65f
AJ
4705init_libfuncs (optab optable, int first_mode, int last_mode,
4706 const char *opname, int suffix)
b092b471 4707{
b3694847
SS
4708 int mode;
4709 unsigned opname_len = strlen (opname);
b092b471 4710
fe0035ff
RS
4711 for (mode = first_mode; (int) mode <= (int) last_mode;
4712 mode = (enum machine_mode) ((int) mode + 1))
b092b471 4713 {
7e1a450d 4714 const char *mname = GET_MODE_NAME (mode);
b3694847
SS
4715 unsigned mname_len = strlen (mname);
4716 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4717 char *p;
4718 const char *q;
b092b471
JW
4719
4720 p = libfunc_name;
4721 *p++ = '_';
4722 *p++ = '_';
4723 for (q = opname; *q; )
4724 *p++ = *q++;
4725 for (q = mname; *q; q++)
92a438d1 4726 *p++ = TOLOWER (*q);
b092b471 4727 *p++ = suffix;
520a57c8 4728 *p = '\0';
76095e2f 4729
b092b471 4730 optable->handlers[(int) mode].libfunc
68d28100 4731 = init_one_libfunc (ggc_alloc_string (libfunc_name, p - libfunc_name));
b092b471
JW
4732 }
4733}
4734
4735/* Initialize the libfunc fields of an entire group of entries in some
4736 optab which correspond to all integer mode operations. The parameters
4737 have the same meaning as similarly named ones for the `init_libfuncs'
4738 routine. (See above). */
4739
4740static void
0c20a65f 4741init_integral_libfuncs (optab optable, const char *opname, int suffix)
b092b471 4742{
c0510d84
DD
4743 int maxsize = 2*BITS_PER_WORD;
4744 if (maxsize < LONG_LONG_TYPE_SIZE)
4745 maxsize = LONG_LONG_TYPE_SIZE;
8275b011 4746 init_libfuncs (optable, word_mode,
c0510d84 4747 mode_for_size (maxsize, MODE_INT, 0),
8275b011 4748 opname, suffix);
b092b471
JW
4749}
4750
4751/* Initialize the libfunc fields of an entire group of entries in some
4752 optab which correspond to all real mode operations. The parameters
4753 have the same meaning as similarly named ones for the `init_libfuncs'
4754 routine. (See above). */
4755
4756static void
0c20a65f 4757init_floating_libfuncs (optab optable, const char *opname, int suffix)
b092b471 4758{
d1d3865f 4759 init_libfuncs (optable, MIN_MODE_FLOAT, MAX_MODE_FLOAT, opname, suffix);
b092b471
JW
4760}
4761
85363ca0
ZW
4762/* Initialize the libfunc fields of an entire group of entries of an
4763 inter-mode-class conversion optab. The string formation rules are
4764 similar to the ones for init_libfuncs, above, but instead of having
4765 a mode name and an operand count these functions have two mode names
4766 and no operand count. */
4767static void
4768init_interclass_conv_libfuncs (convert_optab tab, const char *opname,
4769 enum mode_class from_class,
4770 enum mode_class to_class)
4771{
4772 enum machine_mode first_from_mode = GET_CLASS_NARROWEST_MODE (from_class);
4773 enum machine_mode first_to_mode = GET_CLASS_NARROWEST_MODE (to_class);
4774 size_t opname_len = strlen (opname);
4775 size_t max_mname_len = 0;
4776
4777 enum machine_mode fmode, tmode;
4778 const char *fname, *tname;
4779 const char *q;
4780 char *libfunc_name, *suffix;
4781 char *p;
4782
4783 for (fmode = first_from_mode;
4784 fmode != VOIDmode;
4785 fmode = GET_MODE_WIDER_MODE (fmode))
4786 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (fmode)));
4787
4788 for (tmode = first_to_mode;
4789 tmode != VOIDmode;
4790 tmode = GET_MODE_WIDER_MODE (tmode))
4791 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (tmode)));
4792
4793 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
4794 libfunc_name[0] = '_';
4795 libfunc_name[1] = '_';
4796 memcpy (&libfunc_name[2], opname, opname_len);
4797 suffix = libfunc_name + opname_len + 2;
4798
4799 for (fmode = first_from_mode; fmode != VOIDmode;
4800 fmode = GET_MODE_WIDER_MODE (fmode))
4801 for (tmode = first_to_mode; tmode != VOIDmode;
4802 tmode = GET_MODE_WIDER_MODE (tmode))
4803 {
4804 fname = GET_MODE_NAME (fmode);
4805 tname = GET_MODE_NAME (tmode);
4806
4807 p = suffix;
4808 for (q = fname; *q; p++, q++)
4809 *p = TOLOWER (*q);
4810 for (q = tname; *q; p++, q++)
4811 *p = TOLOWER (*q);
4812
4813 *p = '\0';
4814
4815 tab->handlers[tmode][fmode].libfunc
4816 = init_one_libfunc (ggc_alloc_string (libfunc_name,
4817 p - libfunc_name));
4818 }
4819}
4820
4821/* Initialize the libfunc fields of an entire group of entries of an
4822 intra-mode-class conversion optab. The string formation rules are
4823 similar to the ones for init_libfunc, above. WIDENING says whether
4824 the optab goes from narrow to wide modes or vice versa. These functions
4825 have two mode names _and_ an operand count. */
4826static void
4827init_intraclass_conv_libfuncs (convert_optab tab, const char *opname,
4828 enum mode_class class, bool widening)
4829{
4830 enum machine_mode first_mode = GET_CLASS_NARROWEST_MODE (class);
4831 size_t opname_len = strlen (opname);
4832 size_t max_mname_len = 0;
4833
4834 enum machine_mode nmode, wmode;
4835 const char *nname, *wname;
4836 const char *q;
4837 char *libfunc_name, *suffix;
4838 char *p;
4839
4840 for (nmode = first_mode; nmode != VOIDmode;
4841 nmode = GET_MODE_WIDER_MODE (nmode))
4842 max_mname_len = MAX (max_mname_len, strlen (GET_MODE_NAME (nmode)));
4843
4844 libfunc_name = alloca (2 + opname_len + 2*max_mname_len + 1 + 1);
4845 libfunc_name[0] = '_';
4846 libfunc_name[1] = '_';
4847 memcpy (&libfunc_name[2], opname, opname_len);
4848 suffix = libfunc_name + opname_len + 2;
4849
4850 for (nmode = first_mode; nmode != VOIDmode;
4851 nmode = GET_MODE_WIDER_MODE (nmode))
4852 for (wmode = GET_MODE_WIDER_MODE (nmode); wmode != VOIDmode;
4853 wmode = GET_MODE_WIDER_MODE (wmode))
4854 {
4855 nname = GET_MODE_NAME (nmode);
4856 wname = GET_MODE_NAME (wmode);
4857
4858 p = suffix;
4859 for (q = widening ? nname : wname; *q; p++, q++)
4860 *p = TOLOWER (*q);
4861 for (q = widening ? wname : nname; *q; p++, q++)
4862 *p = TOLOWER (*q);
4863
4864 *p++ = '2';
4865 *p = '\0';
4866
456bc4bb
RE
4867 tab->handlers[widening ? wmode : nmode]
4868 [widening ? nmode : wmode].libfunc
85363ca0
ZW
4869 = init_one_libfunc (ggc_alloc_string (libfunc_name,
4870 p - libfunc_name));
4871 }
4872}
4873
4874
76095e2f 4875rtx
0c20a65f 4876init_one_libfunc (const char *name)
76095e2f 4877{
52859c77
RH
4878 rtx symbol;
4879
fb49053f
RH
4880 /* Create a FUNCTION_DECL that can be passed to
4881 targetm.encode_section_info. */
ee1315aa 4882 /* ??? We don't have any type information except for this is
9c2f7166 4883 a function. Pretend this is "int foo()". */
ee1315aa 4884 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
9c2f7166 4885 build_function_type (integer_type_node, NULL_TREE));
ee1315aa
RH
4886 DECL_ARTIFICIAL (decl) = 1;
4887 DECL_EXTERNAL (decl) = 1;
4888 TREE_PUBLIC (decl) = 1;
4889
52859c77
RH
4890 symbol = XEXP (DECL_RTL (decl), 0);
4891
4892 /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
4893 are the flags assigned by targetm.encode_section_info. */
4894 SYMBOL_REF_DECL (symbol) = 0;
4895
4896 return symbol;
76095e2f
RH
4897}
4898
c15c90bb
ZW
4899/* Call this to reset the function entry for one optab (OPTABLE) in mode
4900 MODE to NAME, which should be either 0 or a string constant. */
4901void
4902set_optab_libfunc (optab optable, enum machine_mode mode, const char *name)
4903{
4904 if (name)
4905 optable->handlers[mode].libfunc = init_one_libfunc (name);
4906 else
4907 optable->handlers[mode].libfunc = 0;
4908}
4909
85363ca0
ZW
4910/* Call this to reset the function entry for one conversion optab
4911 (OPTABLE) from mode FMODE to mode TMODE to NAME, which should be
4912 either 0 or a string constant. */
4913void
4914set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
4915 enum machine_mode fmode, const char *name)
4916{
4917 if (name)
4918 optable->handlers[tmode][fmode].libfunc = init_one_libfunc (name);
4919 else
4920 optable->handlers[tmode][fmode].libfunc = 0;
4921}
4922
77c9c6c2
RK
4923/* Call this once to initialize the contents of the optabs
4924 appropriately for the current target machine. */
4925
4926void
0c20a65f 4927init_optabs (void)
77c9c6c2 4928{
85363ca0 4929 unsigned int i;
77c9c6c2 4930
5d81dc5b 4931 /* Start by initializing all tables to contain CODE_FOR_nothing. */
77c9c6c2 4932
5d81dc5b
RK
4933 for (i = 0; i < NUM_RTX_CODE; i++)
4934 setcc_gen_code[i] = CODE_FOR_nothing;
4935
49c4584c
DE
4936#ifdef HAVE_conditional_move
4937 for (i = 0; i < NUM_MACHINE_MODES; i++)
4938 movcc_gen_code[i] = CODE_FOR_nothing;
4939#endif
4940
7ce67fbe
DP
4941 for (i = 0; i < NUM_MACHINE_MODES; i++)
4942 {
4943 vcond_gen_code[i] = CODE_FOR_nothing;
4944 vcondu_gen_code[i] = CODE_FOR_nothing;
4945 }
4946
5d81dc5b 4947 add_optab = init_optab (PLUS);
ef89d648 4948 addv_optab = init_optabv (PLUS);
5d81dc5b 4949 sub_optab = init_optab (MINUS);
ef89d648 4950 subv_optab = init_optabv (MINUS);
5d81dc5b 4951 smul_optab = init_optab (MULT);
ef89d648 4952 smulv_optab = init_optabv (MULT);
5035bbfe
TG
4953 smul_highpart_optab = init_optab (UNKNOWN);
4954 umul_highpart_optab = init_optab (UNKNOWN);
5d81dc5b
RK
4955 smul_widen_optab = init_optab (UNKNOWN);
4956 umul_widen_optab = init_optab (UNKNOWN);
4957 sdiv_optab = init_optab (DIV);
ef89d648 4958 sdivv_optab = init_optabv (DIV);
5d81dc5b
RK
4959 sdivmod_optab = init_optab (UNKNOWN);
4960 udiv_optab = init_optab (UDIV);
4961 udivmod_optab = init_optab (UNKNOWN);
4962 smod_optab = init_optab (MOD);
4963 umod_optab = init_optab (UMOD);
5ae27cfa
UB
4964 fmod_optab = init_optab (UNKNOWN);
4965 drem_optab = init_optab (UNKNOWN);
77c9c6c2
RK
4966 ftrunc_optab = init_optab (UNKNOWN);
4967 and_optab = init_optab (AND);
4968 ior_optab = init_optab (IOR);
4969 xor_optab = init_optab (XOR);
4970 ashl_optab = init_optab (ASHIFT);
4971 ashr_optab = init_optab (ASHIFTRT);
77c9c6c2
RK
4972 lshr_optab = init_optab (LSHIFTRT);
4973 rotl_optab = init_optab (ROTATE);
4974 rotr_optab = init_optab (ROTATERT);
4975 smin_optab = init_optab (SMIN);
4976 smax_optab = init_optab (SMAX);
4977 umin_optab = init_optab (UMIN);
4978 umax_optab = init_optab (UMAX);
b5e01d4b
RS
4979 pow_optab = init_optab (UNKNOWN);
4980 atan2_optab = init_optab (UNKNOWN);
ef89d648
ZW
4981
4982 /* These three have codes assigned exclusively for the sake of
4983 have_insn_for. */
4984 mov_optab = init_optab (SET);
4985 movstrict_optab = init_optab (STRICT_LOW_PART);
4986 cmp_optab = init_optab (COMPARE);
4987
77c9c6c2
RK
4988 ucmp_optab = init_optab (UNKNOWN);
4989 tst_optab = init_optab (UNKNOWN);
c9034561
ZW
4990
4991 eq_optab = init_optab (EQ);
4992 ne_optab = init_optab (NE);
4993 gt_optab = init_optab (GT);
4994 ge_optab = init_optab (GE);
4995 lt_optab = init_optab (LT);
4996 le_optab = init_optab (LE);
4997 unord_optab = init_optab (UNORDERED);
4998
77c9c6c2 4999 neg_optab = init_optab (NEG);
ef89d648 5000 negv_optab = init_optabv (NEG);
77c9c6c2 5001 abs_optab = init_optab (ABS);
ef89d648 5002 absv_optab = init_optabv (ABS);
068f5dea 5003 addcc_optab = init_optab (UNKNOWN);
77c9c6c2
RK
5004 one_cmpl_optab = init_optab (NOT);
5005 ffs_optab = init_optab (FFS);
2928cd7a
RH
5006 clz_optab = init_optab (CLZ);
5007 ctz_optab = init_optab (CTZ);
5008 popcount_optab = init_optab (POPCOUNT);
5009 parity_optab = init_optab (PARITY);
d45cf215 5010 sqrt_optab = init_optab (SQRT);
4977bab6 5011 floor_optab = init_optab (UNKNOWN);
d8b42d06 5012 lfloor_optab = init_optab (UNKNOWN);
4977bab6 5013 ceil_optab = init_optab (UNKNOWN);
f94b1661 5014 lceil_optab = init_optab (UNKNOWN);
4977bab6 5015 round_optab = init_optab (UNKNOWN);
85363ca0 5016 btrunc_optab = init_optab (UNKNOWN);
4977bab6 5017 nearbyint_optab = init_optab (UNKNOWN);
edeacc14 5018 rint_optab = init_optab (UNKNOWN);
21e01bf1 5019 lrint_optab = init_optab (UNKNOWN);
6c7cf1f0 5020 sincos_optab = init_optab (UNKNOWN);
28cf078d 5021 sin_optab = init_optab (UNKNOWN);
c56122d8 5022 asin_optab = init_optab (UNKNOWN);
28cf078d 5023 cos_optab = init_optab (UNKNOWN);
c56122d8 5024 acos_optab = init_optab (UNKNOWN);
e7b489c8 5025 exp_optab = init_optab (UNKNOWN);
a251102e
UB
5026 exp10_optab = init_optab (UNKNOWN);
5027 exp2_optab = init_optab (UNKNOWN);
7a8e07c7 5028 expm1_optab = init_optab (UNKNOWN);
c94a75af 5029 ldexp_optab = init_optab (UNKNOWN);
88b28a31
UB
5030 logb_optab = init_optab (UNKNOWN);
5031 ilogb_optab = init_optab (UNKNOWN);
e7b489c8 5032 log_optab = init_optab (UNKNOWN);
3b8e0c91
UB
5033 log10_optab = init_optab (UNKNOWN);
5034 log2_optab = init_optab (UNKNOWN);
c2fcfa4f 5035 log1p_optab = init_optab (UNKNOWN);
82d397c7
RS
5036 tan_optab = init_optab (UNKNOWN);
5037 atan_optab = init_optab (UNKNOWN);
046625fa
RH
5038 copysign_optab = init_optab (UNKNOWN);
5039
19c3fc24 5040 strlen_optab = init_optab (UNKNOWN);
1c0290ea
BS
5041 cbranch_optab = init_optab (UNKNOWN);
5042 cmov_optab = init_optab (UNKNOWN);
5043 cstore_optab = init_optab (UNKNOWN);
371b8fc0 5044 push_optab = init_optab (UNKNOWN);
77c9c6c2 5045
997404de
JH
5046 vec_extract_optab = init_optab (UNKNOWN);
5047 vec_set_optab = init_optab (UNKNOWN);
5048 vec_init_optab = init_optab (UNKNOWN);
7ccf35ed 5049 vec_realign_load_optab = init_optab (UNKNOWN);
1e0598e2 5050 movmisalign_optab = init_optab (UNKNOWN);
7ccf35ed 5051
17684d46
RG
5052 powi_optab = init_optab (UNKNOWN);
5053
85363ca0
ZW
5054 /* Conversions. */
5055 sext_optab = init_convert_optab (SIGN_EXTEND);
5056 zext_optab = init_convert_optab (ZERO_EXTEND);
5057 trunc_optab = init_convert_optab (TRUNCATE);
5058 sfix_optab = init_convert_optab (FIX);
5059 ufix_optab = init_convert_optab (UNSIGNED_FIX);
5060 sfixtrunc_optab = init_convert_optab (UNKNOWN);
5061 ufixtrunc_optab = init_convert_optab (UNKNOWN);
5062 sfloat_optab = init_convert_optab (FLOAT);
5063 ufloat_optab = init_convert_optab (UNSIGNED_FLOAT);
5064
5d81dc5b
RK
5065 for (i = 0; i < NUM_MACHINE_MODES; i++)
5066 {
70128ad9
AO
5067 movmem_optab[i] = CODE_FOR_nothing;
5068 clrmem_optab[i] = CODE_FOR_nothing;
118355a0
ZW
5069 cmpstr_optab[i] = CODE_FOR_nothing;
5070 cmpmem_optab[i] = CODE_FOR_nothing;
5d81dc5b 5071
48ae6c13
RH
5072 sync_add_optab[i] = CODE_FOR_nothing;
5073 sync_sub_optab[i] = CODE_FOR_nothing;
5074 sync_ior_optab[i] = CODE_FOR_nothing;
5075 sync_and_optab[i] = CODE_FOR_nothing;
5076 sync_xor_optab[i] = CODE_FOR_nothing;
5077 sync_nand_optab[i] = CODE_FOR_nothing;
5078 sync_old_add_optab[i] = CODE_FOR_nothing;
5079 sync_old_sub_optab[i] = CODE_FOR_nothing;
5080 sync_old_ior_optab[i] = CODE_FOR_nothing;
5081 sync_old_and_optab[i] = CODE_FOR_nothing;
5082 sync_old_xor_optab[i] = CODE_FOR_nothing;
5083 sync_old_nand_optab[i] = CODE_FOR_nothing;
5084 sync_new_add_optab[i] = CODE_FOR_nothing;
5085 sync_new_sub_optab[i] = CODE_FOR_nothing;
5086 sync_new_ior_optab[i] = CODE_FOR_nothing;
5087 sync_new_and_optab[i] = CODE_FOR_nothing;
5088 sync_new_xor_optab[i] = CODE_FOR_nothing;
5089 sync_new_nand_optab[i] = CODE_FOR_nothing;
5090 sync_compare_and_swap[i] = CODE_FOR_nothing;
5091 sync_compare_and_swap_cc[i] = CODE_FOR_nothing;
5092 sync_lock_test_and_set[i] = CODE_FOR_nothing;
5093 sync_lock_release[i] = CODE_FOR_nothing;
5094
5d81dc5b
RK
5095#ifdef HAVE_SECONDARY_RELOADS
5096 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
77c9c6c2 5097#endif
5d81dc5b
RK
5098 }
5099
5100 /* Fill in the optabs with the insns we support. */
5101 init_all_optabs ();
5102
5d81dc5b 5103 /* Initialize the optabs with the names of the library functions. */
d55ab31d
MM
5104 init_integral_libfuncs (add_optab, "add", '3');
5105 init_floating_libfuncs (add_optab, "add", '3');
5106 init_integral_libfuncs (addv_optab, "addv", '3');
5107 init_floating_libfuncs (addv_optab, "add", '3');
5108 init_integral_libfuncs (sub_optab, "sub", '3');
5109 init_floating_libfuncs (sub_optab, "sub", '3');
5110 init_integral_libfuncs (subv_optab, "subv", '3');
5111 init_floating_libfuncs (subv_optab, "sub", '3');
5112 init_integral_libfuncs (smul_optab, "mul", '3');
5113 init_floating_libfuncs (smul_optab, "mul", '3');
5114 init_integral_libfuncs (smulv_optab, "mulv", '3');
5115 init_floating_libfuncs (smulv_optab, "mul", '3');
5116 init_integral_libfuncs (sdiv_optab, "div", '3');
5117 init_floating_libfuncs (sdiv_optab, "div", '3');
5118 init_integral_libfuncs (sdivv_optab, "divv", '3');
5119 init_integral_libfuncs (udiv_optab, "udiv", '3');
5120 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
5121 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
5122 init_integral_libfuncs (smod_optab, "mod", '3');
5123 init_integral_libfuncs (umod_optab, "umod", '3');
5124 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
5125 init_integral_libfuncs (and_optab, "and", '3');
5126 init_integral_libfuncs (ior_optab, "ior", '3');
5127 init_integral_libfuncs (xor_optab, "xor", '3');
5128 init_integral_libfuncs (ashl_optab, "ashl", '3');
5129 init_integral_libfuncs (ashr_optab, "ashr", '3');
5130 init_integral_libfuncs (lshr_optab, "lshr", '3');
5131 init_integral_libfuncs (smin_optab, "min", '3');
5132 init_floating_libfuncs (smin_optab, "min", '3');
5133 init_integral_libfuncs (smax_optab, "max", '3');
5134 init_floating_libfuncs (smax_optab, "max", '3');
5135 init_integral_libfuncs (umin_optab, "umin", '3');
5136 init_integral_libfuncs (umax_optab, "umax", '3');
5137 init_integral_libfuncs (neg_optab, "neg", '2');
5138 init_floating_libfuncs (neg_optab, "neg", '2');
5139 init_integral_libfuncs (negv_optab, "negv", '2');
5140 init_floating_libfuncs (negv_optab, "neg", '2');
5141 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
5142 init_integral_libfuncs (ffs_optab, "ffs", '2');
5143 init_integral_libfuncs (clz_optab, "clz", '2');
5144 init_integral_libfuncs (ctz_optab, "ctz", '2');
5145 init_integral_libfuncs (popcount_optab, "popcount", '2');
5146 init_integral_libfuncs (parity_optab, "parity", '2');
5147
5148 /* Comparison libcalls for integers MUST come in pairs,
5149 signed/unsigned. */
5150 init_integral_libfuncs (cmp_optab, "cmp", '2');
5151 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
5152 init_floating_libfuncs (cmp_optab, "cmp", '2');
5153
5154 /* EQ etc are floating point only. */
5155 init_floating_libfuncs (eq_optab, "eq", '2');
5156 init_floating_libfuncs (ne_optab, "ne", '2');
5157 init_floating_libfuncs (gt_optab, "gt", '2');
5158 init_floating_libfuncs (ge_optab, "ge", '2');
5159 init_floating_libfuncs (lt_optab, "lt", '2');
5160 init_floating_libfuncs (le_optab, "le", '2');
5161 init_floating_libfuncs (unord_optab, "unord", '2');
5162
17684d46
RG
5163 init_floating_libfuncs (powi_optab, "powi", '2');
5164
d55ab31d 5165 /* Conversions. */
5906d013 5166 init_interclass_conv_libfuncs (sfloat_optab, "float",
d55ab31d 5167 MODE_INT, MODE_FLOAT);
5906d013 5168 init_interclass_conv_libfuncs (sfix_optab, "fix",
d55ab31d 5169 MODE_FLOAT, MODE_INT);
5906d013 5170 init_interclass_conv_libfuncs (ufix_optab, "fixuns",
d55ab31d
MM
5171 MODE_FLOAT, MODE_INT);
5172
5173 /* sext_optab is also used for FLOAT_EXTEND. */
5174 init_intraclass_conv_libfuncs (sext_optab, "extend", MODE_FLOAT, true);
5175 init_intraclass_conv_libfuncs (trunc_optab, "trunc", MODE_FLOAT, false);
76095e2f 5176
85363ca0
ZW
5177 /* Use cabs for double complex abs, since systems generally have cabs.
5178 Don't define any libcall for float complex, so that cabs will be used. */
5179 if (complex_double_type_node)
5180 abs_optab->handlers[TYPE_MODE (complex_double_type_node)].libfunc
5181 = init_one_libfunc ("cabs");
76095e2f 5182
d91edf86 5183 /* The ffs function operates on `int'. */
85363ca0
ZW
5184 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5185 = init_one_libfunc ("ffs");
76095e2f 5186
9602f5a0 5187 abort_libfunc = init_one_libfunc ("abort");
76095e2f 5188 memcpy_libfunc = init_one_libfunc ("memcpy");
b215b52e 5189 memmove_libfunc = init_one_libfunc ("memmove");
76095e2f 5190 memcmp_libfunc = init_one_libfunc ("memcmp");
76095e2f 5191 memset_libfunc = init_one_libfunc ("memset");
68d28100 5192 setbits_libfunc = init_one_libfunc ("__setbits");
76095e2f 5193
52a11cbf
RH
5194 unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5195 ? "_Unwind_SjLj_Resume"
5196 : "_Unwind_Resume");
6e6a07d2 5197#ifndef DONT_USE_BUILTIN_SETJMP
76095e2f
RH
5198 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5199 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
27a36778 5200#else
76095e2f
RH
5201 setjmp_libfunc = init_one_libfunc ("setjmp");
5202 longjmp_libfunc = init_one_libfunc ("longjmp");
27a36778 5203#endif
52a11cbf
RH
5204 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5205 unwind_sjlj_unregister_libfunc
5206 = init_one_libfunc ("_Unwind_SjLj_Unregister");
6adb4e3a 5207
07417085
KR
5208 /* For function entry/exit instrumentation. */
5209 profile_function_entry_libfunc
76095e2f 5210 = init_one_libfunc ("__cyg_profile_func_enter");
07417085 5211 profile_function_exit_libfunc
76095e2f 5212 = init_one_libfunc ("__cyg_profile_func_exit");
07417085 5213
68d28100 5214 gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
68d28100 5215
842a431a
DM
5216 if (HAVE_conditional_trap)
5217 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
e0cd0770 5218
159c2aed 5219 /* Allow the target to add more libcalls or rename some, etc. */
c15c90bb 5220 targetm.init_libfuncs ();
77c9c6c2 5221}
b3f8d95d
MM
5222
5223#ifdef DEBUG
5224
5225/* Print information about the current contents of the optabs on
5226 STDERR. */
5227
5228static void
5229debug_optab_libfuncs (void)
5230{
5231 int i;
5232 int j;
5233 int k;
5234
5235 /* Dump the arithmetic optabs. */
5906d013 5236 for (i = 0; i != (int) OTI_MAX; i++)
b3f8d95d
MM
5237 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5238 {
5239 optab o;
5240 struct optab_handlers *h;
5241
5242 o = optab_table[i];
5243 h = &o->handlers[j];
5244 if (h->libfunc)
5245 {
e3feb571 5246 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5906d013 5247 fprintf (stderr, "%s\t%s:\t%s\n",
b3f8d95d
MM
5248 GET_RTX_NAME (o->code),
5249 GET_MODE_NAME (j),
5250 XSTR (h->libfunc, 0));
5251 }
5252 }
5253
5254 /* Dump the conversion optabs. */
5255 for (i = 0; i < (int) CTI_MAX; ++i)
5256 for (j = 0; j < NUM_MACHINE_MODES; ++j)
5257 for (k = 0; k < NUM_MACHINE_MODES; ++k)
5258 {
5259 convert_optab o;
5260 struct optab_handlers *h;
5261
5262 o = &convert_optab_table[i];
5263 h = &o->handlers[j][k];
5264 if (h->libfunc)
5265 {
e3feb571 5266 gcc_assert (GET_CODE (h->libfunc) = SYMBOL_REF);
5906d013 5267 fprintf (stderr, "%s\t%s\t%s:\t%s\n",
b3f8d95d
MM
5268 GET_RTX_NAME (o->code),
5269 GET_MODE_NAME (j),
5270 GET_MODE_NAME (k),
5271 XSTR (h->libfunc, 0));
5272 }
5273 }
5274}
5275
5276#endif /* DEBUG */
5277
7e1966ca 5278\f
e0cd0770
JC
5279/* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5280 CODE. Return 0 on failure. */
5281
5282rtx
0c20a65f
AJ
5283gen_cond_trap (enum rtx_code code ATTRIBUTE_UNUSED, rtx op1,
5284 rtx op2 ATTRIBUTE_UNUSED, rtx tcode ATTRIBUTE_UNUSED)
e0cd0770
JC
5285{
5286 enum machine_mode mode = GET_MODE (op1);
842a431a
DM
5287 enum insn_code icode;
5288 rtx insn;
5289
5290 if (!HAVE_conditional_trap)
5291 return 0;
e0cd0770
JC
5292
5293 if (mode == VOIDmode)
5294 return 0;
5295
842a431a
DM
5296 icode = cmp_optab->handlers[(int) mode].insn_code;
5297 if (icode == CODE_FOR_nothing)
5298 return 0;
5299
5300 start_sequence ();
5301 op1 = prepare_operand (icode, op1, 0, mode, mode, 0);
0310c414 5302 op2 = prepare_operand (icode, op2, 1, mode, mode, 0);
d893ccde
RH
5303 if (!op1 || !op2)
5304 {
5305 end_sequence ();
5306 return 0;
5307 }
842a431a
DM
5308 emit_insn (GEN_FCN (icode) (op1, op2));
5309
5310 PUT_CODE (trap_rtx, code);
e3feb571 5311 gcc_assert (HAVE_conditional_trap);
842a431a
DM
5312 insn = gen_conditional_trap (trap_rtx, tcode);
5313 if (insn)
e0cd0770 5314 {
842a431a
DM
5315 emit_insn (insn);
5316 insn = get_insns ();
e0cd0770 5317 }
842a431a 5318 end_sequence ();
e0cd0770 5319
842a431a 5320 return insn;
e0cd0770 5321}
e2500fed 5322
7ce67fbe
DP
5323/* Return rtx code for TCODE. Use UNSIGNEDP to select signed
5324 or unsigned operation code. */
5325
5326static enum rtx_code
5327get_rtx_code (enum tree_code tcode, bool unsignedp)
5328{
5329 enum rtx_code code;
5330 switch (tcode)
5331 {
5332 case EQ_EXPR:
5333 code = EQ;
5334 break;
5335 case NE_EXPR:
5336 code = NE;
5337 break;
5338 case LT_EXPR:
5339 code = unsignedp ? LTU : LT;
5340 break;
5341 case LE_EXPR:
5342 code = unsignedp ? LEU : LE;
5343 break;
5344 case GT_EXPR:
5345 code = unsignedp ? GTU : GT;
5346 break;
5347 case GE_EXPR:
5348 code = unsignedp ? GEU : GE;
5349 break;
5350
5351 case UNORDERED_EXPR:
5352 code = UNORDERED;
5353 break;
5354 case ORDERED_EXPR:
5355 code = ORDERED;
5356 break;
5357 case UNLT_EXPR:
5358 code = UNLT;
5359 break;
5360 case UNLE_EXPR:
5361 code = UNLE;
5362 break;
5363 case UNGT_EXPR:
5364 code = UNGT;
5365 break;
5366 case UNGE_EXPR:
5367 code = UNGE;
5368 break;
5369 case UNEQ_EXPR:
5370 code = UNEQ;
5371 break;
5372 case LTGT_EXPR:
5373 code = LTGT;
5374 break;
5375
5376 default:
e3feb571 5377 gcc_unreachable ();
7ce67fbe
DP
5378 }
5379 return code;
5380}
5381
5382/* Return comparison rtx for COND. Use UNSIGNEDP to select signed or
5383 unsigned operators. Do not generate compare instruction. */
5384
5385static rtx
5386vector_compare_rtx (tree cond, bool unsignedp, enum insn_code icode)
5387{
5388 enum rtx_code rcode;
5389 tree t_op0, t_op1;
5390 rtx rtx_op0, rtx_op1;
5391
e3feb571
NS
5392 /* This is unlikely. While generating VEC_COND_EXPR, auto vectorizer
5393 ensures that condition is a relational operation. */
5394 gcc_assert (COMPARISON_CLASS_P (cond));
7ce67fbe 5395
e3feb571
NS
5396 rcode = get_rtx_code (TREE_CODE (cond), unsignedp);
5397 t_op0 = TREE_OPERAND (cond, 0);
5398 t_op1 = TREE_OPERAND (cond, 1);
5399
7ce67fbe
DP
5400 /* Expand operands. */
5401 rtx_op0 = expand_expr (t_op0, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op0)), 1);
5402 rtx_op1 = expand_expr (t_op1, NULL_RTX, TYPE_MODE (TREE_TYPE (t_op1)), 1);
5403
e3feb571 5404 if (!insn_data[icode].operand[4].predicate (rtx_op0, GET_MODE (rtx_op0))
7ce67fbe
DP
5405 && GET_MODE (rtx_op0) != VOIDmode)
5406 rtx_op0 = force_reg (GET_MODE (rtx_op0), rtx_op0);
5407
e3feb571 5408 if (!insn_data[icode].operand[5].predicate (rtx_op1, GET_MODE (rtx_op1))
7ce67fbe
DP
5409 && GET_MODE (rtx_op1) != VOIDmode)
5410 rtx_op1 = force_reg (GET_MODE (rtx_op1), rtx_op1);
5411
5412 return gen_rtx_fmt_ee (rcode, VOIDmode, rtx_op0, rtx_op1);
5413}
5414
5415/* Return insn code for VEC_COND_EXPR EXPR. */
5416
5417static inline enum insn_code
5418get_vcond_icode (tree expr, enum machine_mode mode)
5419{
5420 enum insn_code icode = CODE_FOR_nothing;
5421
5422 if (TYPE_UNSIGNED (TREE_TYPE (expr)))
5423 icode = vcondu_gen_code[mode];
5424 else
5425 icode = vcond_gen_code[mode];
5426 return icode;
5427}
5428
5429/* Return TRUE iff, appropriate vector insns are available
5430 for vector cond expr expr in VMODE mode. */
5431
5432bool
5433expand_vec_cond_expr_p (tree expr, enum machine_mode vmode)
5434{
5435 if (get_vcond_icode (expr, vmode) == CODE_FOR_nothing)
5436 return false;
5437 return true;
5438}
5439
5440/* Generate insns for VEC_COND_EXPR. */
5441
5442rtx
5443expand_vec_cond_expr (tree vec_cond_expr, rtx target)
5444{
5445 enum insn_code icode;
5446 rtx comparison, rtx_op1, rtx_op2, cc_op0, cc_op1;
5447 enum machine_mode mode = TYPE_MODE (TREE_TYPE (vec_cond_expr));
5448 bool unsignedp = TYPE_UNSIGNED (TREE_TYPE (vec_cond_expr));
5449
5450 icode = get_vcond_icode (vec_cond_expr, mode);
5451 if (icode == CODE_FOR_nothing)
5452 return 0;
5453
5454 if (!target)
5455 target = gen_reg_rtx (mode);
5456
6dbd43ba 5457 /* Get comparison rtx. First expand both cond expr operands. */
7ce67fbe
DP
5458 comparison = vector_compare_rtx (TREE_OPERAND (vec_cond_expr, 0),
5459 unsignedp, icode);
5460 cc_op0 = XEXP (comparison, 0);
5461 cc_op1 = XEXP (comparison, 1);
5462 /* Expand both operands and force them in reg, if required. */
5463 rtx_op1 = expand_expr (TREE_OPERAND (vec_cond_expr, 1),
5464 NULL_RTX, VOIDmode, 1);
e3feb571 5465 if (!insn_data[icode].operand[1].predicate (rtx_op1, mode)
7ce67fbe
DP
5466 && mode != VOIDmode)
5467 rtx_op1 = force_reg (mode, rtx_op1);
5468
5469 rtx_op2 = expand_expr (TREE_OPERAND (vec_cond_expr, 2),
5470 NULL_RTX, VOIDmode, 1);
e3feb571 5471 if (!insn_data[icode].operand[2].predicate (rtx_op2, mode)
7ce67fbe
DP
5472 && mode != VOIDmode)
5473 rtx_op2 = force_reg (mode, rtx_op2);
5474
5475 /* Emit instruction! */
5476 emit_insn (GEN_FCN (icode) (target, rtx_op1, rtx_op2,
5477 comparison, cc_op0, cc_op1));
5478
5479 return target;
5480}
48ae6c13
RH
5481
5482\f
5483/* This is an internal subroutine of the other compare_and_swap expanders.
5484 MEM, OLD_VAL and NEW_VAL are as you'd expect for a compare-and-swap
5485 operation. TARGET is an optional place to store the value result of
5486 the operation. ICODE is the particular instruction to expand. Return
5487 the result of the operation. */
5488
5489static rtx
5490expand_val_compare_and_swap_1 (rtx mem, rtx old_val, rtx new_val,
5491 rtx target, enum insn_code icode)
5492{
5493 enum machine_mode mode = GET_MODE (mem);
5494 rtx insn;
5495
5496 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5497 target = gen_reg_rtx (mode);
5498
5499 if (GET_MODE (old_val) != VOIDmode && GET_MODE (old_val) != mode)
5500 old_val = convert_modes (mode, GET_MODE (old_val), old_val, 1);
5501 if (!insn_data[icode].operand[2].predicate (old_val, mode))
5502 old_val = force_reg (mode, old_val);
5503
5504 if (GET_MODE (new_val) != VOIDmode && GET_MODE (new_val) != mode)
5505 new_val = convert_modes (mode, GET_MODE (new_val), new_val, 1);
5506 if (!insn_data[icode].operand[3].predicate (new_val, mode))
5507 new_val = force_reg (mode, new_val);
5508
5509 insn = GEN_FCN (icode) (target, mem, old_val, new_val);
5510 if (insn == NULL_RTX)
5511 return NULL_RTX;
5512 emit_insn (insn);
5513
5514 return target;
5515}
5516
5517/* Expand a compare-and-swap operation and return its value. */
5518
5519rtx
5520expand_val_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5521{
5522 enum machine_mode mode = GET_MODE (mem);
5523 enum insn_code icode = sync_compare_and_swap[mode];
5524
5525 if (icode == CODE_FOR_nothing)
5526 return NULL_RTX;
5527
5528 return expand_val_compare_and_swap_1 (mem, old_val, new_val, target, icode);
5529}
5530
5531/* Expand a compare-and-swap operation and store true into the result if
5532 the operation was successful and false otherwise. Return the result.
5533 Unlike other routines, TARGET is not optional. */
5534
5535rtx
5536expand_bool_compare_and_swap (rtx mem, rtx old_val, rtx new_val, rtx target)
5537{
5538 enum machine_mode mode = GET_MODE (mem);
5539 enum insn_code icode;
5540 rtx subtarget, label0, label1;
5541
5542 /* If the target supports a compare-and-swap pattern that simultaneously
5543 sets some flag for success, then use it. Otherwise use the regular
5544 compare-and-swap and follow that immediately with a compare insn. */
5545 icode = sync_compare_and_swap_cc[mode];
5546 switch (icode)
5547 {
5548 default:
5549 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5550 NULL_RTX, icode);
5551 if (subtarget != NULL_RTX)
5552 break;
5553
5554 /* FALLTHRU */
5555 case CODE_FOR_nothing:
5556 icode = sync_compare_and_swap[mode];
5557 if (icode == CODE_FOR_nothing)
5558 return NULL_RTX;
5559
f12b785d
RH
5560 /* Ensure that if old_val == mem, that we're not comparing
5561 against an old value. */
5562 if (GET_CODE (old_val) == MEM)
5563 old_val = force_reg (mode, old_val);
5564
48ae6c13
RH
5565 subtarget = expand_val_compare_and_swap_1 (mem, old_val, new_val,
5566 NULL_RTX, icode);
5567 if (subtarget == NULL_RTX)
5568 return NULL_RTX;
5569
f12b785d 5570 emit_cmp_insn (subtarget, old_val, EQ, const0_rtx, mode, true);
48ae6c13
RH
5571 }
5572
5573 /* If the target has a sane STORE_FLAG_VALUE, then go ahead and use a
5574 setcc instruction from the beginning. We don't work too hard here,
5575 but it's nice to not be stupid about initial code gen either. */
5576 if (STORE_FLAG_VALUE == 1)
5577 {
5578 icode = setcc_gen_code[EQ];
5579 if (icode != CODE_FOR_nothing)
5580 {
5581 enum machine_mode cmode = insn_data[icode].operand[0].mode;
5582 rtx insn;
5583
5584 subtarget = target;
5585 if (!insn_data[icode].operand[0].predicate (target, cmode))
5586 subtarget = gen_reg_rtx (cmode);
5587
5588 insn = GEN_FCN (icode) (subtarget);
5589 if (insn)
5590 {
5591 emit_insn (insn);
5592 if (GET_MODE (target) != GET_MODE (subtarget))
5593 {
5594 convert_move (target, subtarget, 1);
5595 subtarget = target;
5596 }
5597 return subtarget;
5598 }
5599 }
5600 }
5601
5602 /* Without an appropriate setcc instruction, use a set of branches to
5603 get 1 and 0 stored into target. Presumably if the target has a
5604 STORE_FLAG_VALUE that isn't 1, then this will get cleaned up by ifcvt. */
5605
5606 label0 = gen_label_rtx ();
5607 label1 = gen_label_rtx ();
5608
5609 emit_jump_insn (bcc_gen_fctn[EQ] (label0));
5610 emit_move_insn (target, const0_rtx);
5611 emit_jump_insn (gen_jump (label1));
5612 emit_label (label0);
5613 emit_move_insn (target, const1_rtx);
5614 emit_label (label1);
5615
5616 return target;
5617}
5618
5619/* This is a helper function for the other atomic operations. This function
5620 emits a loop that contains SEQ that iterates until a compare-and-swap
5621 operation at the end succeeds. MEM is the memory to be modified. SEQ is
5622 a set of instructions that takes a value from OLD_REG as an input and
5623 produces a value in NEW_REG as an output. Before SEQ, OLD_REG will be
5624 set to the current contents of MEM. After SEQ, a compare-and-swap will
5625 attempt to update MEM with NEW_REG. The function returns true when the
5626 loop was generated successfully. */
5627
5628static bool
5629expand_compare_and_swap_loop (rtx mem, rtx old_reg, rtx new_reg, rtx seq)
5630{
5631 enum machine_mode mode = GET_MODE (mem);
5632 enum insn_code icode;
5633 rtx label, subtarget;
5634
5635 /* The loop we want to generate looks like
5636
5637 old_reg = mem;
5638 label:
5639 seq;
5640 old_reg = compare-and-swap(mem, old_reg, new_reg)
5641 if (old_reg != new_reg)
5642 goto label;
5643
5644 Note that we only do the plain load from memory once. Subsequent
5645 iterations use the value loaded by the compare-and-swap pattern. */
5646
5647 label = gen_label_rtx ();
5648
5649 emit_move_insn (old_reg, mem);
5650 emit_label (label);
5651 if (seq)
5652 emit_insn (seq);
5653
5654 /* If the target supports a compare-and-swap pattern that simultaneously
5655 sets some flag for success, then use it. Otherwise use the regular
5656 compare-and-swap and follow that immediately with a compare insn. */
5657 icode = sync_compare_and_swap_cc[mode];
5658 switch (icode)
5659 {
5660 default:
5661 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5662 old_reg, icode);
5663 if (subtarget != NULL_RTX)
5664 break;
5665
5666 /* FALLTHRU */
5667 case CODE_FOR_nothing:
5668 icode = sync_compare_and_swap[mode];
5669 if (icode == CODE_FOR_nothing)
5670 return false;
5671
5672 subtarget = expand_val_compare_and_swap_1 (mem, old_reg, new_reg,
5673 old_reg, icode);
5674 if (subtarget == NULL_RTX)
5675 return false;
5676
f12b785d 5677 emit_cmp_insn (subtarget, old_reg, EQ, const0_rtx, mode, true);
48ae6c13
RH
5678 }
5679
5680 /* ??? Mark this jump predicted not taken? */
5681 emit_jump_insn (bcc_gen_fctn[NE] (label));
5682
5683 return true;
5684}
5685
5686/* This function generates the atomic operation MEM CODE= VAL. In this
5687 case, we do not care about any resulting value. Returns NULL if we
5688 cannot generate the operation. */
5689
5690rtx
5691expand_sync_operation (rtx mem, rtx val, enum rtx_code code)
5692{
5693 enum machine_mode mode = GET_MODE (mem);
5694 enum insn_code icode;
5695 rtx insn;
5696
5697 /* Look to see if the target supports the operation directly. */
5698 switch (code)
5699 {
5700 case PLUS:
5701 icode = sync_add_optab[mode];
5702 break;
5703 case IOR:
5704 icode = sync_ior_optab[mode];
5705 break;
5706 case XOR:
5707 icode = sync_xor_optab[mode];
5708 break;
5709 case AND:
5710 icode = sync_and_optab[mode];
5711 break;
f12b785d
RH
5712 case NOT:
5713 icode = sync_nand_optab[mode];
5714 break;
48ae6c13
RH
5715
5716 case MINUS:
5717 icode = sync_sub_optab[mode];
5718 if (icode == CODE_FOR_nothing)
5719 {
5720 icode = sync_add_optab[mode];
5721 if (icode != CODE_FOR_nothing)
5722 {
5723 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
5724 code = PLUS;
5725 }
5726 }
5727 break;
5728
48ae6c13
RH
5729 default:
5730 gcc_unreachable ();
5731 }
5732
5733 /* Generate the direct operation, if present. */
5734 if (icode != CODE_FOR_nothing)
5735 {
5736 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5737 val = convert_modes (mode, GET_MODE (val), val, 1);
5738 if (!insn_data[icode].operand[1].predicate (val, mode))
5739 val = force_reg (mode, val);
5740
5741 insn = GEN_FCN (icode) (mem, val);
5742 if (insn)
5743 {
5744 emit_insn (insn);
5745 return const0_rtx;
5746 }
5747 }
5748
5749 /* Failing that, generate a compare-and-swap loop in which we perform the
5750 operation with normal arithmetic instructions. */
5751 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
5752 {
5753 rtx t0 = gen_reg_rtx (mode), t1;
5754
5755 start_sequence ();
5756
f12b785d 5757 t1 = t0;
48ae6c13
RH
5758 if (code == NOT)
5759 {
f12b785d 5760 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
48ae6c13
RH
5761 code = AND;
5762 }
f12b785d 5763 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
48ae6c13
RH
5764 true, OPTAB_LIB_WIDEN);
5765
5766 insn = get_insns ();
5767 end_sequence ();
5768
5769 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
5770 return const0_rtx;
5771 }
5772
5773 return NULL_RTX;
5774}
5775
5776/* This function generates the atomic operation MEM CODE= VAL. In this
5777 case, we do care about the resulting value: if AFTER is true then
5778 return the value MEM holds after the operation, if AFTER is false
5779 then return the value MEM holds before the operation. TARGET is an
5780 optional place for the result value to be stored. */
5781
5782rtx
5783expand_sync_fetch_operation (rtx mem, rtx val, enum rtx_code code,
5784 bool after, rtx target)
5785{
5786 enum machine_mode mode = GET_MODE (mem);
5787 enum insn_code old_code, new_code, icode;
5788 bool compensate;
5789 rtx insn;
5790
5791 /* Look to see if the target supports the operation directly. */
5792 switch (code)
5793 {
5794 case PLUS:
5795 old_code = sync_old_add_optab[mode];
5796 new_code = sync_new_add_optab[mode];
5797 break;
5798 case IOR:
5799 old_code = sync_old_ior_optab[mode];
5800 new_code = sync_new_ior_optab[mode];
5801 break;
5802 case XOR:
5803 old_code = sync_old_xor_optab[mode];
5804 new_code = sync_new_xor_optab[mode];
5805 break;
5806 case AND:
5807 old_code = sync_old_and_optab[mode];
5808 new_code = sync_new_and_optab[mode];
5809 break;
f12b785d
RH
5810 case NOT:
5811 old_code = sync_old_nand_optab[mode];
5812 new_code = sync_new_nand_optab[mode];
5813 break;
48ae6c13
RH
5814
5815 case MINUS:
5816 old_code = sync_old_sub_optab[mode];
5817 new_code = sync_new_sub_optab[mode];
5818 if (old_code == CODE_FOR_nothing && new_code == CODE_FOR_nothing)
5819 {
5820 old_code = sync_old_add_optab[mode];
5821 new_code = sync_new_add_optab[mode];
5822 if (old_code != CODE_FOR_nothing || new_code != CODE_FOR_nothing)
5823 {
5824 val = expand_simple_unop (mode, NEG, val, NULL_RTX, 1);
5825 code = PLUS;
5826 }
5827 }
5828 break;
5829
48ae6c13
RH
5830 default:
5831 gcc_unreachable ();
5832 }
5833
5834 /* If the target does supports the proper new/old operation, great. But
5835 if we only support the opposite old/new operation, check to see if we
5836 can compensate. In the case in which the old value is supported, then
5837 we can always perform the operation again with normal arithmetic. In
5838 the case in which the new value is supported, then we can only handle
5839 this in the case the operation is reversible. */
5840 compensate = false;
5841 if (after)
5842 {
5843 icode = new_code;
5844 if (icode == CODE_FOR_nothing)
5845 {
5846 icode = old_code;
5847 if (icode != CODE_FOR_nothing)
5848 compensate = true;
5849 }
5850 }
5851 else
5852 {
5853 icode = old_code;
5854 if (icode == CODE_FOR_nothing
5855 && (code == PLUS || code == MINUS || code == XOR))
5856 {
5857 icode = new_code;
5858 if (icode != CODE_FOR_nothing)
5859 compensate = true;
5860 }
5861 }
5862
5863 /* If we found something supported, great. */
5864 if (icode != CODE_FOR_nothing)
5865 {
5866 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5867 target = gen_reg_rtx (mode);
5868
5869 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5870 val = convert_modes (mode, GET_MODE (val), val, 1);
5871 if (!insn_data[icode].operand[2].predicate (val, mode))
5872 val = force_reg (mode, val);
5873
5874 insn = GEN_FCN (icode) (target, mem, val);
5875 if (insn)
5876 {
5877 emit_insn (insn);
5878
5879 /* If we need to compensate for using an operation with the
5880 wrong return value, do so now. */
5881 if (compensate)
5882 {
5883 if (!after)
5884 {
5885 if (code == PLUS)
5886 code = MINUS;
5887 else if (code == MINUS)
5888 code = PLUS;
5889 }
f12b785d
RH
5890
5891 if (code == NOT)
5892 target = expand_simple_unop (mode, NOT, target, NULL_RTX, true);
48ae6c13
RH
5893 target = expand_simple_binop (mode, code, target, val, NULL_RTX,
5894 true, OPTAB_LIB_WIDEN);
5895 }
5896
5897 return target;
5898 }
5899 }
5900
5901 /* Failing that, generate a compare-and-swap loop in which we perform the
5902 operation with normal arithmetic instructions. */
5903 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
5904 {
5905 rtx t0 = gen_reg_rtx (mode), t1;
5906
5907 if (!target || !register_operand (target, mode))
5908 target = gen_reg_rtx (mode);
5909
5910 start_sequence ();
5911
f12b785d
RH
5912 if (!after)
5913 emit_move_insn (target, t0);
5914 t1 = t0;
48ae6c13
RH
5915 if (code == NOT)
5916 {
f12b785d 5917 t1 = expand_simple_unop (mode, NOT, t1, NULL_RTX, true);
48ae6c13
RH
5918 code = AND;
5919 }
f12b785d 5920 t1 = expand_simple_binop (mode, code, t1, val, NULL_RTX,
48ae6c13
RH
5921 true, OPTAB_LIB_WIDEN);
5922 if (after)
5923 emit_move_insn (target, t1);
5924
5925 insn = get_insns ();
5926 end_sequence ();
5927
5928 if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
5929 return target;
5930 }
5931
5932 return NULL_RTX;
5933}
5934
5935/* This function expands a test-and-set operation. Ideally we atomically
5936 store VAL in MEM and return the previous value in MEM. Some targets
5937 may not support this operation and only support VAL with the constant 1;
5938 in this case while the return value will be 0/1, but the exact value
5939 stored in MEM is target defined. TARGET is an option place to stick
5940 the return value. */
5941
5942rtx
5943expand_sync_lock_test_and_set (rtx mem, rtx val, rtx target)
5944{
5945 enum machine_mode mode = GET_MODE (mem);
5946 enum insn_code icode;
5947 rtx insn;
5948
5949 /* If the target supports the test-and-set directly, great. */
5950 icode = sync_lock_test_and_set[mode];
5951 if (icode != CODE_FOR_nothing)
5952 {
5953 if (!target || !insn_data[icode].operand[0].predicate (target, mode))
5954 target = gen_reg_rtx (mode);
5955
5956 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5957 val = convert_modes (mode, GET_MODE (val), val, 1);
5958 if (!insn_data[icode].operand[2].predicate (val, mode))
5959 val = force_reg (mode, val);
5960
5961 insn = GEN_FCN (icode) (target, mem, val);
5962 if (insn)
5963 {
5964 emit_insn (insn);
5965 return target;
5966 }
5967 }
5968
5969 /* Otherwise, use a compare-and-swap loop for the exchange. */
5970 if (sync_compare_and_swap[mode] != CODE_FOR_nothing)
5971 {
5972 if (!target || !register_operand (target, mode))
5973 target = gen_reg_rtx (mode);
5974 if (GET_MODE (val) != VOIDmode && GET_MODE (val) != mode)
5975 val = convert_modes (mode, GET_MODE (val), val, 1);
5976 if (expand_compare_and_swap_loop (mem, target, val, NULL_RTX))
5977 return target;
5978 }
5979
5980 return NULL_RTX;
5981}
5982
e2500fed 5983#include "gt-optabs.h"
This page took 3.526558 seconds and 5 git commands to generate.