1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92-97, 1998 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. */
27 #include "insn-flags.h"
28 #include "insn-codes.h"
30 #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
;
163 rtx floatsisf_libfunc
;
164 rtx floatdisf_libfunc
;
165 rtx floattisf_libfunc
;
167 rtx floatsidf_libfunc
;
168 rtx floatdidf_libfunc
;
169 rtx floattidf_libfunc
;
171 rtx floatsixf_libfunc
;
172 rtx floatdixf_libfunc
;
173 rtx floattixf_libfunc
;
175 rtx floatsitf_libfunc
;
176 rtx floatditf_libfunc
;
177 rtx floattitf_libfunc
;
195 rtx fixunssfsi_libfunc
;
196 rtx fixunssfdi_libfunc
;
197 rtx fixunssfti_libfunc
;
199 rtx fixunsdfsi_libfunc
;
200 rtx fixunsdfdi_libfunc
;
201 rtx fixunsdfti_libfunc
;
203 rtx fixunsxfsi_libfunc
;
204 rtx fixunsxfdi_libfunc
;
205 rtx fixunsxfti_libfunc
;
207 rtx fixunstfsi_libfunc
;
208 rtx fixunstfdi_libfunc
;
209 rtx fixunstfti_libfunc
;
211 rtx chkr_check_addr_libfunc
;
212 rtx chkr_set_right_libfunc
;
213 rtx chkr_copy_bitmap_libfunc
;
214 rtx chkr_check_exec_libfunc
;
215 rtx chkr_check_str_libfunc
;
217 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
218 gives the gen_function to make a branch to test that condition. */
220 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
222 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
223 gives the insn code to make a store-condition insn
224 to test that condition. */
226 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
228 #ifdef HAVE_conditional_move
229 /* Indexed by the machine mode, gives the insn code to make a conditional
230 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
231 setcc_gen_code to cut down on the number of named patterns. Consider a day
232 when a lot more rtx codes are conditional (eg: for the ARM). */
234 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
237 static int add_equal_note
PROTO((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
238 static rtx widen_operand
PROTO((rtx
, enum machine_mode
,
239 enum machine_mode
, int, int));
240 static enum insn_code can_fix_p
PROTO((enum machine_mode
, enum machine_mode
,
242 static enum insn_code can_float_p
PROTO((enum machine_mode
, enum machine_mode
,
244 static rtx ftruncify
PROTO((rtx
));
245 static optab init_optab
PROTO((enum rtx_code
));
246 static void init_libfuncs
PROTO((optab
, int, int, char *, int));
247 static void init_integral_libfuncs
PROTO((optab
, char *, int));
248 static void init_floating_libfuncs
PROTO((optab
, char *, int));
249 #ifdef HAVE_conditional_trap
250 static void init_traps
PROTO((void));
253 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
254 the result of operation CODE applied to OP0 (and OP1 if it is a binary
257 If the last insn does not set TARGET, don't do anything, but return 1.
259 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
260 don't add the REG_EQUAL note but return 0. Our caller can then try
261 again, ensuring that TARGET is not one of the operands. */
264 add_equal_note (seq
, target
, code
, op0
, op1
)
274 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
275 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
276 || GET_CODE (seq
) != SEQUENCE
277 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
278 || GET_CODE (target
) == ZERO_EXTRACT
279 || (! rtx_equal_p (SET_DEST (set
), target
)
280 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
282 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
283 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
287 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
288 besides the last insn. */
289 if (reg_overlap_mentioned_p (target
, op0
)
290 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
291 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
292 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
295 if (GET_RTX_CLASS (code
) == '1')
296 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
298 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
300 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))
301 = gen_rtx_EXPR_LIST (REG_EQUAL
, note
,
302 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1)));
307 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
308 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
309 not actually do a sign-extend or zero-extend, but can leave the
310 higher-order bits of the result rtx undefined, for example, in the case
311 of logical operations, but not right shifts. */
314 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
316 enum machine_mode mode
, oldmode
;
322 /* If we must extend do so. If OP is either a constant or a SUBREG
323 for a promoted object, also extend since it will be more efficient to
326 || GET_MODE (op
) == VOIDmode
327 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
328 return convert_modes (mode
, oldmode
, op
, unsignedp
);
330 /* If MODE is no wider than a single word, we return a paradoxical
332 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
333 return gen_rtx_SUBREG (mode
, force_reg (GET_MODE (op
), op
), 0);
335 /* Otherwise, get an object of MODE, clobber it, and set the low-order
338 result
= gen_reg_rtx (mode
);
339 emit_insn (gen_rtx_CLOBBER (VOIDmode
, result
));
340 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
344 /* Generate code to perform an operation specified by BINOPTAB
345 on operands OP0 and OP1, with result having machine-mode MODE.
347 UNSIGNEDP is for the case where we have to widen the operands
348 to perform the operation. It says to use zero-extension.
350 If TARGET is nonzero, the value
351 is generated there, if it is convenient to do so.
352 In all cases an rtx is returned for the locus of the value;
353 this may or may not be TARGET. */
356 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
357 enum machine_mode mode
;
362 enum optab_methods methods
;
364 enum optab_methods next_methods
365 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
366 ? OPTAB_WIDEN
: methods
);
367 enum mode_class
class;
368 enum machine_mode wider_mode
;
370 int commutative_op
= 0;
371 int shift_op
= (binoptab
->code
== ASHIFT
372 || binoptab
->code
== ASHIFTRT
373 || binoptab
->code
== LSHIFTRT
374 || binoptab
->code
== ROTATE
375 || binoptab
->code
== ROTATERT
);
376 rtx entry_last
= get_last_insn ();
379 class = GET_MODE_CLASS (mode
);
381 op0
= protect_from_queue (op0
, 0);
382 op1
= protect_from_queue (op1
, 0);
384 target
= protect_from_queue (target
, 1);
388 op0
= force_not_mem (op0
);
389 op1
= force_not_mem (op1
);
392 /* If subtracting an integer constant, convert this into an addition of
393 the negated constant. */
395 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
397 op1
= negate_rtx (mode
, op1
);
398 binoptab
= add_optab
;
401 /* If we are inside an appropriately-short loop and one operand is an
402 expensive constant, force it into a register. */
403 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
404 && rtx_cost (op0
, binoptab
->code
) > 2)
405 op0
= force_reg (mode
, op0
);
407 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
408 && ! shift_op
&& rtx_cost (op1
, binoptab
->code
) > 2)
409 op1
= force_reg (mode
, op1
);
411 /* Record where to delete back to if we backtrack. */
412 last
= get_last_insn ();
414 /* If operation is commutative,
415 try to make the first operand a register.
416 Even better, try to make it the same as the target.
417 Also try to make the last operand a constant. */
418 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
419 || binoptab
== smul_widen_optab
420 || binoptab
== umul_widen_optab
421 || binoptab
== smul_highpart_optab
422 || binoptab
== umul_highpart_optab
)
426 if (((target
== 0 || GET_CODE (target
) == REG
)
427 ? ((GET_CODE (op1
) == REG
428 && GET_CODE (op0
) != REG
)
430 : rtx_equal_p (op1
, target
))
431 || GET_CODE (op0
) == CONST_INT
)
439 /* If we can do it with a three-operand insn, do so. */
441 if (methods
!= OPTAB_MUST_WIDEN
442 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
444 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
445 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
446 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
448 rtx xop0
= op0
, xop1
= op1
;
453 temp
= gen_reg_rtx (mode
);
455 /* If it is a commutative operator and the modes would match
456 if we would swap the operands, we can save the conversions. */
459 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
460 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
464 tmp
= op0
; op0
= op1
; op1
= tmp
;
465 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
469 /* In case the insn wants input operands in modes different from
470 the result, convert the operands. */
472 if (GET_MODE (op0
) != VOIDmode
473 && GET_MODE (op0
) != mode0
474 && mode0
!= VOIDmode
)
475 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
477 if (GET_MODE (xop1
) != VOIDmode
478 && GET_MODE (xop1
) != mode1
479 && mode1
!= VOIDmode
)
480 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
482 /* Now, if insn's predicates don't allow our operands, put them into
485 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
)
486 && mode0
!= VOIDmode
)
487 xop0
= copy_to_mode_reg (mode0
, xop0
);
489 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
)
490 && mode1
!= VOIDmode
)
491 xop1
= copy_to_mode_reg (mode1
, xop1
);
493 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
494 temp
= gen_reg_rtx (mode
);
496 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
499 /* If PAT is a multi-insn sequence, try to add an appropriate
500 REG_EQUAL note to it. If we can't because TEMP conflicts with an
501 operand, call ourselves again, this time without a target. */
502 if (GET_CODE (pat
) == SEQUENCE
503 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
505 delete_insns_since (last
);
506 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
514 delete_insns_since (last
);
517 /* If this is a multiply, see if we can do a widening operation that
518 takes operands of this mode and makes a wider mode. */
520 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
521 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
522 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
523 != CODE_FOR_nothing
))
525 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
526 unsignedp
? umul_widen_optab
: smul_widen_optab
,
527 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
531 if (GET_MODE_CLASS (mode
) == MODE_INT
)
532 return gen_lowpart (mode
, temp
);
534 return convert_to_mode (mode
, temp
, unsignedp
);
538 /* Look for a wider mode of the same class for which we think we
539 can open-code the operation. Check for a widening multiply at the
540 wider mode as well. */
542 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
543 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
544 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
545 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
547 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
548 || (binoptab
== smul_optab
549 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
550 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
551 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
552 != CODE_FOR_nothing
)))
554 rtx xop0
= op0
, xop1
= op1
;
557 /* For certain integer operations, we need not actually extend
558 the narrow operands, as long as we will truncate
559 the results to the same narrowness. */
561 if ((binoptab
== ior_optab
|| binoptab
== and_optab
562 || binoptab
== xor_optab
563 || binoptab
== add_optab
|| binoptab
== sub_optab
564 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
565 && class == MODE_INT
)
568 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
570 /* The second operand of a shift must always be extended. */
571 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
572 no_extend
&& binoptab
!= ashl_optab
);
574 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
575 unsignedp
, OPTAB_DIRECT
);
578 if (class != MODE_INT
)
581 target
= gen_reg_rtx (mode
);
582 convert_move (target
, temp
, 0);
586 return gen_lowpart (mode
, temp
);
589 delete_insns_since (last
);
593 /* These can be done a word at a time. */
594 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
596 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
597 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
603 /* If TARGET is the same as one of the operands, the REG_EQUAL note
604 won't be accurate, so use a new target. */
605 if (target
== 0 || target
== op0
|| target
== op1
)
606 target
= gen_reg_rtx (mode
);
610 /* Do the actual arithmetic. */
611 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
613 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
614 rtx x
= expand_binop (word_mode
, binoptab
,
615 operand_subword_force (op0
, i
, mode
),
616 operand_subword_force (op1
, i
, mode
),
617 target_piece
, unsignedp
, next_methods
);
622 if (target_piece
!= x
)
623 emit_move_insn (target_piece
, x
);
626 insns
= get_insns ();
629 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
631 if (binoptab
->code
!= UNKNOWN
)
633 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
634 copy_rtx (op0
), copy_rtx (op1
));
638 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
643 /* Synthesize double word shifts from single word shifts. */
644 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
645 || binoptab
== ashr_optab
)
647 && GET_CODE (op1
) == CONST_INT
648 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
649 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
650 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
651 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
653 rtx insns
, inter
, equiv_value
;
654 rtx into_target
, outof_target
;
655 rtx into_input
, outof_input
;
656 int shift_count
, left_shift
, outof_word
;
658 /* If TARGET is the same as one of the operands, the REG_EQUAL note
659 won't be accurate, so use a new target. */
660 if (target
== 0 || target
== op0
|| target
== op1
)
661 target
= gen_reg_rtx (mode
);
665 shift_count
= INTVAL (op1
);
667 /* OUTOF_* is the word we are shifting bits away from, and
668 INTO_* is the word that we are shifting bits towards, thus
669 they differ depending on the direction of the shift and
672 left_shift
= binoptab
== ashl_optab
;
673 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
675 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
676 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
678 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
679 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
681 if (shift_count
>= BITS_PER_WORD
)
683 inter
= expand_binop (word_mode
, binoptab
,
685 GEN_INT (shift_count
- BITS_PER_WORD
),
686 into_target
, unsignedp
, next_methods
);
688 if (inter
!= 0 && inter
!= into_target
)
689 emit_move_insn (into_target
, inter
);
691 /* For a signed right shift, we must fill the word we are shifting
692 out of with copies of the sign bit. Otherwise it is zeroed. */
693 if (inter
!= 0 && binoptab
!= ashr_optab
)
694 inter
= CONST0_RTX (word_mode
);
696 inter
= expand_binop (word_mode
, binoptab
,
698 GEN_INT (BITS_PER_WORD
- 1),
699 outof_target
, unsignedp
, next_methods
);
701 if (inter
!= 0 && inter
!= outof_target
)
702 emit_move_insn (outof_target
, inter
);
707 optab reverse_unsigned_shift
, unsigned_shift
;
709 /* For a shift of less then BITS_PER_WORD, to compute the carry,
710 we must do a logical shift in the opposite direction of the
713 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
715 /* For a shift of less than BITS_PER_WORD, to compute the word
716 shifted towards, we need to unsigned shift the orig value of
719 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
721 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
723 GEN_INT (BITS_PER_WORD
- shift_count
),
724 0, unsignedp
, next_methods
);
729 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
730 op1
, 0, unsignedp
, next_methods
);
733 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
734 into_target
, unsignedp
, next_methods
);
736 if (inter
!= 0 && inter
!= into_target
)
737 emit_move_insn (into_target
, inter
);
740 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
741 op1
, outof_target
, unsignedp
, next_methods
);
743 if (inter
!= 0 && inter
!= outof_target
)
744 emit_move_insn (outof_target
, inter
);
747 insns
= get_insns ();
752 if (binoptab
->code
!= UNKNOWN
)
753 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
757 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
762 /* Synthesize double word rotates from single word shifts. */
763 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
765 && GET_CODE (op1
) == CONST_INT
766 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
767 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
768 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
770 rtx insns
, equiv_value
;
771 rtx into_target
, outof_target
;
772 rtx into_input
, outof_input
;
774 int shift_count
, left_shift
, outof_word
;
776 /* If TARGET is the same as one of the operands, the REG_EQUAL note
777 won't be accurate, so use a new target. */
778 if (target
== 0 || target
== op0
|| target
== op1
)
779 target
= gen_reg_rtx (mode
);
783 shift_count
= INTVAL (op1
);
785 /* OUTOF_* is the word we are shifting bits away from, and
786 INTO_* is the word that we are shifting bits towards, thus
787 they differ depending on the direction of the shift and
790 left_shift
= (binoptab
== rotl_optab
);
791 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
793 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
794 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
796 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
797 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
799 if (shift_count
== BITS_PER_WORD
)
801 /* This is just a word swap. */
802 emit_move_insn (outof_target
, into_input
);
803 emit_move_insn (into_target
, outof_input
);
808 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
809 rtx first_shift_count
, second_shift_count
;
810 optab reverse_unsigned_shift
, unsigned_shift
;
812 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
813 ? lshr_optab
: ashl_optab
);
815 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
816 ? ashl_optab
: lshr_optab
);
818 if (shift_count
> BITS_PER_WORD
)
820 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
821 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
825 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
826 second_shift_count
= GEN_INT (shift_count
);
829 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
830 outof_input
, first_shift_count
,
831 NULL_RTX
, unsignedp
, next_methods
);
832 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
833 into_input
, second_shift_count
,
834 into_target
, unsignedp
, next_methods
);
836 if (into_temp1
!= 0 && into_temp2
!= 0)
837 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
838 into_target
, unsignedp
, next_methods
);
842 if (inter
!= 0 && inter
!= into_target
)
843 emit_move_insn (into_target
, inter
);
845 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
846 into_input
, first_shift_count
,
847 NULL_RTX
, unsignedp
, next_methods
);
848 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
849 outof_input
, second_shift_count
,
850 outof_target
, unsignedp
, next_methods
);
852 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
853 inter
= expand_binop (word_mode
, ior_optab
,
854 outof_temp1
, outof_temp2
,
855 outof_target
, unsignedp
, next_methods
);
857 if (inter
!= 0 && inter
!= outof_target
)
858 emit_move_insn (outof_target
, inter
);
861 insns
= get_insns ();
866 if (binoptab
->code
!= UNKNOWN
)
867 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
871 /* We can't make this a no conflict block if this is a word swap,
872 because the word swap case fails if the input and output values
873 are in the same register. */
874 if (shift_count
!= BITS_PER_WORD
)
875 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
884 /* These can be done a word at a time by propagating carries. */
885 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
887 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
888 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
891 rtx carry_tmp
= gen_reg_rtx (word_mode
);
892 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
893 int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
894 rtx carry_in
, carry_out
;
897 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
898 value is one of those, use it. Otherwise, use 1 since it is the
899 one easiest to get. */
900 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
901 int normalizep
= STORE_FLAG_VALUE
;
906 /* Prepare the operands. */
907 xop0
= force_reg (mode
, op0
);
908 xop1
= force_reg (mode
, op1
);
910 if (target
== 0 || GET_CODE (target
) != REG
911 || target
== xop0
|| target
== xop1
)
912 target
= gen_reg_rtx (mode
);
914 /* Indicate for flow that the entire target reg is being set. */
915 if (GET_CODE (target
) == REG
)
916 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
918 /* Do the actual arithmetic. */
919 for (i
= 0; i
< nwords
; i
++)
921 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
922 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
923 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
924 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
927 /* Main add/subtract of the input operands. */
928 x
= expand_binop (word_mode
, binoptab
,
929 op0_piece
, op1_piece
,
930 target_piece
, unsignedp
, next_methods
);
936 /* Store carry from main add/subtract. */
937 carry_out
= gen_reg_rtx (word_mode
);
938 carry_out
= emit_store_flag_force (carry_out
,
939 (binoptab
== add_optab
942 word_mode
, 1, normalizep
);
947 /* Add/subtract previous carry to main result. */
948 x
= expand_binop (word_mode
,
949 normalizep
== 1 ? binoptab
: otheroptab
,
951 target_piece
, 1, next_methods
);
954 else if (target_piece
!= x
)
955 emit_move_insn (target_piece
, x
);
959 /* THIS CODE HAS NOT BEEN TESTED. */
960 /* Get out carry from adding/subtracting carry in. */
961 carry_tmp
= emit_store_flag_force (carry_tmp
,
962 binoptab
== add_optab
965 word_mode
, 1, normalizep
);
967 /* Logical-ior the two poss. carry together. */
968 carry_out
= expand_binop (word_mode
, ior_optab
,
969 carry_out
, carry_tmp
,
970 carry_out
, 0, next_methods
);
976 carry_in
= carry_out
;
979 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
981 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
983 rtx temp
= emit_move_insn (target
, target
);
986 = gen_rtx_EXPR_LIST (REG_EQUAL
,
987 gen_rtx_fmt_ee (binoptab
->code
, mode
,
995 delete_insns_since (last
);
998 /* If we want to multiply two two-word values and have normal and widening
999 multiplies of single-word values, we can do this with three smaller
1000 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1001 because we are not operating on one word at a time.
1003 The multiplication proceeds as follows:
1004 _______________________
1005 [__op0_high_|__op0_low__]
1006 _______________________
1007 * [__op1_high_|__op1_low__]
1008 _______________________________________________
1009 _______________________
1010 (1) [__op0_low__*__op1_low__]
1011 _______________________
1012 (2a) [__op0_low__*__op1_high_]
1013 _______________________
1014 (2b) [__op0_high_*__op1_low__]
1015 _______________________
1016 (3) [__op0_high_*__op1_high_]
1019 This gives a 4-word result. Since we are only interested in the
1020 lower 2 words, partial result (3) and the upper words of (2a) and
1021 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1022 calculated using non-widening multiplication.
1024 (1), however, needs to be calculated with an unsigned widening
1025 multiplication. If this operation is not directly supported we
1026 try using a signed widening multiplication and adjust the result.
1027 This adjustment works as follows:
1029 If both operands are positive then no adjustment is needed.
1031 If the operands have different signs, for example op0_low < 0 and
1032 op1_low >= 0, the instruction treats the most significant bit of
1033 op0_low as a sign bit instead of a bit with significance
1034 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1035 with 2**BITS_PER_WORD - op0_low, and two's complements the
1036 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1039 Similarly, if both operands are negative, we need to add
1040 (op0_low + op1_low) * 2**BITS_PER_WORD.
1042 We use a trick to adjust quickly. We logically shift op0_low right
1043 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1044 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1045 logical shift exists, we do an arithmetic right shift and subtract
1048 if (binoptab
== smul_optab
1049 && class == MODE_INT
1050 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1051 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1052 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1053 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1054 != CODE_FOR_nothing
)
1055 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1056 != CODE_FOR_nothing
)))
1058 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1059 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1060 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1061 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1062 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1063 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1068 /* If the target is the same as one of the inputs, don't use it. This
1069 prevents problems with the REG_EQUAL note. */
1070 if (target
== op0
|| target
== op1
1071 || (target
!= 0 && GET_CODE (target
) != REG
))
1074 /* Multiply the two lower words to get a double-word product.
1075 If unsigned widening multiplication is available, use that;
1076 otherwise use the signed form and compensate. */
1078 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1080 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1081 target
, 1, OPTAB_DIRECT
);
1083 /* If we didn't succeed, delete everything we did so far. */
1085 delete_insns_since (last
);
1087 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1091 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1092 != CODE_FOR_nothing
)
1094 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1095 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1096 target
, 1, OPTAB_DIRECT
);
1097 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1098 NULL_RTX
, 1, next_methods
);
1100 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1101 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1104 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1105 NULL_RTX
, 0, next_methods
);
1107 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1108 op0_xhigh
, op0_xhigh
, 0,
1112 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1113 NULL_RTX
, 1, next_methods
);
1115 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1116 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1119 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1120 NULL_RTX
, 0, next_methods
);
1122 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1123 op1_xhigh
, op1_xhigh
, 0,
1128 /* If we have been able to directly compute the product of the
1129 low-order words of the operands and perform any required adjustments
1130 of the operands, we proceed by trying two more multiplications
1131 and then computing the appropriate sum.
1133 We have checked above that the required addition is provided.
1134 Full-word addition will normally always succeed, especially if
1135 it is provided at all, so we don't worry about its failure. The
1136 multiplication may well fail, however, so we do handle that. */
1138 if (product
&& op0_xhigh
&& op1_xhigh
)
1140 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1141 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1142 NULL_RTX
, 0, OPTAB_DIRECT
);
1145 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1146 product_high
, 0, next_methods
);
1148 if (temp
!= 0 && temp
!= product_high
)
1149 emit_move_insn (product_high
, temp
);
1152 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1153 NULL_RTX
, 0, OPTAB_DIRECT
);
1156 temp
= expand_binop (word_mode
, add_optab
, temp
,
1157 product_high
, product_high
,
1160 if (temp
!= 0 && temp
!= product_high
)
1161 emit_move_insn (product_high
, temp
);
1165 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1167 temp
= emit_move_insn (product
, product
);
1169 = gen_rtx_EXPR_LIST (REG_EQUAL
,
1170 gen_rtx_fmt_ee (MULT
, mode
,
1179 /* If we get here, we couldn't do it for some reason even though we
1180 originally thought we could. Delete anything we've emitted in
1183 delete_insns_since (last
);
1186 /* We need to open-code the complex type operations: '+, -, * and /' */
1188 /* At this point we allow operations between two similar complex
1189 numbers, and also if one of the operands is not a complex number
1190 but rather of MODE_FLOAT or MODE_INT. However, the caller
1191 must make sure that the MODE of the non-complex operand matches
1192 the SUBMODE of the complex operand. */
1194 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1196 rtx real0
= 0, imag0
= 0;
1197 rtx real1
= 0, imag1
= 0;
1198 rtx realr
, imagr
, res
;
1203 /* Find the correct mode for the real and imaginary parts */
1204 enum machine_mode submode
1205 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1206 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1209 if (submode
== BLKmode
)
1213 target
= gen_reg_rtx (mode
);
1217 realr
= gen_realpart (submode
, target
);
1218 imagr
= gen_imagpart (submode
, target
);
1220 if (GET_MODE (op0
) == mode
)
1222 real0
= gen_realpart (submode
, op0
);
1223 imag0
= gen_imagpart (submode
, op0
);
1228 if (GET_MODE (op1
) == mode
)
1230 real1
= gen_realpart (submode
, op1
);
1231 imag1
= gen_imagpart (submode
, op1
);
1236 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1239 switch (binoptab
->code
)
1242 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1244 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1245 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1246 realr
, unsignedp
, methods
);
1250 else if (res
!= realr
)
1251 emit_move_insn (realr
, res
);
1254 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1255 imagr
, unsignedp
, methods
);
1258 else if (binoptab
->code
== MINUS
)
1259 res
= expand_unop (submode
, neg_optab
, imag1
, imagr
, unsignedp
);
1265 else if (res
!= imagr
)
1266 emit_move_insn (imagr
, res
);
1272 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1278 /* Don't fetch these from memory more than once. */
1279 real0
= force_reg (submode
, real0
);
1280 real1
= force_reg (submode
, real1
);
1281 imag0
= force_reg (submode
, imag0
);
1282 imag1
= force_reg (submode
, imag1
);
1284 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1285 unsignedp
, methods
);
1287 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1288 unsignedp
, methods
);
1290 if (temp1
== 0 || temp2
== 0)
1293 res
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1294 realr
, unsignedp
, methods
);
1298 else if (res
!= realr
)
1299 emit_move_insn (realr
, res
);
1301 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1302 NULL_RTX
, unsignedp
, methods
);
1304 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1305 NULL_RTX
, unsignedp
, methods
);
1307 if (temp1
== 0 || temp2
== 0)
1310 res
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1311 imagr
, unsignedp
, methods
);
1315 else if (res
!= imagr
)
1316 emit_move_insn (imagr
, res
);
1322 /* Don't fetch these from memory more than once. */
1323 real0
= force_reg (submode
, real0
);
1324 real1
= force_reg (submode
, real1
);
1326 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1327 realr
, unsignedp
, methods
);
1330 else if (res
!= realr
)
1331 emit_move_insn (realr
, res
);
1334 res
= expand_binop (submode
, binoptab
,
1335 real1
, imag0
, imagr
, unsignedp
, methods
);
1337 res
= expand_binop (submode
, binoptab
,
1338 real0
, imag1
, imagr
, unsignedp
, methods
);
1342 else if (res
!= imagr
)
1343 emit_move_insn (imagr
, res
);
1350 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1354 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1356 /* Don't fetch these from memory more than once. */
1357 real1
= force_reg (submode
, real1
);
1359 /* Simply divide the real and imaginary parts by `c' */
1360 if (class == MODE_COMPLEX_FLOAT
)
1361 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1362 realr
, unsignedp
, methods
);
1364 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1365 real0
, real1
, realr
, unsignedp
);
1369 else if (res
!= realr
)
1370 emit_move_insn (realr
, res
);
1372 if (class == MODE_COMPLEX_FLOAT
)
1373 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1374 imagr
, unsignedp
, methods
);
1376 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1377 imag0
, real1
, imagr
, unsignedp
);
1381 else if (res
!= imagr
)
1382 emit_move_insn (imagr
, res
);
1388 /* Divisor is of complex type:
1394 /* Don't fetch these from memory more than once. */
1395 real0
= force_reg (submode
, real0
);
1396 real1
= force_reg (submode
, real1
);
1399 imag0
= force_reg (submode
, imag0
);
1401 imag1
= force_reg (submode
, imag1
);
1403 /* Divisor: c*c + d*d */
1404 temp1
= expand_binop (submode
, smul_optab
, real1
, real1
,
1405 NULL_RTX
, unsignedp
, methods
);
1407 temp2
= expand_binop (submode
, smul_optab
, imag1
, imag1
,
1408 NULL_RTX
, unsignedp
, methods
);
1410 if (temp1
== 0 || temp2
== 0)
1413 divisor
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1414 NULL_RTX
, unsignedp
, methods
);
1420 /* ((a)(c-id))/divisor */
1421 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1423 /* Calculate the dividend */
1424 real_t
= expand_binop (submode
, smul_optab
, real0
, real1
,
1425 NULL_RTX
, unsignedp
, methods
);
1427 imag_t
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1428 NULL_RTX
, unsignedp
, methods
);
1430 if (real_t
== 0 || imag_t
== 0)
1433 imag_t
= expand_unop (submode
, neg_optab
, imag_t
,
1434 NULL_RTX
, unsignedp
);
1438 /* ((a+ib)(c-id))/divider */
1439 /* Calculate the dividend */
1440 temp1
= expand_binop (submode
, smul_optab
, real0
, real1
,
1441 NULL_RTX
, unsignedp
, methods
);
1443 temp2
= expand_binop (submode
, smul_optab
, imag0
, imag1
,
1444 NULL_RTX
, unsignedp
, methods
);
1446 if (temp1
== 0 || temp2
== 0)
1449 real_t
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1450 NULL_RTX
, unsignedp
, methods
);
1452 temp1
= expand_binop (submode
, smul_optab
, imag0
, real1
,
1453 NULL_RTX
, unsignedp
, methods
);
1455 temp2
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1456 NULL_RTX
, unsignedp
, methods
);
1458 if (temp1
== 0 || temp2
== 0)
1461 imag_t
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1462 NULL_RTX
, unsignedp
, methods
);
1464 if (real_t
== 0 || imag_t
== 0)
1468 if (class == MODE_COMPLEX_FLOAT
)
1469 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
1470 realr
, unsignedp
, methods
);
1472 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1473 real_t
, divisor
, realr
, unsignedp
);
1477 else if (res
!= realr
)
1478 emit_move_insn (realr
, res
);
1480 if (class == MODE_COMPLEX_FLOAT
)
1481 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
1482 imagr
, unsignedp
, methods
);
1484 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1485 imag_t
, divisor
, imagr
, unsignedp
);
1489 else if (res
!= imagr
)
1490 emit_move_insn (imagr
, res
);
1505 if (binoptab
->code
!= UNKNOWN
)
1507 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
1508 copy_rtx (op0
), copy_rtx (op1
));
1512 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1518 /* It can't be open-coded in this mode.
1519 Use a library call if one is available and caller says that's ok. */
1521 if (binoptab
->handlers
[(int) mode
].libfunc
1522 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1526 enum machine_mode op1_mode
= mode
;
1533 op1_mode
= word_mode
;
1534 /* Specify unsigned here,
1535 since negative shift counts are meaningless. */
1536 op1x
= convert_to_mode (word_mode
, op1
, 1);
1539 if (GET_MODE (op0
) != VOIDmode
1540 && GET_MODE (op0
) != mode
)
1541 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1543 /* Pass 1 for NO_QUEUE so we don't lose any increments
1544 if the libcall is cse'd or moved. */
1545 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1546 NULL_RTX
, 1, mode
, 2,
1547 op0
, mode
, op1x
, op1_mode
);
1549 insns
= get_insns ();
1552 target
= gen_reg_rtx (mode
);
1553 emit_libcall_block (insns
, target
, value
,
1554 gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
));
1559 delete_insns_since (last
);
1561 /* It can't be done in this mode. Can we do it in a wider mode? */
1563 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1564 || methods
== OPTAB_MUST_WIDEN
))
1566 /* Caller says, don't even try. */
1567 delete_insns_since (entry_last
);
1571 /* Compute the value of METHODS to pass to recursive calls.
1572 Don't allow widening to be tried recursively. */
1574 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1576 /* Look for a wider mode of the same class for which it appears we can do
1579 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1581 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1582 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1584 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1585 != CODE_FOR_nothing
)
1586 || (methods
== OPTAB_LIB
1587 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1589 rtx xop0
= op0
, xop1
= op1
;
1592 /* For certain integer operations, we need not actually extend
1593 the narrow operands, as long as we will truncate
1594 the results to the same narrowness. */
1596 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1597 || binoptab
== xor_optab
1598 || binoptab
== add_optab
|| binoptab
== sub_optab
1599 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1600 && class == MODE_INT
)
1603 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1604 unsignedp
, no_extend
);
1606 /* The second operand of a shift must always be extended. */
1607 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1608 no_extend
&& binoptab
!= ashl_optab
);
1610 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1611 unsignedp
, methods
);
1614 if (class != MODE_INT
)
1617 target
= gen_reg_rtx (mode
);
1618 convert_move (target
, temp
, 0);
1622 return gen_lowpart (mode
, temp
);
1625 delete_insns_since (last
);
1630 delete_insns_since (entry_last
);
1634 /* Expand a binary operator which has both signed and unsigned forms.
1635 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1638 If we widen unsigned operands, we may use a signed wider operation instead
1639 of an unsigned wider operation, since the result would be the same. */
1642 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1643 enum machine_mode mode
;
1644 optab uoptab
, soptab
;
1645 rtx op0
, op1
, target
;
1647 enum optab_methods methods
;
1650 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1651 struct optab wide_soptab
;
1653 /* Do it without widening, if possible. */
1654 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1655 unsignedp
, OPTAB_DIRECT
);
1656 if (temp
|| methods
== OPTAB_DIRECT
)
1659 /* Try widening to a signed int. Make a fake signed optab that
1660 hides any signed insn for direct use. */
1661 wide_soptab
= *soptab
;
1662 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1663 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1665 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1666 unsignedp
, OPTAB_WIDEN
);
1668 /* For unsigned operands, try widening to an unsigned int. */
1669 if (temp
== 0 && unsignedp
)
1670 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1671 unsignedp
, OPTAB_WIDEN
);
1672 if (temp
|| methods
== OPTAB_WIDEN
)
1675 /* Use the right width lib call if that exists. */
1676 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1677 if (temp
|| methods
== OPTAB_LIB
)
1680 /* Must widen and use a lib call, use either signed or unsigned. */
1681 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1682 unsignedp
, methods
);
1686 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1687 unsignedp
, methods
);
1691 /* Generate code to perform an operation specified by BINOPTAB
1692 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1693 We assume that the order of the operands for the instruction
1694 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1695 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1697 Either TARG0 or TARG1 may be zero, but what that means is that
1698 the result is not actually wanted. We will generate it into
1699 a dummy pseudo-reg and discard it. They may not both be zero.
1701 Returns 1 if this operation can be performed; 0 if not. */
1704 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1710 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1711 enum mode_class
class;
1712 enum machine_mode wider_mode
;
1713 rtx entry_last
= get_last_insn ();
1716 class = GET_MODE_CLASS (mode
);
1718 op0
= protect_from_queue (op0
, 0);
1719 op1
= protect_from_queue (op1
, 0);
1723 op0
= force_not_mem (op0
);
1724 op1
= force_not_mem (op1
);
1727 /* If we are inside an appropriately-short loop and one operand is an
1728 expensive constant, force it into a register. */
1729 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1730 && rtx_cost (op0
, binoptab
->code
) > 2)
1731 op0
= force_reg (mode
, op0
);
1733 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1734 && rtx_cost (op1
, binoptab
->code
) > 2)
1735 op1
= force_reg (mode
, op1
);
1738 targ0
= protect_from_queue (targ0
, 1);
1740 targ0
= gen_reg_rtx (mode
);
1742 targ1
= protect_from_queue (targ1
, 1);
1744 targ1
= gen_reg_rtx (mode
);
1746 /* Record where to go back to if we fail. */
1747 last
= get_last_insn ();
1749 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1751 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1752 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1753 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
1755 rtx xop0
= op0
, xop1
= op1
;
1757 /* In case this insn wants input operands in modes different from the
1758 result, convert the operands. */
1759 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1760 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1762 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1763 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1765 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1766 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1767 xop0
= copy_to_mode_reg (mode0
, xop0
);
1769 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
1770 xop1
= copy_to_mode_reg (mode1
, xop1
);
1772 /* We could handle this, but we should always be called with a pseudo
1773 for our targets and all insns should take them as outputs. */
1774 if (! (*insn_operand_predicate
[icode
][0]) (targ0
, mode
)
1775 || ! (*insn_operand_predicate
[icode
][3]) (targ1
, mode
))
1778 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1785 delete_insns_since (last
);
1788 /* It can't be done in this mode. Can we do it in a wider mode? */
1790 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1792 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1793 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1795 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1796 != CODE_FOR_nothing
)
1798 register rtx t0
= gen_reg_rtx (wider_mode
);
1799 register rtx t1
= gen_reg_rtx (wider_mode
);
1801 if (expand_twoval_binop (binoptab
,
1802 convert_modes (wider_mode
, mode
, op0
,
1804 convert_modes (wider_mode
, mode
, op1
,
1808 convert_move (targ0
, t0
, unsignedp
);
1809 convert_move (targ1
, t1
, unsignedp
);
1813 delete_insns_since (last
);
1818 delete_insns_since (entry_last
);
1822 /* Generate code to perform an operation specified by UNOPTAB
1823 on operand OP0, with result having machine-mode MODE.
1825 UNSIGNEDP is for the case where we have to widen the operands
1826 to perform the operation. It says to use zero-extension.
1828 If TARGET is nonzero, the value
1829 is generated there, if it is convenient to do so.
1830 In all cases an rtx is returned for the locus of the value;
1831 this may or may not be TARGET. */
1834 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
1835 enum machine_mode mode
;
1841 enum mode_class
class;
1842 enum machine_mode wider_mode
;
1844 rtx last
= get_last_insn ();
1847 class = GET_MODE_CLASS (mode
);
1849 op0
= protect_from_queue (op0
, 0);
1853 op0
= force_not_mem (op0
);
1857 target
= protect_from_queue (target
, 1);
1859 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1861 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
1862 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1868 temp
= gen_reg_rtx (mode
);
1870 if (GET_MODE (xop0
) != VOIDmode
1871 && GET_MODE (xop0
) != mode0
)
1872 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1874 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1876 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1877 xop0
= copy_to_mode_reg (mode0
, xop0
);
1879 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
1880 temp
= gen_reg_rtx (mode
);
1882 pat
= GEN_FCN (icode
) (temp
, xop0
);
1885 if (GET_CODE (pat
) == SEQUENCE
1886 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
1888 delete_insns_since (last
);
1889 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
1897 delete_insns_since (last
);
1900 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1902 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1903 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1904 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1906 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
1910 /* For certain operations, we need not actually extend
1911 the narrow operand, as long as we will truncate the
1912 results to the same narrowness. */
1914 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
1915 (unoptab
== neg_optab
1916 || unoptab
== one_cmpl_optab
)
1917 && class == MODE_INT
);
1919 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
1924 if (class != MODE_INT
)
1927 target
= gen_reg_rtx (mode
);
1928 convert_move (target
, temp
, 0);
1932 return gen_lowpart (mode
, temp
);
1935 delete_insns_since (last
);
1939 /* These can be done a word at a time. */
1940 if (unoptab
== one_cmpl_optab
1941 && class == MODE_INT
1942 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1943 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1948 if (target
== 0 || target
== op0
)
1949 target
= gen_reg_rtx (mode
);
1953 /* Do the actual arithmetic. */
1954 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1956 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1957 rtx x
= expand_unop (word_mode
, unoptab
,
1958 operand_subword_force (op0
, i
, mode
),
1959 target_piece
, unsignedp
);
1960 if (target_piece
!= x
)
1961 emit_move_insn (target_piece
, x
);
1964 insns
= get_insns ();
1967 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
1968 gen_rtx_fmt_e (unoptab
->code
, mode
,
1973 /* Open-code the complex negation operation. */
1974 else if (unoptab
== neg_optab
1975 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
1981 /* Find the correct mode for the real and imaginary parts */
1982 enum machine_mode submode
1983 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1984 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1987 if (submode
== BLKmode
)
1991 target
= gen_reg_rtx (mode
);
1995 target_piece
= gen_imagpart (submode
, target
);
1996 x
= expand_unop (submode
, unoptab
,
1997 gen_imagpart (submode
, op0
),
1998 target_piece
, unsignedp
);
1999 if (target_piece
!= x
)
2000 emit_move_insn (target_piece
, x
);
2002 target_piece
= gen_realpart (submode
, target
);
2003 x
= expand_unop (submode
, unoptab
,
2004 gen_realpart (submode
, op0
),
2005 target_piece
, unsignedp
);
2006 if (target_piece
!= x
)
2007 emit_move_insn (target_piece
, x
);
2012 emit_no_conflict_block (seq
, target
, op0
, 0,
2013 gen_rtx_fmt_e (unoptab
->code
, mode
,
2018 /* Now try a library call in this mode. */
2019 if (unoptab
->handlers
[(int) mode
].libfunc
)
2026 /* Pass 1 for NO_QUEUE so we don't lose any increments
2027 if the libcall is cse'd or moved. */
2028 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
2029 NULL_RTX
, 1, mode
, 1, op0
, mode
);
2030 insns
= get_insns ();
2033 target
= gen_reg_rtx (mode
);
2034 emit_libcall_block (insns
, target
, value
,
2035 gen_rtx_fmt_e (unoptab
->code
, mode
, op0
));
2040 /* It can't be done in this mode. Can we do it in a wider mode? */
2042 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2044 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2045 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2047 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
2048 != CODE_FOR_nothing
)
2049 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
2053 /* For certain operations, we need not actually extend
2054 the narrow operand, as long as we will truncate the
2055 results to the same narrowness. */
2057 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2058 (unoptab
== neg_optab
2059 || unoptab
== one_cmpl_optab
)
2060 && class == MODE_INT
);
2062 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2067 if (class != MODE_INT
)
2070 target
= gen_reg_rtx (mode
);
2071 convert_move (target
, temp
, 0);
2075 return gen_lowpart (mode
, temp
);
2078 delete_insns_since (last
);
2083 /* If there is no negate operation, try doing a subtract from zero.
2084 The US Software GOFAST library needs this. */
2085 if (unoptab
== neg_optab
)
2088 temp
= expand_binop (mode
, sub_optab
, CONST0_RTX (mode
), op0
,
2089 target
, unsignedp
, OPTAB_LIB_WIDEN
);
2097 /* Emit code to compute the absolute value of OP0, with result to
2098 TARGET if convenient. (TARGET may be 0.) The return value says
2099 where the result actually is to be found.
2101 MODE is the mode of the operand; the mode of the result is
2102 different but can be deduced from MODE.
2104 UNSIGNEDP is relevant if extension is needed. */
2107 expand_abs (mode
, op0
, target
, unsignedp
, safe
)
2108 enum machine_mode mode
;
2116 /* First try to do it with a special abs instruction. */
2117 temp
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
2121 /* If this machine has expensive jumps, we can do integer absolute
2122 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2123 where W is the width of MODE. */
2125 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
2127 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
2128 size_int (GET_MODE_BITSIZE (mode
) - 1),
2131 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
2134 temp
= expand_binop (mode
, sub_optab
, temp
, extended
, target
, 0,
2141 /* If that does not win, use conditional jump and negate. */
2143 /* It is safe to use the target if it is the same
2144 as the source if this is also a pseudo register */
2145 if (op0
== target
&& GET_CODE (op0
) == REG
2146 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
2149 op1
= gen_label_rtx ();
2150 if (target
== 0 || ! safe
2151 || GET_MODE (target
) != mode
2152 || (GET_CODE (target
) == MEM
&& MEM_VOLATILE_P (target
))
2153 || (GET_CODE (target
) == REG
2154 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
2155 target
= gen_reg_rtx (mode
);
2157 emit_move_insn (target
, op0
);
2160 /* If this mode is an integer too wide to compare properly,
2161 compare word by word. Rely on CSE to optimize constant cases. */
2162 if (GET_MODE_CLASS (mode
) == MODE_INT
&& ! can_compare_p (mode
))
2163 do_jump_by_parts_greater_rtx (mode
, 0, target
, const0_rtx
,
2167 temp
= compare_from_rtx (target
, CONST0_RTX (mode
), GE
, 0, mode
,
2169 if (temp
== const1_rtx
)
2171 else if (temp
!= const0_rtx
)
2173 if (bcc_gen_fctn
[(int) GET_CODE (temp
)] != 0)
2174 emit_jump_insn ((*bcc_gen_fctn
[(int) GET_CODE (temp
)]) (op1
));
2180 op0
= expand_unop (mode
, neg_optab
, target
, target
, 0);
2182 emit_move_insn (target
, op0
);
2188 /* Emit code to compute the absolute value of OP0, with result to
2189 TARGET if convenient. (TARGET may be 0.) The return value says
2190 where the result actually is to be found.
2192 MODE is the mode of the operand; the mode of the result is
2193 different but can be deduced from MODE.
2195 UNSIGNEDP is relevant for complex integer modes. */
2198 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2199 enum machine_mode mode
;
2204 enum mode_class
class = GET_MODE_CLASS (mode
);
2205 enum machine_mode wider_mode
;
2207 rtx entry_last
= get_last_insn ();
2211 /* Find the correct mode for the real and imaginary parts. */
2212 enum machine_mode submode
2213 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2214 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2217 if (submode
== BLKmode
)
2220 op0
= protect_from_queue (op0
, 0);
2224 op0
= force_not_mem (op0
);
2227 last
= get_last_insn ();
2230 target
= protect_from_queue (target
, 1);
2232 if (abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2234 int icode
= (int) abs_optab
->handlers
[(int) mode
].insn_code
;
2235 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2241 temp
= gen_reg_rtx (submode
);
2243 if (GET_MODE (xop0
) != VOIDmode
2244 && GET_MODE (xop0
) != mode0
)
2245 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2247 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2249 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
2250 xop0
= copy_to_mode_reg (mode0
, xop0
);
2252 if (! (*insn_operand_predicate
[icode
][0]) (temp
, submode
))
2253 temp
= gen_reg_rtx (submode
);
2255 pat
= GEN_FCN (icode
) (temp
, xop0
);
2258 if (GET_CODE (pat
) == SEQUENCE
2259 && ! add_equal_note (pat
, temp
, abs_optab
->code
, xop0
, NULL_RTX
))
2261 delete_insns_since (last
);
2262 return expand_unop (mode
, abs_optab
, op0
, NULL_RTX
, unsignedp
);
2270 delete_insns_since (last
);
2273 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2275 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2276 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2278 if (abs_optab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2282 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2283 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2287 if (class != MODE_COMPLEX_INT
)
2290 target
= gen_reg_rtx (submode
);
2291 convert_move (target
, temp
, 0);
2295 return gen_lowpart (submode
, temp
);
2298 delete_insns_since (last
);
2302 /* Open-code the complex absolute-value operation
2303 if we can open-code sqrt. Otherwise it's not worth while. */
2304 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
)
2306 rtx real
, imag
, total
;
2308 real
= gen_realpart (submode
, op0
);
2309 imag
= gen_imagpart (submode
, op0
);
2311 /* Square both parts. */
2312 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2313 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2315 /* Sum the parts. */
2316 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2317 0, OPTAB_LIB_WIDEN
);
2319 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2320 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2322 delete_insns_since (last
);
2327 /* Now try a library call in this mode. */
2328 if (abs_optab
->handlers
[(int) mode
].libfunc
)
2335 /* Pass 1 for NO_QUEUE so we don't lose any increments
2336 if the libcall is cse'd or moved. */
2337 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2338 NULL_RTX
, 1, submode
, 1, op0
, mode
);
2339 insns
= get_insns ();
2342 target
= gen_reg_rtx (submode
);
2343 emit_libcall_block (insns
, target
, value
,
2344 gen_rtx_fmt_e (abs_optab
->code
, mode
, op0
));
2349 /* It can't be done in this mode. Can we do it in a wider mode? */
2351 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2352 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2354 if ((abs_optab
->handlers
[(int) wider_mode
].insn_code
2355 != CODE_FOR_nothing
)
2356 || abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2360 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2362 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2366 if (class != MODE_COMPLEX_INT
)
2369 target
= gen_reg_rtx (submode
);
2370 convert_move (target
, temp
, 0);
2374 return gen_lowpart (submode
, temp
);
2377 delete_insns_since (last
);
2381 delete_insns_since (entry_last
);
2385 /* Generate an instruction whose insn-code is INSN_CODE,
2386 with two operands: an output TARGET and an input OP0.
2387 TARGET *must* be nonzero, and the output is always stored there.
2388 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2389 the value that is stored into TARGET. */
2392 emit_unop_insn (icode
, target
, op0
, code
)
2399 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2402 temp
= target
= protect_from_queue (target
, 1);
2404 op0
= protect_from_queue (op0
, 0);
2406 /* Sign and zero extension from memory is often done specially on
2407 RISC machines, so forcing into a register here can pessimize
2409 if (flag_force_mem
&& code
!= SIGN_EXTEND
&& code
!= ZERO_EXTEND
)
2410 op0
= force_not_mem (op0
);
2412 /* Now, if insn does not accept our operands, put them into pseudos. */
2414 if (! (*insn_operand_predicate
[icode
][1]) (op0
, mode0
))
2415 op0
= copy_to_mode_reg (mode0
, op0
);
2417 if (! (*insn_operand_predicate
[icode
][0]) (temp
, GET_MODE (temp
))
2418 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2419 temp
= gen_reg_rtx (GET_MODE (temp
));
2421 pat
= GEN_FCN (icode
) (temp
, op0
);
2423 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2424 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2429 emit_move_insn (target
, temp
);
2432 /* Emit code to perform a series of operations on a multi-word quantity, one
2435 Such a block is preceded by a CLOBBER of the output, consists of multiple
2436 insns, each setting one word of the output, and followed by a SET copying
2437 the output to itself.
2439 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2440 note indicating that it doesn't conflict with the (also multi-word)
2441 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2444 INSNS is a block of code generated to perform the operation, not including
2445 the CLOBBER and final copy. All insns that compute intermediate values
2446 are first emitted, followed by the block as described above.
2448 TARGET, OP0, and OP1 are the output and inputs of the operations,
2449 respectively. OP1 may be zero for a unary operation.
2451 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2454 If TARGET is not a register, INSNS is simply emitted with no special
2455 processing. Likewise if anything in INSNS is not an INSN or if
2456 there is a libcall block inside INSNS.
2458 The final insn emitted is returned. */
2461 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2467 rtx prev
, next
, first
, last
, insn
;
2469 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2470 return emit_insns (insns
);
2472 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2473 if (GET_CODE (insn
) != INSN
2474 || find_reg_note (insn
, REG_LIBCALL
, NULL_RTX
))
2475 return emit_insns (insns
);
2477 /* First emit all insns that do not store into words of the output and remove
2478 these from the list. */
2479 for (insn
= insns
; insn
; insn
= next
)
2484 next
= NEXT_INSN (insn
);
2486 if (GET_CODE (PATTERN (insn
)) == SET
)
2487 set
= PATTERN (insn
);
2488 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2490 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2491 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2493 set
= XVECEXP (PATTERN (insn
), 0, i
);
2501 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2503 if (PREV_INSN (insn
))
2504 NEXT_INSN (PREV_INSN (insn
)) = next
;
2509 PREV_INSN (next
) = PREV_INSN (insn
);
2515 prev
= get_last_insn ();
2517 /* Now write the CLOBBER of the output, followed by the setting of each
2518 of the words, followed by the final copy. */
2519 if (target
!= op0
&& target
!= op1
)
2520 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
2522 for (insn
= insns
; insn
; insn
= next
)
2524 next
= NEXT_INSN (insn
);
2527 if (op1
&& GET_CODE (op1
) == REG
)
2528 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op1
,
2531 if (op0
&& GET_CODE (op0
) == REG
)
2532 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op0
,
2536 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2537 != CODE_FOR_nothing
)
2539 last
= emit_move_insn (target
, target
);
2542 = gen_rtx_EXPR_LIST (REG_EQUAL
, equiv
, REG_NOTES (last
));
2545 last
= get_last_insn ();
2548 first
= get_insns ();
2550 first
= NEXT_INSN (prev
);
2552 /* Encapsulate the block so it gets manipulated as a unit. */
2553 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2555 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2560 /* Emit code to make a call to a constant function or a library call.
2562 INSNS is a list containing all insns emitted in the call.
2563 These insns leave the result in RESULT. Our block is to copy RESULT
2564 to TARGET, which is logically equivalent to EQUIV.
2566 We first emit any insns that set a pseudo on the assumption that these are
2567 loading constants into registers; doing so allows them to be safely cse'ed
2568 between blocks. Then we emit all the other insns in the block, followed by
2569 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2570 note with an operand of EQUIV.
2572 Moving assignments to pseudos outside of the block is done to improve
2573 the generated code, but is not required to generate correct code,
2574 hence being unable to move an assignment is not grounds for not making
2575 a libcall block. There are two reasons why it is safe to leave these
2576 insns inside the block: First, we know that these pseudos cannot be
2577 used in generated RTL outside the block since they are created for
2578 temporary purposes within the block. Second, CSE will not record the
2579 values of anything set inside a libcall block, so we know they must
2580 be dead at the end of the block.
2582 Except for the first group of insns (the ones setting pseudos), the
2583 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2586 emit_libcall_block (insns
, target
, result
, equiv
)
2592 rtx prev
, next
, first
, last
, insn
;
2594 /* First emit all insns that set pseudos. Remove them from the list as
2595 we go. Avoid insns that set pseudos which were referenced in previous
2596 insns. These can be generated by move_by_pieces, for example,
2597 to update an address. Similarly, avoid insns that reference things
2598 set in previous insns. */
2600 for (insn
= insns
; insn
; insn
= next
)
2602 rtx set
= single_set (insn
);
2604 next
= NEXT_INSN (insn
);
2606 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2607 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2609 || (! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
))
2610 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2611 && ! modified_in_p (SET_SRC (set
), insns
)
2612 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2614 if (PREV_INSN (insn
))
2615 NEXT_INSN (PREV_INSN (insn
)) = next
;
2620 PREV_INSN (next
) = PREV_INSN (insn
);
2626 prev
= get_last_insn ();
2628 /* Write the remaining insns followed by the final copy. */
2630 for (insn
= insns
; insn
; insn
= next
)
2632 next
= NEXT_INSN (insn
);
2637 last
= emit_move_insn (target
, result
);
2638 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2639 != CODE_FOR_nothing
)
2640 REG_NOTES (last
) = gen_rtx_EXPR_LIST (REG_EQUAL
, copy_rtx (equiv
),
2644 first
= get_insns ();
2646 first
= NEXT_INSN (prev
);
2648 /* Encapsulate the block so it gets manipulated as a unit. */
2649 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2651 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2654 /* Generate code to store zero in X. */
2660 emit_move_insn (x
, const0_rtx
);
2663 /* Generate code to store 1 in X
2664 assuming it contains zero beforehand. */
2667 emit_0_to_1_insn (x
)
2670 emit_move_insn (x
, const1_rtx
);
2673 /* Generate code to compare X with Y
2674 so that the condition codes are set.
2676 MODE is the mode of the inputs (in case they are const_int).
2677 UNSIGNEDP nonzero says that X and Y are unsigned;
2678 this matters if they need to be widened.
2680 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2681 and ALIGN specifies the known shared alignment of X and Y.
2683 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2684 It is ignored for fixed-point and block comparisons;
2685 it is used only for floating-point comparisons. */
2688 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
2690 enum rtx_code comparison
;
2692 enum machine_mode mode
;
2696 enum mode_class
class;
2697 enum machine_mode wider_mode
;
2699 class = GET_MODE_CLASS (mode
);
2701 /* They could both be VOIDmode if both args are immediate constants,
2702 but we should fold that at an earlier stage.
2703 With no special code here, this will call abort,
2704 reminding the programmer to implement such folding. */
2706 if (mode
!= BLKmode
&& flag_force_mem
)
2708 x
= force_not_mem (x
);
2709 y
= force_not_mem (y
);
2712 /* If we are inside an appropriately-short loop and one operand is an
2713 expensive constant, force it into a register. */
2714 if (CONSTANT_P (x
) && preserve_subexpressions_p () && rtx_cost (x
, COMPARE
) > 2)
2715 x
= force_reg (mode
, x
);
2717 if (CONSTANT_P (y
) && preserve_subexpressions_p () && rtx_cost (y
, COMPARE
) > 2)
2718 y
= force_reg (mode
, y
);
2720 /* Don't let both operands fail to indicate the mode. */
2721 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
2722 x
= force_reg (mode
, x
);
2724 /* Handle all BLKmode compares. */
2726 if (mode
== BLKmode
)
2729 x
= protect_from_queue (x
, 0);
2730 y
= protect_from_queue (y
, 0);
2734 #ifdef HAVE_cmpstrqi
2736 && GET_CODE (size
) == CONST_INT
2737 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
2739 enum machine_mode result_mode
2740 = insn_operand_mode
[(int) CODE_FOR_cmpstrqi
][0];
2741 rtx result
= gen_reg_rtx (result_mode
);
2742 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, GEN_INT (align
)));
2743 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2748 #ifdef HAVE_cmpstrhi
2750 && GET_CODE (size
) == CONST_INT
2751 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
2753 enum machine_mode result_mode
2754 = insn_operand_mode
[(int) CODE_FOR_cmpstrhi
][0];
2755 rtx result
= gen_reg_rtx (result_mode
);
2756 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, GEN_INT (align
)));
2757 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2762 #ifdef HAVE_cmpstrsi
2765 enum machine_mode result_mode
2766 = insn_operand_mode
[(int) CODE_FOR_cmpstrsi
][0];
2767 rtx result
= gen_reg_rtx (result_mode
);
2768 size
= protect_from_queue (size
, 0);
2769 emit_insn (gen_cmpstrsi (result
, x
, y
,
2770 convert_to_mode (SImode
, size
, 1),
2772 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2780 #ifdef TARGET_MEM_FUNCTIONS
2781 emit_library_call (memcmp_libfunc
, 0,
2782 TYPE_MODE (integer_type_node
), 3,
2783 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2784 convert_to_mode (TYPE_MODE (sizetype
), size
,
2785 TREE_UNSIGNED (sizetype
)),
2786 TYPE_MODE (sizetype
));
2788 emit_library_call (bcmp_libfunc
, 0,
2789 TYPE_MODE (integer_type_node
), 3,
2790 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2791 convert_to_mode (TYPE_MODE (integer_type_node
),
2793 TREE_UNSIGNED (integer_type_node
)),
2794 TYPE_MODE (integer_type_node
));
2797 /* Immediately move the result of the libcall into a pseudo
2798 register so reload doesn't clobber the value if it needs
2799 the return register for a spill reg. */
2800 result
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
2801 emit_move_insn (result
,
2802 hard_libcall_value (TYPE_MODE (integer_type_node
)));
2803 emit_cmp_insn (result
,
2804 const0_rtx
, comparison
, NULL_RTX
,
2805 TYPE_MODE (integer_type_node
), 0, 0);
2810 /* Handle some compares against zero. */
2812 if (y
== CONST0_RTX (mode
)
2813 && tst_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2815 int icode
= (int) tst_optab
->handlers
[(int) mode
].insn_code
;
2818 x
= protect_from_queue (x
, 0);
2819 y
= protect_from_queue (y
, 0);
2821 /* Now, if insn does accept these operands, put them into pseudos. */
2822 if (! (*insn_operand_predicate
[icode
][0])
2823 (x
, insn_operand_mode
[icode
][0]))
2824 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2826 emit_insn (GEN_FCN (icode
) (x
));
2830 /* Handle compares for which there is a directly suitable insn. */
2832 if (cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2834 int icode
= (int) cmp_optab
->handlers
[(int) mode
].insn_code
;
2837 x
= protect_from_queue (x
, 0);
2838 y
= protect_from_queue (y
, 0);
2840 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2841 if (! (*insn_operand_predicate
[icode
][0])
2842 (x
, insn_operand_mode
[icode
][0]))
2843 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2845 if (! (*insn_operand_predicate
[icode
][1])
2846 (y
, insn_operand_mode
[icode
][1]))
2847 y
= copy_to_mode_reg (insn_operand_mode
[icode
][1], y
);
2849 emit_insn (GEN_FCN (icode
) (x
, y
));
2853 /* Try widening if we can find a direct insn that way. */
2855 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2857 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2858 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2860 if (cmp_optab
->handlers
[(int) wider_mode
].insn_code
2861 != CODE_FOR_nothing
)
2863 x
= protect_from_queue (x
, 0);
2864 y
= protect_from_queue (y
, 0);
2865 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
2866 y
= convert_modes (wider_mode
, mode
, y
, unsignedp
);
2867 emit_cmp_insn (x
, y
, comparison
, NULL_RTX
,
2868 wider_mode
, unsignedp
, align
);
2874 /* Handle a lib call just for the mode we are using. */
2876 if (cmp_optab
->handlers
[(int) mode
].libfunc
2877 && class != MODE_FLOAT
)
2879 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
2882 /* If we want unsigned, and this mode has a distinct unsigned
2883 comparison routine, use that. */
2884 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
2885 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
2887 emit_library_call (libfunc
, 1,
2888 word_mode
, 2, x
, mode
, y
, mode
);
2890 /* Immediately move the result of the libcall into a pseudo
2891 register so reload doesn't clobber the value if it needs
2892 the return register for a spill reg. */
2893 result
= gen_reg_rtx (word_mode
);
2894 emit_move_insn (result
, hard_libcall_value (word_mode
));
2896 /* Integer comparison returns a result that must be compared against 1,
2897 so that even if we do an unsigned compare afterward,
2898 there is still a value that can represent the result "less than". */
2899 emit_cmp_insn (result
, const1_rtx
,
2900 comparison
, NULL_RTX
, word_mode
, unsignedp
, 0);
2904 if (class == MODE_FLOAT
)
2905 emit_float_lib_cmp (x
, y
, comparison
);
2911 /* Nonzero if a compare of mode MODE can be done straightforwardly
2912 (without splitting it into pieces). */
2915 can_compare_p (mode
)
2916 enum machine_mode mode
;
2920 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2922 mode
= GET_MODE_WIDER_MODE (mode
);
2923 } while (mode
!= VOIDmode
);
2928 /* Emit a library call comparison between floating point X and Y.
2929 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2932 emit_float_lib_cmp (x
, y
, comparison
)
2934 enum rtx_code comparison
;
2936 enum machine_mode mode
= GET_MODE (x
);
2944 libfunc
= eqhf2_libfunc
;
2948 libfunc
= nehf2_libfunc
;
2952 libfunc
= gthf2_libfunc
;
2956 libfunc
= gehf2_libfunc
;
2960 libfunc
= lthf2_libfunc
;
2964 libfunc
= lehf2_libfunc
;
2970 else if (mode
== SFmode
)
2974 libfunc
= eqsf2_libfunc
;
2978 libfunc
= nesf2_libfunc
;
2982 libfunc
= gtsf2_libfunc
;
2986 libfunc
= gesf2_libfunc
;
2990 libfunc
= ltsf2_libfunc
;
2994 libfunc
= lesf2_libfunc
;
3000 else if (mode
== DFmode
)
3004 libfunc
= eqdf2_libfunc
;
3008 libfunc
= nedf2_libfunc
;
3012 libfunc
= gtdf2_libfunc
;
3016 libfunc
= gedf2_libfunc
;
3020 libfunc
= ltdf2_libfunc
;
3024 libfunc
= ledf2_libfunc
;
3030 else if (mode
== XFmode
)
3034 libfunc
= eqxf2_libfunc
;
3038 libfunc
= nexf2_libfunc
;
3042 libfunc
= gtxf2_libfunc
;
3046 libfunc
= gexf2_libfunc
;
3050 libfunc
= ltxf2_libfunc
;
3054 libfunc
= lexf2_libfunc
;
3060 else if (mode
== TFmode
)
3064 libfunc
= eqtf2_libfunc
;
3068 libfunc
= netf2_libfunc
;
3072 libfunc
= gttf2_libfunc
;
3076 libfunc
= getf2_libfunc
;
3080 libfunc
= lttf2_libfunc
;
3084 libfunc
= letf2_libfunc
;
3092 enum machine_mode wider_mode
;
3094 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
3095 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3097 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
3098 != CODE_FOR_nothing
)
3099 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
3101 x
= protect_from_queue (x
, 0);
3102 y
= protect_from_queue (y
, 0);
3103 x
= convert_to_mode (wider_mode
, x
, 0);
3104 y
= convert_to_mode (wider_mode
, y
, 0);
3105 emit_float_lib_cmp (x
, y
, comparison
);
3115 emit_library_call (libfunc
, 1,
3116 word_mode
, 2, x
, mode
, y
, mode
);
3118 /* Immediately move the result of the libcall into a pseudo
3119 register so reload doesn't clobber the value if it needs
3120 the return register for a spill reg. */
3121 result
= gen_reg_rtx (word_mode
);
3122 emit_move_insn (result
, hard_libcall_value (word_mode
));
3124 emit_cmp_insn (result
, const0_rtx
, comparison
,
3125 NULL_RTX
, word_mode
, 0, 0);
3128 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3131 emit_indirect_jump (loc
)
3134 if (! ((*insn_operand_predicate
[(int)CODE_FOR_indirect_jump
][0])
3136 loc
= copy_to_mode_reg (Pmode
, loc
);
3138 emit_jump_insn (gen_indirect_jump (loc
));
3142 #ifdef HAVE_conditional_move
3144 /* Emit a conditional move instruction if the machine supports one for that
3145 condition and machine mode.
3147 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3148 the mode to use should they be constants. If it is VOIDmode, they cannot
3151 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3152 should be stored there. MODE is the mode to use should they be constants.
3153 If it is VOIDmode, they cannot both be constants.
3155 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3156 is not supported. */
3159 emit_conditional_move (target
, code
, op0
, op1
, cmode
, op2
, op3
, mode
,
3164 enum machine_mode cmode
;
3166 enum machine_mode mode
;
3169 rtx tem
, subtarget
, comparison
, insn
;
3170 enum insn_code icode
;
3172 /* If one operand is constant, make it the second one. Only do this
3173 if the other operand is not constant as well. */
3175 if ((CONSTANT_P (op0
) && ! CONSTANT_P (op1
))
3176 || (GET_CODE (op0
) == CONST_INT
&& GET_CODE (op1
) != CONST_INT
))
3181 code
= swap_condition (code
);
3184 if (cmode
== VOIDmode
)
3185 cmode
= GET_MODE (op0
);
3187 if (((CONSTANT_P (op2
) && ! CONSTANT_P (op3
))
3188 || (GET_CODE (op2
) == CONST_INT
&& GET_CODE (op3
) != CONST_INT
))
3189 && (GET_MODE_CLASS (GET_MODE (op1
)) != MODE_FLOAT
3190 || TARGET_FLOAT_FORMAT
!= IEEE_FLOAT_FORMAT
|| flag_fast_math
))
3195 code
= reverse_condition (code
);
3198 if (mode
== VOIDmode
)
3199 mode
= GET_MODE (op2
);
3201 icode
= movcc_gen_code
[mode
];
3203 if (icode
== CODE_FOR_nothing
)
3208 op2
= force_not_mem (op2
);
3209 op3
= force_not_mem (op3
);
3213 target
= protect_from_queue (target
, 1);
3215 target
= gen_reg_rtx (mode
);
3221 op2
= protect_from_queue (op2
, 0);
3222 op3
= protect_from_queue (op3
, 0);
3224 /* If the insn doesn't accept these operands, put them in pseudos. */
3226 if (! (*insn_operand_predicate
[icode
][0])
3227 (subtarget
, insn_operand_mode
[icode
][0]))
3228 subtarget
= gen_reg_rtx (insn_operand_mode
[icode
][0]);
3230 if (! (*insn_operand_predicate
[icode
][2])
3231 (op2
, insn_operand_mode
[icode
][2]))
3232 op2
= copy_to_mode_reg (insn_operand_mode
[icode
][2], op2
);
3234 if (! (*insn_operand_predicate
[icode
][3])
3235 (op3
, insn_operand_mode
[icode
][3]))
3236 op3
= copy_to_mode_reg (insn_operand_mode
[icode
][3], op3
);
3238 /* Everything should now be in the suitable form, so emit the compare insn
3239 and then the conditional move. */
3242 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
, 0);
3244 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3245 if (GET_CODE (comparison
) != code
)
3246 /* This shouldn't happen. */
3249 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
3251 /* If that failed, then give up. */
3257 if (subtarget
!= target
)
3258 convert_move (target
, subtarget
, 0);
3263 /* Return non-zero if a conditional move of mode MODE is supported.
3265 This function is for combine so it can tell whether an insn that looks
3266 like a conditional move is actually supported by the hardware. If we
3267 guess wrong we lose a bit on optimization, but that's it. */
3268 /* ??? sparc64 supports conditionally moving integers values based on fp
3269 comparisons, and vice versa. How do we handle them? */
3272 can_conditionally_move_p (mode
)
3273 enum machine_mode mode
;
3275 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
3281 #endif /* HAVE_conditional_move */
3283 /* These three functions generate an insn body and return it
3284 rather than emitting the insn.
3286 They do not protect from queued increments,
3287 because they may be used 1) in protect_from_queue itself
3288 and 2) in other passes where there is no queue. */
3290 /* Generate and return an insn body to add Y to X. */
3293 gen_add2_insn (x
, y
)
3296 int icode
= (int) add_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_add2_insn (mode
)
3308 enum machine_mode mode
;
3310 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3313 /* Generate and return an insn body to subtract Y from X. */
3316 gen_sub2_insn (x
, y
)
3319 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3321 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
3322 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
3323 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
3326 return (GEN_FCN (icode
) (x
, x
, y
));
3330 have_sub2_insn (mode
)
3331 enum machine_mode mode
;
3333 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3336 /* Generate the body of an instruction to copy Y into X.
3337 It may be a SEQUENCE, if one insn isn't enough. */
3340 gen_move_insn (x
, y
)
3343 register enum machine_mode mode
= GET_MODE (x
);
3344 enum insn_code insn_code
;
3347 if (mode
== VOIDmode
)
3348 mode
= GET_MODE (y
);
3350 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
3352 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3353 find a mode to do it in. If we have a movcc, use it. Otherwise,
3354 find the MODE_INT mode of the same width. */
3356 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
3358 enum machine_mode tmode
= VOIDmode
;
3362 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
3365 for (tmode
= QImode
; tmode
!= VOIDmode
;
3366 tmode
= GET_MODE_WIDER_MODE (tmode
))
3367 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
3370 if (tmode
== VOIDmode
)
3373 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3374 may call change_address which is not appropriate if we were
3375 called when a reload was in progress. We don't have to worry
3376 about changing the address since the size in bytes is supposed to
3377 be the same. Copy the MEM to change the mode and move any
3378 substitutions from the old MEM to the new one. */
3380 if (reload_in_progress
)
3382 x
= gen_lowpart_common (tmode
, x1
);
3383 if (x
== 0 && GET_CODE (x1
) == MEM
)
3385 x
= gen_rtx_MEM (tmode
, XEXP (x1
, 0));
3386 RTX_UNCHANGING_P (x
) = RTX_UNCHANGING_P (x1
);
3387 MEM_IN_STRUCT_P (x
) = MEM_IN_STRUCT_P (x1
);
3388 MEM_VOLATILE_P (x
) = MEM_VOLATILE_P (x1
);
3389 copy_replacements (x1
, x
);
3392 y
= gen_lowpart_common (tmode
, y1
);
3393 if (y
== 0 && GET_CODE (y1
) == MEM
)
3395 y
= gen_rtx_MEM (tmode
, XEXP (y1
, 0));
3396 RTX_UNCHANGING_P (y
) = RTX_UNCHANGING_P (y1
);
3397 MEM_IN_STRUCT_P (y
) = MEM_IN_STRUCT_P (y1
);
3398 MEM_VOLATILE_P (y
) = MEM_VOLATILE_P (y1
);
3399 copy_replacements (y1
, y
);
3404 x
= gen_lowpart (tmode
, x
);
3405 y
= gen_lowpart (tmode
, y
);
3408 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3409 return (GEN_FCN (insn_code
) (x
, y
));
3413 emit_move_insn_1 (x
, y
);
3414 seq
= gen_sequence ();
3419 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3420 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3421 no such operation exists, CODE_FOR_nothing will be returned. */
3424 can_extend_p (to_mode
, from_mode
, unsignedp
)
3425 enum machine_mode to_mode
, from_mode
;
3428 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
];
3431 /* Generate the body of an insn to extend Y (with mode MFROM)
3432 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3435 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3437 enum machine_mode mto
, mfrom
;
3440 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
]) (x
, y
));
3443 /* can_fix_p and can_float_p say whether the target machine
3444 can directly convert a given fixed point type to
3445 a given floating point type, or vice versa.
3446 The returned value is the CODE_FOR_... value to use,
3447 or CODE_FOR_nothing if these modes cannot be directly converted.
3449 *TRUNCP_PTR is set to 1 if it is necessary to output
3450 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3452 static enum insn_code
3453 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3454 enum machine_mode fltmode
, fixmode
;
3459 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
] != CODE_FOR_nothing
)
3460 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3462 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3465 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3467 return CODE_FOR_nothing
;
3470 static enum insn_code
3471 can_float_p (fltmode
, fixmode
, unsignedp
)
3472 enum machine_mode fixmode
, fltmode
;
3475 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3478 /* Generate code to convert FROM to floating point
3479 and store in TO. FROM must be fixed point and not VOIDmode.
3480 UNSIGNEDP nonzero means regard FROM as unsigned.
3481 Normally this is done by correcting the final value
3482 if it is negative. */
3485 expand_float (to
, from
, unsignedp
)
3489 enum insn_code icode
;
3490 register rtx target
= to
;
3491 enum machine_mode fmode
, imode
;
3493 /* Crash now, because we won't be able to decide which mode to use. */
3494 if (GET_MODE (from
) == VOIDmode
)
3497 /* Look for an insn to do the conversion. Do it in the specified
3498 modes if possible; otherwise convert either input, output or both to
3499 wider mode. If the integer mode is wider than the mode of FROM,
3500 we can do the conversion signed even if the input is unsigned. */
3502 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3503 imode
= GET_MODE_WIDER_MODE (imode
))
3504 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3505 fmode
= GET_MODE_WIDER_MODE (fmode
))
3507 int doing_unsigned
= unsignedp
;
3509 icode
= can_float_p (fmode
, imode
, unsignedp
);
3510 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3511 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3513 if (icode
!= CODE_FOR_nothing
)
3515 to
= protect_from_queue (to
, 1);
3516 from
= protect_from_queue (from
, 0);
3518 if (imode
!= GET_MODE (from
))
3519 from
= convert_to_mode (imode
, from
, unsignedp
);
3521 if (fmode
!= GET_MODE (to
))
3522 target
= gen_reg_rtx (fmode
);
3524 emit_unop_insn (icode
, target
, from
,
3525 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3528 convert_move (to
, target
, 0);
3533 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3535 /* Unsigned integer, and no way to convert directly.
3536 Convert as signed, then conditionally adjust the result. */
3539 rtx label
= gen_label_rtx ();
3541 REAL_VALUE_TYPE offset
;
3545 to
= protect_from_queue (to
, 1);
3546 from
= protect_from_queue (from
, 0);
3549 from
= force_not_mem (from
);
3551 /* Look for a usable floating mode FMODE wider than the source and at
3552 least as wide as the target. Using FMODE will avoid rounding woes
3553 with unsigned values greater than the signed maximum value. */
3555 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3556 fmode
= GET_MODE_WIDER_MODE (fmode
))
3557 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
3558 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
3561 if (fmode
== VOIDmode
)
3563 /* There is no such mode. Pretend the target is wide enough. */
3564 fmode
= GET_MODE (to
);
3566 /* Avoid double-rounding when TO is narrower than FROM. */
3567 if ((significand_size (fmode
) + 1)
3568 < GET_MODE_BITSIZE (GET_MODE (from
)))
3571 rtx neglabel
= gen_label_rtx ();
3573 /* Don't use TARGET if it isn't a register, is a hard register,
3574 or is the wrong mode. */
3575 if (GET_CODE (target
) != REG
3576 || REGNO (target
) < FIRST_PSEUDO_REGISTER
3577 || GET_MODE (target
) != fmode
)
3578 target
= gen_reg_rtx (fmode
);
3580 imode
= GET_MODE (from
);
3581 do_pending_stack_adjust ();
3583 /* Test whether the sign bit is set. */
3584 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, imode
, 0, 0);
3585 emit_jump_insn (gen_blt (neglabel
));
3587 /* The sign bit is not set. Convert as signed. */
3588 expand_float (target
, from
, 0);
3589 emit_jump_insn (gen_jump (label
));
3592 /* The sign bit is set.
3593 Convert to a usable (positive signed) value by shifting right
3594 one bit, while remembering if a nonzero bit was shifted
3595 out; i.e., compute (from & 1) | (from >> 1). */
3597 emit_label (neglabel
);
3598 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
3599 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3600 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
3602 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
3604 expand_float (target
, temp
, 0);
3606 /* Multiply by 2 to undo the shift above. */
3607 temp
= expand_binop (fmode
, add_optab
, target
, target
,
3608 target
, 0, OPTAB_LIB_WIDEN
);
3610 emit_move_insn (target
, temp
);
3612 do_pending_stack_adjust ();
3618 /* If we are about to do some arithmetic to correct for an
3619 unsigned operand, do it in a pseudo-register. */
3621 if (GET_MODE (to
) != fmode
3622 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
3623 target
= gen_reg_rtx (fmode
);
3625 /* Convert as signed integer to floating. */
3626 expand_float (target
, from
, 0);
3628 /* If FROM is negative (and therefore TO is negative),
3629 correct its value by 2**bitwidth. */
3631 do_pending_stack_adjust ();
3632 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3633 emit_jump_insn (gen_bge (label
));
3635 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3636 Rather than setting up a dconst_dot_5, let's hope SCO
3638 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
3639 temp
= expand_binop (fmode
, add_optab
, target
,
3640 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
3641 target
, 0, OPTAB_LIB_WIDEN
);
3643 emit_move_insn (target
, temp
);
3645 do_pending_stack_adjust ();
3651 /* No hardware instruction available; call a library routine to convert from
3652 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3658 to
= protect_from_queue (to
, 1);
3659 from
= protect_from_queue (from
, 0);
3661 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
3662 from
= convert_to_mode (SImode
, from
, unsignedp
);
3665 from
= force_not_mem (from
);
3667 if (GET_MODE (to
) == SFmode
)
3669 if (GET_MODE (from
) == SImode
)
3670 libfcn
= floatsisf_libfunc
;
3671 else if (GET_MODE (from
) == DImode
)
3672 libfcn
= floatdisf_libfunc
;
3673 else if (GET_MODE (from
) == TImode
)
3674 libfcn
= floattisf_libfunc
;
3678 else if (GET_MODE (to
) == DFmode
)
3680 if (GET_MODE (from
) == SImode
)
3681 libfcn
= floatsidf_libfunc
;
3682 else if (GET_MODE (from
) == DImode
)
3683 libfcn
= floatdidf_libfunc
;
3684 else if (GET_MODE (from
) == TImode
)
3685 libfcn
= floattidf_libfunc
;
3689 else if (GET_MODE (to
) == XFmode
)
3691 if (GET_MODE (from
) == SImode
)
3692 libfcn
= floatsixf_libfunc
;
3693 else if (GET_MODE (from
) == DImode
)
3694 libfcn
= floatdixf_libfunc
;
3695 else if (GET_MODE (from
) == TImode
)
3696 libfcn
= floattixf_libfunc
;
3700 else if (GET_MODE (to
) == TFmode
)
3702 if (GET_MODE (from
) == SImode
)
3703 libfcn
= floatsitf_libfunc
;
3704 else if (GET_MODE (from
) == DImode
)
3705 libfcn
= floatditf_libfunc
;
3706 else if (GET_MODE (from
) == TImode
)
3707 libfcn
= floattitf_libfunc
;
3716 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1,
3718 1, from
, GET_MODE (from
));
3719 insns
= get_insns ();
3722 emit_libcall_block (insns
, target
, value
,
3723 gen_rtx_FLOAT (GET_MODE (to
), from
));
3728 /* Copy result to requested destination
3729 if we have been computing in a temp location. */
3733 if (GET_MODE (target
) == GET_MODE (to
))
3734 emit_move_insn (to
, target
);
3736 convert_move (to
, target
, 0);
3740 /* expand_fix: generate code to convert FROM to fixed point
3741 and store in TO. FROM must be floating point. */
3747 rtx temp
= gen_reg_rtx (GET_MODE (x
));
3748 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
3752 expand_fix (to
, from
, unsignedp
)
3753 register rtx to
, from
;
3756 enum insn_code icode
;
3757 register rtx target
= to
;
3758 enum machine_mode fmode
, imode
;
3762 /* We first try to find a pair of modes, one real and one integer, at
3763 least as wide as FROM and TO, respectively, in which we can open-code
3764 this conversion. If the integer mode is wider than the mode of TO,
3765 we can do the conversion either signed or unsigned. */
3767 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
3768 imode
= GET_MODE_WIDER_MODE (imode
))
3769 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3770 fmode
= GET_MODE_WIDER_MODE (fmode
))
3772 int doing_unsigned
= unsignedp
;
3774 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
3775 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
3776 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
3778 if (icode
!= CODE_FOR_nothing
)
3780 to
= protect_from_queue (to
, 1);
3781 from
= protect_from_queue (from
, 0);
3783 if (fmode
!= GET_MODE (from
))
3784 from
= convert_to_mode (fmode
, from
, 0);
3787 from
= ftruncify (from
);
3789 if (imode
!= GET_MODE (to
))
3790 target
= gen_reg_rtx (imode
);
3792 emit_unop_insn (icode
, target
, from
,
3793 doing_unsigned
? UNSIGNED_FIX
: FIX
);
3795 convert_move (to
, target
, unsignedp
);
3800 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3801 /* For an unsigned conversion, there is one more way to do it.
3802 If we have a signed conversion, we generate code that compares
3803 the real value to the largest representable positive number. If if
3804 is smaller, the conversion is done normally. Otherwise, subtract
3805 one plus the highest signed number, convert, and add it back.
3807 We only need to check all real modes, since we know we didn't find
3808 anything with a wider integer mode. */
3810 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
3811 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3812 fmode
= GET_MODE_WIDER_MODE (fmode
))
3813 /* Make sure we won't lose significant bits doing this. */
3814 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
3815 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
3819 REAL_VALUE_TYPE offset
;
3820 rtx limit
, lab1
, lab2
, insn
;
3822 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
3823 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
3824 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
3825 lab1
= gen_label_rtx ();
3826 lab2
= gen_label_rtx ();
3829 to
= protect_from_queue (to
, 1);
3830 from
= protect_from_queue (from
, 0);
3833 from
= force_not_mem (from
);
3835 if (fmode
!= GET_MODE (from
))
3836 from
= convert_to_mode (fmode
, from
, 0);
3838 /* See if we need to do the subtraction. */
3839 do_pending_stack_adjust ();
3840 emit_cmp_insn (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3841 emit_jump_insn (gen_bge (lab1
));
3843 /* If not, do the signed "fix" and branch around fixup code. */
3844 expand_fix (to
, from
, 0);
3845 emit_jump_insn (gen_jump (lab2
));
3848 /* Otherwise, subtract 2**(N-1), convert to signed number,
3849 then add 2**(N-1). Do the addition using XOR since this
3850 will often generate better code. */
3852 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
3853 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3854 expand_fix (to
, target
, 0);
3855 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
3856 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
3857 to
, 1, OPTAB_LIB_WIDEN
);
3860 emit_move_insn (to
, target
);
3864 if (mov_optab
->handlers
[(int) GET_MODE (to
)].insn_code
3865 != CODE_FOR_nothing
)
3867 /* Make a place for a REG_NOTE and add it. */
3868 insn
= emit_move_insn (to
, to
);
3870 = gen_rtx_EXPR_LIST (REG_EQUAL
,
3871 gen_rtx_fmt_e (UNSIGNED_FIX
,
3880 /* We can't do it with an insn, so use a library call. But first ensure
3881 that the mode of TO is at least as wide as SImode, since those are the
3882 only library calls we know about. */
3884 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
3886 target
= gen_reg_rtx (SImode
);
3888 expand_fix (target
, from
, unsignedp
);
3890 else if (GET_MODE (from
) == SFmode
)
3892 if (GET_MODE (to
) == SImode
)
3893 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
3894 else if (GET_MODE (to
) == DImode
)
3895 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
3896 else if (GET_MODE (to
) == TImode
)
3897 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
3901 else if (GET_MODE (from
) == DFmode
)
3903 if (GET_MODE (to
) == SImode
)
3904 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
3905 else if (GET_MODE (to
) == DImode
)
3906 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
3907 else if (GET_MODE (to
) == TImode
)
3908 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
3912 else if (GET_MODE (from
) == XFmode
)
3914 if (GET_MODE (to
) == SImode
)
3915 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
3916 else if (GET_MODE (to
) == DImode
)
3917 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
3918 else if (GET_MODE (to
) == TImode
)
3919 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
3923 else if (GET_MODE (from
) == TFmode
)
3925 if (GET_MODE (to
) == SImode
)
3926 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
3927 else if (GET_MODE (to
) == DImode
)
3928 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
3929 else if (GET_MODE (to
) == TImode
)
3930 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
3942 to
= protect_from_queue (to
, 1);
3943 from
= protect_from_queue (from
, 0);
3946 from
= force_not_mem (from
);
3950 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1, GET_MODE (to
),
3952 1, from
, GET_MODE (from
));
3953 insns
= get_insns ();
3956 emit_libcall_block (insns
, target
, value
,
3957 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
3958 GET_MODE (to
), from
));
3963 if (GET_MODE (to
) == GET_MODE (target
))
3964 emit_move_insn (to
, target
);
3966 convert_move (to
, target
, 0);
3975 optab op
= (optab
) xmalloc (sizeof (struct optab
));
3977 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3979 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
3980 op
->handlers
[i
].libfunc
= 0;
3983 if (code
!= UNKNOWN
)
3984 code_to_optab
[(int) code
] = op
;
3989 /* Initialize the libfunc fields of an entire group of entries in some
3990 optab. Each entry is set equal to a string consisting of a leading
3991 pair of underscores followed by a generic operation name followed by
3992 a mode name (downshifted to lower case) followed by a single character
3993 representing the number of operands for the given operation (which is
3994 usually one of the characters '2', '3', or '4').
3996 OPTABLE is the table in which libfunc fields are to be initialized.
3997 FIRST_MODE is the first machine mode index in the given optab to
3999 LAST_MODE is the last machine mode index in the given optab to
4001 OPNAME is the generic (string) name of the operation.
4002 SUFFIX is the character which specifies the number of operands for
4003 the given generic operation.
4007 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
4008 register optab optable
;
4009 register int first_mode
;
4010 register int last_mode
;
4011 register char *opname
;
4012 register int suffix
;
4015 register unsigned opname_len
= strlen (opname
);
4017 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
4018 mode
= (enum machine_mode
) ((int) mode
+ 1))
4020 register char *mname
= mode_name
[(int) mode
];
4021 register unsigned mname_len
= strlen (mname
);
4022 register char *libfunc_name
4023 = (char *) xmalloc (2 + opname_len
+ mname_len
+ 1 + 1);
4030 for (q
= opname
; *q
; )
4032 for (q
= mname
; *q
; q
++)
4033 *p
++ = tolower (*q
);
4036 optable
->handlers
[(int) mode
].libfunc
4037 = gen_rtx_SYMBOL_REF (Pmode
, libfunc_name
);
4041 /* Initialize the libfunc fields of an entire group of entries in some
4042 optab which correspond to all integer mode operations. The parameters
4043 have the same meaning as similarly named ones for the `init_libfuncs'
4044 routine. (See above). */
4047 init_integral_libfuncs (optable
, opname
, suffix
)
4048 register optab optable
;
4049 register char *opname
;
4050 register int suffix
;
4052 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
4055 /* Initialize the libfunc fields of an entire group of entries in some
4056 optab which correspond to all real mode operations. The parameters
4057 have the same meaning as similarly named ones for the `init_libfuncs'
4058 routine. (See above). */
4061 init_floating_libfuncs (optable
, opname
, suffix
)
4062 register optab optable
;
4063 register char *opname
;
4064 register int suffix
;
4066 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
4070 /* Call this once to initialize the contents of the optabs
4071 appropriately for the current target machine. */
4077 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4083 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4085 for (p
= fixtab
[0][0];
4086 p
< fixtab
[0][0] + sizeof fixtab
/ sizeof (fixtab
[0][0][0]);
4088 *p
= CODE_FOR_nothing
;
4090 for (p
= fixtrunctab
[0][0];
4091 p
< fixtrunctab
[0][0] + sizeof fixtrunctab
/ sizeof (fixtrunctab
[0][0][0]);
4093 *p
= CODE_FOR_nothing
;
4095 for (p
= floattab
[0][0];
4096 p
< floattab
[0][0] + sizeof floattab
/ sizeof (floattab
[0][0][0]);
4098 *p
= CODE_FOR_nothing
;
4100 for (p
= extendtab
[0][0];
4101 p
< extendtab
[0][0] + sizeof extendtab
/ sizeof extendtab
[0][0][0];
4103 *p
= CODE_FOR_nothing
;
4105 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
4106 setcc_gen_code
[i
] = CODE_FOR_nothing
;
4108 #ifdef HAVE_conditional_move
4109 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4110 movcc_gen_code
[i
] = CODE_FOR_nothing
;
4113 add_optab
= init_optab (PLUS
);
4114 sub_optab
= init_optab (MINUS
);
4115 smul_optab
= init_optab (MULT
);
4116 smul_highpart_optab
= init_optab (UNKNOWN
);
4117 umul_highpart_optab
= init_optab (UNKNOWN
);
4118 smul_widen_optab
= init_optab (UNKNOWN
);
4119 umul_widen_optab
= init_optab (UNKNOWN
);
4120 sdiv_optab
= init_optab (DIV
);
4121 sdivmod_optab
= init_optab (UNKNOWN
);
4122 udiv_optab
= init_optab (UDIV
);
4123 udivmod_optab
= init_optab (UNKNOWN
);
4124 smod_optab
= init_optab (MOD
);
4125 umod_optab
= init_optab (UMOD
);
4126 flodiv_optab
= init_optab (DIV
);
4127 ftrunc_optab
= init_optab (UNKNOWN
);
4128 and_optab
= init_optab (AND
);
4129 ior_optab
= init_optab (IOR
);
4130 xor_optab
= init_optab (XOR
);
4131 ashl_optab
= init_optab (ASHIFT
);
4132 ashr_optab
= init_optab (ASHIFTRT
);
4133 lshr_optab
= init_optab (LSHIFTRT
);
4134 rotl_optab
= init_optab (ROTATE
);
4135 rotr_optab
= init_optab (ROTATERT
);
4136 smin_optab
= init_optab (SMIN
);
4137 smax_optab
= init_optab (SMAX
);
4138 umin_optab
= init_optab (UMIN
);
4139 umax_optab
= init_optab (UMAX
);
4140 mov_optab
= init_optab (UNKNOWN
);
4141 movstrict_optab
= init_optab (UNKNOWN
);
4142 cmp_optab
= init_optab (UNKNOWN
);
4143 ucmp_optab
= init_optab (UNKNOWN
);
4144 tst_optab
= init_optab (UNKNOWN
);
4145 neg_optab
= init_optab (NEG
);
4146 abs_optab
= init_optab (ABS
);
4147 one_cmpl_optab
= init_optab (NOT
);
4148 ffs_optab
= init_optab (FFS
);
4149 sqrt_optab
= init_optab (SQRT
);
4150 sin_optab
= init_optab (UNKNOWN
);
4151 cos_optab
= init_optab (UNKNOWN
);
4152 strlen_optab
= init_optab (UNKNOWN
);
4154 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4156 movstr_optab
[i
] = CODE_FOR_nothing
;
4157 clrstr_optab
[i
] = CODE_FOR_nothing
;
4159 #ifdef HAVE_SECONDARY_RELOADS
4160 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
4164 /* Fill in the optabs with the insns we support. */
4167 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4168 /* This flag says the same insns that convert to a signed fixnum
4169 also convert validly to an unsigned one. */
4170 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4171 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
4172 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
4175 #ifdef EXTRA_CC_MODES
4179 /* Initialize the optabs with the names of the library functions. */
4180 init_integral_libfuncs (add_optab
, "add", '3');
4181 init_floating_libfuncs (add_optab
, "add", '3');
4182 init_integral_libfuncs (sub_optab
, "sub", '3');
4183 init_floating_libfuncs (sub_optab
, "sub", '3');
4184 init_integral_libfuncs (smul_optab
, "mul", '3');
4185 init_floating_libfuncs (smul_optab
, "mul", '3');
4186 init_integral_libfuncs (sdiv_optab
, "div", '3');
4187 init_integral_libfuncs (udiv_optab
, "udiv", '3');
4188 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
4189 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
4190 init_integral_libfuncs (smod_optab
, "mod", '3');
4191 init_integral_libfuncs (umod_optab
, "umod", '3');
4192 init_floating_libfuncs (flodiv_optab
, "div", '3');
4193 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
4194 init_integral_libfuncs (and_optab
, "and", '3');
4195 init_integral_libfuncs (ior_optab
, "ior", '3');
4196 init_integral_libfuncs (xor_optab
, "xor", '3');
4197 init_integral_libfuncs (ashl_optab
, "ashl", '3');
4198 init_integral_libfuncs (ashr_optab
, "ashr", '3');
4199 init_integral_libfuncs (lshr_optab
, "lshr", '3');
4200 init_integral_libfuncs (smin_optab
, "min", '3');
4201 init_floating_libfuncs (smin_optab
, "min", '3');
4202 init_integral_libfuncs (smax_optab
, "max", '3');
4203 init_floating_libfuncs (smax_optab
, "max", '3');
4204 init_integral_libfuncs (umin_optab
, "umin", '3');
4205 init_integral_libfuncs (umax_optab
, "umax", '3');
4206 init_integral_libfuncs (neg_optab
, "neg", '2');
4207 init_floating_libfuncs (neg_optab
, "neg", '2');
4208 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
4209 init_integral_libfuncs (ffs_optab
, "ffs", '2');
4211 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4212 init_integral_libfuncs (cmp_optab
, "cmp", '2');
4213 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
4214 init_floating_libfuncs (cmp_optab
, "cmp", '2');
4216 #ifdef MULSI3_LIBCALL
4217 smul_optab
->handlers
[(int) SImode
].libfunc
4218 = gen_rtx_SYMBOL_REF (Pmode
, MULSI3_LIBCALL
);
4220 #ifdef MULDI3_LIBCALL
4221 smul_optab
->handlers
[(int) DImode
].libfunc
4222 = gen_rtx_SYMBOL_REF (Pmode
, MULDI3_LIBCALL
);
4225 #ifdef DIVSI3_LIBCALL
4226 sdiv_optab
->handlers
[(int) SImode
].libfunc
4227 = gen_rtx_SYMBOL_REF (Pmode
, DIVSI3_LIBCALL
);
4229 #ifdef DIVDI3_LIBCALL
4230 sdiv_optab
->handlers
[(int) DImode
].libfunc
4231 = gen_rtx_SYMBOL_REF (Pmode
, DIVDI3_LIBCALL
);
4234 #ifdef UDIVSI3_LIBCALL
4235 udiv_optab
->handlers
[(int) SImode
].libfunc
4236 = gen_rtx_SYMBOL_REF (Pmode
, UDIVSI3_LIBCALL
);
4238 #ifdef UDIVDI3_LIBCALL
4239 udiv_optab
->handlers
[(int) DImode
].libfunc
4240 = gen_rtx_SYMBOL_REF (Pmode
, UDIVDI3_LIBCALL
);
4243 #ifdef MODSI3_LIBCALL
4244 smod_optab
->handlers
[(int) SImode
].libfunc
4245 = gen_rtx_SYMBOL_REF (Pmode
, MODSI3_LIBCALL
);
4247 #ifdef MODDI3_LIBCALL
4248 smod_optab
->handlers
[(int) DImode
].libfunc
4249 = gen_rtx_SYMBOL_REF (Pmode
, MODDI3_LIBCALL
);
4252 #ifdef UMODSI3_LIBCALL
4253 umod_optab
->handlers
[(int) SImode
].libfunc
4254 = gen_rtx_SYMBOL_REF (Pmode
, UMODSI3_LIBCALL
);
4256 #ifdef UMODDI3_LIBCALL
4257 umod_optab
->handlers
[(int) DImode
].libfunc
4258 = gen_rtx_SYMBOL_REF (Pmode
, UMODDI3_LIBCALL
);
4261 /* Use cabs for DC complex abs, since systems generally have cabs.
4262 Don't define any libcall for SCmode, so that cabs will be used. */
4263 abs_optab
->handlers
[(int) DCmode
].libfunc
4264 = gen_rtx_SYMBOL_REF (Pmode
, "cabs");
4266 /* The ffs function operates on `int'. */
4267 #ifndef INT_TYPE_SIZE
4268 #define INT_TYPE_SIZE BITS_PER_WORD
4270 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)] .libfunc
4271 = gen_rtx_SYMBOL_REF (Pmode
, "ffs");
4273 extendsfdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extendsfdf2");
4274 extendsfxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extendsfxf2");
4275 extendsftf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extendsftf2");
4276 extenddfxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extenddfxf2");
4277 extenddftf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extenddftf2");
4279 truncdfsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__truncdfsf2");
4280 truncxfsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__truncxfsf2");
4281 trunctfsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__trunctfsf2");
4282 truncxfdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__truncxfdf2");
4283 trunctfdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__trunctfdf2");
4285 memcpy_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "memcpy");
4286 bcopy_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "bcopy");
4287 memcmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "memcmp");
4288 bcmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gcc_bcmp");
4289 memset_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "memset");
4290 bzero_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "bzero");
4292 throw_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__throw");
4293 sjthrow_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__sjthrow");
4294 sjpopnthrow_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__sjpopnthrow");
4295 terminate_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__terminate");
4296 #ifndef DONT_USE_BUILTIN_SETJMP
4297 setjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__builtin_setjmp");
4298 longjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__builtin_longjmp");
4300 setjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "setjmp");
4301 longjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "longjmp");
4304 eqhf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqhf2");
4305 nehf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nehf2");
4306 gthf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gthf2");
4307 gehf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gehf2");
4308 lthf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lthf2");
4309 lehf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lehf2");
4311 eqsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqsf2");
4312 nesf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nesf2");
4313 gtsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gtsf2");
4314 gesf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gesf2");
4315 ltsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ltsf2");
4316 lesf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lesf2");
4318 eqdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqdf2");
4319 nedf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nedf2");
4320 gtdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gtdf2");
4321 gedf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gedf2");
4322 ltdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ltdf2");
4323 ledf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ledf2");
4325 eqxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqxf2");
4326 nexf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nexf2");
4327 gtxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gtxf2");
4328 gexf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gexf2");
4329 ltxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ltxf2");
4330 lexf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lexf2");
4332 eqtf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqtf2");
4333 netf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__netf2");
4334 gttf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gttf2");
4335 getf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__getf2");
4336 lttf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lttf2");
4337 letf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__letf2");
4339 floatsisf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsisf");
4340 floatdisf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatdisf");
4341 floattisf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattisf");
4343 floatsidf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsidf");
4344 floatdidf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatdidf");
4345 floattidf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattidf");
4347 floatsixf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsixf");
4348 floatdixf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatdixf");
4349 floattixf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattixf");
4351 floatsitf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsitf");
4352 floatditf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatditf");
4353 floattitf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattitf");
4355 fixsfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixsfsi");
4356 fixsfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixsfdi");
4357 fixsfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixsfti");
4359 fixdfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixdfsi");
4360 fixdfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixdfdi");
4361 fixdfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixdfti");
4363 fixxfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixxfsi");
4364 fixxfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixxfdi");
4365 fixxfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixxfti");
4367 fixtfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixtfsi");
4368 fixtfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixtfdi");
4369 fixtfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixtfti");
4371 fixunssfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunssfsi");
4372 fixunssfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunssfdi");
4373 fixunssfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunssfti");
4375 fixunsdfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsdfsi");
4376 fixunsdfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsdfdi");
4377 fixunsdfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsdfti");
4379 fixunsxfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsxfsi");
4380 fixunsxfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsxfdi");
4381 fixunsxfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsxfti");
4383 fixunstfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunstfsi");
4384 fixunstfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunstfdi");
4385 fixunstfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunstfti");
4387 /* For check-memory-usage. */
4388 chkr_check_addr_libfunc
= gen_rtx_SYMBOL_REF (VOIDmode
, "chkr_check_addr");
4389 chkr_set_right_libfunc
= gen_rtx_SYMBOL_REF (VOIDmode
, "chkr_set_right");
4390 chkr_copy_bitmap_libfunc
= gen_rtx_SYMBOL_REF (VOIDmode
, "chkr_copy_bitmap");
4391 chkr_check_exec_libfunc
= gen_rtx_SYMBOL_REF (VOIDmode
, "chkr_check_exec");
4392 chkr_check_str_libfunc
= gen_rtx_SYMBOL_REF (VOIDmode
, "chkr_check_str");
4394 #ifdef HAVE_conditional_trap
4398 #ifdef INIT_TARGET_OPTABS
4399 /* Allow the target to add more libcalls or rename some, etc. */
4406 /* SCO 3.2 apparently has a broken ldexp. */
4419 #endif /* BROKEN_LDEXP */
4421 #ifdef HAVE_conditional_trap
4422 /* The insn generating function can not take an rtx_code argument.
4423 TRAP_RTX is used as an rtx argument. Its code is replaced with
4424 the code to be used in the trap insn and all other fields are
4427 ??? Will need to change to support garbage collection. */
4428 static rtx trap_rtx
;
4433 if (HAVE_conditional_trap
)
4434 trap_rtx
= gen_rtx_fmt_ee (EQ
, VOIDmode
, NULL_RTX
, NULL_RTX
);
4438 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4439 CODE. Return 0 on failure. */
4442 gen_cond_trap (code
, op1
, op2
, tcode
)
4444 rtx op1
, op2
, tcode
;
4446 enum machine_mode mode
= GET_MODE (op1
);
4448 if (mode
== VOIDmode
)
4451 #ifdef HAVE_conditional_trap
4452 if (HAVE_conditional_trap
4453 && cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
4456 emit_insn (GEN_FCN (cmp_optab
->handlers
[(int) mode
].insn_code
) (op1
, op2
));
4457 PUT_CODE (trap_rtx
, code
);
4458 insn
= gen_conditional_trap (trap_rtx
, tcode
);