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
;
127 rtx eh_rtime_match_libfunc
;
164 rtx floatsisf_libfunc
;
165 rtx floatdisf_libfunc
;
166 rtx floattisf_libfunc
;
168 rtx floatsidf_libfunc
;
169 rtx floatdidf_libfunc
;
170 rtx floattidf_libfunc
;
172 rtx floatsixf_libfunc
;
173 rtx floatdixf_libfunc
;
174 rtx floattixf_libfunc
;
176 rtx floatsitf_libfunc
;
177 rtx floatditf_libfunc
;
178 rtx floattitf_libfunc
;
196 rtx fixunssfsi_libfunc
;
197 rtx fixunssfdi_libfunc
;
198 rtx fixunssfti_libfunc
;
200 rtx fixunsdfsi_libfunc
;
201 rtx fixunsdfdi_libfunc
;
202 rtx fixunsdfti_libfunc
;
204 rtx fixunsxfsi_libfunc
;
205 rtx fixunsxfdi_libfunc
;
206 rtx fixunsxfti_libfunc
;
208 rtx fixunstfsi_libfunc
;
209 rtx fixunstfdi_libfunc
;
210 rtx fixunstfti_libfunc
;
212 rtx chkr_check_addr_libfunc
;
213 rtx chkr_set_right_libfunc
;
214 rtx chkr_copy_bitmap_libfunc
;
215 rtx chkr_check_exec_libfunc
;
216 rtx chkr_check_str_libfunc
;
218 rtx profile_function_entry_libfunc
;
219 rtx profile_function_exit_libfunc
;
221 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
222 gives the gen_function to make a branch to test that condition. */
224 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
226 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
227 gives the insn code to make a store-condition insn
228 to test that condition. */
230 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
232 #ifdef HAVE_conditional_move
233 /* Indexed by the machine mode, gives the insn code to make a conditional
234 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
235 setcc_gen_code to cut down on the number of named patterns. Consider a day
236 when a lot more rtx codes are conditional (eg: for the ARM). */
238 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
241 static int add_equal_note
PROTO((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
242 static rtx widen_operand
PROTO((rtx
, enum machine_mode
,
243 enum machine_mode
, int, int));
244 static enum insn_code can_fix_p
PROTO((enum machine_mode
, enum machine_mode
,
246 static enum insn_code can_float_p
PROTO((enum machine_mode
, enum machine_mode
,
248 static rtx ftruncify
PROTO((rtx
));
249 static optab init_optab
PROTO((enum rtx_code
));
250 static void init_libfuncs
PROTO((optab
, int, int, char *, int));
251 static void init_integral_libfuncs
PROTO((optab
, char *, int));
252 static void init_floating_libfuncs
PROTO((optab
, char *, int));
253 #ifdef HAVE_conditional_trap
254 static void init_traps
PROTO((void));
257 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
258 the result of operation CODE applied to OP0 (and OP1 if it is a binary
261 If the last insn does not set TARGET, don't do anything, but return 1.
263 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
264 don't add the REG_EQUAL note but return 0. Our caller can then try
265 again, ensuring that TARGET is not one of the operands. */
268 add_equal_note (seq
, target
, code
, op0
, op1
)
278 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
279 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
280 || GET_CODE (seq
) != SEQUENCE
281 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
282 || GET_CODE (target
) == ZERO_EXTRACT
283 || (! rtx_equal_p (SET_DEST (set
), target
)
284 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
286 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
287 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
291 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
292 besides the last insn. */
293 if (reg_overlap_mentioned_p (target
, op0
)
294 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
295 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
296 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
299 if (GET_RTX_CLASS (code
) == '1')
300 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
302 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
304 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))
305 = gen_rtx_EXPR_LIST (REG_EQUAL
, note
,
306 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1)));
311 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
312 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
313 not actually do a sign-extend or zero-extend, but can leave the
314 higher-order bits of the result rtx undefined, for example, in the case
315 of logical operations, but not right shifts. */
318 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
320 enum machine_mode mode
, oldmode
;
326 /* If we must extend do so. If OP is either a constant or a SUBREG
327 for a promoted object, also extend since it will be more efficient to
330 || GET_MODE (op
) == VOIDmode
331 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
332 return convert_modes (mode
, oldmode
, op
, unsignedp
);
334 /* If MODE is no wider than a single word, we return a paradoxical
336 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
337 return gen_rtx_SUBREG (mode
, force_reg (GET_MODE (op
), op
), 0);
339 /* Otherwise, get an object of MODE, clobber it, and set the low-order
342 result
= gen_reg_rtx (mode
);
343 emit_insn (gen_rtx_CLOBBER (VOIDmode
, result
));
344 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
348 /* Generate code to perform an operation specified by BINOPTAB
349 on operands OP0 and OP1, with result having machine-mode MODE.
351 UNSIGNEDP is for the case where we have to widen the operands
352 to perform the operation. It says to use zero-extension.
354 If TARGET is nonzero, the value
355 is generated there, if it is convenient to do so.
356 In all cases an rtx is returned for the locus of the value;
357 this may or may not be TARGET. */
360 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
361 enum machine_mode mode
;
366 enum optab_methods methods
;
368 enum optab_methods next_methods
369 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
370 ? OPTAB_WIDEN
: methods
);
371 enum mode_class
class;
372 enum machine_mode wider_mode
;
374 int commutative_op
= 0;
375 int shift_op
= (binoptab
->code
== ASHIFT
376 || binoptab
->code
== ASHIFTRT
377 || binoptab
->code
== LSHIFTRT
378 || binoptab
->code
== ROTATE
379 || binoptab
->code
== ROTATERT
);
380 rtx entry_last
= get_last_insn ();
383 class = GET_MODE_CLASS (mode
);
385 op0
= protect_from_queue (op0
, 0);
386 op1
= protect_from_queue (op1
, 0);
388 target
= protect_from_queue (target
, 1);
392 op0
= force_not_mem (op0
);
393 op1
= force_not_mem (op1
);
396 /* If subtracting an integer constant, convert this into an addition of
397 the negated constant. */
399 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
401 op1
= negate_rtx (mode
, op1
);
402 binoptab
= add_optab
;
405 /* If we are inside an appropriately-short loop and one operand is an
406 expensive constant, force it into a register. */
407 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
408 && rtx_cost (op0
, binoptab
->code
) > 2)
409 op0
= force_reg (mode
, op0
);
411 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
412 && ! shift_op
&& rtx_cost (op1
, binoptab
->code
) > 2)
413 op1
= force_reg (mode
, op1
);
415 /* Record where to delete back to if we backtrack. */
416 last
= get_last_insn ();
418 /* If operation is commutative,
419 try to make the first operand a register.
420 Even better, try to make it the same as the target.
421 Also try to make the last operand a constant. */
422 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
423 || binoptab
== smul_widen_optab
424 || binoptab
== umul_widen_optab
425 || binoptab
== smul_highpart_optab
426 || binoptab
== umul_highpart_optab
)
430 if (((target
== 0 || GET_CODE (target
) == REG
)
431 ? ((GET_CODE (op1
) == REG
432 && GET_CODE (op0
) != REG
)
434 : rtx_equal_p (op1
, target
))
435 || GET_CODE (op0
) == CONST_INT
)
443 /* If we can do it with a three-operand insn, do so. */
445 if (methods
!= OPTAB_MUST_WIDEN
446 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
448 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
449 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
450 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
452 rtx xop0
= op0
, xop1
= op1
;
457 temp
= gen_reg_rtx (mode
);
459 /* If it is a commutative operator and the modes would match
460 if we would swap the operands, we can save the conversions. */
463 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
464 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
468 tmp
= op0
; op0
= op1
; op1
= tmp
;
469 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
473 /* In case the insn wants input operands in modes different from
474 the result, convert the operands. */
476 if (GET_MODE (op0
) != VOIDmode
477 && GET_MODE (op0
) != mode0
478 && mode0
!= VOIDmode
)
479 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
481 if (GET_MODE (xop1
) != VOIDmode
482 && GET_MODE (xop1
) != mode1
483 && mode1
!= VOIDmode
)
484 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
486 /* Now, if insn's predicates don't allow our operands, put them into
489 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
)
490 && mode0
!= VOIDmode
)
491 xop0
= copy_to_mode_reg (mode0
, xop0
);
493 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
)
494 && mode1
!= VOIDmode
)
495 xop1
= copy_to_mode_reg (mode1
, xop1
);
497 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
498 temp
= gen_reg_rtx (mode
);
500 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
503 /* If PAT is a multi-insn sequence, try to add an appropriate
504 REG_EQUAL note to it. If we can't because TEMP conflicts with an
505 operand, call ourselves again, this time without a target. */
506 if (GET_CODE (pat
) == SEQUENCE
507 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
509 delete_insns_since (last
);
510 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
518 delete_insns_since (last
);
521 /* If this is a multiply, see if we can do a widening operation that
522 takes operands of this mode and makes a wider mode. */
524 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
525 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
526 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
527 != CODE_FOR_nothing
))
529 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
530 unsignedp
? umul_widen_optab
: smul_widen_optab
,
531 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
535 if (GET_MODE_CLASS (mode
) == MODE_INT
)
536 return gen_lowpart (mode
, temp
);
538 return convert_to_mode (mode
, temp
, unsignedp
);
542 /* Look for a wider mode of the same class for which we think we
543 can open-code the operation. Check for a widening multiply at the
544 wider mode as well. */
546 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
547 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
548 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
549 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
551 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
552 || (binoptab
== smul_optab
553 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
554 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
555 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
556 != CODE_FOR_nothing
)))
558 rtx xop0
= op0
, xop1
= op1
;
561 /* For certain integer operations, we need not actually extend
562 the narrow operands, as long as we will truncate
563 the results to the same narrowness. */
565 if ((binoptab
== ior_optab
|| binoptab
== and_optab
566 || binoptab
== xor_optab
567 || binoptab
== add_optab
|| binoptab
== sub_optab
568 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
569 && class == MODE_INT
)
572 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
574 /* The second operand of a shift must always be extended. */
575 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
576 no_extend
&& binoptab
!= ashl_optab
);
578 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
579 unsignedp
, OPTAB_DIRECT
);
582 if (class != MODE_INT
)
585 target
= gen_reg_rtx (mode
);
586 convert_move (target
, temp
, 0);
590 return gen_lowpart (mode
, temp
);
593 delete_insns_since (last
);
597 /* These can be done a word at a time. */
598 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
600 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
601 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
607 /* If TARGET is the same as one of the operands, the REG_EQUAL note
608 won't be accurate, so use a new target. */
609 if (target
== 0 || target
== op0
|| target
== op1
)
610 target
= gen_reg_rtx (mode
);
614 /* Do the actual arithmetic. */
615 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
617 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
618 rtx x
= expand_binop (word_mode
, binoptab
,
619 operand_subword_force (op0
, i
, mode
),
620 operand_subword_force (op1
, i
, mode
),
621 target_piece
, unsignedp
, next_methods
);
626 if (target_piece
!= x
)
627 emit_move_insn (target_piece
, x
);
630 insns
= get_insns ();
633 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
635 if (binoptab
->code
!= UNKNOWN
)
637 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
638 copy_rtx (op0
), copy_rtx (op1
));
642 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
647 /* Synthesize double word shifts from single word shifts. */
648 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
649 || binoptab
== ashr_optab
)
651 && GET_CODE (op1
) == CONST_INT
652 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
653 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
654 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
655 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
657 rtx insns
, inter
, equiv_value
;
658 rtx into_target
, outof_target
;
659 rtx into_input
, outof_input
;
660 int shift_count
, left_shift
, outof_word
;
662 /* If TARGET is the same as one of the operands, the REG_EQUAL note
663 won't be accurate, so use a new target. */
664 if (target
== 0 || target
== op0
|| target
== op1
)
665 target
= gen_reg_rtx (mode
);
669 shift_count
= INTVAL (op1
);
671 /* OUTOF_* is the word we are shifting bits away from, and
672 INTO_* is the word that we are shifting bits towards, thus
673 they differ depending on the direction of the shift and
676 left_shift
= binoptab
== ashl_optab
;
677 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
679 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
680 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
682 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
683 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
685 if (shift_count
>= BITS_PER_WORD
)
687 inter
= expand_binop (word_mode
, binoptab
,
689 GEN_INT (shift_count
- BITS_PER_WORD
),
690 into_target
, unsignedp
, next_methods
);
692 if (inter
!= 0 && inter
!= into_target
)
693 emit_move_insn (into_target
, inter
);
695 /* For a signed right shift, we must fill the word we are shifting
696 out of with copies of the sign bit. Otherwise it is zeroed. */
697 if (inter
!= 0 && binoptab
!= ashr_optab
)
698 inter
= CONST0_RTX (word_mode
);
700 inter
= expand_binop (word_mode
, binoptab
,
702 GEN_INT (BITS_PER_WORD
- 1),
703 outof_target
, unsignedp
, next_methods
);
705 if (inter
!= 0 && inter
!= outof_target
)
706 emit_move_insn (outof_target
, inter
);
711 optab reverse_unsigned_shift
, unsigned_shift
;
713 /* For a shift of less then BITS_PER_WORD, to compute the carry,
714 we must do a logical shift in the opposite direction of the
717 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
719 /* For a shift of less than BITS_PER_WORD, to compute the word
720 shifted towards, we need to unsigned shift the orig value of
723 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
725 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
727 GEN_INT (BITS_PER_WORD
- shift_count
),
728 0, unsignedp
, next_methods
);
733 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
734 op1
, 0, unsignedp
, next_methods
);
737 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
738 into_target
, unsignedp
, next_methods
);
740 if (inter
!= 0 && inter
!= into_target
)
741 emit_move_insn (into_target
, inter
);
744 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
745 op1
, outof_target
, unsignedp
, next_methods
);
747 if (inter
!= 0 && inter
!= outof_target
)
748 emit_move_insn (outof_target
, inter
);
751 insns
= get_insns ();
756 if (binoptab
->code
!= UNKNOWN
)
757 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
761 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
766 /* Synthesize double word rotates from single word shifts. */
767 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
769 && GET_CODE (op1
) == CONST_INT
770 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
771 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
772 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
774 rtx insns
, equiv_value
;
775 rtx into_target
, outof_target
;
776 rtx into_input
, outof_input
;
778 int shift_count
, left_shift
, outof_word
;
780 /* If TARGET is the same as one of the operands, the REG_EQUAL note
781 won't be accurate, so use a new target. */
782 if (target
== 0 || target
== op0
|| target
== op1
)
783 target
= gen_reg_rtx (mode
);
787 shift_count
= INTVAL (op1
);
789 /* OUTOF_* is the word we are shifting bits away from, and
790 INTO_* is the word that we are shifting bits towards, thus
791 they differ depending on the direction of the shift and
794 left_shift
= (binoptab
== rotl_optab
);
795 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
797 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
798 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
800 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
801 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
803 if (shift_count
== BITS_PER_WORD
)
805 /* This is just a word swap. */
806 emit_move_insn (outof_target
, into_input
);
807 emit_move_insn (into_target
, outof_input
);
812 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
813 rtx first_shift_count
, second_shift_count
;
814 optab reverse_unsigned_shift
, unsigned_shift
;
816 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
817 ? lshr_optab
: ashl_optab
);
819 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
820 ? ashl_optab
: lshr_optab
);
822 if (shift_count
> BITS_PER_WORD
)
824 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
825 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
829 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
830 second_shift_count
= GEN_INT (shift_count
);
833 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
834 outof_input
, first_shift_count
,
835 NULL_RTX
, unsignedp
, next_methods
);
836 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
837 into_input
, second_shift_count
,
838 into_target
, unsignedp
, next_methods
);
840 if (into_temp1
!= 0 && into_temp2
!= 0)
841 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
842 into_target
, unsignedp
, next_methods
);
846 if (inter
!= 0 && inter
!= into_target
)
847 emit_move_insn (into_target
, inter
);
849 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
850 into_input
, first_shift_count
,
851 NULL_RTX
, unsignedp
, next_methods
);
852 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
853 outof_input
, second_shift_count
,
854 outof_target
, unsignedp
, next_methods
);
856 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
857 inter
= expand_binop (word_mode
, ior_optab
,
858 outof_temp1
, outof_temp2
,
859 outof_target
, unsignedp
, next_methods
);
861 if (inter
!= 0 && inter
!= outof_target
)
862 emit_move_insn (outof_target
, inter
);
865 insns
= get_insns ();
870 if (binoptab
->code
!= UNKNOWN
)
871 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
875 /* We can't make this a no conflict block if this is a word swap,
876 because the word swap case fails if the input and output values
877 are in the same register. */
878 if (shift_count
!= BITS_PER_WORD
)
879 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
888 /* These can be done a word at a time by propagating carries. */
889 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
891 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
892 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
895 rtx carry_tmp
= gen_reg_rtx (word_mode
);
896 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
897 int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
898 rtx carry_in
, carry_out
;
901 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
902 value is one of those, use it. Otherwise, use 1 since it is the
903 one easiest to get. */
904 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
905 int normalizep
= STORE_FLAG_VALUE
;
910 /* Prepare the operands. */
911 xop0
= force_reg (mode
, op0
);
912 xop1
= force_reg (mode
, op1
);
914 if (target
== 0 || GET_CODE (target
) != REG
915 || target
== xop0
|| target
== xop1
)
916 target
= gen_reg_rtx (mode
);
918 /* Indicate for flow that the entire target reg is being set. */
919 if (GET_CODE (target
) == REG
)
920 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
922 /* Do the actual arithmetic. */
923 for (i
= 0; i
< nwords
; i
++)
925 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
926 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
927 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
928 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
931 /* Main add/subtract of the input operands. */
932 x
= expand_binop (word_mode
, binoptab
,
933 op0_piece
, op1_piece
,
934 target_piece
, unsignedp
, next_methods
);
940 /* Store carry from main add/subtract. */
941 carry_out
= gen_reg_rtx (word_mode
);
942 carry_out
= emit_store_flag_force (carry_out
,
943 (binoptab
== add_optab
946 word_mode
, 1, normalizep
);
951 /* Add/subtract previous carry to main result. */
952 x
= expand_binop (word_mode
,
953 normalizep
== 1 ? binoptab
: otheroptab
,
955 target_piece
, 1, next_methods
);
958 else if (target_piece
!= x
)
959 emit_move_insn (target_piece
, x
);
963 /* THIS CODE HAS NOT BEEN TESTED. */
964 /* Get out carry from adding/subtracting carry in. */
965 carry_tmp
= emit_store_flag_force (carry_tmp
,
966 binoptab
== add_optab
969 word_mode
, 1, normalizep
);
971 /* Logical-ior the two poss. carry together. */
972 carry_out
= expand_binop (word_mode
, ior_optab
,
973 carry_out
, carry_tmp
,
974 carry_out
, 0, next_methods
);
980 carry_in
= carry_out
;
983 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
985 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
987 rtx temp
= emit_move_insn (target
, target
);
990 = gen_rtx_EXPR_LIST (REG_EQUAL
,
991 gen_rtx_fmt_ee (binoptab
->code
, mode
,
999 delete_insns_since (last
);
1002 /* If we want to multiply two two-word values and have normal and widening
1003 multiplies of single-word values, we can do this with three smaller
1004 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1005 because we are not operating on one word at a time.
1007 The multiplication proceeds as follows:
1008 _______________________
1009 [__op0_high_|__op0_low__]
1010 _______________________
1011 * [__op1_high_|__op1_low__]
1012 _______________________________________________
1013 _______________________
1014 (1) [__op0_low__*__op1_low__]
1015 _______________________
1016 (2a) [__op0_low__*__op1_high_]
1017 _______________________
1018 (2b) [__op0_high_*__op1_low__]
1019 _______________________
1020 (3) [__op0_high_*__op1_high_]
1023 This gives a 4-word result. Since we are only interested in the
1024 lower 2 words, partial result (3) and the upper words of (2a) and
1025 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1026 calculated using non-widening multiplication.
1028 (1), however, needs to be calculated with an unsigned widening
1029 multiplication. If this operation is not directly supported we
1030 try using a signed widening multiplication and adjust the result.
1031 This adjustment works as follows:
1033 If both operands are positive then no adjustment is needed.
1035 If the operands have different signs, for example op0_low < 0 and
1036 op1_low >= 0, the instruction treats the most significant bit of
1037 op0_low as a sign bit instead of a bit with significance
1038 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1039 with 2**BITS_PER_WORD - op0_low, and two's complements the
1040 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1043 Similarly, if both operands are negative, we need to add
1044 (op0_low + op1_low) * 2**BITS_PER_WORD.
1046 We use a trick to adjust quickly. We logically shift op0_low right
1047 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1048 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1049 logical shift exists, we do an arithmetic right shift and subtract
1052 if (binoptab
== smul_optab
1053 && class == MODE_INT
1054 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1055 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1056 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1057 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1058 != CODE_FOR_nothing
)
1059 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1060 != CODE_FOR_nothing
)))
1062 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1063 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1064 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1065 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1066 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1067 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1072 /* If the target is the same as one of the inputs, don't use it. This
1073 prevents problems with the REG_EQUAL note. */
1074 if (target
== op0
|| target
== op1
1075 || (target
!= 0 && GET_CODE (target
) != REG
))
1078 /* Multiply the two lower words to get a double-word product.
1079 If unsigned widening multiplication is available, use that;
1080 otherwise use the signed form and compensate. */
1082 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1084 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1085 target
, 1, OPTAB_DIRECT
);
1087 /* If we didn't succeed, delete everything we did so far. */
1089 delete_insns_since (last
);
1091 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1095 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1096 != CODE_FOR_nothing
)
1098 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1099 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1100 target
, 1, OPTAB_DIRECT
);
1101 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1102 NULL_RTX
, 1, next_methods
);
1104 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1105 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1108 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1109 NULL_RTX
, 0, next_methods
);
1111 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1112 op0_xhigh
, op0_xhigh
, 0,
1116 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1117 NULL_RTX
, 1, next_methods
);
1119 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1120 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1123 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1124 NULL_RTX
, 0, next_methods
);
1126 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1127 op1_xhigh
, op1_xhigh
, 0,
1132 /* If we have been able to directly compute the product of the
1133 low-order words of the operands and perform any required adjustments
1134 of the operands, we proceed by trying two more multiplications
1135 and then computing the appropriate sum.
1137 We have checked above that the required addition is provided.
1138 Full-word addition will normally always succeed, especially if
1139 it is provided at all, so we don't worry about its failure. The
1140 multiplication may well fail, however, so we do handle that. */
1142 if (product
&& op0_xhigh
&& op1_xhigh
)
1144 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1145 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1146 NULL_RTX
, 0, OPTAB_DIRECT
);
1149 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1150 product_high
, 0, next_methods
);
1152 if (temp
!= 0 && temp
!= product_high
)
1153 emit_move_insn (product_high
, temp
);
1156 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1157 NULL_RTX
, 0, OPTAB_DIRECT
);
1160 temp
= expand_binop (word_mode
, add_optab
, temp
,
1161 product_high
, product_high
,
1164 if (temp
!= 0 && temp
!= product_high
)
1165 emit_move_insn (product_high
, temp
);
1169 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1171 temp
= emit_move_insn (product
, product
);
1173 = gen_rtx_EXPR_LIST (REG_EQUAL
,
1174 gen_rtx_fmt_ee (MULT
, mode
,
1183 /* If we get here, we couldn't do it for some reason even though we
1184 originally thought we could. Delete anything we've emitted in
1187 delete_insns_since (last
);
1190 /* We need to open-code the complex type operations: '+, -, * and /' */
1192 /* At this point we allow operations between two similar complex
1193 numbers, and also if one of the operands is not a complex number
1194 but rather of MODE_FLOAT or MODE_INT. However, the caller
1195 must make sure that the MODE of the non-complex operand matches
1196 the SUBMODE of the complex operand. */
1198 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1200 rtx real0
= 0, imag0
= 0;
1201 rtx real1
= 0, imag1
= 0;
1202 rtx realr
, imagr
, res
;
1207 /* Find the correct mode for the real and imaginary parts */
1208 enum machine_mode submode
1209 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1210 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1213 if (submode
== BLKmode
)
1217 target
= gen_reg_rtx (mode
);
1221 realr
= gen_realpart (submode
, target
);
1222 imagr
= gen_imagpart (submode
, target
);
1224 if (GET_MODE (op0
) == mode
)
1226 real0
= gen_realpart (submode
, op0
);
1227 imag0
= gen_imagpart (submode
, op0
);
1232 if (GET_MODE (op1
) == mode
)
1234 real1
= gen_realpart (submode
, op1
);
1235 imag1
= gen_imagpart (submode
, op1
);
1240 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1243 switch (binoptab
->code
)
1246 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1248 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1249 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1250 realr
, unsignedp
, methods
);
1254 else if (res
!= realr
)
1255 emit_move_insn (realr
, res
);
1258 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1259 imagr
, unsignedp
, methods
);
1262 else if (binoptab
->code
== MINUS
)
1263 res
= expand_unop (submode
, neg_optab
, imag1
, imagr
, unsignedp
);
1269 else if (res
!= imagr
)
1270 emit_move_insn (imagr
, res
);
1276 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1282 /* Don't fetch these from memory more than once. */
1283 real0
= force_reg (submode
, real0
);
1284 real1
= force_reg (submode
, real1
);
1285 imag0
= force_reg (submode
, imag0
);
1286 imag1
= force_reg (submode
, imag1
);
1288 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1289 unsignedp
, methods
);
1291 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1292 unsignedp
, methods
);
1294 if (temp1
== 0 || temp2
== 0)
1297 res
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1298 realr
, unsignedp
, methods
);
1302 else if (res
!= realr
)
1303 emit_move_insn (realr
, res
);
1305 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1306 NULL_RTX
, unsignedp
, methods
);
1308 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1309 NULL_RTX
, unsignedp
, methods
);
1311 if (temp1
== 0 || temp2
== 0)
1314 res
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1315 imagr
, unsignedp
, methods
);
1319 else if (res
!= imagr
)
1320 emit_move_insn (imagr
, res
);
1326 /* Don't fetch these from memory more than once. */
1327 real0
= force_reg (submode
, real0
);
1328 real1
= force_reg (submode
, real1
);
1330 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1331 realr
, unsignedp
, methods
);
1334 else if (res
!= realr
)
1335 emit_move_insn (realr
, res
);
1338 res
= expand_binop (submode
, binoptab
,
1339 real1
, imag0
, imagr
, unsignedp
, methods
);
1341 res
= expand_binop (submode
, binoptab
,
1342 real0
, imag1
, imagr
, unsignedp
, methods
);
1346 else if (res
!= imagr
)
1347 emit_move_insn (imagr
, res
);
1354 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1358 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1360 /* Don't fetch these from memory more than once. */
1361 real1
= force_reg (submode
, real1
);
1363 /* Simply divide the real and imaginary parts by `c' */
1364 if (class == MODE_COMPLEX_FLOAT
)
1365 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1366 realr
, unsignedp
, methods
);
1368 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1369 real0
, real1
, realr
, unsignedp
);
1373 else if (res
!= realr
)
1374 emit_move_insn (realr
, res
);
1376 if (class == MODE_COMPLEX_FLOAT
)
1377 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1378 imagr
, unsignedp
, methods
);
1380 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1381 imag0
, real1
, imagr
, unsignedp
);
1385 else if (res
!= imagr
)
1386 emit_move_insn (imagr
, res
);
1392 /* Divisor is of complex type:
1398 /* Don't fetch these from memory more than once. */
1399 real0
= force_reg (submode
, real0
);
1400 real1
= force_reg (submode
, real1
);
1403 imag0
= force_reg (submode
, imag0
);
1405 imag1
= force_reg (submode
, imag1
);
1407 /* Divisor: c*c + d*d */
1408 temp1
= expand_binop (submode
, smul_optab
, real1
, real1
,
1409 NULL_RTX
, unsignedp
, methods
);
1411 temp2
= expand_binop (submode
, smul_optab
, imag1
, imag1
,
1412 NULL_RTX
, unsignedp
, methods
);
1414 if (temp1
== 0 || temp2
== 0)
1417 divisor
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1418 NULL_RTX
, unsignedp
, methods
);
1424 /* ((a)(c-id))/divisor */
1425 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1427 /* Calculate the dividend */
1428 real_t
= expand_binop (submode
, smul_optab
, real0
, real1
,
1429 NULL_RTX
, unsignedp
, methods
);
1431 imag_t
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1432 NULL_RTX
, unsignedp
, methods
);
1434 if (real_t
== 0 || imag_t
== 0)
1437 imag_t
= expand_unop (submode
, neg_optab
, imag_t
,
1438 NULL_RTX
, unsignedp
);
1442 /* ((a+ib)(c-id))/divider */
1443 /* Calculate the dividend */
1444 temp1
= expand_binop (submode
, smul_optab
, real0
, real1
,
1445 NULL_RTX
, unsignedp
, methods
);
1447 temp2
= expand_binop (submode
, smul_optab
, imag0
, imag1
,
1448 NULL_RTX
, unsignedp
, methods
);
1450 if (temp1
== 0 || temp2
== 0)
1453 real_t
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1454 NULL_RTX
, unsignedp
, methods
);
1456 temp1
= expand_binop (submode
, smul_optab
, imag0
, real1
,
1457 NULL_RTX
, unsignedp
, methods
);
1459 temp2
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1460 NULL_RTX
, unsignedp
, methods
);
1462 if (temp1
== 0 || temp2
== 0)
1465 imag_t
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1466 NULL_RTX
, unsignedp
, methods
);
1468 if (real_t
== 0 || imag_t
== 0)
1472 if (class == MODE_COMPLEX_FLOAT
)
1473 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
1474 realr
, unsignedp
, methods
);
1476 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1477 real_t
, divisor
, realr
, unsignedp
);
1481 else if (res
!= realr
)
1482 emit_move_insn (realr
, res
);
1484 if (class == MODE_COMPLEX_FLOAT
)
1485 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
1486 imagr
, unsignedp
, methods
);
1488 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1489 imag_t
, divisor
, imagr
, unsignedp
);
1493 else if (res
!= imagr
)
1494 emit_move_insn (imagr
, res
);
1509 if (binoptab
->code
!= UNKNOWN
)
1511 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
1512 copy_rtx (op0
), copy_rtx (op1
));
1516 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1522 /* It can't be open-coded in this mode.
1523 Use a library call if one is available and caller says that's ok. */
1525 if (binoptab
->handlers
[(int) mode
].libfunc
1526 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1530 enum machine_mode op1_mode
= mode
;
1537 op1_mode
= word_mode
;
1538 /* Specify unsigned here,
1539 since negative shift counts are meaningless. */
1540 op1x
= convert_to_mode (word_mode
, op1
, 1);
1543 if (GET_MODE (op0
) != VOIDmode
1544 && GET_MODE (op0
) != mode
)
1545 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1547 /* Pass 1 for NO_QUEUE so we don't lose any increments
1548 if the libcall is cse'd or moved. */
1549 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1550 NULL_RTX
, 1, mode
, 2,
1551 op0
, mode
, op1x
, op1_mode
);
1553 insns
= get_insns ();
1556 target
= gen_reg_rtx (mode
);
1557 emit_libcall_block (insns
, target
, value
,
1558 gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
));
1563 delete_insns_since (last
);
1565 /* It can't be done in this mode. Can we do it in a wider mode? */
1567 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1568 || methods
== OPTAB_MUST_WIDEN
))
1570 /* Caller says, don't even try. */
1571 delete_insns_since (entry_last
);
1575 /* Compute the value of METHODS to pass to recursive calls.
1576 Don't allow widening to be tried recursively. */
1578 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1580 /* Look for a wider mode of the same class for which it appears we can do
1583 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1585 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1586 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1588 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1589 != CODE_FOR_nothing
)
1590 || (methods
== OPTAB_LIB
1591 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1593 rtx xop0
= op0
, xop1
= op1
;
1596 /* For certain integer operations, we need not actually extend
1597 the narrow operands, as long as we will truncate
1598 the results to the same narrowness. */
1600 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1601 || binoptab
== xor_optab
1602 || binoptab
== add_optab
|| binoptab
== sub_optab
1603 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1604 && class == MODE_INT
)
1607 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1608 unsignedp
, no_extend
);
1610 /* The second operand of a shift must always be extended. */
1611 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1612 no_extend
&& binoptab
!= ashl_optab
);
1614 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1615 unsignedp
, methods
);
1618 if (class != MODE_INT
)
1621 target
= gen_reg_rtx (mode
);
1622 convert_move (target
, temp
, 0);
1626 return gen_lowpart (mode
, temp
);
1629 delete_insns_since (last
);
1634 delete_insns_since (entry_last
);
1638 /* Expand a binary operator which has both signed and unsigned forms.
1639 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1642 If we widen unsigned operands, we may use a signed wider operation instead
1643 of an unsigned wider operation, since the result would be the same. */
1646 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1647 enum machine_mode mode
;
1648 optab uoptab
, soptab
;
1649 rtx op0
, op1
, target
;
1651 enum optab_methods methods
;
1654 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1655 struct optab wide_soptab
;
1657 /* Do it without widening, if possible. */
1658 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1659 unsignedp
, OPTAB_DIRECT
);
1660 if (temp
|| methods
== OPTAB_DIRECT
)
1663 /* Try widening to a signed int. Make a fake signed optab that
1664 hides any signed insn for direct use. */
1665 wide_soptab
= *soptab
;
1666 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1667 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1669 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1670 unsignedp
, OPTAB_WIDEN
);
1672 /* For unsigned operands, try widening to an unsigned int. */
1673 if (temp
== 0 && unsignedp
)
1674 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1675 unsignedp
, OPTAB_WIDEN
);
1676 if (temp
|| methods
== OPTAB_WIDEN
)
1679 /* Use the right width lib call if that exists. */
1680 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1681 if (temp
|| methods
== OPTAB_LIB
)
1684 /* Must widen and use a lib call, use either signed or unsigned. */
1685 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1686 unsignedp
, methods
);
1690 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1691 unsignedp
, methods
);
1695 /* Generate code to perform an operation specified by BINOPTAB
1696 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1697 We assume that the order of the operands for the instruction
1698 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1699 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1701 Either TARG0 or TARG1 may be zero, but what that means is that
1702 the result is not actually wanted. We will generate it into
1703 a dummy pseudo-reg and discard it. They may not both be zero.
1705 Returns 1 if this operation can be performed; 0 if not. */
1708 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1714 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1715 enum mode_class
class;
1716 enum machine_mode wider_mode
;
1717 rtx entry_last
= get_last_insn ();
1720 class = GET_MODE_CLASS (mode
);
1722 op0
= protect_from_queue (op0
, 0);
1723 op1
= protect_from_queue (op1
, 0);
1727 op0
= force_not_mem (op0
);
1728 op1
= force_not_mem (op1
);
1731 /* If we are inside an appropriately-short loop and one operand is an
1732 expensive constant, force it into a register. */
1733 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1734 && rtx_cost (op0
, binoptab
->code
) > 2)
1735 op0
= force_reg (mode
, op0
);
1737 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1738 && rtx_cost (op1
, binoptab
->code
) > 2)
1739 op1
= force_reg (mode
, op1
);
1742 targ0
= protect_from_queue (targ0
, 1);
1744 targ0
= gen_reg_rtx (mode
);
1746 targ1
= protect_from_queue (targ1
, 1);
1748 targ1
= gen_reg_rtx (mode
);
1750 /* Record where to go back to if we fail. */
1751 last
= get_last_insn ();
1753 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1755 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1756 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1757 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
1759 rtx xop0
= op0
, xop1
= op1
;
1761 /* In case this insn wants input operands in modes different from the
1762 result, convert the operands. */
1763 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1764 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1766 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1767 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1769 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1770 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1771 xop0
= copy_to_mode_reg (mode0
, xop0
);
1773 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
1774 xop1
= copy_to_mode_reg (mode1
, xop1
);
1776 /* We could handle this, but we should always be called with a pseudo
1777 for our targets and all insns should take them as outputs. */
1778 if (! (*insn_operand_predicate
[icode
][0]) (targ0
, mode
)
1779 || ! (*insn_operand_predicate
[icode
][3]) (targ1
, mode
))
1782 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1789 delete_insns_since (last
);
1792 /* It can't be done in this mode. Can we do it in a wider mode? */
1794 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1796 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1797 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1799 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1800 != CODE_FOR_nothing
)
1802 register rtx t0
= gen_reg_rtx (wider_mode
);
1803 register rtx t1
= gen_reg_rtx (wider_mode
);
1805 if (expand_twoval_binop (binoptab
,
1806 convert_modes (wider_mode
, mode
, op0
,
1808 convert_modes (wider_mode
, mode
, op1
,
1812 convert_move (targ0
, t0
, unsignedp
);
1813 convert_move (targ1
, t1
, unsignedp
);
1817 delete_insns_since (last
);
1822 delete_insns_since (entry_last
);
1826 /* Generate code to perform an operation specified by UNOPTAB
1827 on operand OP0, with result having machine-mode MODE.
1829 UNSIGNEDP is for the case where we have to widen the operands
1830 to perform the operation. It says to use zero-extension.
1832 If TARGET is nonzero, the value
1833 is generated there, if it is convenient to do so.
1834 In all cases an rtx is returned for the locus of the value;
1835 this may or may not be TARGET. */
1838 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
1839 enum machine_mode mode
;
1845 enum mode_class
class;
1846 enum machine_mode wider_mode
;
1848 rtx last
= get_last_insn ();
1851 class = GET_MODE_CLASS (mode
);
1853 op0
= protect_from_queue (op0
, 0);
1857 op0
= force_not_mem (op0
);
1861 target
= protect_from_queue (target
, 1);
1863 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1865 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
1866 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1872 temp
= gen_reg_rtx (mode
);
1874 if (GET_MODE (xop0
) != VOIDmode
1875 && GET_MODE (xop0
) != mode0
)
1876 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1878 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1880 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1881 xop0
= copy_to_mode_reg (mode0
, xop0
);
1883 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
1884 temp
= gen_reg_rtx (mode
);
1886 pat
= GEN_FCN (icode
) (temp
, xop0
);
1889 if (GET_CODE (pat
) == SEQUENCE
1890 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
1892 delete_insns_since (last
);
1893 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
1901 delete_insns_since (last
);
1904 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1906 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1907 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1908 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1910 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
1914 /* For certain operations, we need not actually extend
1915 the narrow operand, as long as we will truncate the
1916 results to the same narrowness. */
1918 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
1919 (unoptab
== neg_optab
1920 || unoptab
== one_cmpl_optab
)
1921 && class == MODE_INT
);
1923 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
1928 if (class != MODE_INT
)
1931 target
= gen_reg_rtx (mode
);
1932 convert_move (target
, temp
, 0);
1936 return gen_lowpart (mode
, temp
);
1939 delete_insns_since (last
);
1943 /* These can be done a word at a time. */
1944 if (unoptab
== one_cmpl_optab
1945 && class == MODE_INT
1946 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1947 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1952 if (target
== 0 || target
== op0
)
1953 target
= gen_reg_rtx (mode
);
1957 /* Do the actual arithmetic. */
1958 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1960 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1961 rtx x
= expand_unop (word_mode
, unoptab
,
1962 operand_subword_force (op0
, i
, mode
),
1963 target_piece
, unsignedp
);
1964 if (target_piece
!= x
)
1965 emit_move_insn (target_piece
, x
);
1968 insns
= get_insns ();
1971 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
1972 gen_rtx_fmt_e (unoptab
->code
, mode
,
1977 /* Open-code the complex negation operation. */
1978 else if (unoptab
== neg_optab
1979 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
1985 /* Find the correct mode for the real and imaginary parts */
1986 enum machine_mode submode
1987 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1988 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1991 if (submode
== BLKmode
)
1995 target
= gen_reg_rtx (mode
);
1999 target_piece
= gen_imagpart (submode
, target
);
2000 x
= expand_unop (submode
, unoptab
,
2001 gen_imagpart (submode
, op0
),
2002 target_piece
, unsignedp
);
2003 if (target_piece
!= x
)
2004 emit_move_insn (target_piece
, x
);
2006 target_piece
= gen_realpart (submode
, target
);
2007 x
= expand_unop (submode
, unoptab
,
2008 gen_realpart (submode
, op0
),
2009 target_piece
, unsignedp
);
2010 if (target_piece
!= x
)
2011 emit_move_insn (target_piece
, x
);
2016 emit_no_conflict_block (seq
, target
, op0
, 0,
2017 gen_rtx_fmt_e (unoptab
->code
, mode
,
2022 /* Now try a library call in this mode. */
2023 if (unoptab
->handlers
[(int) mode
].libfunc
)
2030 /* Pass 1 for NO_QUEUE so we don't lose any increments
2031 if the libcall is cse'd or moved. */
2032 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
2033 NULL_RTX
, 1, mode
, 1, op0
, mode
);
2034 insns
= get_insns ();
2037 target
= gen_reg_rtx (mode
);
2038 emit_libcall_block (insns
, target
, value
,
2039 gen_rtx_fmt_e (unoptab
->code
, mode
, op0
));
2044 /* It can't be done in this mode. Can we do it in a wider mode? */
2046 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2048 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2049 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2051 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
2052 != CODE_FOR_nothing
)
2053 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
2057 /* For certain operations, we need not actually extend
2058 the narrow operand, as long as we will truncate the
2059 results to the same narrowness. */
2061 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2062 (unoptab
== neg_optab
2063 || unoptab
== one_cmpl_optab
)
2064 && class == MODE_INT
);
2066 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2071 if (class != MODE_INT
)
2074 target
= gen_reg_rtx (mode
);
2075 convert_move (target
, temp
, 0);
2079 return gen_lowpart (mode
, temp
);
2082 delete_insns_since (last
);
2087 /* If there is no negate operation, try doing a subtract from zero.
2088 The US Software GOFAST library needs this. */
2089 if (unoptab
== neg_optab
)
2092 temp
= expand_binop (mode
, sub_optab
, CONST0_RTX (mode
), op0
,
2093 target
, unsignedp
, OPTAB_LIB_WIDEN
);
2101 /* Emit code to compute the absolute value of OP0, with result to
2102 TARGET if convenient. (TARGET may be 0.) The return value says
2103 where the result actually is to be found.
2105 MODE is the mode of the operand; the mode of the result is
2106 different but can be deduced from MODE.
2108 UNSIGNEDP is relevant if extension is needed. */
2111 expand_abs (mode
, op0
, target
, unsignedp
, safe
)
2112 enum machine_mode mode
;
2120 /* First try to do it with a special abs instruction. */
2121 temp
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
2125 /* If this machine has expensive jumps, we can do integer absolute
2126 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2127 where W is the width of MODE. */
2129 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
2131 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
2132 size_int (GET_MODE_BITSIZE (mode
) - 1),
2135 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
2138 temp
= expand_binop (mode
, sub_optab
, temp
, extended
, target
, 0,
2145 /* If that does not win, use conditional jump and negate. */
2147 /* It is safe to use the target if it is the same
2148 as the source if this is also a pseudo register */
2149 if (op0
== target
&& GET_CODE (op0
) == REG
2150 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
2153 op1
= gen_label_rtx ();
2154 if (target
== 0 || ! safe
2155 || GET_MODE (target
) != mode
2156 || (GET_CODE (target
) == MEM
&& MEM_VOLATILE_P (target
))
2157 || (GET_CODE (target
) == REG
2158 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
2159 target
= gen_reg_rtx (mode
);
2161 emit_move_insn (target
, op0
);
2164 /* If this mode is an integer too wide to compare properly,
2165 compare word by word. Rely on CSE to optimize constant cases. */
2166 if (GET_MODE_CLASS (mode
) == MODE_INT
&& ! can_compare_p (mode
))
2167 do_jump_by_parts_greater_rtx (mode
, 0, target
, const0_rtx
,
2171 temp
= compare_from_rtx (target
, CONST0_RTX (mode
), GE
, 0, mode
,
2173 if (temp
== const1_rtx
)
2175 else if (temp
!= const0_rtx
)
2177 if (bcc_gen_fctn
[(int) GET_CODE (temp
)] != 0)
2178 emit_jump_insn ((*bcc_gen_fctn
[(int) GET_CODE (temp
)]) (op1
));
2184 op0
= expand_unop (mode
, neg_optab
, target
, target
, 0);
2186 emit_move_insn (target
, op0
);
2192 /* Emit code to compute the absolute value of OP0, with result to
2193 TARGET if convenient. (TARGET may be 0.) The return value says
2194 where the result actually is to be found.
2196 MODE is the mode of the operand; the mode of the result is
2197 different but can be deduced from MODE.
2199 UNSIGNEDP is relevant for complex integer modes. */
2202 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2203 enum machine_mode mode
;
2208 enum mode_class
class = GET_MODE_CLASS (mode
);
2209 enum machine_mode wider_mode
;
2211 rtx entry_last
= get_last_insn ();
2215 /* Find the correct mode for the real and imaginary parts. */
2216 enum machine_mode submode
2217 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2218 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2221 if (submode
== BLKmode
)
2224 op0
= protect_from_queue (op0
, 0);
2228 op0
= force_not_mem (op0
);
2231 last
= get_last_insn ();
2234 target
= protect_from_queue (target
, 1);
2236 if (abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2238 int icode
= (int) abs_optab
->handlers
[(int) mode
].insn_code
;
2239 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2245 temp
= gen_reg_rtx (submode
);
2247 if (GET_MODE (xop0
) != VOIDmode
2248 && GET_MODE (xop0
) != mode0
)
2249 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2251 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2253 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
2254 xop0
= copy_to_mode_reg (mode0
, xop0
);
2256 if (! (*insn_operand_predicate
[icode
][0]) (temp
, submode
))
2257 temp
= gen_reg_rtx (submode
);
2259 pat
= GEN_FCN (icode
) (temp
, xop0
);
2262 if (GET_CODE (pat
) == SEQUENCE
2263 && ! add_equal_note (pat
, temp
, abs_optab
->code
, xop0
, NULL_RTX
))
2265 delete_insns_since (last
);
2266 return expand_unop (mode
, abs_optab
, op0
, NULL_RTX
, unsignedp
);
2274 delete_insns_since (last
);
2277 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2279 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2280 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2282 if (abs_optab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2286 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2287 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2291 if (class != MODE_COMPLEX_INT
)
2294 target
= gen_reg_rtx (submode
);
2295 convert_move (target
, temp
, 0);
2299 return gen_lowpart (submode
, temp
);
2302 delete_insns_since (last
);
2306 /* Open-code the complex absolute-value operation
2307 if we can open-code sqrt. Otherwise it's not worth while. */
2308 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
)
2310 rtx real
, imag
, total
;
2312 real
= gen_realpart (submode
, op0
);
2313 imag
= gen_imagpart (submode
, op0
);
2315 /* Square both parts. */
2316 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2317 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2319 /* Sum the parts. */
2320 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2321 0, OPTAB_LIB_WIDEN
);
2323 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2324 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2326 delete_insns_since (last
);
2331 /* Now try a library call in this mode. */
2332 if (abs_optab
->handlers
[(int) mode
].libfunc
)
2339 /* Pass 1 for NO_QUEUE so we don't lose any increments
2340 if the libcall is cse'd or moved. */
2341 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2342 NULL_RTX
, 1, submode
, 1, op0
, mode
);
2343 insns
= get_insns ();
2346 target
= gen_reg_rtx (submode
);
2347 emit_libcall_block (insns
, target
, value
,
2348 gen_rtx_fmt_e (abs_optab
->code
, mode
, op0
));
2353 /* It can't be done in this mode. Can we do it in a wider mode? */
2355 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2356 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2358 if ((abs_optab
->handlers
[(int) wider_mode
].insn_code
2359 != CODE_FOR_nothing
)
2360 || abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2364 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2366 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2370 if (class != MODE_COMPLEX_INT
)
2373 target
= gen_reg_rtx (submode
);
2374 convert_move (target
, temp
, 0);
2378 return gen_lowpart (submode
, temp
);
2381 delete_insns_since (last
);
2385 delete_insns_since (entry_last
);
2389 /* Generate an instruction whose insn-code is INSN_CODE,
2390 with two operands: an output TARGET and an input OP0.
2391 TARGET *must* be nonzero, and the output is always stored there.
2392 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2393 the value that is stored into TARGET. */
2396 emit_unop_insn (icode
, target
, op0
, code
)
2403 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2406 temp
= target
= protect_from_queue (target
, 1);
2408 op0
= protect_from_queue (op0
, 0);
2410 /* Sign and zero extension from memory is often done specially on
2411 RISC machines, so forcing into a register here can pessimize
2413 if (flag_force_mem
&& code
!= SIGN_EXTEND
&& code
!= ZERO_EXTEND
)
2414 op0
= force_not_mem (op0
);
2416 /* Now, if insn does not accept our operands, put them into pseudos. */
2418 if (! (*insn_operand_predicate
[icode
][1]) (op0
, mode0
))
2419 op0
= copy_to_mode_reg (mode0
, op0
);
2421 if (! (*insn_operand_predicate
[icode
][0]) (temp
, GET_MODE (temp
))
2422 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2423 temp
= gen_reg_rtx (GET_MODE (temp
));
2425 pat
= GEN_FCN (icode
) (temp
, op0
);
2427 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2428 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2433 emit_move_insn (target
, temp
);
2436 /* Emit code to perform a series of operations on a multi-word quantity, one
2439 Such a block is preceded by a CLOBBER of the output, consists of multiple
2440 insns, each setting one word of the output, and followed by a SET copying
2441 the output to itself.
2443 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2444 note indicating that it doesn't conflict with the (also multi-word)
2445 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2448 INSNS is a block of code generated to perform the operation, not including
2449 the CLOBBER and final copy. All insns that compute intermediate values
2450 are first emitted, followed by the block as described above.
2452 TARGET, OP0, and OP1 are the output and inputs of the operations,
2453 respectively. OP1 may be zero for a unary operation.
2455 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2458 If TARGET is not a register, INSNS is simply emitted with no special
2459 processing. Likewise if anything in INSNS is not an INSN or if
2460 there is a libcall block inside INSNS.
2462 The final insn emitted is returned. */
2465 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2471 rtx prev
, next
, first
, last
, insn
;
2473 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2474 return emit_insns (insns
);
2476 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2477 if (GET_CODE (insn
) != INSN
2478 || find_reg_note (insn
, REG_LIBCALL
, NULL_RTX
))
2479 return emit_insns (insns
);
2481 /* First emit all insns that do not store into words of the output and remove
2482 these from the list. */
2483 for (insn
= insns
; insn
; insn
= next
)
2488 next
= NEXT_INSN (insn
);
2490 if (GET_CODE (PATTERN (insn
)) == SET
)
2491 set
= PATTERN (insn
);
2492 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2494 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2495 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2497 set
= XVECEXP (PATTERN (insn
), 0, i
);
2505 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2507 if (PREV_INSN (insn
))
2508 NEXT_INSN (PREV_INSN (insn
)) = next
;
2513 PREV_INSN (next
) = PREV_INSN (insn
);
2519 prev
= get_last_insn ();
2521 /* Now write the CLOBBER of the output, followed by the setting of each
2522 of the words, followed by the final copy. */
2523 if (target
!= op0
&& target
!= op1
)
2524 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
2526 for (insn
= insns
; insn
; insn
= next
)
2528 next
= NEXT_INSN (insn
);
2531 if (op1
&& GET_CODE (op1
) == REG
)
2532 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op1
,
2535 if (op0
&& GET_CODE (op0
) == REG
)
2536 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op0
,
2540 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2541 != CODE_FOR_nothing
)
2543 last
= emit_move_insn (target
, target
);
2546 = gen_rtx_EXPR_LIST (REG_EQUAL
, equiv
, REG_NOTES (last
));
2549 last
= get_last_insn ();
2552 first
= get_insns ();
2554 first
= NEXT_INSN (prev
);
2556 /* Encapsulate the block so it gets manipulated as a unit. */
2557 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2559 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2564 /* Emit code to make a call to a constant function or a library call.
2566 INSNS is a list containing all insns emitted in the call.
2567 These insns leave the result in RESULT. Our block is to copy RESULT
2568 to TARGET, which is logically equivalent to EQUIV.
2570 We first emit any insns that set a pseudo on the assumption that these are
2571 loading constants into registers; doing so allows them to be safely cse'ed
2572 between blocks. Then we emit all the other insns in the block, followed by
2573 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2574 note with an operand of EQUIV.
2576 Moving assignments to pseudos outside of the block is done to improve
2577 the generated code, but is not required to generate correct code,
2578 hence being unable to move an assignment is not grounds for not making
2579 a libcall block. There are two reasons why it is safe to leave these
2580 insns inside the block: First, we know that these pseudos cannot be
2581 used in generated RTL outside the block since they are created for
2582 temporary purposes within the block. Second, CSE will not record the
2583 values of anything set inside a libcall block, so we know they must
2584 be dead at the end of the block.
2586 Except for the first group of insns (the ones setting pseudos), the
2587 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2590 emit_libcall_block (insns
, target
, result
, equiv
)
2596 rtx prev
, next
, first
, last
, insn
;
2598 /* First emit all insns that set pseudos. Remove them from the list as
2599 we go. Avoid insns that set pseudos which were referenced in previous
2600 insns. These can be generated by move_by_pieces, for example,
2601 to update an address. Similarly, avoid insns that reference things
2602 set in previous insns. */
2604 for (insn
= insns
; insn
; insn
= next
)
2606 rtx set
= single_set (insn
);
2608 next
= NEXT_INSN (insn
);
2610 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2611 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2613 || (! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
))
2614 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2615 && ! modified_in_p (SET_SRC (set
), insns
)
2616 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2618 if (PREV_INSN (insn
))
2619 NEXT_INSN (PREV_INSN (insn
)) = next
;
2624 PREV_INSN (next
) = PREV_INSN (insn
);
2630 prev
= get_last_insn ();
2632 /* Write the remaining insns followed by the final copy. */
2634 for (insn
= insns
; insn
; insn
= next
)
2636 next
= NEXT_INSN (insn
);
2641 last
= emit_move_insn (target
, result
);
2642 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2643 != CODE_FOR_nothing
)
2644 REG_NOTES (last
) = gen_rtx_EXPR_LIST (REG_EQUAL
, copy_rtx (equiv
),
2648 first
= get_insns ();
2650 first
= NEXT_INSN (prev
);
2652 /* Encapsulate the block so it gets manipulated as a unit. */
2653 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2655 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2658 /* Generate code to store zero in X. */
2664 emit_move_insn (x
, const0_rtx
);
2667 /* Generate code to store 1 in X
2668 assuming it contains zero beforehand. */
2671 emit_0_to_1_insn (x
)
2674 emit_move_insn (x
, const1_rtx
);
2677 /* Generate code to compare X with Y
2678 so that the condition codes are set.
2680 MODE is the mode of the inputs (in case they are const_int).
2681 UNSIGNEDP nonzero says that X and Y are unsigned;
2682 this matters if they need to be widened.
2684 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2685 and ALIGN specifies the known shared alignment of X and Y.
2687 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2688 It is ignored for fixed-point and block comparisons;
2689 it is used only for floating-point comparisons. */
2692 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
2694 enum rtx_code comparison
;
2696 enum machine_mode mode
;
2700 enum mode_class
class;
2701 enum machine_mode wider_mode
;
2703 class = GET_MODE_CLASS (mode
);
2705 /* They could both be VOIDmode if both args are immediate constants,
2706 but we should fold that at an earlier stage.
2707 With no special code here, this will call abort,
2708 reminding the programmer to implement such folding. */
2710 if (mode
!= BLKmode
&& flag_force_mem
)
2712 x
= force_not_mem (x
);
2713 y
= force_not_mem (y
);
2716 /* If we are inside an appropriately-short loop and one operand is an
2717 expensive constant, force it into a register. */
2718 if (CONSTANT_P (x
) && preserve_subexpressions_p () && rtx_cost (x
, COMPARE
) > 2)
2719 x
= force_reg (mode
, x
);
2721 if (CONSTANT_P (y
) && preserve_subexpressions_p () && rtx_cost (y
, COMPARE
) > 2)
2722 y
= force_reg (mode
, y
);
2724 /* Don't let both operands fail to indicate the mode. */
2725 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
2726 x
= force_reg (mode
, x
);
2728 /* Handle all BLKmode compares. */
2730 if (mode
== BLKmode
)
2733 x
= protect_from_queue (x
, 0);
2734 y
= protect_from_queue (y
, 0);
2738 #ifdef HAVE_cmpstrqi
2740 && GET_CODE (size
) == CONST_INT
2741 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
2743 enum machine_mode result_mode
2744 = insn_operand_mode
[(int) CODE_FOR_cmpstrqi
][0];
2745 rtx result
= gen_reg_rtx (result_mode
);
2746 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, GEN_INT (align
)));
2747 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2752 #ifdef HAVE_cmpstrhi
2754 && GET_CODE (size
) == CONST_INT
2755 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
2757 enum machine_mode result_mode
2758 = insn_operand_mode
[(int) CODE_FOR_cmpstrhi
][0];
2759 rtx result
= gen_reg_rtx (result_mode
);
2760 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, GEN_INT (align
)));
2761 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2766 #ifdef HAVE_cmpstrsi
2769 enum machine_mode result_mode
2770 = insn_operand_mode
[(int) CODE_FOR_cmpstrsi
][0];
2771 rtx result
= gen_reg_rtx (result_mode
);
2772 size
= protect_from_queue (size
, 0);
2773 emit_insn (gen_cmpstrsi (result
, x
, y
,
2774 convert_to_mode (SImode
, size
, 1),
2776 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2784 #ifdef TARGET_MEM_FUNCTIONS
2785 emit_library_call (memcmp_libfunc
, 0,
2786 TYPE_MODE (integer_type_node
), 3,
2787 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2788 convert_to_mode (TYPE_MODE (sizetype
), size
,
2789 TREE_UNSIGNED (sizetype
)),
2790 TYPE_MODE (sizetype
));
2792 emit_library_call (bcmp_libfunc
, 0,
2793 TYPE_MODE (integer_type_node
), 3,
2794 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2795 convert_to_mode (TYPE_MODE (integer_type_node
),
2797 TREE_UNSIGNED (integer_type_node
)),
2798 TYPE_MODE (integer_type_node
));
2801 /* Immediately move the result of the libcall into a pseudo
2802 register so reload doesn't clobber the value if it needs
2803 the return register for a spill reg. */
2804 result
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
2805 emit_move_insn (result
,
2806 hard_libcall_value (TYPE_MODE (integer_type_node
)));
2807 emit_cmp_insn (result
,
2808 const0_rtx
, comparison
, NULL_RTX
,
2809 TYPE_MODE (integer_type_node
), 0, 0);
2814 /* Handle some compares against zero. */
2816 if (y
== CONST0_RTX (mode
)
2817 && tst_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2819 int icode
= (int) tst_optab
->handlers
[(int) mode
].insn_code
;
2822 x
= protect_from_queue (x
, 0);
2823 y
= protect_from_queue (y
, 0);
2825 /* Now, if insn does accept these operands, put them into pseudos. */
2826 if (! (*insn_operand_predicate
[icode
][0])
2827 (x
, insn_operand_mode
[icode
][0]))
2828 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2830 emit_insn (GEN_FCN (icode
) (x
));
2834 /* Handle compares for which there is a directly suitable insn. */
2836 if (cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2838 int icode
= (int) cmp_optab
->handlers
[(int) mode
].insn_code
;
2841 x
= protect_from_queue (x
, 0);
2842 y
= protect_from_queue (y
, 0);
2844 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2845 if (! (*insn_operand_predicate
[icode
][0])
2846 (x
, insn_operand_mode
[icode
][0]))
2847 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2849 if (! (*insn_operand_predicate
[icode
][1])
2850 (y
, insn_operand_mode
[icode
][1]))
2851 y
= copy_to_mode_reg (insn_operand_mode
[icode
][1], y
);
2853 emit_insn (GEN_FCN (icode
) (x
, y
));
2857 /* Try widening if we can find a direct insn that way. */
2859 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2861 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2862 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2864 if (cmp_optab
->handlers
[(int) wider_mode
].insn_code
2865 != CODE_FOR_nothing
)
2867 x
= protect_from_queue (x
, 0);
2868 y
= protect_from_queue (y
, 0);
2869 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
2870 y
= convert_modes (wider_mode
, mode
, y
, unsignedp
);
2871 emit_cmp_insn (x
, y
, comparison
, NULL_RTX
,
2872 wider_mode
, unsignedp
, align
);
2878 /* Handle a lib call just for the mode we are using. */
2880 if (cmp_optab
->handlers
[(int) mode
].libfunc
2881 && class != MODE_FLOAT
)
2883 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
2886 /* If we want unsigned, and this mode has a distinct unsigned
2887 comparison routine, use that. */
2888 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
2889 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
2891 emit_library_call (libfunc
, 1,
2892 word_mode
, 2, x
, mode
, y
, mode
);
2894 /* Immediately move the result of the libcall into a pseudo
2895 register so reload doesn't clobber the value if it needs
2896 the return register for a spill reg. */
2897 result
= gen_reg_rtx (word_mode
);
2898 emit_move_insn (result
, hard_libcall_value (word_mode
));
2900 /* Integer comparison returns a result that must be compared against 1,
2901 so that even if we do an unsigned compare afterward,
2902 there is still a value that can represent the result "less than". */
2903 emit_cmp_insn (result
, const1_rtx
,
2904 comparison
, NULL_RTX
, word_mode
, unsignedp
, 0);
2908 if (class == MODE_FLOAT
)
2909 emit_float_lib_cmp (x
, y
, comparison
);
2915 /* Nonzero if a compare of mode MODE can be done straightforwardly
2916 (without splitting it into pieces). */
2919 can_compare_p (mode
)
2920 enum machine_mode mode
;
2924 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2926 mode
= GET_MODE_WIDER_MODE (mode
);
2927 } while (mode
!= VOIDmode
);
2932 /* Emit a library call comparison between floating point X and Y.
2933 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2936 emit_float_lib_cmp (x
, y
, comparison
)
2938 enum rtx_code comparison
;
2940 enum machine_mode mode
= GET_MODE (x
);
2948 libfunc
= eqhf2_libfunc
;
2952 libfunc
= nehf2_libfunc
;
2956 libfunc
= gthf2_libfunc
;
2960 libfunc
= gehf2_libfunc
;
2964 libfunc
= lthf2_libfunc
;
2968 libfunc
= lehf2_libfunc
;
2974 else if (mode
== SFmode
)
2978 libfunc
= eqsf2_libfunc
;
2982 libfunc
= nesf2_libfunc
;
2986 libfunc
= gtsf2_libfunc
;
2990 libfunc
= gesf2_libfunc
;
2994 libfunc
= ltsf2_libfunc
;
2998 libfunc
= lesf2_libfunc
;
3004 else if (mode
== DFmode
)
3008 libfunc
= eqdf2_libfunc
;
3012 libfunc
= nedf2_libfunc
;
3016 libfunc
= gtdf2_libfunc
;
3020 libfunc
= gedf2_libfunc
;
3024 libfunc
= ltdf2_libfunc
;
3028 libfunc
= ledf2_libfunc
;
3034 else if (mode
== XFmode
)
3038 libfunc
= eqxf2_libfunc
;
3042 libfunc
= nexf2_libfunc
;
3046 libfunc
= gtxf2_libfunc
;
3050 libfunc
= gexf2_libfunc
;
3054 libfunc
= ltxf2_libfunc
;
3058 libfunc
= lexf2_libfunc
;
3064 else if (mode
== TFmode
)
3068 libfunc
= eqtf2_libfunc
;
3072 libfunc
= netf2_libfunc
;
3076 libfunc
= gttf2_libfunc
;
3080 libfunc
= getf2_libfunc
;
3084 libfunc
= lttf2_libfunc
;
3088 libfunc
= letf2_libfunc
;
3096 enum machine_mode wider_mode
;
3098 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
3099 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3101 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
3102 != CODE_FOR_nothing
)
3103 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
3105 x
= protect_from_queue (x
, 0);
3106 y
= protect_from_queue (y
, 0);
3107 x
= convert_to_mode (wider_mode
, x
, 0);
3108 y
= convert_to_mode (wider_mode
, y
, 0);
3109 emit_float_lib_cmp (x
, y
, comparison
);
3119 emit_library_call (libfunc
, 1,
3120 word_mode
, 2, x
, mode
, y
, mode
);
3122 /* Immediately move the result of the libcall into a pseudo
3123 register so reload doesn't clobber the value if it needs
3124 the return register for a spill reg. */
3125 result
= gen_reg_rtx (word_mode
);
3126 emit_move_insn (result
, hard_libcall_value (word_mode
));
3128 emit_cmp_insn (result
, const0_rtx
, comparison
,
3129 NULL_RTX
, word_mode
, 0, 0);
3132 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3135 emit_indirect_jump (loc
)
3138 if (! ((*insn_operand_predicate
[(int)CODE_FOR_indirect_jump
][0])
3140 loc
= copy_to_mode_reg (Pmode
, loc
);
3142 emit_jump_insn (gen_indirect_jump (loc
));
3146 #ifdef HAVE_conditional_move
3148 /* Emit a conditional move instruction if the machine supports one for that
3149 condition and machine mode.
3151 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3152 the mode to use should they be constants. If it is VOIDmode, they cannot
3155 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3156 should be stored there. MODE is the mode to use should they be constants.
3157 If it is VOIDmode, they cannot both be constants.
3159 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3160 is not supported. */
3163 emit_conditional_move (target
, code
, op0
, op1
, cmode
, op2
, op3
, mode
,
3168 enum machine_mode cmode
;
3170 enum machine_mode mode
;
3173 rtx tem
, subtarget
, comparison
, insn
;
3174 enum insn_code icode
;
3176 /* If one operand is constant, make it the second one. Only do this
3177 if the other operand is not constant as well. */
3179 if ((CONSTANT_P (op0
) && ! CONSTANT_P (op1
))
3180 || (GET_CODE (op0
) == CONST_INT
&& GET_CODE (op1
) != CONST_INT
))
3185 code
= swap_condition (code
);
3188 if (cmode
== VOIDmode
)
3189 cmode
= GET_MODE (op0
);
3191 if (((CONSTANT_P (op2
) && ! CONSTANT_P (op3
))
3192 || (GET_CODE (op2
) == CONST_INT
&& GET_CODE (op3
) != CONST_INT
))
3193 && (GET_MODE_CLASS (GET_MODE (op1
)) != MODE_FLOAT
3194 || TARGET_FLOAT_FORMAT
!= IEEE_FLOAT_FORMAT
|| flag_fast_math
))
3199 code
= reverse_condition (code
);
3202 if (mode
== VOIDmode
)
3203 mode
= GET_MODE (op2
);
3205 icode
= movcc_gen_code
[mode
];
3207 if (icode
== CODE_FOR_nothing
)
3212 op2
= force_not_mem (op2
);
3213 op3
= force_not_mem (op3
);
3217 target
= protect_from_queue (target
, 1);
3219 target
= gen_reg_rtx (mode
);
3225 op2
= protect_from_queue (op2
, 0);
3226 op3
= protect_from_queue (op3
, 0);
3228 /* If the insn doesn't accept these operands, put them in pseudos. */
3230 if (! (*insn_operand_predicate
[icode
][0])
3231 (subtarget
, insn_operand_mode
[icode
][0]))
3232 subtarget
= gen_reg_rtx (insn_operand_mode
[icode
][0]);
3234 if (! (*insn_operand_predicate
[icode
][2])
3235 (op2
, insn_operand_mode
[icode
][2]))
3236 op2
= copy_to_mode_reg (insn_operand_mode
[icode
][2], op2
);
3238 if (! (*insn_operand_predicate
[icode
][3])
3239 (op3
, insn_operand_mode
[icode
][3]))
3240 op3
= copy_to_mode_reg (insn_operand_mode
[icode
][3], op3
);
3242 /* Everything should now be in the suitable form, so emit the compare insn
3243 and then the conditional move. */
3246 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
, 0);
3248 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3249 if (GET_CODE (comparison
) != code
)
3250 /* This shouldn't happen. */
3253 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
3255 /* If that failed, then give up. */
3261 if (subtarget
!= target
)
3262 convert_move (target
, subtarget
, 0);
3267 /* Return non-zero if a conditional move of mode MODE is supported.
3269 This function is for combine so it can tell whether an insn that looks
3270 like a conditional move is actually supported by the hardware. If we
3271 guess wrong we lose a bit on optimization, but that's it. */
3272 /* ??? sparc64 supports conditionally moving integers values based on fp
3273 comparisons, and vice versa. How do we handle them? */
3276 can_conditionally_move_p (mode
)
3277 enum machine_mode mode
;
3279 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
3285 #endif /* HAVE_conditional_move */
3287 /* These three functions generate an insn body and return it
3288 rather than emitting the insn.
3290 They do not protect from queued increments,
3291 because they may be used 1) in protect_from_queue itself
3292 and 2) in other passes where there is no queue. */
3294 /* Generate and return an insn body to add Y to X. */
3297 gen_add2_insn (x
, y
)
3300 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3302 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
3303 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
3304 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
3307 return (GEN_FCN (icode
) (x
, x
, y
));
3311 have_add2_insn (mode
)
3312 enum machine_mode mode
;
3314 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3317 /* Generate and return an insn body to subtract Y from X. */
3320 gen_sub2_insn (x
, y
)
3323 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3325 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
3326 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
3327 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
3330 return (GEN_FCN (icode
) (x
, x
, y
));
3334 have_sub2_insn (mode
)
3335 enum machine_mode mode
;
3337 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3340 /* Generate the body of an instruction to copy Y into X.
3341 It may be a SEQUENCE, if one insn isn't enough. */
3344 gen_move_insn (x
, y
)
3347 register enum machine_mode mode
= GET_MODE (x
);
3348 enum insn_code insn_code
;
3351 if (mode
== VOIDmode
)
3352 mode
= GET_MODE (y
);
3354 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
3356 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3357 find a mode to do it in. If we have a movcc, use it. Otherwise,
3358 find the MODE_INT mode of the same width. */
3360 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
3362 enum machine_mode tmode
= VOIDmode
;
3366 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
3369 for (tmode
= QImode
; tmode
!= VOIDmode
;
3370 tmode
= GET_MODE_WIDER_MODE (tmode
))
3371 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
3374 if (tmode
== VOIDmode
)
3377 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3378 may call change_address which is not appropriate if we were
3379 called when a reload was in progress. We don't have to worry
3380 about changing the address since the size in bytes is supposed to
3381 be the same. Copy the MEM to change the mode and move any
3382 substitutions from the old MEM to the new one. */
3384 if (reload_in_progress
)
3386 x
= gen_lowpart_common (tmode
, x1
);
3387 if (x
== 0 && GET_CODE (x1
) == MEM
)
3389 x
= gen_rtx_MEM (tmode
, XEXP (x1
, 0));
3390 RTX_UNCHANGING_P (x
) = RTX_UNCHANGING_P (x1
);
3391 MEM_IN_STRUCT_P (x
) = MEM_IN_STRUCT_P (x1
);
3392 MEM_VOLATILE_P (x
) = MEM_VOLATILE_P (x1
);
3393 copy_replacements (x1
, x
);
3396 y
= gen_lowpart_common (tmode
, y1
);
3397 if (y
== 0 && GET_CODE (y1
) == MEM
)
3399 y
= gen_rtx_MEM (tmode
, XEXP (y1
, 0));
3400 RTX_UNCHANGING_P (y
) = RTX_UNCHANGING_P (y1
);
3401 MEM_IN_STRUCT_P (y
) = MEM_IN_STRUCT_P (y1
);
3402 MEM_VOLATILE_P (y
) = MEM_VOLATILE_P (y1
);
3403 copy_replacements (y1
, y
);
3408 x
= gen_lowpart (tmode
, x
);
3409 y
= gen_lowpart (tmode
, y
);
3412 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3413 return (GEN_FCN (insn_code
) (x
, y
));
3417 emit_move_insn_1 (x
, y
);
3418 seq
= gen_sequence ();
3423 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3424 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3425 no such operation exists, CODE_FOR_nothing will be returned. */
3428 can_extend_p (to_mode
, from_mode
, unsignedp
)
3429 enum machine_mode to_mode
, from_mode
;
3432 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
];
3435 /* Generate the body of an insn to extend Y (with mode MFROM)
3436 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3439 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3441 enum machine_mode mto
, mfrom
;
3444 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
]) (x
, y
));
3447 /* can_fix_p and can_float_p say whether the target machine
3448 can directly convert a given fixed point type to
3449 a given floating point type, or vice versa.
3450 The returned value is the CODE_FOR_... value to use,
3451 or CODE_FOR_nothing if these modes cannot be directly converted.
3453 *TRUNCP_PTR is set to 1 if it is necessary to output
3454 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3456 static enum insn_code
3457 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3458 enum machine_mode fltmode
, fixmode
;
3463 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
] != CODE_FOR_nothing
)
3464 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3466 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3469 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3471 return CODE_FOR_nothing
;
3474 static enum insn_code
3475 can_float_p (fltmode
, fixmode
, unsignedp
)
3476 enum machine_mode fixmode
, fltmode
;
3479 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3482 /* Generate code to convert FROM to floating point
3483 and store in TO. FROM must be fixed point and not VOIDmode.
3484 UNSIGNEDP nonzero means regard FROM as unsigned.
3485 Normally this is done by correcting the final value
3486 if it is negative. */
3489 expand_float (to
, from
, unsignedp
)
3493 enum insn_code icode
;
3494 register rtx target
= to
;
3495 enum machine_mode fmode
, imode
;
3497 /* Crash now, because we won't be able to decide which mode to use. */
3498 if (GET_MODE (from
) == VOIDmode
)
3501 /* Look for an insn to do the conversion. Do it in the specified
3502 modes if possible; otherwise convert either input, output or both to
3503 wider mode. If the integer mode is wider than the mode of FROM,
3504 we can do the conversion signed even if the input is unsigned. */
3506 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3507 imode
= GET_MODE_WIDER_MODE (imode
))
3508 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3509 fmode
= GET_MODE_WIDER_MODE (fmode
))
3511 int doing_unsigned
= unsignedp
;
3513 icode
= can_float_p (fmode
, imode
, unsignedp
);
3514 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3515 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3517 if (icode
!= CODE_FOR_nothing
)
3519 to
= protect_from_queue (to
, 1);
3520 from
= protect_from_queue (from
, 0);
3522 if (imode
!= GET_MODE (from
))
3523 from
= convert_to_mode (imode
, from
, unsignedp
);
3525 if (fmode
!= GET_MODE (to
))
3526 target
= gen_reg_rtx (fmode
);
3528 emit_unop_insn (icode
, target
, from
,
3529 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3532 convert_move (to
, target
, 0);
3537 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3539 /* Unsigned integer, and no way to convert directly.
3540 Convert as signed, then conditionally adjust the result. */
3543 rtx label
= gen_label_rtx ();
3545 REAL_VALUE_TYPE offset
;
3549 to
= protect_from_queue (to
, 1);
3550 from
= protect_from_queue (from
, 0);
3553 from
= force_not_mem (from
);
3555 /* Look for a usable floating mode FMODE wider than the source and at
3556 least as wide as the target. Using FMODE will avoid rounding woes
3557 with unsigned values greater than the signed maximum value. */
3559 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3560 fmode
= GET_MODE_WIDER_MODE (fmode
))
3561 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
3562 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
3565 if (fmode
== VOIDmode
)
3567 /* There is no such mode. Pretend the target is wide enough. */
3568 fmode
= GET_MODE (to
);
3570 /* Avoid double-rounding when TO is narrower than FROM. */
3571 if ((significand_size (fmode
) + 1)
3572 < GET_MODE_BITSIZE (GET_MODE (from
)))
3575 rtx neglabel
= gen_label_rtx ();
3577 /* Don't use TARGET if it isn't a register, is a hard register,
3578 or is the wrong mode. */
3579 if (GET_CODE (target
) != REG
3580 || REGNO (target
) < FIRST_PSEUDO_REGISTER
3581 || GET_MODE (target
) != fmode
)
3582 target
= gen_reg_rtx (fmode
);
3584 imode
= GET_MODE (from
);
3585 do_pending_stack_adjust ();
3587 /* Test whether the sign bit is set. */
3588 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, imode
, 0, 0);
3589 emit_jump_insn (gen_blt (neglabel
));
3591 /* The sign bit is not set. Convert as signed. */
3592 expand_float (target
, from
, 0);
3593 emit_jump_insn (gen_jump (label
));
3596 /* The sign bit is set.
3597 Convert to a usable (positive signed) value by shifting right
3598 one bit, while remembering if a nonzero bit was shifted
3599 out; i.e., compute (from & 1) | (from >> 1). */
3601 emit_label (neglabel
);
3602 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
3603 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3604 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
3606 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
3608 expand_float (target
, temp
, 0);
3610 /* Multiply by 2 to undo the shift above. */
3611 temp
= expand_binop (fmode
, add_optab
, target
, target
,
3612 target
, 0, OPTAB_LIB_WIDEN
);
3614 emit_move_insn (target
, temp
);
3616 do_pending_stack_adjust ();
3622 /* If we are about to do some arithmetic to correct for an
3623 unsigned operand, do it in a pseudo-register. */
3625 if (GET_MODE (to
) != fmode
3626 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
3627 target
= gen_reg_rtx (fmode
);
3629 /* Convert as signed integer to floating. */
3630 expand_float (target
, from
, 0);
3632 /* If FROM is negative (and therefore TO is negative),
3633 correct its value by 2**bitwidth. */
3635 do_pending_stack_adjust ();
3636 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3637 emit_jump_insn (gen_bge (label
));
3639 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3640 Rather than setting up a dconst_dot_5, let's hope SCO
3642 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
3643 temp
= expand_binop (fmode
, add_optab
, target
,
3644 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
3645 target
, 0, OPTAB_LIB_WIDEN
);
3647 emit_move_insn (target
, temp
);
3649 do_pending_stack_adjust ();
3655 /* No hardware instruction available; call a library routine to convert from
3656 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3662 to
= protect_from_queue (to
, 1);
3663 from
= protect_from_queue (from
, 0);
3665 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
3666 from
= convert_to_mode (SImode
, from
, unsignedp
);
3669 from
= force_not_mem (from
);
3671 if (GET_MODE (to
) == SFmode
)
3673 if (GET_MODE (from
) == SImode
)
3674 libfcn
= floatsisf_libfunc
;
3675 else if (GET_MODE (from
) == DImode
)
3676 libfcn
= floatdisf_libfunc
;
3677 else if (GET_MODE (from
) == TImode
)
3678 libfcn
= floattisf_libfunc
;
3682 else if (GET_MODE (to
) == DFmode
)
3684 if (GET_MODE (from
) == SImode
)
3685 libfcn
= floatsidf_libfunc
;
3686 else if (GET_MODE (from
) == DImode
)
3687 libfcn
= floatdidf_libfunc
;
3688 else if (GET_MODE (from
) == TImode
)
3689 libfcn
= floattidf_libfunc
;
3693 else if (GET_MODE (to
) == XFmode
)
3695 if (GET_MODE (from
) == SImode
)
3696 libfcn
= floatsixf_libfunc
;
3697 else if (GET_MODE (from
) == DImode
)
3698 libfcn
= floatdixf_libfunc
;
3699 else if (GET_MODE (from
) == TImode
)
3700 libfcn
= floattixf_libfunc
;
3704 else if (GET_MODE (to
) == TFmode
)
3706 if (GET_MODE (from
) == SImode
)
3707 libfcn
= floatsitf_libfunc
;
3708 else if (GET_MODE (from
) == DImode
)
3709 libfcn
= floatditf_libfunc
;
3710 else if (GET_MODE (from
) == TImode
)
3711 libfcn
= floattitf_libfunc
;
3720 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1,
3722 1, from
, GET_MODE (from
));
3723 insns
= get_insns ();
3726 emit_libcall_block (insns
, target
, value
,
3727 gen_rtx_FLOAT (GET_MODE (to
), from
));
3732 /* Copy result to requested destination
3733 if we have been computing in a temp location. */
3737 if (GET_MODE (target
) == GET_MODE (to
))
3738 emit_move_insn (to
, target
);
3740 convert_move (to
, target
, 0);
3744 /* expand_fix: generate code to convert FROM to fixed point
3745 and store in TO. FROM must be floating point. */
3751 rtx temp
= gen_reg_rtx (GET_MODE (x
));
3752 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
3756 expand_fix (to
, from
, unsignedp
)
3757 register rtx to
, from
;
3760 enum insn_code icode
;
3761 register rtx target
= to
;
3762 enum machine_mode fmode
, imode
;
3766 /* We first try to find a pair of modes, one real and one integer, at
3767 least as wide as FROM and TO, respectively, in which we can open-code
3768 this conversion. If the integer mode is wider than the mode of TO,
3769 we can do the conversion either signed or unsigned. */
3771 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
3772 imode
= GET_MODE_WIDER_MODE (imode
))
3773 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3774 fmode
= GET_MODE_WIDER_MODE (fmode
))
3776 int doing_unsigned
= unsignedp
;
3778 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
3779 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
3780 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
3782 if (icode
!= CODE_FOR_nothing
)
3784 to
= protect_from_queue (to
, 1);
3785 from
= protect_from_queue (from
, 0);
3787 if (fmode
!= GET_MODE (from
))
3788 from
= convert_to_mode (fmode
, from
, 0);
3791 from
= ftruncify (from
);
3793 if (imode
!= GET_MODE (to
))
3794 target
= gen_reg_rtx (imode
);
3796 emit_unop_insn (icode
, target
, from
,
3797 doing_unsigned
? UNSIGNED_FIX
: FIX
);
3799 convert_move (to
, target
, unsignedp
);
3804 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3805 /* For an unsigned conversion, there is one more way to do it.
3806 If we have a signed conversion, we generate code that compares
3807 the real value to the largest representable positive number. If if
3808 is smaller, the conversion is done normally. Otherwise, subtract
3809 one plus the highest signed number, convert, and add it back.
3811 We only need to check all real modes, since we know we didn't find
3812 anything with a wider integer mode. */
3814 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
3815 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3816 fmode
= GET_MODE_WIDER_MODE (fmode
))
3817 /* Make sure we won't lose significant bits doing this. */
3818 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
3819 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
3823 REAL_VALUE_TYPE offset
;
3824 rtx limit
, lab1
, lab2
, insn
;
3826 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
3827 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
3828 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
3829 lab1
= gen_label_rtx ();
3830 lab2
= gen_label_rtx ();
3833 to
= protect_from_queue (to
, 1);
3834 from
= protect_from_queue (from
, 0);
3837 from
= force_not_mem (from
);
3839 if (fmode
!= GET_MODE (from
))
3840 from
= convert_to_mode (fmode
, from
, 0);
3842 /* See if we need to do the subtraction. */
3843 do_pending_stack_adjust ();
3844 emit_cmp_insn (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3845 emit_jump_insn (gen_bge (lab1
));
3847 /* If not, do the signed "fix" and branch around fixup code. */
3848 expand_fix (to
, from
, 0);
3849 emit_jump_insn (gen_jump (lab2
));
3852 /* Otherwise, subtract 2**(N-1), convert to signed number,
3853 then add 2**(N-1). Do the addition using XOR since this
3854 will often generate better code. */
3856 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
3857 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3858 expand_fix (to
, target
, 0);
3859 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
3860 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
3861 to
, 1, OPTAB_LIB_WIDEN
);
3864 emit_move_insn (to
, target
);
3868 if (mov_optab
->handlers
[(int) GET_MODE (to
)].insn_code
3869 != CODE_FOR_nothing
)
3871 /* Make a place for a REG_NOTE and add it. */
3872 insn
= emit_move_insn (to
, to
);
3874 = gen_rtx_EXPR_LIST (REG_EQUAL
,
3875 gen_rtx_fmt_e (UNSIGNED_FIX
,
3884 /* We can't do it with an insn, so use a library call. But first ensure
3885 that the mode of TO is at least as wide as SImode, since those are the
3886 only library calls we know about. */
3888 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
3890 target
= gen_reg_rtx (SImode
);
3892 expand_fix (target
, from
, unsignedp
);
3894 else if (GET_MODE (from
) == SFmode
)
3896 if (GET_MODE (to
) == SImode
)
3897 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
3898 else if (GET_MODE (to
) == DImode
)
3899 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
3900 else if (GET_MODE (to
) == TImode
)
3901 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
3905 else if (GET_MODE (from
) == DFmode
)
3907 if (GET_MODE (to
) == SImode
)
3908 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
3909 else if (GET_MODE (to
) == DImode
)
3910 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
3911 else if (GET_MODE (to
) == TImode
)
3912 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
3916 else if (GET_MODE (from
) == XFmode
)
3918 if (GET_MODE (to
) == SImode
)
3919 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
3920 else if (GET_MODE (to
) == DImode
)
3921 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
3922 else if (GET_MODE (to
) == TImode
)
3923 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
3927 else if (GET_MODE (from
) == TFmode
)
3929 if (GET_MODE (to
) == SImode
)
3930 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
3931 else if (GET_MODE (to
) == DImode
)
3932 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
3933 else if (GET_MODE (to
) == TImode
)
3934 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
3946 to
= protect_from_queue (to
, 1);
3947 from
= protect_from_queue (from
, 0);
3950 from
= force_not_mem (from
);
3954 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1, GET_MODE (to
),
3956 1, from
, GET_MODE (from
));
3957 insns
= get_insns ();
3960 emit_libcall_block (insns
, target
, value
,
3961 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
3962 GET_MODE (to
), from
));
3967 if (GET_MODE (to
) == GET_MODE (target
))
3968 emit_move_insn (to
, target
);
3970 convert_move (to
, target
, 0);
3979 optab op
= (optab
) xmalloc (sizeof (struct optab
));
3981 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3983 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
3984 op
->handlers
[i
].libfunc
= 0;
3987 if (code
!= UNKNOWN
)
3988 code_to_optab
[(int) code
] = op
;
3993 /* Initialize the libfunc fields of an entire group of entries in some
3994 optab. Each entry is set equal to a string consisting of a leading
3995 pair of underscores followed by a generic operation name followed by
3996 a mode name (downshifted to lower case) followed by a single character
3997 representing the number of operands for the given operation (which is
3998 usually one of the characters '2', '3', or '4').
4000 OPTABLE is the table in which libfunc fields are to be initialized.
4001 FIRST_MODE is the first machine mode index in the given optab to
4003 LAST_MODE is the last machine mode index in the given optab to
4005 OPNAME is the generic (string) name of the operation.
4006 SUFFIX is the character which specifies the number of operands for
4007 the given generic operation.
4011 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
4012 register optab optable
;
4013 register int first_mode
;
4014 register int last_mode
;
4015 register char *opname
;
4016 register int suffix
;
4019 register unsigned opname_len
= strlen (opname
);
4021 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
4022 mode
= (enum machine_mode
) ((int) mode
+ 1))
4024 register char *mname
= mode_name
[(int) mode
];
4025 register unsigned mname_len
= strlen (mname
);
4026 register char *libfunc_name
4027 = (char *) xmalloc (2 + opname_len
+ mname_len
+ 1 + 1);
4034 for (q
= opname
; *q
; )
4036 for (q
= mname
; *q
; q
++)
4037 *p
++ = tolower (*q
);
4040 optable
->handlers
[(int) mode
].libfunc
4041 = gen_rtx_SYMBOL_REF (Pmode
, libfunc_name
);
4045 /* Initialize the libfunc fields of an entire group of entries in some
4046 optab which correspond to all integer mode operations. The parameters
4047 have the same meaning as similarly named ones for the `init_libfuncs'
4048 routine. (See above). */
4051 init_integral_libfuncs (optable
, opname
, suffix
)
4052 register optab optable
;
4053 register char *opname
;
4054 register int suffix
;
4056 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
4059 /* Initialize the libfunc fields of an entire group of entries in some
4060 optab which correspond to all real mode operations. The parameters
4061 have the same meaning as similarly named ones for the `init_libfuncs'
4062 routine. (See above). */
4065 init_floating_libfuncs (optable
, opname
, suffix
)
4066 register optab optable
;
4067 register char *opname
;
4068 register int suffix
;
4070 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
4074 /* Call this once to initialize the contents of the optabs
4075 appropriately for the current target machine. */
4081 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4087 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4089 for (p
= fixtab
[0][0];
4090 p
< fixtab
[0][0] + sizeof fixtab
/ sizeof (fixtab
[0][0][0]);
4092 *p
= CODE_FOR_nothing
;
4094 for (p
= fixtrunctab
[0][0];
4095 p
< fixtrunctab
[0][0] + sizeof fixtrunctab
/ sizeof (fixtrunctab
[0][0][0]);
4097 *p
= CODE_FOR_nothing
;
4099 for (p
= floattab
[0][0];
4100 p
< floattab
[0][0] + sizeof floattab
/ sizeof (floattab
[0][0][0]);
4102 *p
= CODE_FOR_nothing
;
4104 for (p
= extendtab
[0][0];
4105 p
< extendtab
[0][0] + sizeof extendtab
/ sizeof extendtab
[0][0][0];
4107 *p
= CODE_FOR_nothing
;
4109 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
4110 setcc_gen_code
[i
] = CODE_FOR_nothing
;
4112 #ifdef HAVE_conditional_move
4113 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4114 movcc_gen_code
[i
] = CODE_FOR_nothing
;
4117 add_optab
= init_optab (PLUS
);
4118 sub_optab
= init_optab (MINUS
);
4119 smul_optab
= init_optab (MULT
);
4120 smul_highpart_optab
= init_optab (UNKNOWN
);
4121 umul_highpart_optab
= init_optab (UNKNOWN
);
4122 smul_widen_optab
= init_optab (UNKNOWN
);
4123 umul_widen_optab
= init_optab (UNKNOWN
);
4124 sdiv_optab
= init_optab (DIV
);
4125 sdivmod_optab
= init_optab (UNKNOWN
);
4126 udiv_optab
= init_optab (UDIV
);
4127 udivmod_optab
= init_optab (UNKNOWN
);
4128 smod_optab
= init_optab (MOD
);
4129 umod_optab
= init_optab (UMOD
);
4130 flodiv_optab
= init_optab (DIV
);
4131 ftrunc_optab
= init_optab (UNKNOWN
);
4132 and_optab
= init_optab (AND
);
4133 ior_optab
= init_optab (IOR
);
4134 xor_optab
= init_optab (XOR
);
4135 ashl_optab
= init_optab (ASHIFT
);
4136 ashr_optab
= init_optab (ASHIFTRT
);
4137 lshr_optab
= init_optab (LSHIFTRT
);
4138 rotl_optab
= init_optab (ROTATE
);
4139 rotr_optab
= init_optab (ROTATERT
);
4140 smin_optab
= init_optab (SMIN
);
4141 smax_optab
= init_optab (SMAX
);
4142 umin_optab
= init_optab (UMIN
);
4143 umax_optab
= init_optab (UMAX
);
4144 mov_optab
= init_optab (UNKNOWN
);
4145 movstrict_optab
= init_optab (UNKNOWN
);
4146 cmp_optab
= init_optab (UNKNOWN
);
4147 ucmp_optab
= init_optab (UNKNOWN
);
4148 tst_optab
= init_optab (UNKNOWN
);
4149 neg_optab
= init_optab (NEG
);
4150 abs_optab
= init_optab (ABS
);
4151 one_cmpl_optab
= init_optab (NOT
);
4152 ffs_optab
= init_optab (FFS
);
4153 sqrt_optab
= init_optab (SQRT
);
4154 sin_optab
= init_optab (UNKNOWN
);
4155 cos_optab
= init_optab (UNKNOWN
);
4156 strlen_optab
= init_optab (UNKNOWN
);
4158 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4160 movstr_optab
[i
] = CODE_FOR_nothing
;
4161 clrstr_optab
[i
] = CODE_FOR_nothing
;
4163 #ifdef HAVE_SECONDARY_RELOADS
4164 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
4168 /* Fill in the optabs with the insns we support. */
4171 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4172 /* This flag says the same insns that convert to a signed fixnum
4173 also convert validly to an unsigned one. */
4174 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4175 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
4176 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
4179 #ifdef EXTRA_CC_MODES
4183 /* Initialize the optabs with the names of the library functions. */
4184 init_integral_libfuncs (add_optab
, "add", '3');
4185 init_floating_libfuncs (add_optab
, "add", '3');
4186 init_integral_libfuncs (sub_optab
, "sub", '3');
4187 init_floating_libfuncs (sub_optab
, "sub", '3');
4188 init_integral_libfuncs (smul_optab
, "mul", '3');
4189 init_floating_libfuncs (smul_optab
, "mul", '3');
4190 init_integral_libfuncs (sdiv_optab
, "div", '3');
4191 init_integral_libfuncs (udiv_optab
, "udiv", '3');
4192 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
4193 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
4194 init_integral_libfuncs (smod_optab
, "mod", '3');
4195 init_integral_libfuncs (umod_optab
, "umod", '3');
4196 init_floating_libfuncs (flodiv_optab
, "div", '3');
4197 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
4198 init_integral_libfuncs (and_optab
, "and", '3');
4199 init_integral_libfuncs (ior_optab
, "ior", '3');
4200 init_integral_libfuncs (xor_optab
, "xor", '3');
4201 init_integral_libfuncs (ashl_optab
, "ashl", '3');
4202 init_integral_libfuncs (ashr_optab
, "ashr", '3');
4203 init_integral_libfuncs (lshr_optab
, "lshr", '3');
4204 init_integral_libfuncs (smin_optab
, "min", '3');
4205 init_floating_libfuncs (smin_optab
, "min", '3');
4206 init_integral_libfuncs (smax_optab
, "max", '3');
4207 init_floating_libfuncs (smax_optab
, "max", '3');
4208 init_integral_libfuncs (umin_optab
, "umin", '3');
4209 init_integral_libfuncs (umax_optab
, "umax", '3');
4210 init_integral_libfuncs (neg_optab
, "neg", '2');
4211 init_floating_libfuncs (neg_optab
, "neg", '2');
4212 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
4213 init_integral_libfuncs (ffs_optab
, "ffs", '2');
4215 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4216 init_integral_libfuncs (cmp_optab
, "cmp", '2');
4217 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
4218 init_floating_libfuncs (cmp_optab
, "cmp", '2');
4220 #ifdef MULSI3_LIBCALL
4221 smul_optab
->handlers
[(int) SImode
].libfunc
4222 = gen_rtx_SYMBOL_REF (Pmode
, MULSI3_LIBCALL
);
4224 #ifdef MULDI3_LIBCALL
4225 smul_optab
->handlers
[(int) DImode
].libfunc
4226 = gen_rtx_SYMBOL_REF (Pmode
, MULDI3_LIBCALL
);
4229 #ifdef DIVSI3_LIBCALL
4230 sdiv_optab
->handlers
[(int) SImode
].libfunc
4231 = gen_rtx_SYMBOL_REF (Pmode
, DIVSI3_LIBCALL
);
4233 #ifdef DIVDI3_LIBCALL
4234 sdiv_optab
->handlers
[(int) DImode
].libfunc
4235 = gen_rtx_SYMBOL_REF (Pmode
, DIVDI3_LIBCALL
);
4238 #ifdef UDIVSI3_LIBCALL
4239 udiv_optab
->handlers
[(int) SImode
].libfunc
4240 = gen_rtx_SYMBOL_REF (Pmode
, UDIVSI3_LIBCALL
);
4242 #ifdef UDIVDI3_LIBCALL
4243 udiv_optab
->handlers
[(int) DImode
].libfunc
4244 = gen_rtx_SYMBOL_REF (Pmode
, UDIVDI3_LIBCALL
);
4247 #ifdef MODSI3_LIBCALL
4248 smod_optab
->handlers
[(int) SImode
].libfunc
4249 = gen_rtx_SYMBOL_REF (Pmode
, MODSI3_LIBCALL
);
4251 #ifdef MODDI3_LIBCALL
4252 smod_optab
->handlers
[(int) DImode
].libfunc
4253 = gen_rtx_SYMBOL_REF (Pmode
, MODDI3_LIBCALL
);
4256 #ifdef UMODSI3_LIBCALL
4257 umod_optab
->handlers
[(int) SImode
].libfunc
4258 = gen_rtx_SYMBOL_REF (Pmode
, UMODSI3_LIBCALL
);
4260 #ifdef UMODDI3_LIBCALL
4261 umod_optab
->handlers
[(int) DImode
].libfunc
4262 = gen_rtx_SYMBOL_REF (Pmode
, UMODDI3_LIBCALL
);
4265 /* Use cabs for DC complex abs, since systems generally have cabs.
4266 Don't define any libcall for SCmode, so that cabs will be used. */
4267 abs_optab
->handlers
[(int) DCmode
].libfunc
4268 = gen_rtx_SYMBOL_REF (Pmode
, "cabs");
4270 /* The ffs function operates on `int'. */
4271 #ifndef INT_TYPE_SIZE
4272 #define INT_TYPE_SIZE BITS_PER_WORD
4274 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)] .libfunc
4275 = gen_rtx_SYMBOL_REF (Pmode
, "ffs");
4277 extendsfdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extendsfdf2");
4278 extendsfxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extendsfxf2");
4279 extendsftf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extendsftf2");
4280 extenddfxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extenddfxf2");
4281 extenddftf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__extenddftf2");
4283 truncdfsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__truncdfsf2");
4284 truncxfsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__truncxfsf2");
4285 trunctfsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__trunctfsf2");
4286 truncxfdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__truncxfdf2");
4287 trunctfdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__trunctfdf2");
4289 memcpy_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "memcpy");
4290 bcopy_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "bcopy");
4291 memcmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "memcmp");
4292 bcmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gcc_bcmp");
4293 memset_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "memset");
4294 bzero_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "bzero");
4296 throw_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__throw");
4297 sjthrow_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__sjthrow");
4298 sjpopnthrow_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__sjpopnthrow");
4299 terminate_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__terminate");
4300 eh_rtime_match_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eh_rtime_match");
4301 #ifndef DONT_USE_BUILTIN_SETJMP
4302 setjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__builtin_setjmp");
4303 longjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__builtin_longjmp");
4305 setjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "setjmp");
4306 longjmp_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "longjmp");
4309 eqhf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqhf2");
4310 nehf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nehf2");
4311 gthf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gthf2");
4312 gehf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gehf2");
4313 lthf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lthf2");
4314 lehf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lehf2");
4316 eqsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqsf2");
4317 nesf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nesf2");
4318 gtsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gtsf2");
4319 gesf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gesf2");
4320 ltsf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ltsf2");
4321 lesf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lesf2");
4323 eqdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqdf2");
4324 nedf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nedf2");
4325 gtdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gtdf2");
4326 gedf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gedf2");
4327 ltdf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ltdf2");
4328 ledf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ledf2");
4330 eqxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqxf2");
4331 nexf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__nexf2");
4332 gtxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gtxf2");
4333 gexf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gexf2");
4334 ltxf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__ltxf2");
4335 lexf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lexf2");
4337 eqtf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__eqtf2");
4338 netf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__netf2");
4339 gttf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__gttf2");
4340 getf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__getf2");
4341 lttf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__lttf2");
4342 letf2_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__letf2");
4344 floatsisf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsisf");
4345 floatdisf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatdisf");
4346 floattisf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattisf");
4348 floatsidf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsidf");
4349 floatdidf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatdidf");
4350 floattidf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattidf");
4352 floatsixf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsixf");
4353 floatdixf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatdixf");
4354 floattixf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattixf");
4356 floatsitf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatsitf");
4357 floatditf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floatditf");
4358 floattitf_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__floattitf");
4360 fixsfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixsfsi");
4361 fixsfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixsfdi");
4362 fixsfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixsfti");
4364 fixdfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixdfsi");
4365 fixdfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixdfdi");
4366 fixdfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixdfti");
4368 fixxfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixxfsi");
4369 fixxfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixxfdi");
4370 fixxfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixxfti");
4372 fixtfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixtfsi");
4373 fixtfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixtfdi");
4374 fixtfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixtfti");
4376 fixunssfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunssfsi");
4377 fixunssfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunssfdi");
4378 fixunssfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunssfti");
4380 fixunsdfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsdfsi");
4381 fixunsdfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsdfdi");
4382 fixunsdfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsdfti");
4384 fixunsxfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsxfsi");
4385 fixunsxfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsxfdi");
4386 fixunsxfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunsxfti");
4388 fixunstfsi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunstfsi");
4389 fixunstfdi_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunstfdi");
4390 fixunstfti_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "__fixunstfti");
4392 /* For check-memory-usage. */
4393 chkr_check_addr_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "chkr_check_addr");
4394 chkr_set_right_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "chkr_set_right");
4395 chkr_copy_bitmap_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "chkr_copy_bitmap");
4396 chkr_check_exec_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "chkr_check_exec");
4397 chkr_check_str_libfunc
= gen_rtx_SYMBOL_REF (Pmode
, "chkr_check_str");
4399 /* For function entry/exit instrumentation. */
4400 profile_function_entry_libfunc
4401 = gen_rtx_SYMBOL_REF (Pmode
, "__cyg_profile_func_enter");
4402 profile_function_exit_libfunc
4403 = gen_rtx_SYMBOL_REF (Pmode
, "__cyg_profile_func_exit");
4405 #ifdef HAVE_conditional_trap
4409 #ifdef INIT_TARGET_OPTABS
4410 /* Allow the target to add more libcalls or rename some, etc. */
4417 /* SCO 3.2 apparently has a broken ldexp. */
4430 #endif /* BROKEN_LDEXP */
4432 #ifdef HAVE_conditional_trap
4433 /* The insn generating function can not take an rtx_code argument.
4434 TRAP_RTX is used as an rtx argument. Its code is replaced with
4435 the code to be used in the trap insn and all other fields are
4438 ??? Will need to change to support garbage collection. */
4439 static rtx trap_rtx
;
4444 if (HAVE_conditional_trap
)
4445 trap_rtx
= gen_rtx_fmt_ee (EQ
, VOIDmode
, NULL_RTX
, NULL_RTX
);
4449 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4450 CODE. Return 0 on failure. */
4453 gen_cond_trap (code
, op1
, op2
, tcode
)
4455 rtx op1
, op2
, tcode
;
4457 enum machine_mode mode
= GET_MODE (op1
);
4459 if (mode
== VOIDmode
)
4462 #ifdef HAVE_conditional_trap
4463 if (HAVE_conditional_trap
4464 && cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
4467 emit_insn (GEN_FCN (cmp_optab
->handlers
[(int) mode
].insn_code
) (op1
, op2
));
4468 PUT_CODE (trap_rtx
, code
);
4469 insn
= gen_conditional_trap (trap_rtx
, tcode
);