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