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