1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 #include "insn-flags.h"
27 #include "insn-codes.h"
29 #include "insn-config.h"
34 /* Each optab contains info on how this target machine
35 can perform a particular operation
36 for all sizes and kinds of operands.
38 The operation to be performed is often specified
39 by passing one of these optabs as an argument.
41 See expr.h for documentation of these optabs. */
46 optab smul_highpart_optab
;
47 optab umul_highpart_optab
;
48 optab smul_widen_optab
;
49 optab umul_widen_optab
;
72 optab movstrict_optab
;
83 optab ucmp_optab
; /* Used only for libcalls for unsigned comparisons. */
88 /* Tables of patterns for extending one integer mode to another. */
89 enum insn_code extendtab
[MAX_MACHINE_MODE
][MAX_MACHINE_MODE
][2];
91 /* Tables of patterns for converting between fixed and floating point. */
92 enum insn_code fixtab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
93 enum insn_code fixtrunctab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
94 enum insn_code floattab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
96 /* Contains the optab used for each rtx code. */
97 optab code_to_optab
[NUM_RTX_CODE
+ 1];
99 /* SYMBOL_REF rtx's for the library functions that are called
100 implicitly and not via optabs. */
102 rtx extendsfdf2_libfunc
;
103 rtx extendsfxf2_libfunc
;
104 rtx extendsftf2_libfunc
;
105 rtx extenddfxf2_libfunc
;
106 rtx extenddftf2_libfunc
;
108 rtx truncdfsf2_libfunc
;
109 rtx truncxfsf2_libfunc
;
110 rtx trunctfsf2_libfunc
;
111 rtx truncxfdf2_libfunc
;
112 rtx trunctfdf2_libfunc
;
123 rtx sjpopnthrow_libfunc
;
124 rtx terminate_libfunc
;
127 rtx get_dynamic_handler_chain_libfunc
;
164 rtx floatsisf_libfunc
;
165 rtx floatdisf_libfunc
;
166 rtx floattisf_libfunc
;
168 rtx floatsidf_libfunc
;
169 rtx floatdidf_libfunc
;
170 rtx floattidf_libfunc
;
172 rtx floatsixf_libfunc
;
173 rtx floatdixf_libfunc
;
174 rtx floattixf_libfunc
;
176 rtx floatsitf_libfunc
;
177 rtx floatditf_libfunc
;
178 rtx floattitf_libfunc
;
196 rtx fixunssfsi_libfunc
;
197 rtx fixunssfdi_libfunc
;
198 rtx fixunssfti_libfunc
;
200 rtx fixunsdfsi_libfunc
;
201 rtx fixunsdfdi_libfunc
;
202 rtx fixunsdfti_libfunc
;
204 rtx fixunsxfsi_libfunc
;
205 rtx fixunsxfdi_libfunc
;
206 rtx fixunsxfti_libfunc
;
208 rtx fixunstfsi_libfunc
;
209 rtx fixunstfdi_libfunc
;
210 rtx fixunstfti_libfunc
;
212 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
213 gives the gen_function to make a branch to test that condition. */
215 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
217 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
218 gives the insn code to make a store-condition insn
219 to test that condition. */
221 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
223 #ifdef HAVE_conditional_move
224 /* Indexed by the machine mode, gives the insn code to make a conditional
225 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
226 setcc_gen_code to cut down on the number of named patterns. Consider a day
227 when a lot more rtx codes are conditional (eg: for the ARM). */
229 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
232 static int add_equal_note
PROTO((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
233 static rtx widen_operand
PROTO((rtx
, enum machine_mode
,
234 enum machine_mode
, int, int));
235 static enum insn_code can_fix_p
PROTO((enum machine_mode
, enum machine_mode
,
237 static enum insn_code can_float_p
PROTO((enum machine_mode
, enum machine_mode
,
239 static rtx ftruncify
PROTO((rtx
));
240 static optab init_optab
PROTO((enum rtx_code
));
241 static void init_libfuncs
PROTO((optab
, int, int, char *, int));
242 static void init_integral_libfuncs
PROTO((optab
, char *, int));
243 static void init_floating_libfuncs
PROTO((optab
, char *, int));
244 static void init_complex_libfuncs
PROTO((optab
, char *, int));
246 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
247 the result of operation CODE applied to OP0 (and OP1 if it is a binary
250 If the last insn does not set TARGET, don't do anything, but return 1.
252 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
253 don't add the REG_EQUAL note but return 0. Our caller can then try
254 again, ensuring that TARGET is not one of the operands. */
257 add_equal_note (seq
, target
, code
, op0
, op1
)
267 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
268 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
269 || GET_CODE (seq
) != SEQUENCE
270 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
271 || GET_CODE (target
) == ZERO_EXTRACT
272 || (! rtx_equal_p (SET_DEST (set
), target
)
273 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
275 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
276 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
280 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
281 besides the last insn. */
282 if (reg_overlap_mentioned_p (target
, op0
)
283 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
284 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
285 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
288 if (GET_RTX_CLASS (code
) == '1')
289 note
= gen_rtx (code
, GET_MODE (target
), copy_rtx (op0
));
291 note
= gen_rtx (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
293 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))
294 = gen_rtx (EXPR_LIST
, REG_EQUAL
, note
,
295 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1)));
300 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
301 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
302 not actually do a sign-extend or zero-extend, but can leave the
303 higher-order bits of the result rtx undefined, for example, in the case
304 of logical operations, but not right shifts. */
307 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
309 enum machine_mode mode
, oldmode
;
315 /* If we must extend do so. If OP is either a constant or a SUBREG
316 for a promoted object, also extend since it will be more efficient to
319 || GET_MODE (op
) == VOIDmode
320 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
321 return convert_modes (mode
, oldmode
, op
, unsignedp
);
323 /* If MODE is no wider than a single word, we return a paradoxical
325 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
326 return gen_rtx (SUBREG
, mode
, force_reg (GET_MODE (op
), op
), 0);
328 /* Otherwise, get an object of MODE, clobber it, and set the low-order
331 result
= gen_reg_rtx (mode
);
332 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, result
));
333 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
337 /* Generate code to perform an operation specified by BINOPTAB
338 on operands OP0 and OP1, with result having machine-mode MODE.
340 UNSIGNEDP is for the case where we have to widen the operands
341 to perform the operation. It says to use zero-extension.
343 If TARGET is nonzero, the value
344 is generated there, if it is convenient to do so.
345 In all cases an rtx is returned for the locus of the value;
346 this may or may not be TARGET. */
349 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
350 enum machine_mode mode
;
355 enum optab_methods methods
;
357 enum optab_methods next_methods
358 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
359 ? OPTAB_WIDEN
: methods
);
360 enum mode_class
class;
361 enum machine_mode wider_mode
;
363 int commutative_op
= 0;
364 int shift_op
= (binoptab
->code
== ASHIFT
365 || binoptab
->code
== ASHIFTRT
366 || binoptab
->code
== LSHIFTRT
367 || binoptab
->code
== ROTATE
368 || binoptab
->code
== ROTATERT
);
369 rtx entry_last
= get_last_insn ();
372 class = GET_MODE_CLASS (mode
);
374 op0
= protect_from_queue (op0
, 0);
375 op1
= protect_from_queue (op1
, 0);
377 target
= protect_from_queue (target
, 1);
381 op0
= force_not_mem (op0
);
382 op1
= force_not_mem (op1
);
385 /* If subtracting an integer constant, convert this into an addition of
386 the negated constant. */
388 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
390 op1
= negate_rtx (mode
, op1
);
391 binoptab
= add_optab
;
394 /* If we are inside an appropriately-short loop and one operand is an
395 expensive constant, force it into a register. */
396 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
397 && rtx_cost (op0
, binoptab
->code
) > 2)
398 op0
= force_reg (mode
, op0
);
400 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
401 && ! shift_op
&& rtx_cost (op1
, binoptab
->code
) > 2)
402 op1
= force_reg (mode
, op1
);
404 /* Record where to delete back to if we backtrack. */
405 last
= get_last_insn ();
407 /* If operation is commutative,
408 try to make the first operand a register.
409 Even better, try to make it the same as the target.
410 Also try to make the last operand a constant. */
411 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
412 || binoptab
== smul_widen_optab
413 || binoptab
== umul_widen_optab
414 || binoptab
== smul_highpart_optab
415 || binoptab
== umul_highpart_optab
)
419 if (((target
== 0 || GET_CODE (target
) == REG
)
420 ? ((GET_CODE (op1
) == REG
421 && GET_CODE (op0
) != REG
)
423 : rtx_equal_p (op1
, target
))
424 || GET_CODE (op0
) == CONST_INT
)
432 /* If we can do it with a three-operand insn, do so. */
434 if (methods
!= OPTAB_MUST_WIDEN
435 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
437 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
438 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
439 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
441 rtx xop0
= op0
, xop1
= op1
;
446 temp
= gen_reg_rtx (mode
);
448 /* If it is a commutative operator and the modes would match
449 if we would swap the operands, we can save the conversions. */
452 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
453 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
457 tmp
= op0
; op0
= op1
; op1
= tmp
;
458 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
462 /* In case the insn wants input operands in modes different from
463 the result, convert the operands. */
465 if (GET_MODE (op0
) != VOIDmode
466 && GET_MODE (op0
) != mode0
467 && mode0
!= VOIDmode
)
468 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
470 if (GET_MODE (xop1
) != VOIDmode
471 && GET_MODE (xop1
) != mode1
472 && mode1
!= VOIDmode
)
473 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
475 /* Now, if insn's predicates don't allow our operands, put them into
478 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
)
479 && mode0
!= VOIDmode
)
480 xop0
= copy_to_mode_reg (mode0
, xop0
);
482 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
)
483 && mode1
!= VOIDmode
)
484 xop1
= copy_to_mode_reg (mode1
, xop1
);
486 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
487 temp
= gen_reg_rtx (mode
);
489 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
492 /* If PAT is a multi-insn sequence, try to add an appropriate
493 REG_EQUAL note to it. If we can't because TEMP conflicts with an
494 operand, call ourselves again, this time without a target. */
495 if (GET_CODE (pat
) == SEQUENCE
496 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
498 delete_insns_since (last
);
499 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
507 delete_insns_since (last
);
510 /* If this is a multiply, see if we can do a widening operation that
511 takes operands of this mode and makes a wider mode. */
513 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
514 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
515 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
516 != CODE_FOR_nothing
))
518 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
519 unsignedp
? umul_widen_optab
: smul_widen_optab
,
520 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
524 if (GET_MODE_CLASS (mode
) == MODE_INT
)
525 return gen_lowpart (mode
, temp
);
527 return convert_to_mode (mode
, temp
, unsignedp
);
531 /* Look for a wider mode of the same class for which we think we
532 can open-code the operation. Check for a widening multiply at the
533 wider mode as well. */
535 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
536 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
537 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
538 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
540 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
541 || (binoptab
== smul_optab
542 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
543 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
544 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
545 != CODE_FOR_nothing
)))
547 rtx xop0
= op0
, xop1
= op1
;
550 /* For certain integer operations, we need not actually extend
551 the narrow operands, as long as we will truncate
552 the results to the same narrowness. */
554 if ((binoptab
== ior_optab
|| binoptab
== and_optab
555 || binoptab
== xor_optab
556 || binoptab
== add_optab
|| binoptab
== sub_optab
557 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
558 && class == MODE_INT
)
561 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
563 /* The second operand of a shift must always be extended. */
564 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
565 no_extend
&& binoptab
!= ashl_optab
);
567 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
568 unsignedp
, OPTAB_DIRECT
);
571 if (class != MODE_INT
)
574 target
= gen_reg_rtx (mode
);
575 convert_move (target
, temp
, 0);
579 return gen_lowpart (mode
, temp
);
582 delete_insns_since (last
);
586 /* These can be done a word at a time. */
587 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
589 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
590 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
596 /* If TARGET is the same as one of the operands, the REG_EQUAL note
597 won't be accurate, so use a new target. */
598 if (target
== 0 || target
== op0
|| target
== op1
)
599 target
= gen_reg_rtx (mode
);
603 /* Do the actual arithmetic. */
604 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
606 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
607 rtx x
= expand_binop (word_mode
, binoptab
,
608 operand_subword_force (op0
, i
, mode
),
609 operand_subword_force (op1
, i
, mode
),
610 target_piece
, unsignedp
, next_methods
);
615 if (target_piece
!= x
)
616 emit_move_insn (target_piece
, x
);
619 insns
= get_insns ();
622 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
624 if (binoptab
->code
!= UNKNOWN
)
626 = gen_rtx (binoptab
->code
, mode
, copy_rtx (op0
), copy_rtx (op1
));
630 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
635 /* Synthesize double word shifts from single word shifts. */
636 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
637 || binoptab
== ashr_optab
)
639 && GET_CODE (op1
) == CONST_INT
640 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
641 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
642 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
643 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
645 rtx insns
, inter
, equiv_value
;
646 rtx into_target
, outof_target
;
647 rtx into_input
, outof_input
;
648 int shift_count
, left_shift
, outof_word
;
650 /* If TARGET is the same as one of the operands, the REG_EQUAL note
651 won't be accurate, so use a new target. */
652 if (target
== 0 || target
== op0
|| target
== op1
)
653 target
= gen_reg_rtx (mode
);
657 shift_count
= INTVAL (op1
);
659 /* OUTOF_* is the word we are shifting bits away from, and
660 INTO_* is the word that we are shifting bits towards, thus
661 they differ depending on the direction of the shift and
664 left_shift
= binoptab
== ashl_optab
;
665 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
667 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
668 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
670 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
671 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
673 if (shift_count
>= BITS_PER_WORD
)
675 inter
= expand_binop (word_mode
, binoptab
,
677 GEN_INT (shift_count
- BITS_PER_WORD
),
678 into_target
, unsignedp
, next_methods
);
680 if (inter
!= 0 && inter
!= into_target
)
681 emit_move_insn (into_target
, inter
);
683 /* For a signed right shift, we must fill the word we are shifting
684 out of with copies of the sign bit. Otherwise it is zeroed. */
685 if (inter
!= 0 && binoptab
!= ashr_optab
)
686 inter
= CONST0_RTX (word_mode
);
688 inter
= expand_binop (word_mode
, binoptab
,
690 GEN_INT (BITS_PER_WORD
- 1),
691 outof_target
, unsignedp
, next_methods
);
693 if (inter
!= 0 && inter
!= outof_target
)
694 emit_move_insn (outof_target
, inter
);
699 optab reverse_unsigned_shift
, unsigned_shift
;
701 /* For a shift of less then BITS_PER_WORD, to compute the carry,
702 we must do a logical shift in the opposite direction of the
705 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
707 /* For a shift of less than BITS_PER_WORD, to compute the word
708 shifted towards, we need to unsigned shift the orig value of
711 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
713 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
715 GEN_INT (BITS_PER_WORD
- shift_count
),
716 0, unsignedp
, next_methods
);
721 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
722 op1
, 0, unsignedp
, next_methods
);
725 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
726 into_target
, unsignedp
, next_methods
);
728 if (inter
!= 0 && inter
!= into_target
)
729 emit_move_insn (into_target
, inter
);
732 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
733 op1
, outof_target
, unsignedp
, next_methods
);
735 if (inter
!= 0 && inter
!= outof_target
)
736 emit_move_insn (outof_target
, inter
);
739 insns
= get_insns ();
744 if (binoptab
->code
!= UNKNOWN
)
745 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
749 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
754 /* Synthesize double word rotates from single word shifts. */
755 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
757 && GET_CODE (op1
) == CONST_INT
758 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
759 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
760 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
762 rtx insns
, equiv_value
;
763 rtx into_target
, outof_target
;
764 rtx into_input
, outof_input
;
766 int shift_count
, left_shift
, outof_word
;
768 /* If TARGET is the same as one of the operands, the REG_EQUAL note
769 won't be accurate, so use a new target. */
770 if (target
== 0 || target
== op0
|| target
== op1
)
771 target
= gen_reg_rtx (mode
);
775 shift_count
= INTVAL (op1
);
777 /* OUTOF_* is the word we are shifting bits away from, and
778 INTO_* is the word that we are shifting bits towards, thus
779 they differ depending on the direction of the shift and
782 left_shift
= (binoptab
== rotl_optab
);
783 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
785 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
786 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
788 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
789 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
791 if (shift_count
== BITS_PER_WORD
)
793 /* This is just a word swap. */
794 emit_move_insn (outof_target
, into_input
);
795 emit_move_insn (into_target
, outof_input
);
800 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
801 rtx first_shift_count
, second_shift_count
;
802 optab reverse_unsigned_shift
, unsigned_shift
;
804 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
805 ? lshr_optab
: ashl_optab
);
807 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
808 ? ashl_optab
: lshr_optab
);
810 if (shift_count
> BITS_PER_WORD
)
812 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
813 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
817 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
818 second_shift_count
= GEN_INT (shift_count
);
821 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
822 outof_input
, first_shift_count
,
823 NULL_RTX
, unsignedp
, next_methods
);
824 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
825 into_input
, second_shift_count
,
826 into_target
, unsignedp
, next_methods
);
828 if (into_temp1
!= 0 && into_temp2
!= 0)
829 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
830 into_target
, unsignedp
, next_methods
);
834 if (inter
!= 0 && inter
!= into_target
)
835 emit_move_insn (into_target
, inter
);
837 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
838 into_input
, first_shift_count
,
839 NULL_RTX
, unsignedp
, next_methods
);
840 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
841 outof_input
, second_shift_count
,
842 outof_target
, unsignedp
, next_methods
);
844 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
845 inter
= expand_binop (word_mode
, ior_optab
,
846 outof_temp1
, outof_temp2
,
847 outof_target
, unsignedp
, next_methods
);
849 if (inter
!= 0 && inter
!= outof_target
)
850 emit_move_insn (outof_target
, inter
);
853 insns
= get_insns ();
858 if (binoptab
->code
!= UNKNOWN
)
859 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
863 /* We can't make this a no conflict block if this is a word swap,
864 because the word swap case fails if the input and output values
865 are in the same register. */
866 if (shift_count
!= BITS_PER_WORD
)
867 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
876 /* These can be done a word at a time by propagating carries. */
877 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
879 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
880 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
883 rtx carry_tmp
= gen_reg_rtx (word_mode
);
884 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
885 int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
886 rtx carry_in
, carry_out
;
889 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
890 value is one of those, use it. Otherwise, use 1 since it is the
891 one easiest to get. */
892 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
893 int normalizep
= STORE_FLAG_VALUE
;
898 /* Prepare the operands. */
899 xop0
= force_reg (mode
, op0
);
900 xop1
= force_reg (mode
, op1
);
902 if (target
== 0 || GET_CODE (target
) != REG
903 || target
== xop0
|| target
== xop1
)
904 target
= gen_reg_rtx (mode
);
906 /* Indicate for flow that the entire target reg is being set. */
907 if (GET_CODE (target
) == REG
)
908 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, target
));
910 /* Do the actual arithmetic. */
911 for (i
= 0; i
< nwords
; i
++)
913 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
914 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
915 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
916 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
919 /* Main add/subtract of the input operands. */
920 x
= expand_binop (word_mode
, binoptab
,
921 op0_piece
, op1_piece
,
922 target_piece
, unsignedp
, next_methods
);
928 /* Store carry from main add/subtract. */
929 carry_out
= gen_reg_rtx (word_mode
);
930 carry_out
= emit_store_flag_force (carry_out
,
931 (binoptab
== add_optab
934 word_mode
, 1, normalizep
);
939 /* Add/subtract previous carry to main result. */
940 x
= expand_binop (word_mode
,
941 normalizep
== 1 ? binoptab
: otheroptab
,
943 target_piece
, 1, next_methods
);
946 else if (target_piece
!= x
)
947 emit_move_insn (target_piece
, x
);
951 /* THIS CODE HAS NOT BEEN TESTED. */
952 /* Get out carry from adding/subtracting carry in. */
953 carry_tmp
= emit_store_flag_force (carry_tmp
,
954 binoptab
== add_optab
957 word_mode
, 1, normalizep
);
959 /* Logical-ior the two poss. carry together. */
960 carry_out
= expand_binop (word_mode
, ior_optab
,
961 carry_out
, carry_tmp
,
962 carry_out
, 0, next_methods
);
968 carry_in
= carry_out
;
971 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
973 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
975 rtx temp
= emit_move_insn (target
, target
);
977 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
978 gen_rtx (binoptab
->code
, mode
,
986 delete_insns_since (last
);
989 /* If we want to multiply two two-word values and have normal and widening
990 multiplies of single-word values, we can do this with three smaller
991 multiplications. Note that we do not make a REG_NO_CONFLICT block here
992 because we are not operating on one word at a time.
994 The multiplication proceeds as follows:
995 _______________________
996 [__op0_high_|__op0_low__]
997 _______________________
998 * [__op1_high_|__op1_low__]
999 _______________________________________________
1000 _______________________
1001 (1) [__op0_low__*__op1_low__]
1002 _______________________
1003 (2a) [__op0_low__*__op1_high_]
1004 _______________________
1005 (2b) [__op0_high_*__op1_low__]
1006 _______________________
1007 (3) [__op0_high_*__op1_high_]
1010 This gives a 4-word result. Since we are only interested in the
1011 lower 2 words, partial result (3) and the upper words of (2a) and
1012 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1013 calculated using non-widening multiplication.
1015 (1), however, needs to be calculated with an unsigned widening
1016 multiplication. If this operation is not directly supported we
1017 try using a signed widening multiplication and adjust the result.
1018 This adjustment works as follows:
1020 If both operands are positive then no adjustment is needed.
1022 If the operands have different signs, for example op0_low < 0 and
1023 op1_low >= 0, the instruction treats the most significant bit of
1024 op0_low as a sign bit instead of a bit with significance
1025 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1026 with 2**BITS_PER_WORD - op0_low, and two's complements the
1027 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1030 Similarly, if both operands are negative, we need to add
1031 (op0_low + op1_low) * 2**BITS_PER_WORD.
1033 We use a trick to adjust quickly. We logically shift op0_low right
1034 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1035 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1036 logical shift exists, we do an arithmetic right shift and subtract
1039 if (binoptab
== smul_optab
1040 && class == MODE_INT
1041 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1042 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1043 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1044 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1045 != CODE_FOR_nothing
)
1046 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1047 != CODE_FOR_nothing
)))
1049 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1050 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1051 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1052 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1053 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1054 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1059 /* If the target is the same as one of the inputs, don't use it. This
1060 prevents problems with the REG_EQUAL note. */
1061 if (target
== op0
|| target
== op1
1062 || (target
!= 0 && GET_CODE (target
) != REG
))
1065 /* Multiply the two lower words to get a double-word product.
1066 If unsigned widening multiplication is available, use that;
1067 otherwise use the signed form and compensate. */
1069 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1071 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1072 target
, 1, OPTAB_DIRECT
);
1074 /* If we didn't succeed, delete everything we did so far. */
1076 delete_insns_since (last
);
1078 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1082 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1083 != CODE_FOR_nothing
)
1085 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1086 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1087 target
, 1, OPTAB_DIRECT
);
1088 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1089 NULL_RTX
, 1, next_methods
);
1091 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1092 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1095 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1096 NULL_RTX
, 0, next_methods
);
1098 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1099 op0_xhigh
, op0_xhigh
, 0,
1103 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1104 NULL_RTX
, 1, next_methods
);
1106 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1107 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1110 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1111 NULL_RTX
, 0, next_methods
);
1113 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1114 op1_xhigh
, op1_xhigh
, 0,
1119 /* If we have been able to directly compute the product of the
1120 low-order words of the operands and perform any required adjustments
1121 of the operands, we proceed by trying two more multiplications
1122 and then computing the appropriate sum.
1124 We have checked above that the required addition is provided.
1125 Full-word addition will normally always succeed, especially if
1126 it is provided at all, so we don't worry about its failure. The
1127 multiplication may well fail, however, so we do handle that. */
1129 if (product
&& op0_xhigh
&& op1_xhigh
)
1131 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1132 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1133 NULL_RTX
, 0, OPTAB_DIRECT
);
1136 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1137 product_high
, 0, next_methods
);
1139 if (temp
!= 0 && temp
!= product_high
)
1140 emit_move_insn (product_high
, temp
);
1143 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1144 NULL_RTX
, 0, OPTAB_DIRECT
);
1147 temp
= expand_binop (word_mode
, add_optab
, temp
,
1148 product_high
, product_high
,
1151 if (temp
!= 0 && temp
!= product_high
)
1152 emit_move_insn (product_high
, temp
);
1156 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1158 temp
= emit_move_insn (product
, product
);
1159 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
1160 gen_rtx (MULT
, mode
,
1169 /* If we get here, we couldn't do it for some reason even though we
1170 originally thought we could. Delete anything we've emitted in
1173 delete_insns_since (last
);
1176 /* We need to open-code the complex type operations: '+, -, * and /' */
1178 /* At this point we allow operations between two similar complex
1179 numbers, and also if one of the operands is not a complex number
1180 but rather of MODE_FLOAT or MODE_INT. However, the caller
1181 must make sure that the MODE of the non-complex operand matches
1182 the SUBMODE of the complex operand. */
1184 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1186 rtx real0
= 0, imag0
= 0;
1187 rtx real1
= 0, imag1
= 0;
1188 rtx realr
, imagr
, res
;
1193 /* Find the correct mode for the real and imaginary parts */
1194 enum machine_mode submode
1195 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1196 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1199 if (submode
== BLKmode
)
1203 target
= gen_reg_rtx (mode
);
1207 realr
= gen_realpart (submode
, target
);
1208 imagr
= gen_imagpart (submode
, target
);
1210 if (GET_MODE (op0
) == mode
)
1212 real0
= gen_realpart (submode
, op0
);
1213 imag0
= gen_imagpart (submode
, op0
);
1218 if (GET_MODE (op1
) == mode
)
1220 real1
= gen_realpart (submode
, op1
);
1221 imag1
= gen_imagpart (submode
, op1
);
1226 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1229 switch (binoptab
->code
)
1232 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1234 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1235 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1236 realr
, unsignedp
, methods
);
1240 else if (res
!= realr
)
1241 emit_move_insn (realr
, res
);
1244 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1245 imagr
, unsignedp
, methods
);
1248 else if (binoptab
->code
== MINUS
)
1249 res
= expand_unop (submode
, neg_optab
, imag1
, imagr
, unsignedp
);
1255 else if (res
!= imagr
)
1256 emit_move_insn (imagr
, res
);
1262 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1268 /* Don't fetch these from memory more than once. */
1269 real0
= force_reg (submode
, real0
);
1270 real1
= force_reg (submode
, real1
);
1271 imag0
= force_reg (submode
, imag0
);
1272 imag1
= force_reg (submode
, imag1
);
1274 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1275 unsignedp
, methods
);
1277 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1278 unsignedp
, methods
);
1280 if (temp1
== 0 || temp2
== 0)
1283 res
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1284 realr
, unsignedp
, methods
);
1288 else if (res
!= realr
)
1289 emit_move_insn (realr
, res
);
1291 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1292 NULL_RTX
, unsignedp
, methods
);
1294 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1295 NULL_RTX
, unsignedp
, methods
);
1297 if (temp1
== 0 || temp2
== 0)
1300 res
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1301 imagr
, unsignedp
, methods
);
1305 else if (res
!= imagr
)
1306 emit_move_insn (imagr
, res
);
1312 /* Don't fetch these from memory more than once. */
1313 real0
= force_reg (submode
, real0
);
1314 real1
= force_reg (submode
, real1
);
1316 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1317 realr
, unsignedp
, methods
);
1320 else if (res
!= realr
)
1321 emit_move_insn (realr
, res
);
1324 res
= expand_binop (submode
, binoptab
,
1325 real1
, imag0
, imagr
, unsignedp
, methods
);
1327 res
= expand_binop (submode
, binoptab
,
1328 real0
, imag1
, imagr
, unsignedp
, methods
);
1332 else if (res
!= imagr
)
1333 emit_move_insn (imagr
, res
);
1340 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1344 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1346 /* Don't fetch these from memory more than once. */
1347 real1
= force_reg (submode
, real1
);
1349 /* Simply divide the real and imaginary parts by `c' */
1350 if (class == MODE_COMPLEX_FLOAT
)
1351 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1352 realr
, unsignedp
, methods
);
1354 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1355 real0
, real1
, realr
, unsignedp
);
1359 else if (res
!= realr
)
1360 emit_move_insn (realr
, res
);
1362 if (class == MODE_COMPLEX_FLOAT
)
1363 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1364 imagr
, unsignedp
, methods
);
1366 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1367 imag0
, real1
, imagr
, unsignedp
);
1371 else if (res
!= imagr
)
1372 emit_move_insn (imagr
, res
);
1378 /* Divisor is of complex type:
1385 /* Don't fetch these from memory more than once. */
1386 real0
= force_reg (submode
, real0
);
1387 real1
= force_reg (submode
, real1
);
1390 imag0
= force_reg (submode
, imag0
);
1392 imag1
= force_reg (submode
, imag1
);
1394 /* Divisor: c*c + d*d */
1395 temp1
= expand_binop (submode
, smul_optab
, real1
, real1
,
1396 NULL_RTX
, unsignedp
, methods
);
1398 temp2
= expand_binop (submode
, smul_optab
, imag1
, imag1
,
1399 NULL_RTX
, unsignedp
, methods
);
1401 if (temp1
== 0 || temp2
== 0)
1404 divisor
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1405 NULL_RTX
, unsignedp
, methods
);
1411 /* ((a)(c-id))/divisor */
1412 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1414 /* Calculate the dividend */
1415 real_t
= expand_binop (submode
, smul_optab
, real0
, real1
,
1416 NULL_RTX
, unsignedp
, methods
);
1418 imag_t
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1419 NULL_RTX
, unsignedp
, methods
);
1421 if (real_t
== 0 || imag_t
== 0)
1424 imag_t
= expand_unop (submode
, neg_optab
, imag_t
,
1425 NULL_RTX
, unsignedp
);
1429 /* ((a+ib)(c-id))/divider */
1430 /* Calculate the dividend */
1431 temp1
= expand_binop (submode
, smul_optab
, real0
, real1
,
1432 NULL_RTX
, unsignedp
, methods
);
1434 temp2
= expand_binop (submode
, smul_optab
, imag0
, imag1
,
1435 NULL_RTX
, unsignedp
, methods
);
1437 if (temp1
== 0 || temp2
== 0)
1440 real_t
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1441 NULL_RTX
, unsignedp
, methods
);
1443 temp1
= expand_binop (submode
, smul_optab
, imag0
, real1
,
1444 NULL_RTX
, unsignedp
, methods
);
1446 temp2
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1447 NULL_RTX
, unsignedp
, methods
);
1449 if (temp1
== 0 || temp2
== 0)
1452 imag_t
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1453 NULL_RTX
, unsignedp
, methods
);
1455 if (real_t
== 0 || imag_t
== 0)
1459 if (class == MODE_COMPLEX_FLOAT
)
1460 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
1461 realr
, unsignedp
, methods
);
1463 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1464 real_t
, divisor
, realr
, unsignedp
);
1468 else if (res
!= realr
)
1469 emit_move_insn (realr
, res
);
1471 if (class == MODE_COMPLEX_FLOAT
)
1472 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
1473 imagr
, unsignedp
, methods
);
1475 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1476 imag_t
, divisor
, imagr
, unsignedp
);
1480 else if (res
!= imagr
)
1481 emit_move_insn (imagr
, res
);
1496 if (binoptab
->code
!= UNKNOWN
)
1498 = gen_rtx (binoptab
->code
, mode
, copy_rtx (op0
), copy_rtx (op1
));
1502 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1508 /* It can't be open-coded in this mode.
1509 Use a library call if one is available and caller says that's ok. */
1511 if (binoptab
->handlers
[(int) mode
].libfunc
1512 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1515 rtx funexp
= binoptab
->handlers
[(int) mode
].libfunc
;
1517 enum machine_mode op1_mode
= mode
;
1524 op1_mode
= word_mode
;
1525 /* Specify unsigned here,
1526 since negative shift counts are meaningless. */
1527 op1x
= convert_to_mode (word_mode
, op1
, 1);
1530 if (GET_MODE (op0
) != VOIDmode
1531 && GET_MODE (op0
) != mode
)
1532 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1534 /* Pass 1 for NO_QUEUE so we don't lose any increments
1535 if the libcall is cse'd or moved. */
1536 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1537 NULL_RTX
, 1, mode
, 2,
1538 op0
, mode
, op1x
, op1_mode
);
1540 insns
= get_insns ();
1543 target
= gen_reg_rtx (mode
);
1544 emit_libcall_block (insns
, target
, value
,
1545 gen_rtx (binoptab
->code
, mode
, op0
, op1
));
1550 delete_insns_since (last
);
1552 /* It can't be done in this mode. Can we do it in a wider mode? */
1554 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1555 || methods
== OPTAB_MUST_WIDEN
))
1557 /* Caller says, don't even try. */
1558 delete_insns_since (entry_last
);
1562 /* Compute the value of METHODS to pass to recursive calls.
1563 Don't allow widening to be tried recursively. */
1565 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1567 /* Look for a wider mode of the same class for which it appears we can do
1570 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1572 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1573 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1575 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1576 != CODE_FOR_nothing
)
1577 || (methods
== OPTAB_LIB
1578 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1580 rtx xop0
= op0
, xop1
= op1
;
1583 /* For certain integer operations, we need not actually extend
1584 the narrow operands, as long as we will truncate
1585 the results to the same narrowness. */
1587 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1588 || binoptab
== xor_optab
1589 || binoptab
== add_optab
|| binoptab
== sub_optab
1590 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1591 && class == MODE_INT
)
1594 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1595 unsignedp
, no_extend
);
1597 /* The second operand of a shift must always be extended. */
1598 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1599 no_extend
&& binoptab
!= ashl_optab
);
1601 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1602 unsignedp
, methods
);
1605 if (class != MODE_INT
)
1608 target
= gen_reg_rtx (mode
);
1609 convert_move (target
, temp
, 0);
1613 return gen_lowpart (mode
, temp
);
1616 delete_insns_since (last
);
1621 delete_insns_since (entry_last
);
1625 /* Expand a binary operator which has both signed and unsigned forms.
1626 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1629 If we widen unsigned operands, we may use a signed wider operation instead
1630 of an unsigned wider operation, since the result would be the same. */
1633 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1634 enum machine_mode mode
;
1635 optab uoptab
, soptab
;
1636 rtx op0
, op1
, target
;
1638 enum optab_methods methods
;
1641 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1642 struct optab wide_soptab
;
1644 /* Do it without widening, if possible. */
1645 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1646 unsignedp
, OPTAB_DIRECT
);
1647 if (temp
|| methods
== OPTAB_DIRECT
)
1650 /* Try widening to a signed int. Make a fake signed optab that
1651 hides any signed insn for direct use. */
1652 wide_soptab
= *soptab
;
1653 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1654 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1656 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1657 unsignedp
, OPTAB_WIDEN
);
1659 /* For unsigned operands, try widening to an unsigned int. */
1660 if (temp
== 0 && unsignedp
)
1661 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1662 unsignedp
, OPTAB_WIDEN
);
1663 if (temp
|| methods
== OPTAB_WIDEN
)
1666 /* Use the right width lib call if that exists. */
1667 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1668 if (temp
|| methods
== OPTAB_LIB
)
1671 /* Must widen and use a lib call, use either signed or unsigned. */
1672 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1673 unsignedp
, methods
);
1677 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1678 unsignedp
, methods
);
1682 /* Generate code to perform an operation specified by BINOPTAB
1683 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1684 We assume that the order of the operands for the instruction
1685 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1686 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1688 Either TARG0 or TARG1 may be zero, but what that means is that
1689 that result is not actually wanted. We will generate it into
1690 a dummy pseudo-reg and discard it. They may not both be zero.
1692 Returns 1 if this operation can be performed; 0 if not. */
1695 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1701 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1702 enum mode_class
class;
1703 enum machine_mode wider_mode
;
1704 rtx entry_last
= get_last_insn ();
1707 class = GET_MODE_CLASS (mode
);
1709 op0
= protect_from_queue (op0
, 0);
1710 op1
= protect_from_queue (op1
, 0);
1714 op0
= force_not_mem (op0
);
1715 op1
= force_not_mem (op1
);
1718 /* If we are inside an appropriately-short loop and one operand is an
1719 expensive constant, force it into a register. */
1720 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1721 && rtx_cost (op0
, binoptab
->code
) > 2)
1722 op0
= force_reg (mode
, op0
);
1724 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1725 && rtx_cost (op1
, binoptab
->code
) > 2)
1726 op1
= force_reg (mode
, op1
);
1729 targ0
= protect_from_queue (targ0
, 1);
1731 targ0
= gen_reg_rtx (mode
);
1733 targ1
= protect_from_queue (targ1
, 1);
1735 targ1
= gen_reg_rtx (mode
);
1737 /* Record where to go back to if we fail. */
1738 last
= get_last_insn ();
1740 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1742 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1743 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1744 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
1746 rtx xop0
= op0
, xop1
= op1
;
1748 /* In case this insn wants input operands in modes different from the
1749 result, convert the operands. */
1750 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1751 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1753 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1754 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1756 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1757 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1758 xop0
= copy_to_mode_reg (mode0
, xop0
);
1760 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
1761 xop1
= copy_to_mode_reg (mode1
, xop1
);
1763 /* We could handle this, but we should always be called with a pseudo
1764 for our targets and all insns should take them as outputs. */
1765 if (! (*insn_operand_predicate
[icode
][0]) (targ0
, mode
)
1766 || ! (*insn_operand_predicate
[icode
][3]) (targ1
, mode
))
1769 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1776 delete_insns_since (last
);
1779 /* It can't be done in this mode. Can we do it in a wider mode? */
1781 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1783 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1784 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1786 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1787 != CODE_FOR_nothing
)
1789 register rtx t0
= gen_reg_rtx (wider_mode
);
1790 register rtx t1
= gen_reg_rtx (wider_mode
);
1792 if (expand_twoval_binop (binoptab
,
1793 convert_modes (wider_mode
, mode
, op0
,
1795 convert_modes (wider_mode
, mode
, op1
,
1799 convert_move (targ0
, t0
, unsignedp
);
1800 convert_move (targ1
, t1
, unsignedp
);
1804 delete_insns_since (last
);
1809 delete_insns_since (entry_last
);
1813 /* Generate code to perform an operation specified by UNOPTAB
1814 on operand OP0, with result having machine-mode MODE.
1816 UNSIGNEDP is for the case where we have to widen the operands
1817 to perform the operation. It says to use zero-extension.
1819 If TARGET is nonzero, the value
1820 is generated there, if it is convenient to do so.
1821 In all cases an rtx is returned for the locus of the value;
1822 this may or may not be TARGET. */
1825 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
1826 enum machine_mode mode
;
1832 enum mode_class
class;
1833 enum machine_mode wider_mode
;
1835 rtx last
= get_last_insn ();
1838 class = GET_MODE_CLASS (mode
);
1840 op0
= protect_from_queue (op0
, 0);
1844 op0
= force_not_mem (op0
);
1848 target
= protect_from_queue (target
, 1);
1850 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1852 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
1853 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1859 temp
= gen_reg_rtx (mode
);
1861 if (GET_MODE (xop0
) != VOIDmode
1862 && GET_MODE (xop0
) != mode0
)
1863 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1865 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1867 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1868 xop0
= copy_to_mode_reg (mode0
, xop0
);
1870 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
1871 temp
= gen_reg_rtx (mode
);
1873 pat
= GEN_FCN (icode
) (temp
, xop0
);
1876 if (GET_CODE (pat
) == SEQUENCE
1877 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
1879 delete_insns_since (last
);
1880 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
1888 delete_insns_since (last
);
1891 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1893 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1894 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1895 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1897 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
1901 /* For certain operations, we need not actually extend
1902 the narrow operand, as long as we will truncate the
1903 results to the same narrowness. */
1905 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
1906 (unoptab
== neg_optab
1907 || unoptab
== one_cmpl_optab
)
1908 && class == MODE_INT
);
1910 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
1915 if (class != MODE_INT
)
1918 target
= gen_reg_rtx (mode
);
1919 convert_move (target
, temp
, 0);
1923 return gen_lowpart (mode
, temp
);
1926 delete_insns_since (last
);
1930 /* These can be done a word at a time. */
1931 if (unoptab
== one_cmpl_optab
1932 && class == MODE_INT
1933 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1934 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1939 if (target
== 0 || target
== op0
)
1940 target
= gen_reg_rtx (mode
);
1944 /* Do the actual arithmetic. */
1945 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1947 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1948 rtx x
= expand_unop (word_mode
, unoptab
,
1949 operand_subword_force (op0
, i
, mode
),
1950 target_piece
, unsignedp
);
1951 if (target_piece
!= x
)
1952 emit_move_insn (target_piece
, x
);
1955 insns
= get_insns ();
1958 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
1959 gen_rtx (unoptab
->code
, mode
, copy_rtx (op0
)));
1963 /* Open-code the complex negation operation. */
1964 else if (unoptab
== neg_optab
1965 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
1971 /* Find the correct mode for the real and imaginary parts */
1972 enum machine_mode submode
1973 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1974 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1977 if (submode
== BLKmode
)
1981 target
= gen_reg_rtx (mode
);
1985 target_piece
= gen_imagpart (submode
, target
);
1986 x
= expand_unop (submode
, unoptab
,
1987 gen_imagpart (submode
, op0
),
1988 target_piece
, unsignedp
);
1989 if (target_piece
!= x
)
1990 emit_move_insn (target_piece
, x
);
1992 target_piece
= gen_realpart (submode
, target
);
1993 x
= expand_unop (submode
, unoptab
,
1994 gen_realpart (submode
, op0
),
1995 target_piece
, unsignedp
);
1996 if (target_piece
!= x
)
1997 emit_move_insn (target_piece
, x
);
2002 emit_no_conflict_block (seq
, target
, op0
, 0,
2003 gen_rtx (unoptab
->code
, mode
, copy_rtx (op0
)));
2007 /* Now try a library call in this mode. */
2008 if (unoptab
->handlers
[(int) mode
].libfunc
)
2011 rtx funexp
= unoptab
->handlers
[(int) mode
].libfunc
;
2016 /* Pass 1 for NO_QUEUE so we don't lose any increments
2017 if the libcall is cse'd or moved. */
2018 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
2019 NULL_RTX
, 1, mode
, 1, op0
, mode
);
2020 insns
= get_insns ();
2023 target
= gen_reg_rtx (mode
);
2024 emit_libcall_block (insns
, target
, value
,
2025 gen_rtx (unoptab
->code
, mode
, op0
));
2030 /* It can't be done in this mode. Can we do it in a wider mode? */
2032 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2034 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2035 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2037 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
2038 != CODE_FOR_nothing
)
2039 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
2043 /* For certain operations, we need not actually extend
2044 the narrow operand, as long as we will truncate the
2045 results to the same narrowness. */
2047 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2048 (unoptab
== neg_optab
2049 || unoptab
== one_cmpl_optab
)
2050 && class == MODE_INT
);
2052 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2057 if (class != MODE_INT
)
2060 target
= gen_reg_rtx (mode
);
2061 convert_move (target
, temp
, 0);
2065 return gen_lowpart (mode
, temp
);
2068 delete_insns_since (last
);
2073 /* If there is no negate operation, try doing a subtract from zero.
2074 The US Software GOFAST library needs this. */
2075 if (unoptab
== neg_optab
)
2078 temp
= expand_binop (mode
, sub_optab
, CONST0_RTX (mode
), op0
,
2079 target
, unsignedp
, OPTAB_LIB_WIDEN
);
2087 /* Emit code to compute the absolute value of OP0, with result to
2088 TARGET if convenient. (TARGET may be 0.) The return value says
2089 where the result actually is to be found.
2091 MODE is the mode of the operand; the mode of the result is
2092 different but can be deduced from MODE.
2094 UNSIGNEDP is relevant if extension is needed. */
2097 expand_abs (mode
, op0
, target
, unsignedp
, safe
)
2098 enum machine_mode mode
;
2106 /* First try to do it with a special abs instruction. */
2107 temp
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
2111 /* If this machine has expensive jumps, we can do integer absolute
2112 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2113 where W is the width of MODE. */
2115 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
2117 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
2118 size_int (GET_MODE_BITSIZE (mode
) - 1),
2121 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
2124 temp
= expand_binop (mode
, sub_optab
, temp
, extended
, target
, 0,
2131 /* If that does not win, use conditional jump and negate. */
2133 /* It is safe to use the target if it is the same
2134 as the source if this is also a pseudo register */
2135 if (op0
== target
&& GET_CODE (op0
) == REG
2136 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
2139 op1
= gen_label_rtx ();
2140 if (target
== 0 || ! safe
2141 || GET_MODE (target
) != mode
2142 || (GET_CODE (target
) == MEM
&& MEM_VOLATILE_P (target
))
2143 || (GET_CODE (target
) == REG
2144 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
2145 target
= gen_reg_rtx (mode
);
2147 emit_move_insn (target
, op0
);
2150 /* If this mode is an integer too wide to compare properly,
2151 compare word by word. Rely on CSE to optimize constant cases. */
2152 if (GET_MODE_CLASS (mode
) == MODE_INT
&& ! can_compare_p (mode
))
2153 do_jump_by_parts_greater_rtx (mode
, 0, target
, const0_rtx
,
2157 temp
= compare_from_rtx (target
, CONST0_RTX (mode
), GE
, 0, mode
,
2159 if (temp
== const1_rtx
)
2161 else if (temp
!= const0_rtx
)
2163 if (bcc_gen_fctn
[(int) GET_CODE (temp
)] != 0)
2164 emit_jump_insn ((*bcc_gen_fctn
[(int) GET_CODE (temp
)]) (op1
));
2170 op0
= expand_unop (mode
, neg_optab
, target
, target
, 0);
2172 emit_move_insn (target
, op0
);
2178 /* Emit code to compute the absolute value of OP0, with result to
2179 TARGET if convenient. (TARGET may be 0.) The return value says
2180 where the result actually is to be found.
2182 MODE is the mode of the operand; the mode of the result is
2183 different but can be deduced from MODE.
2185 UNSIGNEDP is relevant for complex integer modes. */
2188 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2189 enum machine_mode mode
;
2194 enum mode_class
class = GET_MODE_CLASS (mode
);
2195 enum machine_mode wider_mode
;
2197 rtx entry_last
= get_last_insn ();
2201 /* Find the correct mode for the real and imaginary parts. */
2202 enum machine_mode submode
2203 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2204 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2207 if (submode
== BLKmode
)
2210 op0
= protect_from_queue (op0
, 0);
2214 op0
= force_not_mem (op0
);
2217 last
= get_last_insn ();
2220 target
= protect_from_queue (target
, 1);
2222 if (abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2224 int icode
= (int) abs_optab
->handlers
[(int) mode
].insn_code
;
2225 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2231 temp
= gen_reg_rtx (submode
);
2233 if (GET_MODE (xop0
) != VOIDmode
2234 && GET_MODE (xop0
) != mode0
)
2235 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2237 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2239 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
2240 xop0
= copy_to_mode_reg (mode0
, xop0
);
2242 if (! (*insn_operand_predicate
[icode
][0]) (temp
, submode
))
2243 temp
= gen_reg_rtx (submode
);
2245 pat
= GEN_FCN (icode
) (temp
, xop0
);
2248 if (GET_CODE (pat
) == SEQUENCE
2249 && ! add_equal_note (pat
, temp
, abs_optab
->code
, xop0
, NULL_RTX
))
2251 delete_insns_since (last
);
2252 return expand_unop (mode
, abs_optab
, op0
, NULL_RTX
, unsignedp
);
2260 delete_insns_since (last
);
2263 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2265 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2266 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2268 if (abs_optab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2272 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2273 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2277 if (class != MODE_COMPLEX_INT
)
2280 target
= gen_reg_rtx (submode
);
2281 convert_move (target
, temp
, 0);
2285 return gen_lowpart (submode
, temp
);
2288 delete_insns_since (last
);
2292 /* Open-code the complex absolute-value operation
2293 if we can open-code sqrt. Otherwise it's not worth while. */
2294 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
)
2296 rtx real
, imag
, total
;
2298 real
= gen_realpart (submode
, op0
);
2299 imag
= gen_imagpart (submode
, op0
);
2301 /* Square both parts. */
2302 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2303 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2305 /* Sum the parts. */
2306 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2307 0, OPTAB_LIB_WIDEN
);
2309 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2310 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2312 delete_insns_since (last
);
2317 /* Now try a library call in this mode. */
2318 if (abs_optab
->handlers
[(int) mode
].libfunc
)
2321 rtx funexp
= abs_optab
->handlers
[(int) mode
].libfunc
;
2326 /* Pass 1 for NO_QUEUE so we don't lose any increments
2327 if the libcall is cse'd or moved. */
2328 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2329 NULL_RTX
, 1, submode
, 1, op0
, mode
);
2330 insns
= get_insns ();
2333 target
= gen_reg_rtx (submode
);
2334 emit_libcall_block (insns
, target
, value
,
2335 gen_rtx (abs_optab
->code
, mode
, op0
));
2340 /* It can't be done in this mode. Can we do it in a wider mode? */
2342 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2343 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2345 if ((abs_optab
->handlers
[(int) wider_mode
].insn_code
2346 != CODE_FOR_nothing
)
2347 || abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2351 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2353 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2357 if (class != MODE_COMPLEX_INT
)
2360 target
= gen_reg_rtx (submode
);
2361 convert_move (target
, temp
, 0);
2365 return gen_lowpart (submode
, temp
);
2368 delete_insns_since (last
);
2372 delete_insns_since (entry_last
);
2376 /* Generate an instruction whose insn-code is INSN_CODE,
2377 with two operands: an output TARGET and an input OP0.
2378 TARGET *must* be nonzero, and the output is always stored there.
2379 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2380 the value that is stored into TARGET. */
2383 emit_unop_insn (icode
, target
, op0
, code
)
2390 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2393 temp
= target
= protect_from_queue (target
, 1);
2395 op0
= protect_from_queue (op0
, 0);
2397 /* Sign and zero extension from memory is often done specially on
2398 RISC machines, so forcing into a register here can pessimize
2400 if (flag_force_mem
&& code
!= SIGN_EXTEND
&& code
!= ZERO_EXTEND
)
2401 op0
= force_not_mem (op0
);
2403 /* Now, if insn does not accept our operands, put them into pseudos. */
2405 if (! (*insn_operand_predicate
[icode
][1]) (op0
, mode0
))
2406 op0
= copy_to_mode_reg (mode0
, op0
);
2408 if (! (*insn_operand_predicate
[icode
][0]) (temp
, GET_MODE (temp
))
2409 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2410 temp
= gen_reg_rtx (GET_MODE (temp
));
2412 pat
= GEN_FCN (icode
) (temp
, op0
);
2414 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2415 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2420 emit_move_insn (target
, temp
);
2423 /* Emit code to perform a series of operations on a multi-word quantity, one
2426 Such a block is preceded by a CLOBBER of the output, consists of multiple
2427 insns, each setting one word of the output, and followed by a SET copying
2428 the output to itself.
2430 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2431 note indicating that it doesn't conflict with the (also multi-word)
2432 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2435 INSNS is a block of code generated to perform the operation, not including
2436 the CLOBBER and final copy. All insns that compute intermediate values
2437 are first emitted, followed by the block as described above.
2439 TARGET, OP0, and OP1 are the output and inputs of the operations,
2440 respectively. OP1 may be zero for a unary operation.
2442 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2445 If TARGET is not a register, INSNS is simply emitted with no special
2446 processing. Likewise if anything in INSNS is not an INSN or if
2447 there is a libcall block inside INSNS.
2449 The final insn emitted is returned. */
2452 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2458 rtx prev
, next
, first
, last
, insn
;
2460 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2461 return emit_insns (insns
);
2463 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2464 if (GET_CODE (insn
) != INSN
2465 || find_reg_note (insn
, REG_LIBCALL
, NULL_RTX
))
2466 return emit_insns (insns
);
2468 /* First emit all insns that do not store into words of the output and remove
2469 these from the list. */
2470 for (insn
= insns
; insn
; insn
= next
)
2475 next
= NEXT_INSN (insn
);
2477 if (GET_CODE (PATTERN (insn
)) == SET
)
2478 set
= PATTERN (insn
);
2479 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2481 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2482 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2484 set
= XVECEXP (PATTERN (insn
), 0, i
);
2492 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2494 if (PREV_INSN (insn
))
2495 NEXT_INSN (PREV_INSN (insn
)) = next
;
2500 PREV_INSN (next
) = PREV_INSN (insn
);
2506 prev
= get_last_insn ();
2508 /* Now write the CLOBBER of the output, followed by the setting of each
2509 of the words, followed by the final copy. */
2510 if (target
!= op0
&& target
!= op1
)
2511 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, target
));
2513 for (insn
= insns
; insn
; insn
= next
)
2515 next
= NEXT_INSN (insn
);
2518 if (op1
&& GET_CODE (op1
) == REG
)
2519 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op1
,
2522 if (op0
&& GET_CODE (op0
) == REG
)
2523 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op0
,
2527 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2528 != CODE_FOR_nothing
)
2530 last
= emit_move_insn (target
, target
);
2533 = gen_rtx (EXPR_LIST
, REG_EQUAL
, equiv
, REG_NOTES (last
));
2536 last
= get_last_insn ();
2539 first
= get_insns ();
2541 first
= NEXT_INSN (prev
);
2543 /* Encapsulate the block so it gets manipulated as a unit. */
2544 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
2546 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2551 /* Emit code to make a call to a constant function or a library call.
2553 INSNS is a list containing all insns emitted in the call.
2554 These insns leave the result in RESULT. Our block is to copy RESULT
2555 to TARGET, which is logically equivalent to EQUIV.
2557 We first emit any insns that set a pseudo on the assumption that these are
2558 loading constants into registers; doing so allows them to be safely cse'ed
2559 between blocks. Then we emit all the other insns in the block, followed by
2560 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2561 note with an operand of EQUIV.
2563 Moving assignments to pseudos outside of the block is done to improve
2564 the generated code, but is not required to generate correct code,
2565 hence being unable to move an assignment is not grounds for not making
2566 a libcall block. There are two reasons why it is safe to leave these
2567 insns inside the block: First, we know that these pseudos cannot be
2568 used in generated RTL outside the block since they are created for
2569 temporary purposes within the block. Second, CSE will not record the
2570 values of anything set inside a libcall block, so we know they must
2571 be dead at the end of the block.
2573 Except for the first group of insns (the ones setting pseudos), the
2574 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2577 emit_libcall_block (insns
, target
, result
, equiv
)
2583 rtx prev
, next
, first
, last
, insn
;
2585 /* First emit all insns that set pseudos. Remove them from the list as
2586 we go. Avoid insns that set pseudos which were referenced in previous
2587 insns. These can be generated by move_by_pieces, for example,
2588 to update an address. Similarly, avoid insns that reference things
2589 set in previous insns. */
2591 for (insn
= insns
; insn
; insn
= next
)
2593 rtx set
= single_set (insn
);
2595 next
= NEXT_INSN (insn
);
2597 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2598 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2600 || (! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
))
2601 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2602 && ! modified_in_p (SET_SRC (set
), insns
)
2603 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2605 if (PREV_INSN (insn
))
2606 NEXT_INSN (PREV_INSN (insn
)) = next
;
2611 PREV_INSN (next
) = PREV_INSN (insn
);
2617 prev
= get_last_insn ();
2619 /* Write the remaining insns followed by the final copy. */
2621 for (insn
= insns
; insn
; insn
= next
)
2623 next
= NEXT_INSN (insn
);
2628 last
= emit_move_insn (target
, result
);
2629 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2630 != CODE_FOR_nothing
)
2631 REG_NOTES (last
) = gen_rtx (EXPR_LIST
,
2632 REG_EQUAL
, copy_rtx (equiv
), REG_NOTES (last
));
2635 first
= get_insns ();
2637 first
= NEXT_INSN (prev
);
2639 /* Encapsulate the block so it gets manipulated as a unit. */
2640 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
2642 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2645 /* Generate code to store zero in X. */
2651 emit_move_insn (x
, const0_rtx
);
2654 /* Generate code to store 1 in X
2655 assuming it contains zero beforehand. */
2658 emit_0_to_1_insn (x
)
2661 emit_move_insn (x
, const1_rtx
);
2664 /* Generate code to compare X with Y
2665 so that the condition codes are set.
2667 MODE is the mode of the inputs (in case they are const_int).
2668 UNSIGNEDP nonzero says that X and Y are unsigned;
2669 this matters if they need to be widened.
2671 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2672 and ALIGN specifies the known shared alignment of X and Y.
2674 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2675 It is ignored for fixed-point and block comparisons;
2676 it is used only for floating-point comparisons. */
2679 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
2681 enum rtx_code comparison
;
2683 enum machine_mode mode
;
2687 enum mode_class
class;
2688 enum machine_mode wider_mode
;
2690 class = GET_MODE_CLASS (mode
);
2692 /* They could both be VOIDmode if both args are immediate constants,
2693 but we should fold that at an earlier stage.
2694 With no special code here, this will call abort,
2695 reminding the programmer to implement such folding. */
2697 if (mode
!= BLKmode
&& flag_force_mem
)
2699 x
= force_not_mem (x
);
2700 y
= force_not_mem (y
);
2703 /* If we are inside an appropriately-short loop and one operand is an
2704 expensive constant, force it into a register. */
2705 if (CONSTANT_P (x
) && preserve_subexpressions_p () && rtx_cost (x
, COMPARE
) > 2)
2706 x
= force_reg (mode
, x
);
2708 if (CONSTANT_P (y
) && preserve_subexpressions_p () && rtx_cost (y
, COMPARE
) > 2)
2709 y
= force_reg (mode
, y
);
2711 /* Don't let both operands fail to indicate the mode. */
2712 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
2713 x
= force_reg (mode
, x
);
2715 /* Handle all BLKmode compares. */
2717 if (mode
== BLKmode
)
2720 x
= protect_from_queue (x
, 0);
2721 y
= protect_from_queue (y
, 0);
2725 #ifdef HAVE_cmpstrqi
2727 && GET_CODE (size
) == CONST_INT
2728 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
2730 enum machine_mode result_mode
2731 = insn_operand_mode
[(int) CODE_FOR_cmpstrqi
][0];
2732 rtx result
= gen_reg_rtx (result_mode
);
2733 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, GEN_INT (align
)));
2734 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2739 #ifdef HAVE_cmpstrhi
2741 && GET_CODE (size
) == CONST_INT
2742 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
2744 enum machine_mode result_mode
2745 = insn_operand_mode
[(int) CODE_FOR_cmpstrhi
][0];
2746 rtx result
= gen_reg_rtx (result_mode
);
2747 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, GEN_INT (align
)));
2748 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2753 #ifdef HAVE_cmpstrsi
2756 enum machine_mode result_mode
2757 = insn_operand_mode
[(int) CODE_FOR_cmpstrsi
][0];
2758 rtx result
= gen_reg_rtx (result_mode
);
2759 size
= protect_from_queue (size
, 0);
2760 emit_insn (gen_cmpstrsi (result
, x
, y
,
2761 convert_to_mode (SImode
, size
, 1),
2763 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2771 #ifdef TARGET_MEM_FUNCTIONS
2772 emit_library_call (memcmp_libfunc
, 0,
2773 TYPE_MODE (integer_type_node
), 3,
2774 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2775 convert_to_mode (TYPE_MODE (sizetype
), size
,
2776 TREE_UNSIGNED (sizetype
)),
2777 TYPE_MODE (sizetype
));
2779 emit_library_call (bcmp_libfunc
, 0,
2780 TYPE_MODE (integer_type_node
), 3,
2781 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2782 convert_to_mode (TYPE_MODE (integer_type_node
),
2784 TREE_UNSIGNED (integer_type_node
)),
2785 TYPE_MODE (integer_type_node
));
2788 /* Immediately move the result of the libcall into a pseudo
2789 register so reload doesn't clobber the value if it needs
2790 the return register for a spill reg. */
2791 result
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
2792 emit_move_insn (result
,
2793 hard_libcall_value (TYPE_MODE (integer_type_node
)));
2794 emit_cmp_insn (result
,
2795 const0_rtx
, comparison
, NULL_RTX
,
2796 TYPE_MODE (integer_type_node
), 0, 0);
2801 /* Handle some compares against zero. */
2803 if (y
== CONST0_RTX (mode
)
2804 && tst_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2806 int icode
= (int) tst_optab
->handlers
[(int) mode
].insn_code
;
2809 x
= protect_from_queue (x
, 0);
2810 y
= protect_from_queue (y
, 0);
2812 /* Now, if insn does accept these operands, put them into pseudos. */
2813 if (! (*insn_operand_predicate
[icode
][0])
2814 (x
, insn_operand_mode
[icode
][0]))
2815 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2817 emit_insn (GEN_FCN (icode
) (x
));
2821 /* Handle compares for which there is a directly suitable insn. */
2823 if (cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2825 int icode
= (int) cmp_optab
->handlers
[(int) mode
].insn_code
;
2828 x
= protect_from_queue (x
, 0);
2829 y
= protect_from_queue (y
, 0);
2831 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2832 if (! (*insn_operand_predicate
[icode
][0])
2833 (x
, insn_operand_mode
[icode
][0]))
2834 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2836 if (! (*insn_operand_predicate
[icode
][1])
2837 (y
, insn_operand_mode
[icode
][1]))
2838 y
= copy_to_mode_reg (insn_operand_mode
[icode
][1], y
);
2840 emit_insn (GEN_FCN (icode
) (x
, y
));
2844 /* Try widening if we can find a direct insn that way. */
2846 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2848 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2849 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2851 if (cmp_optab
->handlers
[(int) wider_mode
].insn_code
2852 != CODE_FOR_nothing
)
2854 x
= protect_from_queue (x
, 0);
2855 y
= protect_from_queue (y
, 0);
2856 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
2857 y
= convert_modes (wider_mode
, mode
, y
, unsignedp
);
2858 emit_cmp_insn (x
, y
, comparison
, NULL_RTX
,
2859 wider_mode
, unsignedp
, align
);
2865 /* Handle a lib call just for the mode we are using. */
2867 if (cmp_optab
->handlers
[(int) mode
].libfunc
2868 && class != MODE_FLOAT
)
2870 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
2873 /* If we want unsigned, and this mode has a distinct unsigned
2874 comparison routine, use that. */
2875 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
2876 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
2878 emit_library_call (libfunc
, 1,
2879 word_mode
, 2, x
, mode
, y
, mode
);
2881 /* Immediately move the result of the libcall into a pseudo
2882 register so reload doesn't clobber the value if it needs
2883 the return register for a spill reg. */
2884 result
= gen_reg_rtx (word_mode
);
2885 emit_move_insn (result
, hard_libcall_value (word_mode
));
2887 /* Integer comparison returns a result that must be compared against 1,
2888 so that even if we do an unsigned compare afterward,
2889 there is still a value that can represent the result "less than". */
2890 emit_cmp_insn (result
, const1_rtx
,
2891 comparison
, NULL_RTX
, word_mode
, unsignedp
, 0);
2895 if (class == MODE_FLOAT
)
2896 emit_float_lib_cmp (x
, y
, comparison
);
2902 /* Nonzero if a compare of mode MODE can be done straightforwardly
2903 (without splitting it into pieces). */
2906 can_compare_p (mode
)
2907 enum machine_mode mode
;
2911 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2913 mode
= GET_MODE_WIDER_MODE (mode
);
2914 } while (mode
!= VOIDmode
);
2919 /* Emit a library call comparison between floating point X and Y.
2920 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2923 emit_float_lib_cmp (x
, y
, comparison
)
2925 enum rtx_code comparison
;
2927 enum machine_mode mode
= GET_MODE (x
);
2935 libfunc
= eqhf2_libfunc
;
2939 libfunc
= nehf2_libfunc
;
2943 libfunc
= gthf2_libfunc
;
2947 libfunc
= gehf2_libfunc
;
2951 libfunc
= lthf2_libfunc
;
2955 libfunc
= lehf2_libfunc
;
2958 else if (mode
== SFmode
)
2962 libfunc
= eqsf2_libfunc
;
2966 libfunc
= nesf2_libfunc
;
2970 libfunc
= gtsf2_libfunc
;
2974 libfunc
= gesf2_libfunc
;
2978 libfunc
= ltsf2_libfunc
;
2982 libfunc
= lesf2_libfunc
;
2985 else if (mode
== DFmode
)
2989 libfunc
= eqdf2_libfunc
;
2993 libfunc
= nedf2_libfunc
;
2997 libfunc
= gtdf2_libfunc
;
3001 libfunc
= gedf2_libfunc
;
3005 libfunc
= ltdf2_libfunc
;
3009 libfunc
= ledf2_libfunc
;
3012 else if (mode
== XFmode
)
3016 libfunc
= eqxf2_libfunc
;
3020 libfunc
= nexf2_libfunc
;
3024 libfunc
= gtxf2_libfunc
;
3028 libfunc
= gexf2_libfunc
;
3032 libfunc
= ltxf2_libfunc
;
3036 libfunc
= lexf2_libfunc
;
3039 else if (mode
== TFmode
)
3043 libfunc
= eqtf2_libfunc
;
3047 libfunc
= netf2_libfunc
;
3051 libfunc
= gttf2_libfunc
;
3055 libfunc
= getf2_libfunc
;
3059 libfunc
= lttf2_libfunc
;
3063 libfunc
= letf2_libfunc
;
3068 enum machine_mode wider_mode
;
3070 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
3071 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3073 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
3074 != CODE_FOR_nothing
)
3075 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
3077 x
= protect_from_queue (x
, 0);
3078 y
= protect_from_queue (y
, 0);
3079 x
= convert_to_mode (wider_mode
, x
, 0);
3080 y
= convert_to_mode (wider_mode
, y
, 0);
3081 emit_float_lib_cmp (x
, y
, comparison
);
3091 emit_library_call (libfunc
, 1,
3092 word_mode
, 2, x
, mode
, y
, mode
);
3094 /* Immediately move the result of the libcall into a pseudo
3095 register so reload doesn't clobber the value if it needs
3096 the return register for a spill reg. */
3097 result
= gen_reg_rtx (word_mode
);
3098 emit_move_insn (result
, hard_libcall_value (word_mode
));
3100 emit_cmp_insn (result
, const0_rtx
, comparison
,
3101 NULL_RTX
, word_mode
, 0, 0);
3104 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3107 emit_indirect_jump (loc
)
3110 if (! ((*insn_operand_predicate
[(int)CODE_FOR_indirect_jump
][0])
3112 loc
= copy_to_mode_reg (Pmode
, loc
);
3114 emit_jump_insn (gen_indirect_jump (loc
));
3118 #ifdef HAVE_conditional_move
3120 /* Emit a conditional move instruction if the machine supports one for that
3121 condition and machine mode.
3123 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3124 the mode to use should they be constants. If it is VOIDmode, they cannot
3127 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3128 should be stored there. MODE is the mode to use should they be constants.
3129 If it is VOIDmode, they cannot both be constants.
3131 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3132 is not supported. */
3135 emit_conditional_move (target
, code
, op0
, op1
, cmode
, op2
, op3
, mode
,
3140 enum machine_mode cmode
;
3142 enum machine_mode mode
;
3145 rtx tem
, subtarget
, comparison
, insn
;
3146 enum insn_code icode
;
3148 /* If one operand is constant, make it the second one. Only do this
3149 if the other operand is not constant as well. */
3151 if ((CONSTANT_P (op0
) && ! CONSTANT_P (op1
))
3152 || (GET_CODE (op0
) == CONST_INT
&& GET_CODE (op1
) != CONST_INT
))
3157 code
= swap_condition (code
);
3160 if (cmode
== VOIDmode
)
3161 cmode
= GET_MODE (op0
);
3163 if ((CONSTANT_P (op2
) && ! CONSTANT_P (op3
))
3164 || (GET_CODE (op2
) == CONST_INT
&& GET_CODE (op3
) != CONST_INT
))
3169 /* ??? This may not be appropriate (consider IEEE). Perhaps we should
3170 call can_reverse_comparison_p here and bail out if necessary.
3171 It's not clear whether we need to do this canonicalization though. */
3172 code
= reverse_condition (code
);
3175 if (mode
== VOIDmode
)
3176 mode
= GET_MODE (op2
);
3178 icode
= movcc_gen_code
[mode
];
3180 if (icode
== CODE_FOR_nothing
)
3185 op2
= force_not_mem (op2
);
3186 op3
= force_not_mem (op3
);
3190 target
= protect_from_queue (target
, 1);
3192 target
= gen_reg_rtx (mode
);
3198 op2
= protect_from_queue (op2
, 0);
3199 op3
= protect_from_queue (op3
, 0);
3201 /* If the insn doesn't accept these operands, put them in pseudos. */
3203 if (! (*insn_operand_predicate
[icode
][0])
3204 (subtarget
, insn_operand_mode
[icode
][0]))
3205 subtarget
= gen_reg_rtx (insn_operand_mode
[icode
][0]);
3207 if (! (*insn_operand_predicate
[icode
][2])
3208 (op2
, insn_operand_mode
[icode
][2]))
3209 op2
= copy_to_mode_reg (insn_operand_mode
[icode
][2], op2
);
3211 if (! (*insn_operand_predicate
[icode
][3])
3212 (op3
, insn_operand_mode
[icode
][3]))
3213 op3
= copy_to_mode_reg (insn_operand_mode
[icode
][3], op3
);
3215 /* Everything should now be in the suitable form, so emit the compare insn
3216 and then the conditional move. */
3219 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
, 0);
3221 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3222 if (GET_CODE (comparison
) != code
)
3223 /* This shouldn't happen. */
3226 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
3228 /* If that failed, then give up. */
3234 if (subtarget
!= target
)
3235 convert_move (target
, subtarget
, 0);
3240 /* Return non-zero if a conditional move of mode MODE is supported.
3242 This function is for combine so it can tell whether an insn that looks
3243 like a conditional move is actually supported by the hardware. If we
3244 guess wrong we lose a bit on optimization, but that's it. */
3245 /* ??? sparc64 supports conditionally moving integers values based on fp
3246 comparisons, and vice versa. How do we handle them? */
3249 can_conditionally_move_p (mode
)
3250 enum machine_mode mode
;
3252 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
3258 #endif /* HAVE_conditional_move */
3260 /* These three functions generate an insn body and return it
3261 rather than emitting the insn.
3263 They do not protect from queued increments,
3264 because they may be used 1) in protect_from_queue itself
3265 and 2) in other passes where there is no queue. */
3267 /* Generate and return an insn body to add Y to X. */
3270 gen_add2_insn (x
, y
)
3273 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3275 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
3276 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
3277 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
3280 return (GEN_FCN (icode
) (x
, x
, y
));
3284 have_add2_insn (mode
)
3285 enum machine_mode mode
;
3287 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3290 /* Generate and return an insn body to subtract Y from X. */
3293 gen_sub2_insn (x
, y
)
3296 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3298 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
3299 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
3300 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
3303 return (GEN_FCN (icode
) (x
, x
, y
));
3307 have_sub2_insn (mode
)
3308 enum machine_mode mode
;
3310 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3313 /* Generate the body of an instruction to copy Y into X.
3314 It may be a SEQUENCE, if one insn isn't enough. */
3317 gen_move_insn (x
, y
)
3320 register enum machine_mode mode
= GET_MODE (x
);
3321 enum insn_code insn_code
;
3324 if (mode
== VOIDmode
)
3325 mode
= GET_MODE (y
);
3327 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
3329 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3330 find a mode to do it in. If we have a movcc, use it. Otherwise,
3331 find the MODE_INT mode of the same width. */
3333 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
3335 enum machine_mode tmode
= VOIDmode
;
3339 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
3342 for (tmode
= QImode
; tmode
!= VOIDmode
;
3343 tmode
= GET_MODE_WIDER_MODE (tmode
))
3344 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
3347 if (tmode
== VOIDmode
)
3350 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3351 may call change_address which is not appropriate if we were
3352 called when a reload was in progress. We don't have to worry
3353 about changing the address since the size in bytes is supposed to
3354 be the same. Copy the MEM to change the mode and move any
3355 substitutions from the old MEM to the new one. */
3357 if (reload_in_progress
)
3359 x
= gen_lowpart_common (tmode
, x1
);
3360 if (x
== 0 && GET_CODE (x1
) == MEM
)
3362 x
= gen_rtx (MEM
, tmode
, XEXP (x1
, 0));
3363 RTX_UNCHANGING_P (x
) = RTX_UNCHANGING_P (x1
);
3364 MEM_IN_STRUCT_P (x
) = MEM_IN_STRUCT_P (x1
);
3365 MEM_VOLATILE_P (x
) = MEM_VOLATILE_P (x1
);
3366 copy_replacements (x1
, x
);
3369 y
= gen_lowpart_common (tmode
, y1
);
3370 if (y
== 0 && GET_CODE (y1
) == MEM
)
3372 y
= gen_rtx (MEM
, tmode
, XEXP (y1
, 0));
3373 RTX_UNCHANGING_P (y
) = RTX_UNCHANGING_P (y1
);
3374 MEM_IN_STRUCT_P (y
) = MEM_IN_STRUCT_P (y1
);
3375 MEM_VOLATILE_P (y
) = MEM_VOLATILE_P (y1
);
3376 copy_replacements (y1
, y
);
3381 x
= gen_lowpart (tmode
, x
);
3382 y
= gen_lowpart (tmode
, y
);
3385 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3386 return (GEN_FCN (insn_code
) (x
, y
));
3390 emit_move_insn_1 (x
, y
);
3391 seq
= gen_sequence ();
3396 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3397 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3398 no such operation exists, CODE_FOR_nothing will be returned. */
3401 can_extend_p (to_mode
, from_mode
, unsignedp
)
3402 enum machine_mode to_mode
, from_mode
;
3405 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
];
3408 /* Generate the body of an insn to extend Y (with mode MFROM)
3409 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3412 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3414 enum machine_mode mto
, mfrom
;
3417 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
]) (x
, y
));
3420 /* can_fix_p and can_float_p say whether the target machine
3421 can directly convert a given fixed point type to
3422 a given floating point type, or vice versa.
3423 The returned value is the CODE_FOR_... value to use,
3424 or CODE_FOR_nothing if these modes cannot be directly converted.
3426 *TRUNCP_PTR is set to 1 if it is necessary to output
3427 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3429 static enum insn_code
3430 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3431 enum machine_mode fltmode
, fixmode
;
3436 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
] != CODE_FOR_nothing
)
3437 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3439 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3442 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3444 return CODE_FOR_nothing
;
3447 static enum insn_code
3448 can_float_p (fltmode
, fixmode
, unsignedp
)
3449 enum machine_mode fixmode
, fltmode
;
3452 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3455 /* Generate code to convert FROM to floating point
3456 and store in TO. FROM must be fixed point and not VOIDmode.
3457 UNSIGNEDP nonzero means regard FROM as unsigned.
3458 Normally this is done by correcting the final value
3459 if it is negative. */
3462 expand_float (to
, from
, unsignedp
)
3466 enum insn_code icode
;
3467 register rtx target
= to
;
3468 enum machine_mode fmode
, imode
;
3470 /* Crash now, because we won't be able to decide which mode to use. */
3471 if (GET_MODE (from
) == VOIDmode
)
3474 /* Look for an insn to do the conversion. Do it in the specified
3475 modes if possible; otherwise convert either input, output or both to
3476 wider mode. If the integer mode is wider than the mode of FROM,
3477 we can do the conversion signed even if the input is unsigned. */
3479 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3480 imode
= GET_MODE_WIDER_MODE (imode
))
3481 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3482 fmode
= GET_MODE_WIDER_MODE (fmode
))
3484 int doing_unsigned
= unsignedp
;
3486 icode
= can_float_p (fmode
, imode
, unsignedp
);
3487 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3488 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3490 if (icode
!= CODE_FOR_nothing
)
3492 to
= protect_from_queue (to
, 1);
3493 from
= protect_from_queue (from
, 0);
3495 if (imode
!= GET_MODE (from
))
3496 from
= convert_to_mode (imode
, from
, unsignedp
);
3498 if (fmode
!= GET_MODE (to
))
3499 target
= gen_reg_rtx (fmode
);
3501 emit_unop_insn (icode
, target
, from
,
3502 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3505 convert_move (to
, target
, 0);
3510 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3512 /* Unsigned integer, and no way to convert directly.
3513 Convert as signed, then conditionally adjust the result. */
3516 rtx label
= gen_label_rtx ();
3518 REAL_VALUE_TYPE offset
;
3522 to
= protect_from_queue (to
, 1);
3523 from
= protect_from_queue (from
, 0);
3526 from
= force_not_mem (from
);
3528 /* Look for a usable floating mode FMODE wider than the source and at
3529 least as wide as the target. Using FMODE will avoid rounding woes
3530 with unsigned values greater than the signed maximum value. */
3532 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3533 fmode
= GET_MODE_WIDER_MODE (fmode
))
3534 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
3535 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
3538 if (fmode
== VOIDmode
)
3540 /* There is no such mode. Pretend the target is wide enough. */
3541 fmode
= GET_MODE (to
);
3543 /* Avoid double-rounding when TO is narrower than FROM. */
3544 if ((significand_size (fmode
) + 1)
3545 < GET_MODE_BITSIZE (GET_MODE (from
)))
3548 rtx neglabel
= gen_label_rtx ();
3550 /* Don't use TARGET if it isn't a register, is a hard register,
3551 or is the wrong mode. */
3552 if (GET_CODE (target
) != REG
3553 || REGNO (target
) < FIRST_PSEUDO_REGISTER
3554 || GET_MODE (target
) != fmode
)
3555 target
= gen_reg_rtx (fmode
);
3557 imode
= GET_MODE (from
);
3558 do_pending_stack_adjust ();
3560 /* Test whether the sign bit is set. */
3561 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, imode
, 0, 0);
3562 emit_jump_insn (gen_blt (neglabel
));
3564 /* The sign bit is not set. Convert as signed. */
3565 expand_float (target
, from
, 0);
3566 emit_jump_insn (gen_jump (label
));
3569 /* The sign bit is set.
3570 Convert to a usable (positive signed) value by shifting right
3571 one bit, while remembering if a nonzero bit was shifted
3572 out; i.e., compute (from & 1) | (from >> 1). */
3574 emit_label (neglabel
);
3575 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
3576 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3577 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
3579 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
3581 expand_float (target
, temp
, 0);
3583 /* Multiply by 2 to undo the shift above. */
3584 temp
= expand_binop (fmode
, add_optab
, target
, target
,
3585 target
, 0, OPTAB_LIB_WIDEN
);
3587 emit_move_insn (target
, temp
);
3589 do_pending_stack_adjust ();
3595 /* If we are about to do some arithmetic to correct for an
3596 unsigned operand, do it in a pseudo-register. */
3598 if (GET_MODE (to
) != fmode
3599 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
3600 target
= gen_reg_rtx (fmode
);
3602 /* Convert as signed integer to floating. */
3603 expand_float (target
, from
, 0);
3605 /* If FROM is negative (and therefore TO is negative),
3606 correct its value by 2**bitwidth. */
3608 do_pending_stack_adjust ();
3609 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3610 emit_jump_insn (gen_bge (label
));
3612 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3613 Rather than setting up a dconst_dot_5, let's hope SCO
3615 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
3616 temp
= expand_binop (fmode
, add_optab
, target
,
3617 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
3618 target
, 0, OPTAB_LIB_WIDEN
);
3620 emit_move_insn (target
, temp
);
3622 do_pending_stack_adjust ();
3628 /* No hardware instruction available; call a library routine to convert from
3629 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3635 to
= protect_from_queue (to
, 1);
3636 from
= protect_from_queue (from
, 0);
3638 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
3639 from
= convert_to_mode (SImode
, from
, unsignedp
);
3642 from
= force_not_mem (from
);
3644 if (GET_MODE (to
) == SFmode
)
3646 if (GET_MODE (from
) == SImode
)
3647 libfcn
= floatsisf_libfunc
;
3648 else if (GET_MODE (from
) == DImode
)
3649 libfcn
= floatdisf_libfunc
;
3650 else if (GET_MODE (from
) == TImode
)
3651 libfcn
= floattisf_libfunc
;
3655 else if (GET_MODE (to
) == DFmode
)
3657 if (GET_MODE (from
) == SImode
)
3658 libfcn
= floatsidf_libfunc
;
3659 else if (GET_MODE (from
) == DImode
)
3660 libfcn
= floatdidf_libfunc
;
3661 else if (GET_MODE (from
) == TImode
)
3662 libfcn
= floattidf_libfunc
;
3666 else if (GET_MODE (to
) == XFmode
)
3668 if (GET_MODE (from
) == SImode
)
3669 libfcn
= floatsixf_libfunc
;
3670 else if (GET_MODE (from
) == DImode
)
3671 libfcn
= floatdixf_libfunc
;
3672 else if (GET_MODE (from
) == TImode
)
3673 libfcn
= floattixf_libfunc
;
3677 else if (GET_MODE (to
) == TFmode
)
3679 if (GET_MODE (from
) == SImode
)
3680 libfcn
= floatsitf_libfunc
;
3681 else if (GET_MODE (from
) == DImode
)
3682 libfcn
= floatditf_libfunc
;
3683 else if (GET_MODE (from
) == TImode
)
3684 libfcn
= floattitf_libfunc
;
3693 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1,
3695 1, from
, GET_MODE (from
));
3696 insns
= get_insns ();
3699 emit_libcall_block (insns
, target
, value
,
3700 gen_rtx (FLOAT
, GET_MODE (to
), from
));
3705 /* Copy result to requested destination
3706 if we have been computing in a temp location. */
3710 if (GET_MODE (target
) == GET_MODE (to
))
3711 emit_move_insn (to
, target
);
3713 convert_move (to
, target
, 0);
3717 /* expand_fix: generate code to convert FROM to fixed point
3718 and store in TO. FROM must be floating point. */
3724 rtx temp
= gen_reg_rtx (GET_MODE (x
));
3725 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
3729 expand_fix (to
, from
, unsignedp
)
3730 register rtx to
, from
;
3733 enum insn_code icode
;
3734 register rtx target
= to
;
3735 enum machine_mode fmode
, imode
;
3739 /* We first try to find a pair of modes, one real and one integer, at
3740 least as wide as FROM and TO, respectively, in which we can open-code
3741 this conversion. If the integer mode is wider than the mode of TO,
3742 we can do the conversion either signed or unsigned. */
3744 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
3745 imode
= GET_MODE_WIDER_MODE (imode
))
3746 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3747 fmode
= GET_MODE_WIDER_MODE (fmode
))
3749 int doing_unsigned
= unsignedp
;
3751 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
3752 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
3753 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
3755 if (icode
!= CODE_FOR_nothing
)
3757 to
= protect_from_queue (to
, 1);
3758 from
= protect_from_queue (from
, 0);
3760 if (fmode
!= GET_MODE (from
))
3761 from
= convert_to_mode (fmode
, from
, 0);
3764 from
= ftruncify (from
);
3766 if (imode
!= GET_MODE (to
))
3767 target
= gen_reg_rtx (imode
);
3769 emit_unop_insn (icode
, target
, from
,
3770 doing_unsigned
? UNSIGNED_FIX
: FIX
);
3772 convert_move (to
, target
, unsignedp
);
3777 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3778 /* For an unsigned conversion, there is one more way to do it.
3779 If we have a signed conversion, we generate code that compares
3780 the real value to the largest representable positive number. If if
3781 is smaller, the conversion is done normally. Otherwise, subtract
3782 one plus the highest signed number, convert, and add it back.
3784 We only need to check all real modes, since we know we didn't find
3785 anything with a wider integer mode. */
3787 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
3788 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3789 fmode
= GET_MODE_WIDER_MODE (fmode
))
3790 /* Make sure we won't lose significant bits doing this. */
3791 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
3792 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
3796 REAL_VALUE_TYPE offset
;
3797 rtx limit
, lab1
, lab2
, insn
;
3799 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
3800 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
3801 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
3802 lab1
= gen_label_rtx ();
3803 lab2
= gen_label_rtx ();
3806 to
= protect_from_queue (to
, 1);
3807 from
= protect_from_queue (from
, 0);
3810 from
= force_not_mem (from
);
3812 if (fmode
!= GET_MODE (from
))
3813 from
= convert_to_mode (fmode
, from
, 0);
3815 /* See if we need to do the subtraction. */
3816 do_pending_stack_adjust ();
3817 emit_cmp_insn (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3818 emit_jump_insn (gen_bge (lab1
));
3820 /* If not, do the signed "fix" and branch around fixup code. */
3821 expand_fix (to
, from
, 0);
3822 emit_jump_insn (gen_jump (lab2
));
3825 /* Otherwise, subtract 2**(N-1), convert to signed number,
3826 then add 2**(N-1). Do the addition using XOR since this
3827 will often generate better code. */
3829 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
3830 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3831 expand_fix (to
, target
, 0);
3832 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
3833 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
3834 to
, 1, OPTAB_LIB_WIDEN
);
3837 emit_move_insn (to
, target
);
3841 if (mov_optab
->handlers
[(int) GET_MODE (to
)].insn_code
3842 != CODE_FOR_nothing
)
3844 /* Make a place for a REG_NOTE and add it. */
3845 insn
= emit_move_insn (to
, to
);
3846 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
3847 gen_rtx (UNSIGNED_FIX
, GET_MODE (to
),
3855 /* We can't do it with an insn, so use a library call. But first ensure
3856 that the mode of TO is at least as wide as SImode, since those are the
3857 only library calls we know about. */
3859 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
3861 target
= gen_reg_rtx (SImode
);
3863 expand_fix (target
, from
, unsignedp
);
3865 else if (GET_MODE (from
) == SFmode
)
3867 if (GET_MODE (to
) == SImode
)
3868 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
3869 else if (GET_MODE (to
) == DImode
)
3870 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
3871 else if (GET_MODE (to
) == TImode
)
3872 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
3876 else if (GET_MODE (from
) == DFmode
)
3878 if (GET_MODE (to
) == SImode
)
3879 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
3880 else if (GET_MODE (to
) == DImode
)
3881 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
3882 else if (GET_MODE (to
) == TImode
)
3883 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
3887 else if (GET_MODE (from
) == XFmode
)
3889 if (GET_MODE (to
) == SImode
)
3890 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
3891 else if (GET_MODE (to
) == DImode
)
3892 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
3893 else if (GET_MODE (to
) == TImode
)
3894 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
3898 else if (GET_MODE (from
) == TFmode
)
3900 if (GET_MODE (to
) == SImode
)
3901 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
3902 else if (GET_MODE (to
) == DImode
)
3903 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
3904 else if (GET_MODE (to
) == TImode
)
3905 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
3917 to
= protect_from_queue (to
, 1);
3918 from
= protect_from_queue (from
, 0);
3921 from
= force_not_mem (from
);
3925 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1, GET_MODE (to
),
3927 1, from
, GET_MODE (from
));
3928 insns
= get_insns ();
3931 emit_libcall_block (insns
, target
, value
,
3932 gen_rtx (unsignedp
? UNSIGNED_FIX
: FIX
,
3933 GET_MODE (to
), from
));
3938 if (GET_MODE (to
) == GET_MODE (target
))
3939 emit_move_insn (to
, target
);
3941 convert_move (to
, target
, 0);
3950 optab op
= (optab
) xmalloc (sizeof (struct optab
));
3952 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3954 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
3955 op
->handlers
[i
].libfunc
= 0;
3958 if (code
!= UNKNOWN
)
3959 code_to_optab
[(int) code
] = op
;
3964 /* Initialize the libfunc fields of an entire group of entries in some
3965 optab. Each entry is set equal to a string consisting of a leading
3966 pair of underscores followed by a generic operation name followed by
3967 a mode name (downshifted to lower case) followed by a single character
3968 representing the number of operands for the given operation (which is
3969 usually one of the characters '2', '3', or '4').
3971 OPTABLE is the table in which libfunc fields are to be initialized.
3972 FIRST_MODE is the first machine mode index in the given optab to
3974 LAST_MODE is the last machine mode index in the given optab to
3976 OPNAME is the generic (string) name of the operation.
3977 SUFFIX is the character which specifies the number of operands for
3978 the given generic operation.
3982 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
3983 register optab optable
;
3984 register int first_mode
;
3985 register int last_mode
;
3986 register char *opname
;
3987 register int suffix
;
3990 register unsigned opname_len
= strlen (opname
);
3992 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
3993 mode
= (enum machine_mode
) ((int) mode
+ 1))
3995 register char *mname
= mode_name
[(int) mode
];
3996 register unsigned mname_len
= strlen (mname
);
3997 register char *libfunc_name
3998 = (char *) xmalloc (2 + opname_len
+ mname_len
+ 1 + 1);
4005 for (q
= opname
; *q
; )
4007 for (q
= mname
; *q
; q
++)
4008 *p
++ = tolower (*q
);
4011 optable
->handlers
[(int) mode
].libfunc
4012 = gen_rtx (SYMBOL_REF
, Pmode
, libfunc_name
);
4016 /* Initialize the libfunc fields of an entire group of entries in some
4017 optab which correspond to all integer mode operations. The parameters
4018 have the same meaning as similarly named ones for the `init_libfuncs'
4019 routine. (See above). */
4022 init_integral_libfuncs (optable
, opname
, suffix
)
4023 register optab optable
;
4024 register char *opname
;
4025 register int suffix
;
4027 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
4030 /* Initialize the libfunc fields of an entire group of entries in some
4031 optab which correspond to all real mode operations. The parameters
4032 have the same meaning as similarly named ones for the `init_libfuncs'
4033 routine. (See above). */
4036 init_floating_libfuncs (optable
, opname
, suffix
)
4037 register optab optable
;
4038 register char *opname
;
4039 register int suffix
;
4041 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
4044 /* Initialize the libfunc fields of an entire group of entries in some
4045 optab which correspond to all complex floating modes. The parameters
4046 have the same meaning as similarly named ones for the `init_libfuncs'
4047 routine. (See above). */
4050 init_complex_libfuncs (optable
, opname
, suffix
)
4051 register optab optable
;
4052 register char *opname
;
4053 register int suffix
;
4055 init_libfuncs (optable
, SCmode
, TCmode
, opname
, suffix
);
4058 /* Call this once to initialize the contents of the optabs
4059 appropriately for the current target machine. */
4067 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4069 for (p
= fixtab
[0][0];
4070 p
< fixtab
[0][0] + sizeof fixtab
/ sizeof (fixtab
[0][0][0]);
4072 *p
= CODE_FOR_nothing
;
4074 for (p
= fixtrunctab
[0][0];
4075 p
< fixtrunctab
[0][0] + sizeof fixtrunctab
/ sizeof (fixtrunctab
[0][0][0]);
4077 *p
= CODE_FOR_nothing
;
4079 for (p
= floattab
[0][0];
4080 p
< floattab
[0][0] + sizeof floattab
/ sizeof (floattab
[0][0][0]);
4082 *p
= CODE_FOR_nothing
;
4084 for (p
= extendtab
[0][0];
4085 p
< extendtab
[0][0] + sizeof extendtab
/ sizeof extendtab
[0][0][0];
4087 *p
= CODE_FOR_nothing
;
4089 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
4090 setcc_gen_code
[i
] = CODE_FOR_nothing
;
4092 #ifdef HAVE_conditional_move
4093 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4094 movcc_gen_code
[i
] = CODE_FOR_nothing
;
4097 add_optab
= init_optab (PLUS
);
4098 sub_optab
= init_optab (MINUS
);
4099 smul_optab
= init_optab (MULT
);
4100 smul_highpart_optab
= init_optab (UNKNOWN
);
4101 umul_highpart_optab
= init_optab (UNKNOWN
);
4102 smul_widen_optab
= init_optab (UNKNOWN
);
4103 umul_widen_optab
= init_optab (UNKNOWN
);
4104 sdiv_optab
= init_optab (DIV
);
4105 sdivmod_optab
= init_optab (UNKNOWN
);
4106 udiv_optab
= init_optab (UDIV
);
4107 udivmod_optab
= init_optab (UNKNOWN
);
4108 smod_optab
= init_optab (MOD
);
4109 umod_optab
= init_optab (UMOD
);
4110 flodiv_optab
= init_optab (DIV
);
4111 ftrunc_optab
= init_optab (UNKNOWN
);
4112 and_optab
= init_optab (AND
);
4113 ior_optab
= init_optab (IOR
);
4114 xor_optab
= init_optab (XOR
);
4115 ashl_optab
= init_optab (ASHIFT
);
4116 ashr_optab
= init_optab (ASHIFTRT
);
4117 lshr_optab
= init_optab (LSHIFTRT
);
4118 rotl_optab
= init_optab (ROTATE
);
4119 rotr_optab
= init_optab (ROTATERT
);
4120 smin_optab
= init_optab (SMIN
);
4121 smax_optab
= init_optab (SMAX
);
4122 umin_optab
= init_optab (UMIN
);
4123 umax_optab
= init_optab (UMAX
);
4124 mov_optab
= init_optab (UNKNOWN
);
4125 movstrict_optab
= init_optab (UNKNOWN
);
4126 cmp_optab
= init_optab (UNKNOWN
);
4127 ucmp_optab
= init_optab (UNKNOWN
);
4128 tst_optab
= init_optab (UNKNOWN
);
4129 neg_optab
= init_optab (NEG
);
4130 abs_optab
= init_optab (ABS
);
4131 one_cmpl_optab
= init_optab (NOT
);
4132 ffs_optab
= init_optab (FFS
);
4133 sqrt_optab
= init_optab (SQRT
);
4134 sin_optab
= init_optab (UNKNOWN
);
4135 cos_optab
= init_optab (UNKNOWN
);
4136 strlen_optab
= init_optab (UNKNOWN
);
4138 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4140 movstr_optab
[i
] = CODE_FOR_nothing
;
4141 clrstr_optab
[i
] = CODE_FOR_nothing
;
4143 #ifdef HAVE_SECONDARY_RELOADS
4144 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
4148 /* Fill in the optabs with the insns we support. */
4151 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4152 /* This flag says the same insns that convert to a signed fixnum
4153 also convert validly to an unsigned one. */
4154 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4155 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
4156 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
4159 #ifdef EXTRA_CC_MODES
4163 /* Initialize the optabs with the names of the library functions. */
4164 init_integral_libfuncs (add_optab
, "add", '3');
4165 init_floating_libfuncs (add_optab
, "add", '3');
4166 init_integral_libfuncs (sub_optab
, "sub", '3');
4167 init_floating_libfuncs (sub_optab
, "sub", '3');
4168 init_integral_libfuncs (smul_optab
, "mul", '3');
4169 init_floating_libfuncs (smul_optab
, "mul", '3');
4170 init_integral_libfuncs (sdiv_optab
, "div", '3');
4171 init_integral_libfuncs (udiv_optab
, "udiv", '3');
4172 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
4173 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
4174 init_integral_libfuncs (smod_optab
, "mod", '3');
4175 init_integral_libfuncs (umod_optab
, "umod", '3');
4176 init_floating_libfuncs (flodiv_optab
, "div", '3');
4177 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
4178 init_integral_libfuncs (and_optab
, "and", '3');
4179 init_integral_libfuncs (ior_optab
, "ior", '3');
4180 init_integral_libfuncs (xor_optab
, "xor", '3');
4181 init_integral_libfuncs (ashl_optab
, "ashl", '3');
4182 init_integral_libfuncs (ashr_optab
, "ashr", '3');
4183 init_integral_libfuncs (lshr_optab
, "lshr", '3');
4184 init_integral_libfuncs (smin_optab
, "min", '3');
4185 init_floating_libfuncs (smin_optab
, "min", '3');
4186 init_integral_libfuncs (smax_optab
, "max", '3');
4187 init_floating_libfuncs (smax_optab
, "max", '3');
4188 init_integral_libfuncs (umin_optab
, "umin", '3');
4189 init_integral_libfuncs (umax_optab
, "umax", '3');
4190 init_integral_libfuncs (neg_optab
, "neg", '2');
4191 init_floating_libfuncs (neg_optab
, "neg", '2');
4192 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
4193 init_integral_libfuncs (ffs_optab
, "ffs", '2');
4195 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4196 init_integral_libfuncs (cmp_optab
, "cmp", '2');
4197 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
4198 init_floating_libfuncs (cmp_optab
, "cmp", '2');
4200 #ifdef MULSI3_LIBCALL
4201 smul_optab
->handlers
[(int) SImode
].libfunc
4202 = gen_rtx (SYMBOL_REF
, Pmode
, MULSI3_LIBCALL
);
4204 #ifdef MULDI3_LIBCALL
4205 smul_optab
->handlers
[(int) DImode
].libfunc
4206 = gen_rtx (SYMBOL_REF
, Pmode
, MULDI3_LIBCALL
);
4209 #ifdef DIVSI3_LIBCALL
4210 sdiv_optab
->handlers
[(int) SImode
].libfunc
4211 = gen_rtx (SYMBOL_REF
, Pmode
, DIVSI3_LIBCALL
);
4213 #ifdef DIVDI3_LIBCALL
4214 sdiv_optab
->handlers
[(int) DImode
].libfunc
4215 = gen_rtx (SYMBOL_REF
, Pmode
, DIVDI3_LIBCALL
);
4218 #ifdef UDIVSI3_LIBCALL
4219 udiv_optab
->handlers
[(int) SImode
].libfunc
4220 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVSI3_LIBCALL
);
4222 #ifdef UDIVDI3_LIBCALL
4223 udiv_optab
->handlers
[(int) DImode
].libfunc
4224 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVDI3_LIBCALL
);
4227 #ifdef MODSI3_LIBCALL
4228 smod_optab
->handlers
[(int) SImode
].libfunc
4229 = gen_rtx (SYMBOL_REF
, Pmode
, MODSI3_LIBCALL
);
4231 #ifdef MODDI3_LIBCALL
4232 smod_optab
->handlers
[(int) DImode
].libfunc
4233 = gen_rtx (SYMBOL_REF
, Pmode
, MODDI3_LIBCALL
);
4236 #ifdef UMODSI3_LIBCALL
4237 umod_optab
->handlers
[(int) SImode
].libfunc
4238 = gen_rtx (SYMBOL_REF
, Pmode
, UMODSI3_LIBCALL
);
4240 #ifdef UMODDI3_LIBCALL
4241 umod_optab
->handlers
[(int) DImode
].libfunc
4242 = gen_rtx (SYMBOL_REF
, Pmode
, UMODDI3_LIBCALL
);
4245 /* Use cabs for DC complex abs, since systems generally have cabs.
4246 Don't define any libcall for SCmode, so that cabs will be used. */
4247 abs_optab
->handlers
[(int) DCmode
].libfunc
4248 = gen_rtx (SYMBOL_REF
, Pmode
, "cabs");
4250 /* The ffs function operates on `int'. */
4251 #ifndef INT_TYPE_SIZE
4252 #define INT_TYPE_SIZE BITS_PER_WORD
4254 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)] .libfunc
4255 = gen_rtx (SYMBOL_REF
, Pmode
, "ffs");
4257 extendsfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfdf2");
4258 extendsfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfxf2");
4259 extendsftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsftf2");
4260 extenddfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddfxf2");
4261 extenddftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddftf2");
4263 truncdfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncdfsf2");
4264 truncxfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfsf2");
4265 trunctfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfsf2");
4266 truncxfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfdf2");
4267 trunctfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfdf2");
4269 memcpy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcpy");
4270 bcopy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bcopy");
4271 memcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcmp");
4272 bcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gcc_bcmp");
4273 memset_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memset");
4274 bzero_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bzero");
4276 throw_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__throw");
4277 sjthrow_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__sjthrow");
4278 sjpopnthrow_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__sjpopnthrow");
4279 terminate_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__terminate");
4280 #ifndef DONT_USE_BUILTIN_SETJMP
4281 setjmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__builtin_setjmp");
4282 longjmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__builtin_longjmp");
4284 setjmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "setjmp");
4285 longjmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "longjmp");
4287 get_dynamic_handler_chain_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__get_dynamic_handler_chain");
4289 eqhf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqhf2");
4290 nehf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nehf2");
4291 gthf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gthf2");
4292 gehf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gehf2");
4293 lthf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lthf2");
4294 lehf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lehf2");
4296 eqsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqsf2");
4297 nesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nesf2");
4298 gtsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtsf2");
4299 gesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gesf2");
4300 ltsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltsf2");
4301 lesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lesf2");
4303 eqdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqdf2");
4304 nedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nedf2");
4305 gtdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtdf2");
4306 gedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gedf2");
4307 ltdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltdf2");
4308 ledf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ledf2");
4310 eqxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqxf2");
4311 nexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nexf2");
4312 gtxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtxf2");
4313 gexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gexf2");
4314 ltxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltxf2");
4315 lexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lexf2");
4317 eqtf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqtf2");
4318 netf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__netf2");
4319 gttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gttf2");
4320 getf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__getf2");
4321 lttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lttf2");
4322 letf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__letf2");
4324 floatsisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsisf");
4325 floatdisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdisf");
4326 floattisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattisf");
4328 floatsidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsidf");
4329 floatdidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdidf");
4330 floattidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattidf");
4332 floatsixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsixf");
4333 floatdixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdixf");
4334 floattixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattixf");
4336 floatsitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsitf");
4337 floatditf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatditf");
4338 floattitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattitf");
4340 fixsfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfsi");
4341 fixsfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfdi");
4342 fixsfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfti");
4344 fixdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfsi");
4345 fixdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfdi");
4346 fixdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfti");
4348 fixxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfsi");
4349 fixxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfdi");
4350 fixxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfti");
4352 fixtfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfsi");
4353 fixtfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfdi");
4354 fixtfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfti");
4356 fixunssfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfsi");
4357 fixunssfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfdi");
4358 fixunssfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfti");
4360 fixunsdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfsi");
4361 fixunsdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfdi");
4362 fixunsdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfti");
4364 fixunsxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfsi");
4365 fixunsxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfdi");
4366 fixunsxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfti");
4368 fixunstfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfsi");
4369 fixunstfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfdi");
4370 fixunstfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfti");
4372 #ifdef INIT_TARGET_OPTABS
4373 /* Allow the target to add more libcalls or rename some, etc. */
4380 /* SCO 3.2 apparently has a broken ldexp. */
4393 #endif /* BROKEN_LDEXP */