1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "insn-flags.h"
26 #include "insn-codes.h"
28 #include "insn-config.h"
33 /* Each optab contains info on how this target machine
34 can perform a particular operation
35 for all sizes and kinds of operands.
37 The operation to be performed is often specified
38 by passing one of these optabs as an argument.
40 See expr.h for documentation of these optabs. */
45 optab smul_highpart_optab;
46 optab umul_highpart_optab;
47 optab smul_widen_optab;
48 optab umul_widen_optab;
71 optab movstrict_optab;
82 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
87 /* Tables of patterns for extending one integer mode to another. */
88 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
90 /* Tables of patterns for converting between fixed and floating point. */
91 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
92 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
95 /* Contains the optab used for each rtx code. */
96 optab code_to_optab[NUM_RTX_CODE + 1];
98 /* SYMBOL_REF rtx's for the library functions that are called
99 implicitly and not via optabs. */
101 rtx extendsfdf2_libfunc;
102 rtx extendsfxf2_libfunc;
103 rtx extendsftf2_libfunc;
104 rtx extenddfxf2_libfunc;
105 rtx extenddftf2_libfunc;
107 rtx truncdfsf2_libfunc;
108 rtx truncxfsf2_libfunc;
109 rtx trunctfsf2_libfunc;
110 rtx truncxfdf2_libfunc;
111 rtx trunctfdf2_libfunc;
155 rtx floatsisf_libfunc;
156 rtx floatdisf_libfunc;
157 rtx floattisf_libfunc;
159 rtx floatsidf_libfunc;
160 rtx floatdidf_libfunc;
161 rtx floattidf_libfunc;
163 rtx floatsixf_libfunc;
164 rtx floatdixf_libfunc;
165 rtx floattixf_libfunc;
167 rtx floatsitf_libfunc;
168 rtx floatditf_libfunc;
169 rtx floattitf_libfunc;
187 rtx fixunssfsi_libfunc;
188 rtx fixunssfdi_libfunc;
189 rtx fixunssfti_libfunc;
191 rtx fixunsdfsi_libfunc;
192 rtx fixunsdfdi_libfunc;
193 rtx fixunsdfti_libfunc;
195 rtx fixunsxfsi_libfunc;
196 rtx fixunsxfdi_libfunc;
197 rtx fixunsxfti_libfunc;
199 rtx fixunstfsi_libfunc;
200 rtx fixunstfdi_libfunc;
201 rtx fixunstfti_libfunc;
203 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
204 gives the gen_function to make a branch to test that condition. */
206 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
208 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
209 gives the insn code to make a store-condition insn
210 to test that condition. */
212 enum insn_code setcc_gen_code[NUM_RTX_CODE];
214 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
215 static rtx widen_operand PROTO((rtx, enum machine_mode,
216 enum machine_mode, int, int));
217 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
219 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
221 static rtx ftruncify PROTO((rtx));
222 static optab init_optab PROTO((enum rtx_code));
223 static void init_libfuncs PROTO((optab, int, int, char *, int));
224 static void init_integral_libfuncs PROTO((optab, char *, int));
225 static void init_floating_libfuncs PROTO((optab, char *, int));
226 static void init_complex_libfuncs PROTO((optab, char *, int));
228 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
229 the result of operation CODE applied to OP0 (and OP1 if it is a binary
232 If the last insn does not set TARGET, don't do anything, but return 1.
234 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
235 don't add the REG_EQUAL note but return 0. Our caller can then try
236 again, ensuring that TARGET is not one of the operands. */
239 add_equal_note (seq, target, code, op0, op1)
249 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
250 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
251 || GET_CODE (seq) != SEQUENCE
252 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
253 || GET_CODE (target) == ZERO_EXTRACT
254 || (! rtx_equal_p (SET_DEST (set), target)
255 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
257 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
258 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
262 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
263 besides the last insn. */
264 if (reg_overlap_mentioned_p (target, op0)
265 || (op1 && reg_overlap_mentioned_p (target, op1)))
266 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
267 if (reg_set_p (target, XVECEXP (seq, 0, i)))
270 if (GET_RTX_CLASS (code) == '1')
271 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
273 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
275 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
276 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
277 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
282 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
283 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
284 not actually do a sign-extend or zero-extend, but can leave the
285 higher-order bits of the result rtx undefined, for example, in the case
286 of logical operations, but not right shifts. */
289 widen_operand (op, mode, oldmode, unsignedp, no_extend)
291 enum machine_mode mode, oldmode;
297 /* If we must extend do so. If OP is either a constant or a SUBREG
298 for a promoted object, also extend since it will be more efficient to
301 || GET_MODE (op) == VOIDmode
302 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
303 return convert_modes (mode, oldmode, op, unsignedp);
305 /* If MODE is no wider than a single word, we return a paradoxical
307 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
308 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
310 /* Otherwise, get an object of MODE, clobber it, and set the low-order
313 result = gen_reg_rtx (mode);
314 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
315 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
319 /* Generate code to perform an operation specified by BINOPTAB
320 on operands OP0 and OP1, with result having machine-mode MODE.
322 UNSIGNEDP is for the case where we have to widen the operands
323 to perform the operation. It says to use zero-extension.
325 If TARGET is nonzero, the value
326 is generated there, if it is convenient to do so.
327 In all cases an rtx is returned for the locus of the value;
328 this may or may not be TARGET. */
331 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
332 enum machine_mode mode;
337 enum optab_methods methods;
339 enum optab_methods next_methods
340 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
341 ? OPTAB_WIDEN : methods);
342 enum mode_class class;
343 enum machine_mode wider_mode;
345 int commutative_op = 0;
346 int shift_op = (binoptab->code == ASHIFT
347 || binoptab->code == ASHIFTRT
348 || binoptab->code == LSHIFTRT
349 || binoptab->code == ROTATE
350 || binoptab->code == ROTATERT);
351 rtx entry_last = get_last_insn ();
354 class = GET_MODE_CLASS (mode);
356 op0 = protect_from_queue (op0, 0);
357 op1 = protect_from_queue (op1, 0);
359 target = protect_from_queue (target, 1);
363 op0 = force_not_mem (op0);
364 op1 = force_not_mem (op1);
367 /* If subtracting an integer constant, convert this into an addition of
368 the negated constant. */
370 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
372 op1 = negate_rtx (mode, op1);
373 binoptab = add_optab;
376 /* If we are inside an appropriately-short loop and one operand is an
377 expensive constant, force it into a register. */
378 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
379 && rtx_cost (op0, binoptab->code) > 2)
380 op0 = force_reg (mode, op0);
382 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
383 && rtx_cost (op1, binoptab->code) > 2)
384 op1 = force_reg (shift_op ? word_mode : mode, op1);
386 /* Record where to delete back to if we backtrack. */
387 last = get_last_insn ();
389 /* If operation is commutative,
390 try to make the first operand a register.
391 Even better, try to make it the same as the target.
392 Also try to make the last operand a constant. */
393 if (GET_RTX_CLASS (binoptab->code) == 'c'
394 || binoptab == smul_widen_optab
395 || binoptab == umul_widen_optab
396 || binoptab == smul_highpart_optab
397 || binoptab == umul_highpart_optab)
401 if (((target == 0 || GET_CODE (target) == REG)
402 ? ((GET_CODE (op1) == REG
403 && GET_CODE (op0) != REG)
405 : rtx_equal_p (op1, target))
406 || GET_CODE (op0) == CONST_INT)
414 /* If we can do it with a three-operand insn, do so. */
416 if (methods != OPTAB_MUST_WIDEN
417 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
419 int icode = (int) binoptab->handlers[(int) mode].insn_code;
420 enum machine_mode mode0 = insn_operand_mode[icode][1];
421 enum machine_mode mode1 = insn_operand_mode[icode][2];
423 rtx xop0 = op0, xop1 = op1;
428 temp = gen_reg_rtx (mode);
430 /* If it is a commutative operator and the modes would match
431 if we would swap the operands, we can save the conversions. */
434 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
435 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
439 tmp = op0; op0 = op1; op1 = tmp;
440 tmp = xop0; xop0 = xop1; xop1 = tmp;
444 /* In case the insn wants input operands in modes different from
445 the result, convert the operands. */
447 if (GET_MODE (op0) != VOIDmode
448 && GET_MODE (op0) != mode0)
449 xop0 = convert_to_mode (mode0, xop0, unsignedp);
451 if (GET_MODE (xop1) != VOIDmode
452 && GET_MODE (xop1) != mode1)
453 xop1 = convert_to_mode (mode1, xop1, unsignedp);
455 /* Now, if insn's predicates don't allow our operands, put them into
458 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
459 xop0 = copy_to_mode_reg (mode0, xop0);
461 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
462 xop1 = copy_to_mode_reg (mode1, xop1);
464 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
465 temp = gen_reg_rtx (mode);
467 pat = GEN_FCN (icode) (temp, xop0, xop1);
470 /* If PAT is a multi-insn sequence, try to add an appropriate
471 REG_EQUAL note to it. If we can't because TEMP conflicts with an
472 operand, call ourselves again, this time without a target. */
473 if (GET_CODE (pat) == SEQUENCE
474 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
476 delete_insns_since (last);
477 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
485 delete_insns_since (last);
488 /* If this is a multiply, see if we can do a widening operation that
489 takes operands of this mode and makes a wider mode. */
491 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
492 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
493 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
494 != CODE_FOR_nothing))
496 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
497 unsignedp ? umul_widen_optab : smul_widen_optab,
498 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
502 if (GET_MODE_CLASS (mode) == MODE_INT)
503 return gen_lowpart (mode, temp);
505 return convert_to_mode (mode, temp, unsignedp);
509 /* Look for a wider mode of the same class for which we think we
510 can open-code the operation. Check for a widening multiply at the
511 wider mode as well. */
513 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
514 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
515 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
516 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
518 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
519 || (binoptab == smul_optab
520 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
521 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
522 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
523 != CODE_FOR_nothing)))
525 rtx xop0 = op0, xop1 = op1;
528 /* For certain integer operations, we need not actually extend
529 the narrow operands, as long as we will truncate
530 the results to the same narrowness. */
532 if ((binoptab == ior_optab || binoptab == and_optab
533 || binoptab == xor_optab
534 || binoptab == add_optab || binoptab == sub_optab
535 || binoptab == smul_optab || binoptab == ashl_optab)
536 && class == MODE_INT)
539 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
541 /* The second operand of a shift must always be extended. */
542 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
543 no_extend && binoptab != ashl_optab);
545 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
546 unsignedp, OPTAB_DIRECT);
549 if (class != MODE_INT)
552 target = gen_reg_rtx (mode);
553 convert_move (target, temp, 0);
557 return gen_lowpart (mode, temp);
560 delete_insns_since (last);
564 /* These can be done a word at a time. */
565 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
567 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
568 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
574 /* If TARGET is the same as one of the operands, the REG_EQUAL note
575 won't be accurate, so use a new target. */
576 if (target == 0 || target == op0 || target == op1)
577 target = gen_reg_rtx (mode);
581 /* Do the actual arithmetic. */
582 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
584 rtx target_piece = operand_subword (target, i, 1, mode);
585 rtx x = expand_binop (word_mode, binoptab,
586 operand_subword_force (op0, i, mode),
587 operand_subword_force (op1, i, mode),
588 target_piece, unsignedp, next_methods);
593 if (target_piece != x)
594 emit_move_insn (target_piece, x);
597 insns = get_insns ();
600 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
602 if (binoptab->code != UNKNOWN)
604 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
608 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
613 /* Synthesize double word shifts from single word shifts. */
614 if ((binoptab == lshr_optab || binoptab == ashl_optab
615 || binoptab == ashr_optab)
617 && GET_CODE (op1) == CONST_INT
618 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
619 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
620 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
621 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
623 rtx insns, inter, equiv_value;
624 rtx into_target, outof_target;
625 rtx into_input, outof_input;
626 int shift_count, left_shift, outof_word;
628 /* If TARGET is the same as one of the operands, the REG_EQUAL note
629 won't be accurate, so use a new target. */
630 if (target == 0 || target == op0 || target == op1)
631 target = gen_reg_rtx (mode);
635 shift_count = INTVAL (op1);
637 /* OUTOF_* is the word we are shifting bits away from, and
638 INTO_* is the word that we are shifting bits towards, thus
639 they differ depending on the direction of the shift and
642 left_shift = binoptab == ashl_optab;
643 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
645 outof_target = operand_subword (target, outof_word, 1, mode);
646 into_target = operand_subword (target, 1 - outof_word, 1, mode);
648 outof_input = operand_subword_force (op0, outof_word, mode);
649 into_input = operand_subword_force (op0, 1 - outof_word, mode);
651 if (shift_count >= BITS_PER_WORD)
653 inter = expand_binop (word_mode, binoptab,
655 GEN_INT (shift_count - BITS_PER_WORD),
656 into_target, unsignedp, next_methods);
658 if (inter != 0 && inter != into_target)
659 emit_move_insn (into_target, inter);
661 /* For a signed right shift, we must fill the word we are shifting
662 out of with copies of the sign bit. Otherwise it is zeroed. */
663 if (inter != 0 && binoptab != ashr_optab)
664 inter = CONST0_RTX (word_mode);
666 inter = expand_binop (word_mode, binoptab,
668 GEN_INT (BITS_PER_WORD - 1),
669 outof_target, unsignedp, next_methods);
671 if (inter != 0 && inter != outof_target)
672 emit_move_insn (outof_target, inter);
677 optab reverse_unsigned_shift, unsigned_shift;
679 /* For a shift of less then BITS_PER_WORD, to compute the carry,
680 we must do a logical shift in the opposite direction of the
683 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
685 /* For a shift of less than BITS_PER_WORD, to compute the word
686 shifted towards, we need to unsigned shift the orig value of
689 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
691 carries = expand_binop (word_mode, reverse_unsigned_shift,
693 GEN_INT (BITS_PER_WORD - shift_count),
694 0, unsignedp, next_methods);
699 inter = expand_binop (word_mode, unsigned_shift, into_input,
700 op1, 0, unsignedp, next_methods);
703 inter = expand_binop (word_mode, ior_optab, carries, inter,
704 into_target, unsignedp, next_methods);
706 if (inter != 0 && inter != into_target)
707 emit_move_insn (into_target, inter);
710 inter = expand_binop (word_mode, binoptab, outof_input,
711 op1, outof_target, unsignedp, next_methods);
713 if (inter != 0 && inter != outof_target)
714 emit_move_insn (outof_target, inter);
717 insns = get_insns ();
722 if (binoptab->code != UNKNOWN)
723 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
727 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
732 /* Synthesize double word rotates from single word shifts. */
733 if ((binoptab == rotl_optab || binoptab == rotr_optab)
735 && GET_CODE (op1) == CONST_INT
736 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
737 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
738 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
740 rtx insns, equiv_value;
741 rtx into_target, outof_target;
742 rtx into_input, outof_input;
744 int shift_count, left_shift, outof_word;
746 /* If TARGET is the same as one of the operands, the REG_EQUAL note
747 won't be accurate, so use a new target. */
748 if (target == 0 || target == op0 || target == op1)
749 target = gen_reg_rtx (mode);
753 shift_count = INTVAL (op1);
755 /* OUTOF_* is the word we are shifting bits away from, and
756 INTO_* is the word that we are shifting bits towards, thus
757 they differ depending on the direction of the shift and
760 left_shift = (binoptab == rotl_optab);
761 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
763 outof_target = operand_subword (target, outof_word, 1, mode);
764 into_target = operand_subword (target, 1 - outof_word, 1, mode);
766 outof_input = operand_subword_force (op0, outof_word, mode);
767 into_input = operand_subword_force (op0, 1 - outof_word, mode);
769 if (shift_count == BITS_PER_WORD)
771 /* This is just a word swap. */
772 emit_move_insn (outof_target, into_input);
773 emit_move_insn (into_target, outof_input);
778 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
779 rtx first_shift_count, second_shift_count;
780 optab reverse_unsigned_shift, unsigned_shift;
782 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
783 ? lshr_optab : ashl_optab);
785 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
786 ? ashl_optab : lshr_optab);
788 if (shift_count > BITS_PER_WORD)
790 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
791 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
795 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
796 second_shift_count = GEN_INT (shift_count);
799 into_temp1 = expand_binop (word_mode, unsigned_shift,
800 outof_input, first_shift_count,
801 NULL_RTX, unsignedp, next_methods);
802 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
803 into_input, second_shift_count,
804 into_target, unsignedp, next_methods);
806 if (into_temp1 != 0 && into_temp2 != 0)
807 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
808 into_target, unsignedp, next_methods);
812 if (inter != 0 && inter != into_target)
813 emit_move_insn (into_target, inter);
815 outof_temp1 = expand_binop (word_mode, unsigned_shift,
816 into_input, first_shift_count,
817 NULL_RTX, unsignedp, next_methods);
818 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
819 outof_input, second_shift_count,
820 outof_target, unsignedp, next_methods);
822 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
823 inter = expand_binop (word_mode, ior_optab,
824 outof_temp1, outof_temp2,
825 outof_target, unsignedp, next_methods);
827 if (inter != 0 && inter != outof_target)
828 emit_move_insn (outof_target, inter);
831 insns = get_insns ();
836 if (binoptab->code != UNKNOWN)
837 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
841 /* We can't make this a no conflict block if this is a word swap,
842 because the word swap case fails if the input and output values
843 are in the same register. */
844 if (shift_count != BITS_PER_WORD)
845 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
854 /* These can be done a word at a time by propagating carries. */
855 if ((binoptab == add_optab || binoptab == sub_optab)
857 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
858 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
861 rtx carry_tmp = gen_reg_rtx (word_mode);
862 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
863 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
864 rtx carry_in, carry_out;
867 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
868 value is one of those, use it. Otherwise, use 1 since it is the
869 one easiest to get. */
870 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
871 int normalizep = STORE_FLAG_VALUE;
876 /* Prepare the operands. */
877 xop0 = force_reg (mode, op0);
878 xop1 = force_reg (mode, op1);
880 if (target == 0 || GET_CODE (target) != REG
881 || target == xop0 || target == xop1)
882 target = gen_reg_rtx (mode);
884 /* Indicate for flow that the entire target reg is being set. */
885 if (GET_CODE (target) == REG)
886 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
888 /* Do the actual arithmetic. */
889 for (i = 0; i < nwords; i++)
891 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
892 rtx target_piece = operand_subword (target, index, 1, mode);
893 rtx op0_piece = operand_subword_force (xop0, index, mode);
894 rtx op1_piece = operand_subword_force (xop1, index, mode);
897 /* Main add/subtract of the input operands. */
898 x = expand_binop (word_mode, binoptab,
899 op0_piece, op1_piece,
900 target_piece, unsignedp, next_methods);
906 /* Store carry from main add/subtract. */
907 carry_out = gen_reg_rtx (word_mode);
908 carry_out = emit_store_flag (carry_out,
909 binoptab == add_optab ? LTU : GTU,
911 word_mode, 1, normalizep);
918 /* Add/subtract previous carry to main result. */
919 x = expand_binop (word_mode,
920 normalizep == 1 ? binoptab : otheroptab,
922 target_piece, 1, next_methods);
925 else if (target_piece != x)
926 emit_move_insn (target_piece, x);
930 /* THIS CODE HAS NOT BEEN TESTED. */
931 /* Get out carry from adding/subtracting carry in. */
932 carry_tmp = emit_store_flag (carry_tmp,
933 binoptab == add_optab
936 word_mode, 1, normalizep);
938 /* Logical-ior the two poss. carry together. */
939 carry_out = expand_binop (word_mode, ior_optab,
940 carry_out, carry_tmp,
941 carry_out, 0, next_methods);
947 carry_in = carry_out;
950 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
952 rtx temp = emit_move_insn (target, target);
954 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
955 gen_rtx (binoptab->code, mode,
962 delete_insns_since (last);
965 /* If we want to multiply two two-word values and have normal and widening
966 multiplies of single-word values, we can do this with three smaller
967 multiplications. Note that we do not make a REG_NO_CONFLICT block here
968 because we are not operating on one word at a time.
970 The multiplication proceeds as follows:
971 _______________________
972 [__op0_high_|__op0_low__]
973 _______________________
974 * [__op1_high_|__op1_low__]
975 _______________________________________________
976 _______________________
977 (1) [__op0_low__*__op1_low__]
978 _______________________
979 (2a) [__op0_low__*__op1_high_]
980 _______________________
981 (2b) [__op0_high_*__op1_low__]
982 _______________________
983 (3) [__op0_high_*__op1_high_]
986 This gives a 4-word result. Since we are only interested in the
987 lower 2 words, partial result (3) and the upper words of (2a) and
988 (2b) don't need to be calculated. Hence (2a) and (2b) can be
989 calculated using non-widening multiplication.
991 (1), however, needs to be calculated with an unsigned widening
992 multiplication. If this operation is not directly supported we
993 try using a signed widening multiplication and adjust the result.
994 This adjustment works as follows:
996 If both operands are positive then no adjustment is needed.
998 If the operands have different signs, for example op0_low < 0 and
999 op1_low >= 0, the instruction treats the most significant bit of
1000 op0_low as a sign bit instead of a bit with significance
1001 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1002 with 2**BITS_PER_WORD - op0_low, and two's complements the
1003 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1006 Similarly, if both operands are negative, we need to add
1007 (op0_low + op1_low) * 2**BITS_PER_WORD.
1009 We use a trick to adjust quickly. We logically shift op0_low right
1010 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1011 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1012 logical shift exists, we do an arithmetic right shift and subtract
1015 if (binoptab == smul_optab
1016 && class == MODE_INT
1017 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1018 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1019 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1020 && ((umul_widen_optab->handlers[(int) mode].insn_code
1021 != CODE_FOR_nothing)
1022 || (smul_widen_optab->handlers[(int) mode].insn_code
1023 != CODE_FOR_nothing)))
1025 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1026 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1027 rtx op0_high = operand_subword_force (op0, high, mode);
1028 rtx op0_low = operand_subword_force (op0, low, mode);
1029 rtx op1_high = operand_subword_force (op1, high, mode);
1030 rtx op1_low = operand_subword_force (op1, low, mode);
1035 /* If the target is the same as one of the inputs, don't use it. This
1036 prevents problems with the REG_EQUAL note. */
1037 if (target == op0 || target == op1)
1040 /* Multiply the two lower words to get a double-word product.
1041 If unsigned widening multiplication is available, use that;
1042 otherwise use the signed form and compensate. */
1044 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1046 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1047 target, 1, OPTAB_DIRECT);
1049 /* If we didn't succeed, delete everything we did so far. */
1051 delete_insns_since (last);
1053 op0_xhigh = op0_high, op1_xhigh = op1_high;
1057 && smul_widen_optab->handlers[(int) mode].insn_code
1058 != CODE_FOR_nothing)
1060 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1061 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1062 target, 1, OPTAB_DIRECT);
1063 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1064 NULL_RTX, 1, next_methods);
1066 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1067 op0_xhigh, op0_xhigh, 0, next_methods);
1070 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1071 NULL_RTX, 0, next_methods);
1073 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1074 op0_xhigh, op0_xhigh, 0,
1078 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1079 NULL_RTX, 1, next_methods);
1081 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1082 op1_xhigh, op1_xhigh, 0, next_methods);
1085 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1086 NULL_RTX, 0, next_methods);
1088 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1089 op1_xhigh, op1_xhigh, 0,
1094 /* If we have been able to directly compute the product of the
1095 low-order words of the operands and perform any required adjustments
1096 of the operands, we proceed by trying two more multiplications
1097 and then computing the appropriate sum.
1099 We have checked above that the required addition is provided.
1100 Full-word addition will normally always succeed, especially if
1101 it is provided at all, so we don't worry about its failure. The
1102 multiplication may well fail, however, so we do handle that. */
1104 if (product && op0_xhigh && op1_xhigh)
1106 rtx product_high = operand_subword (product, high, 1, mode);
1107 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1108 NULL_RTX, 0, OPTAB_DIRECT);
1111 temp = expand_binop (word_mode, add_optab, temp, product_high,
1112 product_high, 0, next_methods);
1114 if (temp != 0 && temp != product_high)
1115 emit_move_insn (product_high, temp);
1118 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1119 NULL_RTX, 0, OPTAB_DIRECT);
1122 temp = expand_binop (word_mode, add_optab, temp,
1123 product_high, product_high,
1126 if (temp != 0 && temp != product_high)
1127 emit_move_insn (product_high, temp);
1131 temp = emit_move_insn (product, product);
1132 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1133 gen_rtx (MULT, mode, copy_rtx (op0),
1141 /* If we get here, we couldn't do it for some reason even though we
1142 originally thought we could. Delete anything we've emitted in
1145 delete_insns_since (last);
1148 /* We need to open-code the complex type operations: '+, -, * and /' */
1150 /* At this point we allow operations between two similar complex
1151 numbers, and also if one of the operands is not a complex number
1152 but rather of MODE_FLOAT or MODE_INT. However, the caller
1153 must make sure that the MODE of the non-complex operand matches
1154 the SUBMODE of the complex operand. */
1156 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1158 rtx real0 = 0, imag0 = 0;
1159 rtx real1 = 0, imag1 = 0;
1160 rtx realr, imagr, res;
1165 /* Find the correct mode for the real and imaginary parts */
1166 enum machine_mode submode
1167 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1168 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1171 if (submode == BLKmode)
1175 target = gen_reg_rtx (mode);
1179 realr = gen_realpart (submode, target);
1180 imagr = gen_imagpart (submode, target);
1182 if (GET_MODE (op0) == mode)
1184 real0 = gen_realpart (submode, op0);
1185 imag0 = gen_imagpart (submode, op0);
1190 if (GET_MODE (op1) == mode)
1192 real1 = gen_realpart (submode, op1);
1193 imag1 = gen_imagpart (submode, op1);
1198 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1201 switch (binoptab->code)
1204 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1206 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1207 res = expand_binop (submode, binoptab, real0, real1,
1208 realr, unsignedp, methods);
1212 else if (res != realr)
1213 emit_move_insn (realr, res);
1216 res = expand_binop (submode, binoptab, imag0, imag1,
1217 imagr, unsignedp, methods);
1220 else if (binoptab->code == MINUS)
1221 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1227 else if (res != imagr)
1228 emit_move_insn (imagr, res);
1234 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1240 /* Don't fetch these from memory more than once. */
1241 real0 = force_reg (submode, real0);
1242 real1 = force_reg (submode, real1);
1243 imag0 = force_reg (submode, imag0);
1244 imag1 = force_reg (submode, imag1);
1246 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1247 unsignedp, methods);
1249 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1250 unsignedp, methods);
1252 if (temp1 == 0 || temp2 == 0)
1255 res = expand_binop (submode, sub_optab, temp1, temp2,
1256 realr, unsignedp, methods);
1260 else if (res != realr)
1261 emit_move_insn (realr, res);
1263 temp1 = expand_binop (submode, binoptab, real0, imag1,
1264 NULL_RTX, unsignedp, methods);
1266 temp2 = expand_binop (submode, binoptab, real1, imag0,
1267 NULL_RTX, unsignedp, methods);
1269 if (temp1 == 0 || temp2 == 0)
1272 res = expand_binop (submode, add_optab, temp1, temp2,
1273 imagr, unsignedp, methods);
1277 else if (res != imagr)
1278 emit_move_insn (imagr, res);
1284 /* Don't fetch these from memory more than once. */
1285 real0 = force_reg (submode, real0);
1286 real1 = force_reg (submode, real1);
1288 res = expand_binop (submode, binoptab, real0, real1,
1289 realr, unsignedp, methods);
1292 else if (res != realr)
1293 emit_move_insn (realr, res);
1296 res = expand_binop (submode, binoptab,
1297 real1, imag0, imagr, unsignedp, methods);
1299 res = expand_binop (submode, binoptab,
1300 real0, imag1, imagr, unsignedp, methods);
1304 else if (res != imagr)
1305 emit_move_insn (imagr, res);
1312 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1316 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1318 /* Don't fetch these from memory more than once. */
1319 real1 = force_reg (submode, real1);
1321 /* Simply divide the real and imaginary parts by `c' */
1322 if (class == MODE_COMPLEX_FLOAT)
1323 res = expand_binop (submode, binoptab, real0, real1,
1324 realr, unsignedp, methods);
1326 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1327 real0, real1, realr, unsignedp);
1331 else if (res != realr)
1332 emit_move_insn (realr, res);
1334 if (class == MODE_COMPLEX_FLOAT)
1335 res = expand_binop (submode, binoptab, imag0, real1,
1336 imagr, unsignedp, methods);
1338 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1339 imag0, real1, imagr, unsignedp);
1343 else if (res != imagr)
1344 emit_move_insn (imagr, res);
1350 /* Divisor is of complex type:
1357 /* Don't fetch these from memory more than once. */
1358 real0 = force_reg (submode, real0);
1359 real1 = force_reg (submode, real1);
1362 imag0 = force_reg (submode, imag0);
1364 imag1 = force_reg (submode, imag1);
1366 /* Divisor: c*c + d*d */
1367 temp1 = expand_binop (submode, smul_optab, real1, real1,
1368 NULL_RTX, unsignedp, methods);
1370 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1371 NULL_RTX, unsignedp, methods);
1373 if (temp1 == 0 || temp2 == 0)
1376 divisor = expand_binop (submode, add_optab, temp1, temp2,
1377 NULL_RTX, unsignedp, methods);
1383 /* ((a)(c-id))/divisor */
1384 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1386 /* Calculate the dividend */
1387 real_t = expand_binop (submode, smul_optab, real0, real1,
1388 NULL_RTX, unsignedp, methods);
1390 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1391 NULL_RTX, unsignedp, methods);
1393 if (real_t == 0 || imag_t == 0)
1396 imag_t = expand_unop (submode, neg_optab, imag_t,
1397 NULL_RTX, unsignedp);
1401 /* ((a+ib)(c-id))/divider */
1402 /* Calculate the dividend */
1403 temp1 = expand_binop (submode, smul_optab, real0, real1,
1404 NULL_RTX, unsignedp, methods);
1406 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1407 NULL_RTX, unsignedp, methods);
1409 if (temp1 == 0 || temp2 == 0)
1412 real_t = expand_binop (submode, add_optab, temp1, temp2,
1413 NULL_RTX, unsignedp, methods);
1415 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1416 NULL_RTX, unsignedp, methods);
1418 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1419 NULL_RTX, unsignedp, methods);
1421 if (temp1 == 0 || temp2 == 0)
1424 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1425 NULL_RTX, unsignedp, methods);
1427 if (real_t == 0 || imag_t == 0)
1431 if (class == MODE_COMPLEX_FLOAT)
1432 res = expand_binop (submode, binoptab, real_t, divisor,
1433 realr, unsignedp, methods);
1435 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1436 real_t, divisor, realr, unsignedp);
1440 else if (res != realr)
1441 emit_move_insn (realr, res);
1443 if (class == MODE_COMPLEX_FLOAT)
1444 res = expand_binop (submode, binoptab, imag_t, divisor,
1445 imagr, unsignedp, methods);
1447 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1448 imag_t, divisor, imagr, unsignedp);
1452 else if (res != imagr)
1453 emit_move_insn (imagr, res);
1468 if (binoptab->code != UNKNOWN)
1470 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1474 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1480 /* It can't be open-coded in this mode.
1481 Use a library call if one is available and caller says that's ok. */
1483 if (binoptab->handlers[(int) mode].libfunc
1484 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1487 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1489 enum machine_mode op1_mode = mode;
1496 op1_mode = word_mode;
1497 /* Specify unsigned here,
1498 since negative shift counts are meaningless. */
1499 op1x = convert_to_mode (word_mode, op1, 1);
1502 if (GET_MODE (op0) != mode)
1503 op0 = convert_to_mode (mode, op0, unsignedp);
1505 /* Pass 1 for NO_QUEUE so we don't lose any increments
1506 if the libcall is cse'd or moved. */
1507 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1508 NULL_RTX, 1, mode, 2,
1509 op0, mode, op1x, op1_mode);
1511 insns = get_insns ();
1514 target = gen_reg_rtx (mode);
1515 emit_libcall_block (insns, target, value,
1516 gen_rtx (binoptab->code, mode, op0, op1));
1521 delete_insns_since (last);
1523 /* It can't be done in this mode. Can we do it in a wider mode? */
1525 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1526 || methods == OPTAB_MUST_WIDEN))
1528 /* Caller says, don't even try. */
1529 delete_insns_since (entry_last);
1533 /* Compute the value of METHODS to pass to recursive calls.
1534 Don't allow widening to be tried recursively. */
1536 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1538 /* Look for a wider mode of the same class for which it appears we can do
1541 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1543 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1544 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1546 if ((binoptab->handlers[(int) wider_mode].insn_code
1547 != CODE_FOR_nothing)
1548 || (methods == OPTAB_LIB
1549 && binoptab->handlers[(int) wider_mode].libfunc))
1551 rtx xop0 = op0, xop1 = op1;
1554 /* For certain integer operations, we need not actually extend
1555 the narrow operands, as long as we will truncate
1556 the results to the same narrowness. */
1558 if ((binoptab == ior_optab || binoptab == and_optab
1559 || binoptab == xor_optab
1560 || binoptab == add_optab || binoptab == sub_optab
1561 || binoptab == smul_optab || binoptab == ashl_optab)
1562 && class == MODE_INT)
1565 xop0 = widen_operand (xop0, wider_mode, mode,
1566 unsignedp, no_extend);
1568 /* The second operand of a shift must always be extended. */
1569 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1570 no_extend && binoptab != ashl_optab);
1572 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1573 unsignedp, methods);
1576 if (class != MODE_INT)
1579 target = gen_reg_rtx (mode);
1580 convert_move (target, temp, 0);
1584 return gen_lowpart (mode, temp);
1587 delete_insns_since (last);
1592 delete_insns_since (entry_last);
1596 /* Expand a binary operator which has both signed and unsigned forms.
1597 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1600 If we widen unsigned operands, we may use a signed wider operation instead
1601 of an unsigned wider operation, since the result would be the same. */
1604 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1605 enum machine_mode mode;
1606 optab uoptab, soptab;
1607 rtx op0, op1, target;
1609 enum optab_methods methods;
1612 optab direct_optab = unsignedp ? uoptab : soptab;
1613 struct optab wide_soptab;
1615 /* Do it without widening, if possible. */
1616 temp = expand_binop (mode, direct_optab, op0, op1, target,
1617 unsignedp, OPTAB_DIRECT);
1618 if (temp || methods == OPTAB_DIRECT)
1621 /* Try widening to a signed int. Make a fake signed optab that
1622 hides any signed insn for direct use. */
1623 wide_soptab = *soptab;
1624 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1625 wide_soptab.handlers[(int) mode].libfunc = 0;
1627 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1628 unsignedp, OPTAB_WIDEN);
1630 /* For unsigned operands, try widening to an unsigned int. */
1631 if (temp == 0 && unsignedp)
1632 temp = expand_binop (mode, uoptab, op0, op1, target,
1633 unsignedp, OPTAB_WIDEN);
1634 if (temp || methods == OPTAB_WIDEN)
1637 /* Use the right width lib call if that exists. */
1638 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1639 if (temp || methods == OPTAB_LIB)
1642 /* Must widen and use a lib call, use either signed or unsigned. */
1643 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1644 unsignedp, methods);
1648 return expand_binop (mode, uoptab, op0, op1, target,
1649 unsignedp, methods);
1653 /* Generate code to perform an operation specified by BINOPTAB
1654 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1655 We assume that the order of the operands for the instruction
1656 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1657 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1659 Either TARG0 or TARG1 may be zero, but what that means is that
1660 that result is not actually wanted. We will generate it into
1661 a dummy pseudo-reg and discard it. They may not both be zero.
1663 Returns 1 if this operation can be performed; 0 if not. */
1666 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1672 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1673 enum mode_class class;
1674 enum machine_mode wider_mode;
1675 rtx entry_last = get_last_insn ();
1678 class = GET_MODE_CLASS (mode);
1680 op0 = protect_from_queue (op0, 0);
1681 op1 = protect_from_queue (op1, 0);
1685 op0 = force_not_mem (op0);
1686 op1 = force_not_mem (op1);
1689 /* If we are inside an appropriately-short loop and one operand is an
1690 expensive constant, force it into a register. */
1691 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1692 && rtx_cost (op0, binoptab->code) > 2)
1693 op0 = force_reg (mode, op0);
1695 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1696 && rtx_cost (op1, binoptab->code) > 2)
1697 op1 = force_reg (mode, op1);
1700 targ0 = protect_from_queue (targ0, 1);
1702 targ0 = gen_reg_rtx (mode);
1704 targ1 = protect_from_queue (targ1, 1);
1706 targ1 = gen_reg_rtx (mode);
1708 /* Record where to go back to if we fail. */
1709 last = get_last_insn ();
1711 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1713 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1714 enum machine_mode mode0 = insn_operand_mode[icode][1];
1715 enum machine_mode mode1 = insn_operand_mode[icode][2];
1717 rtx xop0 = op0, xop1 = op1;
1719 /* In case this insn wants input operands in modes different from the
1720 result, convert the operands. */
1721 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1722 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1724 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1725 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1727 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1728 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1729 xop0 = copy_to_mode_reg (mode0, xop0);
1731 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1732 xop1 = copy_to_mode_reg (mode1, xop1);
1734 /* We could handle this, but we should always be called with a pseudo
1735 for our targets and all insns should take them as outputs. */
1736 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1737 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1740 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1747 delete_insns_since (last);
1750 /* It can't be done in this mode. Can we do it in a wider mode? */
1752 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1754 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1755 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1757 if (binoptab->handlers[(int) wider_mode].insn_code
1758 != CODE_FOR_nothing)
1760 register rtx t0 = gen_reg_rtx (wider_mode);
1761 register rtx t1 = gen_reg_rtx (wider_mode);
1763 if (expand_twoval_binop (binoptab,
1764 convert_modes (wider_mode, mode, op0,
1766 convert_modes (wider_mode, mode, op1,
1770 convert_move (targ0, t0, unsignedp);
1771 convert_move (targ1, t1, unsignedp);
1775 delete_insns_since (last);
1780 delete_insns_since (entry_last);
1784 /* Generate code to perform an operation specified by UNOPTAB
1785 on operand OP0, with result having machine-mode MODE.
1787 UNSIGNEDP is for the case where we have to widen the operands
1788 to perform the operation. It says to use zero-extension.
1790 If TARGET is nonzero, the value
1791 is generated there, if it is convenient to do so.
1792 In all cases an rtx is returned for the locus of the value;
1793 this may or may not be TARGET. */
1796 expand_unop (mode, unoptab, op0, target, unsignedp)
1797 enum machine_mode mode;
1803 enum mode_class class;
1804 enum machine_mode wider_mode;
1806 rtx last = get_last_insn ();
1809 class = GET_MODE_CLASS (mode);
1811 op0 = protect_from_queue (op0, 0);
1815 op0 = force_not_mem (op0);
1819 target = protect_from_queue (target, 1);
1821 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1823 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1824 enum machine_mode mode0 = insn_operand_mode[icode][1];
1830 temp = gen_reg_rtx (mode);
1832 if (GET_MODE (xop0) != VOIDmode
1833 && GET_MODE (xop0) != mode0)
1834 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1836 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1838 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1839 xop0 = copy_to_mode_reg (mode0, xop0);
1841 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1842 temp = gen_reg_rtx (mode);
1844 pat = GEN_FCN (icode) (temp, xop0);
1847 if (GET_CODE (pat) == SEQUENCE
1848 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1850 delete_insns_since (last);
1851 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1859 delete_insns_since (last);
1862 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1864 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1865 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1866 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1868 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1872 /* For certain operations, we need not actually extend
1873 the narrow operand, as long as we will truncate the
1874 results to the same narrowness. */
1876 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1877 (unoptab == neg_optab
1878 || unoptab == one_cmpl_optab)
1879 && class == MODE_INT);
1881 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1886 if (class != MODE_INT)
1889 target = gen_reg_rtx (mode);
1890 convert_move (target, temp, 0);
1894 return gen_lowpart (mode, temp);
1897 delete_insns_since (last);
1901 /* These can be done a word at a time. */
1902 if (unoptab == one_cmpl_optab
1903 && class == MODE_INT
1904 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1905 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1910 if (target == 0 || target == op0)
1911 target = gen_reg_rtx (mode);
1915 /* Do the actual arithmetic. */
1916 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1918 rtx target_piece = operand_subword (target, i, 1, mode);
1919 rtx x = expand_unop (word_mode, unoptab,
1920 operand_subword_force (op0, i, mode),
1921 target_piece, unsignedp);
1922 if (target_piece != x)
1923 emit_move_insn (target_piece, x);
1926 insns = get_insns ();
1929 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1930 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1934 /* Open-code the complex negation operation. */
1935 else if (unoptab == neg_optab
1936 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1942 /* Find the correct mode for the real and imaginary parts */
1943 enum machine_mode submode
1944 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1945 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1948 if (submode == BLKmode)
1952 target = gen_reg_rtx (mode);
1956 target_piece = gen_imagpart (submode, target);
1957 x = expand_unop (submode, unoptab,
1958 gen_imagpart (submode, op0),
1959 target_piece, unsignedp);
1960 if (target_piece != x)
1961 emit_move_insn (target_piece, x);
1963 target_piece = gen_realpart (submode, target);
1964 x = expand_unop (submode, unoptab,
1965 gen_realpart (submode, op0),
1966 target_piece, unsignedp);
1967 if (target_piece != x)
1968 emit_move_insn (target_piece, x);
1973 emit_no_conflict_block (seq, target, op0, 0,
1974 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1978 /* Now try a library call in this mode. */
1979 if (unoptab->handlers[(int) mode].libfunc)
1982 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1987 /* Pass 1 for NO_QUEUE so we don't lose any increments
1988 if the libcall is cse'd or moved. */
1989 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
1990 NULL_RTX, 1, mode, 1, op0, mode);
1991 insns = get_insns ();
1994 target = gen_reg_rtx (mode);
1995 emit_libcall_block (insns, target, value,
1996 gen_rtx (unoptab->code, mode, op0));
2001 /* It can't be done in this mode. Can we do it in a wider mode? */
2003 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2005 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2006 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2008 if ((unoptab->handlers[(int) wider_mode].insn_code
2009 != CODE_FOR_nothing)
2010 || unoptab->handlers[(int) wider_mode].libfunc)
2014 /* For certain operations, we need not actually extend
2015 the narrow operand, as long as we will truncate the
2016 results to the same narrowness. */
2018 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2019 (unoptab == neg_optab
2020 || unoptab == one_cmpl_optab)
2021 && class == MODE_INT);
2023 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2028 if (class != MODE_INT)
2031 target = gen_reg_rtx (mode);
2032 convert_move (target, temp, 0);
2036 return gen_lowpart (mode, temp);
2039 delete_insns_since (last);
2047 /* Emit code to compute the absolute value of OP0, with result to
2048 TARGET if convenient. (TARGET may be 0.) The return value says
2049 where the result actually is to be found.
2051 MODE is the mode of the operand; the mode of the result is
2052 different but can be deduced from MODE.
2054 UNSIGNEDP is relevant for complex integer modes. */
2057 expand_complex_abs (mode, op0, target, unsignedp)
2058 enum machine_mode mode;
2063 enum mode_class class = GET_MODE_CLASS (mode);
2064 enum machine_mode wider_mode;
2066 rtx entry_last = get_last_insn ();
2070 /* Find the correct mode for the real and imaginary parts. */
2071 enum machine_mode submode
2072 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2073 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2076 if (submode == BLKmode)
2079 op0 = protect_from_queue (op0, 0);
2083 op0 = force_not_mem (op0);
2086 last = get_last_insn ();
2089 target = protect_from_queue (target, 1);
2091 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2093 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2094 enum machine_mode mode0 = insn_operand_mode[icode][1];
2100 temp = gen_reg_rtx (submode);
2102 if (GET_MODE (xop0) != VOIDmode
2103 && GET_MODE (xop0) != mode0)
2104 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2106 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2108 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2109 xop0 = copy_to_mode_reg (mode0, xop0);
2111 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2112 temp = gen_reg_rtx (submode);
2114 pat = GEN_FCN (icode) (temp, xop0);
2117 if (GET_CODE (pat) == SEQUENCE
2118 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2120 delete_insns_since (last);
2121 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2129 delete_insns_since (last);
2132 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2134 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2135 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2137 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2141 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2142 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2146 if (class != MODE_COMPLEX_INT)
2149 target = gen_reg_rtx (submode);
2150 convert_move (target, temp, 0);
2154 return gen_lowpart (submode, temp);
2157 delete_insns_since (last);
2161 /* Open-code the complex absolute-value operation
2162 if we can open-code sqrt. Otherwise it's not worth while. */
2163 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2165 rtx real, imag, total;
2167 real = gen_realpart (submode, op0);
2168 imag = gen_imagpart (submode, op0);
2170 /* Square both parts. */
2171 real = expand_mult (submode, real, real, NULL_RTX, 0);
2172 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2174 /* Sum the parts. */
2175 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2176 0, OPTAB_LIB_WIDEN);
2178 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2179 target = expand_unop (submode, sqrt_optab, total, target, 0);
2181 delete_insns_since (last);
2186 /* Now try a library call in this mode. */
2187 if (abs_optab->handlers[(int) mode].libfunc)
2190 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2195 /* Pass 1 for NO_QUEUE so we don't lose any increments
2196 if the libcall is cse'd or moved. */
2197 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2198 NULL_RTX, 1, submode, 1, op0, mode);
2199 insns = get_insns ();
2202 target = gen_reg_rtx (submode);
2203 emit_libcall_block (insns, target, value,
2204 gen_rtx (abs_optab->code, mode, op0));
2209 /* It can't be done in this mode. Can we do it in a wider mode? */
2211 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2212 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2214 if ((abs_optab->handlers[(int) wider_mode].insn_code
2215 != CODE_FOR_nothing)
2216 || abs_optab->handlers[(int) wider_mode].libfunc)
2220 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2222 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2226 if (class != MODE_COMPLEX_INT)
2229 target = gen_reg_rtx (submode);
2230 convert_move (target, temp, 0);
2234 return gen_lowpart (submode, temp);
2237 delete_insns_since (last);
2241 delete_insns_since (entry_last);
2245 /* Generate an instruction whose insn-code is INSN_CODE,
2246 with two operands: an output TARGET and an input OP0.
2247 TARGET *must* be nonzero, and the output is always stored there.
2248 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2249 the value that is stored into TARGET. */
2252 emit_unop_insn (icode, target, op0, code)
2259 enum machine_mode mode0 = insn_operand_mode[icode][1];
2262 temp = target = protect_from_queue (target, 1);
2264 op0 = protect_from_queue (op0, 0);
2267 op0 = force_not_mem (op0);
2269 /* Now, if insn does not accept our operands, put them into pseudos. */
2271 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2272 op0 = copy_to_mode_reg (mode0, op0);
2274 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2275 || (flag_force_mem && GET_CODE (temp) == MEM))
2276 temp = gen_reg_rtx (GET_MODE (temp));
2278 pat = GEN_FCN (icode) (temp, op0);
2280 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2281 add_equal_note (pat, temp, code, op0, NULL_RTX);
2286 emit_move_insn (target, temp);
2289 /* Emit code to perform a series of operations on a multi-word quantity, one
2292 Such a block is preceded by a CLOBBER of the output, consists of multiple
2293 insns, each setting one word of the output, and followed by a SET copying
2294 the output to itself.
2296 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2297 note indicating that it doesn't conflict with the (also multi-word)
2298 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2301 INSNS is a block of code generated to perform the operation, not including
2302 the CLOBBER and final copy. All insns that compute intermediate values
2303 are first emitted, followed by the block as described above. Only
2304 INSNs are allowed in the block; no library calls or jumps may be
2307 TARGET, OP0, and OP1 are the output and inputs of the operations,
2308 respectively. OP1 may be zero for a unary operation.
2310 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2313 If TARGET is not a register, INSNS is simply emitted with no special
2316 The final insn emitted is returned. */
2319 emit_no_conflict_block (insns, target, op0, op1, equiv)
2325 rtx prev, next, first, last, insn;
2327 if (GET_CODE (target) != REG || reload_in_progress)
2328 return emit_insns (insns);
2330 /* First emit all insns that do not store into words of the output and remove
2331 these from the list. */
2332 for (insn = insns; insn; insn = next)
2337 next = NEXT_INSN (insn);
2339 if (GET_CODE (insn) != INSN)
2342 if (GET_CODE (PATTERN (insn)) == SET)
2343 set = PATTERN (insn);
2344 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2346 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2347 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2349 set = XVECEXP (PATTERN (insn), 0, i);
2357 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2359 if (PREV_INSN (insn))
2360 NEXT_INSN (PREV_INSN (insn)) = next;
2365 PREV_INSN (next) = PREV_INSN (insn);
2371 prev = get_last_insn ();
2373 /* Now write the CLOBBER of the output, followed by the setting of each
2374 of the words, followed by the final copy. */
2375 if (target != op0 && target != op1)
2376 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2378 for (insn = insns; insn; insn = next)
2380 next = NEXT_INSN (insn);
2383 if (op1 && GET_CODE (op1) == REG)
2384 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2387 if (op0 && GET_CODE (op0) == REG)
2388 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2392 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2393 != CODE_FOR_nothing)
2395 last = emit_move_insn (target, target);
2398 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2401 last = get_last_insn ();
2404 first = get_insns ();
2406 first = NEXT_INSN (prev);
2408 /* Encapsulate the block so it gets manipulated as a unit. */
2409 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2411 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2416 /* Emit code to make a call to a constant function or a library call.
2418 INSNS is a list containing all insns emitted in the call.
2419 These insns leave the result in RESULT. Our block is to copy RESULT
2420 to TARGET, which is logically equivalent to EQUIV.
2422 We first emit any insns that set a pseudo on the assumption that these are
2423 loading constants into registers; doing so allows them to be safely cse'ed
2424 between blocks. Then we emit all the other insns in the block, followed by
2425 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2426 note with an operand of EQUIV.
2428 Moving assignments to pseudos outside of the block is done to improve
2429 the generated code, but is not required to generate correct code,
2430 hence being unable to move an assignment is not grounds for not making
2431 a libcall block. There are two reasons why it is safe to leave these
2432 insns inside the block: First, we know that these pseudos cannot be
2433 used in generated RTL outside the block since they are created for
2434 temporary purposes within the block. Second, CSE will not record the
2435 values of anything set inside a libcall block, so we know they must
2436 be dead at the end of the block.
2438 Except for the first group of insns (the ones setting pseudos), the
2439 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2442 emit_libcall_block (insns, target, result, equiv)
2448 rtx prev, next, first, last, insn;
2450 /* First emit all insns that set pseudos. Remove them from the list as
2451 we go. Avoid insns that set pseudos which were referenced in previous
2452 insns. These can be generated by move_by_pieces, for example,
2453 to update an address. Similarly, avoid insns that reference things
2454 set in previous insns. */
2456 for (insn = insns; insn; insn = next)
2458 rtx set = single_set (insn);
2460 next = NEXT_INSN (insn);
2462 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2463 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2465 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2466 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2467 && ! modified_in_p (SET_SRC (set), insns)
2468 && ! modified_between_p (SET_SRC (set), insns, insn))))
2470 if (PREV_INSN (insn))
2471 NEXT_INSN (PREV_INSN (insn)) = next;
2476 PREV_INSN (next) = PREV_INSN (insn);
2482 prev = get_last_insn ();
2484 /* Write the remaining insns followed by the final copy. */
2486 for (insn = insns; insn; insn = next)
2488 next = NEXT_INSN (insn);
2493 last = emit_move_insn (target, result);
2494 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2495 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2498 first = get_insns ();
2500 first = NEXT_INSN (prev);
2502 /* Encapsulate the block so it gets manipulated as a unit. */
2503 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2505 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2508 /* Generate code to store zero in X. */
2514 emit_move_insn (x, const0_rtx);
2517 /* Generate code to store 1 in X
2518 assuming it contains zero beforehand. */
2521 emit_0_to_1_insn (x)
2524 emit_move_insn (x, const1_rtx);
2527 /* Generate code to compare X with Y
2528 so that the condition codes are set.
2530 MODE is the mode of the inputs (in case they are const_int).
2531 UNSIGNEDP nonzero says that X and Y are unsigned;
2532 this matters if they need to be widened.
2534 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2535 and ALIGN specifies the known shared alignment of X and Y.
2537 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2538 It is ignored for fixed-point and block comparisons;
2539 it is used only for floating-point comparisons. */
2542 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2544 enum rtx_code comparison;
2546 enum machine_mode mode;
2550 enum mode_class class;
2551 enum machine_mode wider_mode;
2553 class = GET_MODE_CLASS (mode);
2555 /* They could both be VOIDmode if both args are immediate constants,
2556 but we should fold that at an earlier stage.
2557 With no special code here, this will call abort,
2558 reminding the programmer to implement such folding. */
2560 if (mode != BLKmode && flag_force_mem)
2562 x = force_not_mem (x);
2563 y = force_not_mem (y);
2566 /* If we are inside an appropriately-short loop and one operand is an
2567 expensive constant, force it into a register. */
2568 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2569 x = force_reg (mode, x);
2571 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2572 y = force_reg (mode, y);
2574 /* Don't let both operands fail to indicate the mode. */
2575 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2576 x = force_reg (mode, x);
2578 /* Handle all BLKmode compares. */
2580 if (mode == BLKmode)
2583 x = protect_from_queue (x, 0);
2584 y = protect_from_queue (y, 0);
2588 #ifdef HAVE_cmpstrqi
2590 && GET_CODE (size) == CONST_INT
2591 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2593 enum machine_mode result_mode
2594 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2595 rtx result = gen_reg_rtx (result_mode);
2596 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2597 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2602 #ifdef HAVE_cmpstrhi
2604 && GET_CODE (size) == CONST_INT
2605 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2607 enum machine_mode result_mode
2608 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2609 rtx result = gen_reg_rtx (result_mode);
2610 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2611 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2616 #ifdef HAVE_cmpstrsi
2619 enum machine_mode result_mode
2620 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2621 rtx result = gen_reg_rtx (result_mode);
2622 size = protect_from_queue (size, 0);
2623 emit_insn (gen_cmpstrsi (result, x, y,
2624 convert_to_mode (SImode, size, 1),
2626 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2632 #ifdef TARGET_MEM_FUNCTIONS
2633 emit_library_call (memcmp_libfunc, 0,
2634 TYPE_MODE (integer_type_node), 3,
2635 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2638 emit_library_call (bcmp_libfunc, 0,
2639 TYPE_MODE (integer_type_node), 3,
2640 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2643 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2644 const0_rtx, comparison, NULL_RTX,
2645 TYPE_MODE (integer_type_node), 0, 0);
2650 /* Handle some compares against zero. */
2652 if (y == CONST0_RTX (mode)
2653 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2655 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2658 x = protect_from_queue (x, 0);
2659 y = protect_from_queue (y, 0);
2661 /* Now, if insn does accept these operands, put them into pseudos. */
2662 if (! (*insn_operand_predicate[icode][0])
2663 (x, insn_operand_mode[icode][0]))
2664 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2666 emit_insn (GEN_FCN (icode) (x));
2670 /* Handle compares for which there is a directly suitable insn. */
2672 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2674 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2677 x = protect_from_queue (x, 0);
2678 y = protect_from_queue (y, 0);
2680 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2681 if (! (*insn_operand_predicate[icode][0])
2682 (x, insn_operand_mode[icode][0]))
2683 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2685 if (! (*insn_operand_predicate[icode][1])
2686 (y, insn_operand_mode[icode][1]))
2687 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2689 emit_insn (GEN_FCN (icode) (x, y));
2693 /* Try widening if we can find a direct insn that way. */
2695 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2697 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2698 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2700 if (cmp_optab->handlers[(int) wider_mode].insn_code
2701 != CODE_FOR_nothing)
2703 x = protect_from_queue (x, 0);
2704 y = protect_from_queue (y, 0);
2705 x = convert_modes (wider_mode, mode, x, unsignedp);
2706 y = convert_modes (wider_mode, mode, y, unsignedp);
2707 emit_cmp_insn (x, y, comparison, NULL_RTX,
2708 wider_mode, unsignedp, align);
2714 /* Handle a lib call just for the mode we are using. */
2716 if (cmp_optab->handlers[(int) mode].libfunc
2717 && class != MODE_FLOAT)
2719 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2720 /* If we want unsigned, and this mode has a distinct unsigned
2721 comparison routine, use that. */
2722 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2723 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2725 emit_library_call (libfunc, 1,
2726 word_mode, 2, x, mode, y, mode);
2728 /* Integer comparison returns a result that must be compared against 1,
2729 so that even if we do an unsigned compare afterward,
2730 there is still a value that can represent the result "less than". */
2732 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2733 comparison, NULL_RTX, word_mode, unsignedp, 0);
2737 if (class == MODE_FLOAT)
2738 emit_float_lib_cmp (x, y, comparison);
2744 /* Nonzero if a compare of mode MODE can be done straightforwardly
2745 (without splitting it into pieces). */
2748 can_compare_p (mode)
2749 enum machine_mode mode;
2753 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2755 mode = GET_MODE_WIDER_MODE (mode);
2756 } while (mode != VOIDmode);
2761 /* Emit a library call comparison between floating point X and Y.
2762 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2765 emit_float_lib_cmp (x, y, comparison)
2767 enum rtx_code comparison;
2769 enum machine_mode mode = GET_MODE (x);
2776 libfunc = eqhf2_libfunc;
2780 libfunc = nehf2_libfunc;
2784 libfunc = gthf2_libfunc;
2788 libfunc = gehf2_libfunc;
2792 libfunc = lthf2_libfunc;
2796 libfunc = lehf2_libfunc;
2799 else if (mode == SFmode)
2803 libfunc = eqsf2_libfunc;
2807 libfunc = nesf2_libfunc;
2811 libfunc = gtsf2_libfunc;
2815 libfunc = gesf2_libfunc;
2819 libfunc = ltsf2_libfunc;
2823 libfunc = lesf2_libfunc;
2826 else if (mode == DFmode)
2830 libfunc = eqdf2_libfunc;
2834 libfunc = nedf2_libfunc;
2838 libfunc = gtdf2_libfunc;
2842 libfunc = gedf2_libfunc;
2846 libfunc = ltdf2_libfunc;
2850 libfunc = ledf2_libfunc;
2853 else if (mode == XFmode)
2857 libfunc = eqxf2_libfunc;
2861 libfunc = nexf2_libfunc;
2865 libfunc = gtxf2_libfunc;
2869 libfunc = gexf2_libfunc;
2873 libfunc = ltxf2_libfunc;
2877 libfunc = lexf2_libfunc;
2880 else if (mode == TFmode)
2884 libfunc = eqtf2_libfunc;
2888 libfunc = netf2_libfunc;
2892 libfunc = gttf2_libfunc;
2896 libfunc = getf2_libfunc;
2900 libfunc = lttf2_libfunc;
2904 libfunc = letf2_libfunc;
2909 enum machine_mode wider_mode;
2911 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2912 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2914 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2915 != CODE_FOR_nothing)
2916 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2918 x = protect_from_queue (x, 0);
2919 y = protect_from_queue (y, 0);
2920 x = convert_to_mode (wider_mode, x, 0);
2921 y = convert_to_mode (wider_mode, y, 0);
2922 emit_float_lib_cmp (x, y, comparison);
2932 emit_library_call (libfunc, 1,
2933 word_mode, 2, x, mode, y, mode);
2935 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
2936 NULL_RTX, word_mode, 0, 0);
2939 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2942 emit_indirect_jump (loc)
2945 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2947 loc = copy_to_mode_reg (Pmode, loc);
2949 emit_jump_insn (gen_indirect_jump (loc));
2953 /* These three functions generate an insn body and return it
2954 rather than emitting the insn.
2956 They do not protect from queued increments,
2957 because they may be used 1) in protect_from_queue itself
2958 and 2) in other passes where there is no queue. */
2960 /* Generate and return an insn body to add Y to X. */
2963 gen_add2_insn (x, y)
2966 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2968 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2969 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2970 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2973 return (GEN_FCN (icode) (x, x, y));
2977 have_add2_insn (mode)
2978 enum machine_mode mode;
2980 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2983 /* Generate and return an insn body to subtract Y from X. */
2986 gen_sub2_insn (x, y)
2989 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2991 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2992 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2993 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2996 return (GEN_FCN (icode) (x, x, y));
3000 have_sub2_insn (mode)
3001 enum machine_mode mode;
3003 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3006 /* Generate the body of an instruction to copy Y into X.
3007 It may be a SEQUENCE, if one insn isn't enough. */
3010 gen_move_insn (x, y)
3013 register enum machine_mode mode = GET_MODE (x);
3014 enum insn_code insn_code;
3017 if (mode == VOIDmode)
3018 mode = GET_MODE (y);
3020 insn_code = mov_optab->handlers[(int) mode].insn_code;
3022 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3023 find a mode to do it in. If we have a movcc, use it. Otherwise,
3024 find the MODE_INT mode of the same width. */
3026 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3028 enum machine_mode tmode = VOIDmode;
3032 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3035 for (tmode = QImode; tmode != VOIDmode;
3036 tmode = GET_MODE_WIDER_MODE (tmode))
3037 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3040 if (tmode == VOIDmode)
3043 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3044 may call change_address which is not appropriate if we were
3045 called when a reload was in progress. We don't have to worry
3046 about changing the address since the size in bytes is supposed to
3047 be the same. Copy the MEM to change the mode and move any
3048 substitutions from the old MEM to the new one. */
3050 if (reload_in_progress)
3052 x = gen_lowpart_common (tmode, x1);
3053 if (x == 0 && GET_CODE (x1) == MEM)
3055 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3056 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3057 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3058 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3059 copy_replacements (x1, x);
3062 y = gen_lowpart_common (tmode, y1);
3063 if (y == 0 && GET_CODE (y1) == MEM)
3065 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3066 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3067 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3068 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3069 copy_replacements (y1, y);
3074 x = gen_lowpart (tmode, x);
3075 y = gen_lowpart (tmode, y);
3078 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3079 return (GEN_FCN (insn_code) (x, y));
3083 emit_move_insn_1 (x, y);
3084 seq = gen_sequence ();
3089 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3090 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3091 no such operation exists, CODE_FOR_nothing will be returned. */
3094 can_extend_p (to_mode, from_mode, unsignedp)
3095 enum machine_mode to_mode, from_mode;
3098 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3101 /* Generate the body of an insn to extend Y (with mode MFROM)
3102 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3105 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3107 enum machine_mode mto, mfrom;
3110 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3113 /* can_fix_p and can_float_p say whether the target machine
3114 can directly convert a given fixed point type to
3115 a given floating point type, or vice versa.
3116 The returned value is the CODE_FOR_... value to use,
3117 or CODE_FOR_nothing if these modes cannot be directly converted.
3119 *TRUNCP_PTR is set to 1 if it is necessary to output
3120 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3122 static enum insn_code
3123 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3124 enum machine_mode fltmode, fixmode;
3129 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3130 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3132 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3135 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3137 return CODE_FOR_nothing;
3140 static enum insn_code
3141 can_float_p (fltmode, fixmode, unsignedp)
3142 enum machine_mode fixmode, fltmode;
3145 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3148 /* Generate code to convert FROM to floating point
3149 and store in TO. FROM must be fixed point and not VOIDmode.
3150 UNSIGNEDP nonzero means regard FROM as unsigned.
3151 Normally this is done by correcting the final value
3152 if it is negative. */
3155 expand_float (to, from, unsignedp)
3159 enum insn_code icode;
3160 register rtx target = to;
3161 enum machine_mode fmode, imode;
3163 /* Crash now, because we won't be able to decide which mode to use. */
3164 if (GET_MODE (from) == VOIDmode)
3167 /* Look for an insn to do the conversion. Do it in the specified
3168 modes if possible; otherwise convert either input, output or both to
3169 wider mode. If the integer mode is wider than the mode of FROM,
3170 we can do the conversion signed even if the input is unsigned. */
3172 for (imode = GET_MODE (from); imode != VOIDmode;
3173 imode = GET_MODE_WIDER_MODE (imode))
3174 for (fmode = GET_MODE (to); fmode != VOIDmode;
3175 fmode = GET_MODE_WIDER_MODE (fmode))
3177 int doing_unsigned = unsignedp;
3179 icode = can_float_p (fmode, imode, unsignedp);
3180 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3181 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3183 if (icode != CODE_FOR_nothing)
3185 to = protect_from_queue (to, 1);
3186 from = protect_from_queue (from, 0);
3188 if (imode != GET_MODE (from))
3189 from = convert_to_mode (imode, from, unsignedp);
3191 if (fmode != GET_MODE (to))
3192 target = gen_reg_rtx (fmode);
3194 emit_unop_insn (icode, target, from,
3195 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3198 convert_move (to, target, 0);
3203 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3205 /* Unsigned integer, and no way to convert directly.
3206 Convert as signed, then conditionally adjust the result. */
3209 rtx label = gen_label_rtx ();
3211 REAL_VALUE_TYPE offset;
3215 to = protect_from_queue (to, 1);
3216 from = protect_from_queue (from, 0);
3219 from = force_not_mem (from);
3221 /* Look for a usable floating mode FMODE wider than the source and at
3222 least as wide as the target. Using FMODE will avoid rounding woes
3223 with unsigned values greater than the signed maximum value. */
3225 for (fmode = GET_MODE (to); fmode != VOIDmode;
3226 fmode = GET_MODE_WIDER_MODE (fmode))
3227 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3228 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3231 if (fmode == VOIDmode)
3233 /* There is no such mode. Pretend the target is wide enough. */
3234 fmode = GET_MODE (to);
3236 /* Avoid double-rounding when TO is narrower than FROM. */
3237 if ((significand_size (fmode) + 1)
3238 < GET_MODE_BITSIZE (GET_MODE (from)))
3241 rtx neglabel = gen_label_rtx ();
3243 /* Don't use TARGET if it isn't a register, is a hard register,
3244 or is the wrong mode. */
3245 if (GET_CODE (target) != REG
3246 || REGNO (target) < FIRST_PSEUDO_REGISTER
3247 || GET_MODE (target) != fmode)
3248 target = gen_reg_rtx (fmode);
3250 imode = GET_MODE (from);
3251 do_pending_stack_adjust ();
3253 /* Test whether the sign bit is set. */
3254 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3255 emit_jump_insn (gen_blt (neglabel));
3257 /* The sign bit is not set. Convert as signed. */
3258 expand_float (target, from, 0);
3259 emit_jump_insn (gen_jump (label));
3261 /* The sign bit is set.
3262 Convert to a usable (positive signed) value by shifting right
3263 one bit, while remembering if a nonzero bit was shifted
3264 out; i.e., compute (from & 1) | (from >> 1). */
3266 emit_label (neglabel);
3267 temp = expand_binop (imode, and_optab, from, const1_rtx,
3268 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3269 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3271 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3273 expand_float (target, temp, 0);
3275 /* Multiply by 2 to undo the shift above. */
3276 temp = expand_binop (fmode, add_optab, target, target,
3277 target, 0, OPTAB_LIB_WIDEN);
3279 emit_move_insn (target, temp);
3281 do_pending_stack_adjust ();
3287 /* If we are about to do some arithmetic to correct for an
3288 unsigned operand, do it in a pseudo-register. */
3290 if (GET_MODE (to) != fmode
3291 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3292 target = gen_reg_rtx (fmode);
3294 /* Convert as signed integer to floating. */
3295 expand_float (target, from, 0);
3297 /* If FROM is negative (and therefore TO is negative),
3298 correct its value by 2**bitwidth. */
3300 do_pending_stack_adjust ();
3301 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3302 emit_jump_insn (gen_bge (label));
3304 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3305 Rather than setting up a dconst_dot_5, let's hope SCO
3307 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3308 temp = expand_binop (fmode, add_optab, target,
3309 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3310 target, 0, OPTAB_LIB_WIDEN);
3312 emit_move_insn (target, temp);
3314 do_pending_stack_adjust ();
3320 /* No hardware instruction available; call a library routine to convert from
3321 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3327 to = protect_from_queue (to, 1);
3328 from = protect_from_queue (from, 0);
3330 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3331 from = convert_to_mode (SImode, from, unsignedp);
3334 from = force_not_mem (from);
3336 if (GET_MODE (to) == SFmode)
3338 if (GET_MODE (from) == SImode)
3339 libfcn = floatsisf_libfunc;
3340 else if (GET_MODE (from) == DImode)
3341 libfcn = floatdisf_libfunc;
3342 else if (GET_MODE (from) == TImode)
3343 libfcn = floattisf_libfunc;
3347 else if (GET_MODE (to) == DFmode)
3349 if (GET_MODE (from) == SImode)
3350 libfcn = floatsidf_libfunc;
3351 else if (GET_MODE (from) == DImode)
3352 libfcn = floatdidf_libfunc;
3353 else if (GET_MODE (from) == TImode)
3354 libfcn = floattidf_libfunc;
3358 else if (GET_MODE (to) == XFmode)
3360 if (GET_MODE (from) == SImode)
3361 libfcn = floatsixf_libfunc;
3362 else if (GET_MODE (from) == DImode)
3363 libfcn = floatdixf_libfunc;
3364 else if (GET_MODE (from) == TImode)
3365 libfcn = floattixf_libfunc;
3369 else if (GET_MODE (to) == TFmode)
3371 if (GET_MODE (from) == SImode)
3372 libfcn = floatsitf_libfunc;
3373 else if (GET_MODE (from) == DImode)
3374 libfcn = floatditf_libfunc;
3375 else if (GET_MODE (from) == TImode)
3376 libfcn = floattitf_libfunc;
3385 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3387 1, from, GET_MODE (from));
3388 insns = get_insns ();
3391 emit_libcall_block (insns, target, value,
3392 gen_rtx (FLOAT, GET_MODE (to), from));
3397 /* Copy result to requested destination
3398 if we have been computing in a temp location. */
3402 if (GET_MODE (target) == GET_MODE (to))
3403 emit_move_insn (to, target);
3405 convert_move (to, target, 0);
3409 /* expand_fix: generate code to convert FROM to fixed point
3410 and store in TO. FROM must be floating point. */
3416 rtx temp = gen_reg_rtx (GET_MODE (x));
3417 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3421 expand_fix (to, from, unsignedp)
3422 register rtx to, from;
3425 enum insn_code icode;
3426 register rtx target = to;
3427 enum machine_mode fmode, imode;
3431 /* We first try to find a pair of modes, one real and one integer, at
3432 least as wide as FROM and TO, respectively, in which we can open-code
3433 this conversion. If the integer mode is wider than the mode of TO,
3434 we can do the conversion either signed or unsigned. */
3436 for (imode = GET_MODE (to); imode != VOIDmode;
3437 imode = GET_MODE_WIDER_MODE (imode))
3438 for (fmode = GET_MODE (from); fmode != VOIDmode;
3439 fmode = GET_MODE_WIDER_MODE (fmode))
3441 int doing_unsigned = unsignedp;
3443 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3444 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3445 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3447 if (icode != CODE_FOR_nothing)
3449 to = protect_from_queue (to, 1);
3450 from = protect_from_queue (from, 0);
3452 if (fmode != GET_MODE (from))
3453 from = convert_to_mode (fmode, from, 0);
3456 from = ftruncify (from);
3458 if (imode != GET_MODE (to))
3459 target = gen_reg_rtx (imode);
3461 emit_unop_insn (icode, target, from,
3462 doing_unsigned ? UNSIGNED_FIX : FIX);
3464 convert_move (to, target, unsignedp);
3469 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3470 /* For an unsigned conversion, there is one more way to do it.
3471 If we have a signed conversion, we generate code that compares
3472 the real value to the largest representable positive number. If if
3473 is smaller, the conversion is done normally. Otherwise, subtract
3474 one plus the highest signed number, convert, and add it back.
3476 We only need to check all real modes, since we know we didn't find
3477 anything with a wider integer mode. */
3479 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3480 for (fmode = GET_MODE (from); fmode != VOIDmode;
3481 fmode = GET_MODE_WIDER_MODE (fmode))
3482 /* Make sure we won't lose significant bits doing this. */
3483 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3484 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3488 REAL_VALUE_TYPE offset;
3489 rtx limit, lab1, lab2, insn;
3491 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3492 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3493 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3494 lab1 = gen_label_rtx ();
3495 lab2 = gen_label_rtx ();
3498 to = protect_from_queue (to, 1);
3499 from = protect_from_queue (from, 0);
3502 from = force_not_mem (from);
3504 if (fmode != GET_MODE (from))
3505 from = convert_to_mode (fmode, from, 0);
3507 /* See if we need to do the subtraction. */
3508 do_pending_stack_adjust ();
3509 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3510 emit_jump_insn (gen_bge (lab1));
3512 /* If not, do the signed "fix" and branch around fixup code. */
3513 expand_fix (to, from, 0);
3514 emit_jump_insn (gen_jump (lab2));
3517 /* Otherwise, subtract 2**(N-1), convert to signed number,
3518 then add 2**(N-1). Do the addition using XOR since this
3519 will often generate better code. */
3521 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3522 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3523 expand_fix (to, target, 0);
3524 target = expand_binop (GET_MODE (to), xor_optab, to,
3525 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3526 to, 1, OPTAB_LIB_WIDEN);
3529 emit_move_insn (to, target);
3533 /* Make a place for a REG_NOTE and add it. */
3534 insn = emit_move_insn (to, to);
3535 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3536 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3544 /* We can't do it with an insn, so use a library call. But first ensure
3545 that the mode of TO is at least as wide as SImode, since those are the
3546 only library calls we know about. */
3548 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3550 target = gen_reg_rtx (SImode);
3552 expand_fix (target, from, unsignedp);
3554 else if (GET_MODE (from) == SFmode)
3556 if (GET_MODE (to) == SImode)
3557 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3558 else if (GET_MODE (to) == DImode)
3559 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3560 else if (GET_MODE (to) == TImode)
3561 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3565 else if (GET_MODE (from) == DFmode)
3567 if (GET_MODE (to) == SImode)
3568 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3569 else if (GET_MODE (to) == DImode)
3570 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3571 else if (GET_MODE (to) == TImode)
3572 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3576 else if (GET_MODE (from) == XFmode)
3578 if (GET_MODE (to) == SImode)
3579 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3580 else if (GET_MODE (to) == DImode)
3581 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3582 else if (GET_MODE (to) == TImode)
3583 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3587 else if (GET_MODE (from) == TFmode)
3589 if (GET_MODE (to) == SImode)
3590 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3591 else if (GET_MODE (to) == DImode)
3592 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3593 else if (GET_MODE (to) == TImode)
3594 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3606 to = protect_from_queue (to, 1);
3607 from = protect_from_queue (from, 0);
3610 from = force_not_mem (from);
3614 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3616 1, from, GET_MODE (from));
3617 insns = get_insns ();
3620 emit_libcall_block (insns, target, value,
3621 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3622 GET_MODE (to), from));
3625 if (GET_MODE (to) == GET_MODE (target))
3626 emit_move_insn (to, target);
3628 convert_move (to, target, 0);
3636 optab op = (optab) xmalloc (sizeof (struct optab));
3638 for (i = 0; i < NUM_MACHINE_MODES; i++)
3640 op->handlers[i].insn_code = CODE_FOR_nothing;
3641 op->handlers[i].libfunc = 0;
3644 if (code != UNKNOWN)
3645 code_to_optab[(int) code] = op;
3650 /* Initialize the libfunc fields of an entire group of entries in some
3651 optab. Each entry is set equal to a string consisting of a leading
3652 pair of underscores followed by a generic operation name followed by
3653 a mode name (downshifted to lower case) followed by a single character
3654 representing the number of operands for the given operation (which is
3655 usually one of the characters '2', '3', or '4').
3657 OPTABLE is the table in which libfunc fields are to be initialized.
3658 FIRST_MODE is the first machine mode index in the given optab to
3660 LAST_MODE is the last machine mode index in the given optab to
3662 OPNAME is the generic (string) name of the operation.
3663 SUFFIX is the character which specifies the number of operands for
3664 the given generic operation.
3668 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3669 register optab optable;
3670 register int first_mode;
3671 register int last_mode;
3672 register char *opname;
3673 register char suffix;
3676 register unsigned opname_len = strlen (opname);
3678 for (mode = first_mode; (int) mode <= (int) last_mode;
3679 mode = (enum machine_mode) ((int) mode + 1))
3681 register char *mname = mode_name[(int) mode];
3682 register unsigned mname_len = strlen (mname);
3683 register char *libfunc_name
3684 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3691 for (q = opname; *q; )
3693 for (q = mname; *q; q++)
3694 *p++ = tolower (*q);
3697 optable->handlers[(int) mode].libfunc
3698 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3702 /* Initialize the libfunc fields of an entire group of entries in some
3703 optab which correspond to all integer mode operations. The parameters
3704 have the same meaning as similarly named ones for the `init_libfuncs'
3705 routine. (See above). */
3708 init_integral_libfuncs (optable, opname, suffix)
3709 register optab optable;
3710 register char *opname;
3711 register char suffix;
3713 init_libfuncs (optable, SImode, TImode, opname, suffix);
3716 /* Initialize the libfunc fields of an entire group of entries in some
3717 optab which correspond to all real mode operations. The parameters
3718 have the same meaning as similarly named ones for the `init_libfuncs'
3719 routine. (See above). */
3722 init_floating_libfuncs (optable, opname, suffix)
3723 register optab optable;
3724 register char *opname;
3725 register char suffix;
3727 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3730 /* Initialize the libfunc fields of an entire group of entries in some
3731 optab which correspond to all complex floating modes. The parameters
3732 have the same meaning as similarly named ones for the `init_libfuncs'
3733 routine. (See above). */
3736 init_complex_libfuncs (optable, opname, suffix)
3737 register optab optable;
3738 register char *opname;
3739 register char suffix;
3741 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3744 /* Call this once to initialize the contents of the optabs
3745 appropriately for the current target machine. */
3753 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3755 for (p = fixtab[0][0];
3756 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
3758 *p = CODE_FOR_nothing;
3760 for (p = fixtrunctab[0][0];
3761 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
3763 *p = CODE_FOR_nothing;
3765 for (p = floattab[0][0];
3766 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3768 *p = CODE_FOR_nothing;
3770 for (p = extendtab[0][0];
3771 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
3773 *p = CODE_FOR_nothing;
3775 for (i = 0; i < NUM_RTX_CODE; i++)
3776 setcc_gen_code[i] = CODE_FOR_nothing;
3778 add_optab = init_optab (PLUS);
3779 sub_optab = init_optab (MINUS);
3780 smul_optab = init_optab (MULT);
3781 smul_highpart_optab = init_optab (UNKNOWN);
3782 umul_highpart_optab = init_optab (UNKNOWN);
3783 smul_widen_optab = init_optab (UNKNOWN);
3784 umul_widen_optab = init_optab (UNKNOWN);
3785 sdiv_optab = init_optab (DIV);
3786 sdivmod_optab = init_optab (UNKNOWN);
3787 udiv_optab = init_optab (UDIV);
3788 udivmod_optab = init_optab (UNKNOWN);
3789 smod_optab = init_optab (MOD);
3790 umod_optab = init_optab (UMOD);
3791 flodiv_optab = init_optab (DIV);
3792 ftrunc_optab = init_optab (UNKNOWN);
3793 and_optab = init_optab (AND);
3794 ior_optab = init_optab (IOR);
3795 xor_optab = init_optab (XOR);
3796 ashl_optab = init_optab (ASHIFT);
3797 ashr_optab = init_optab (ASHIFTRT);
3798 lshr_optab = init_optab (LSHIFTRT);
3799 rotl_optab = init_optab (ROTATE);
3800 rotr_optab = init_optab (ROTATERT);
3801 smin_optab = init_optab (SMIN);
3802 smax_optab = init_optab (SMAX);
3803 umin_optab = init_optab (UMIN);
3804 umax_optab = init_optab (UMAX);
3805 mov_optab = init_optab (UNKNOWN);
3806 movstrict_optab = init_optab (UNKNOWN);
3807 cmp_optab = init_optab (UNKNOWN);
3808 ucmp_optab = init_optab (UNKNOWN);
3809 tst_optab = init_optab (UNKNOWN);
3810 neg_optab = init_optab (NEG);
3811 abs_optab = init_optab (ABS);
3812 one_cmpl_optab = init_optab (NOT);
3813 ffs_optab = init_optab (FFS);
3814 sqrt_optab = init_optab (SQRT);
3815 sin_optab = init_optab (UNKNOWN);
3816 cos_optab = init_optab (UNKNOWN);
3817 strlen_optab = init_optab (UNKNOWN);
3819 for (i = 0; i < NUM_MACHINE_MODES; i++)
3821 movstr_optab[i] = CODE_FOR_nothing;
3823 #ifdef HAVE_SECONDARY_RELOADS
3824 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
3828 /* Fill in the optabs with the insns we support. */
3831 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3832 /* This flag says the same insns that convert to a signed fixnum
3833 also convert validly to an unsigned one. */
3834 for (i = 0; i < NUM_MACHINE_MODES; i++)
3835 for (j = 0; j < NUM_MACHINE_MODES; j++)
3836 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3839 #ifdef EXTRA_CC_MODES
3843 /* Initialize the optabs with the names of the library functions. */
3844 init_integral_libfuncs (add_optab, "add", '3');
3845 init_floating_libfuncs (add_optab, "add", '3');
3846 init_integral_libfuncs (sub_optab, "sub", '3');
3847 init_floating_libfuncs (sub_optab, "sub", '3');
3848 init_integral_libfuncs (smul_optab, "mul", '3');
3849 init_floating_libfuncs (smul_optab, "mul", '3');
3850 init_integral_libfuncs (sdiv_optab, "div", '3');
3851 init_integral_libfuncs (udiv_optab, "udiv", '3');
3852 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3853 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3854 init_integral_libfuncs (smod_optab, "mod", '3');
3855 init_integral_libfuncs (umod_optab, "umod", '3');
3856 init_floating_libfuncs (flodiv_optab, "div", '3');
3857 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3858 init_integral_libfuncs (and_optab, "and", '3');
3859 init_integral_libfuncs (ior_optab, "ior", '3');
3860 init_integral_libfuncs (xor_optab, "xor", '3');
3861 init_integral_libfuncs (ashl_optab, "ashl", '3');
3862 init_integral_libfuncs (ashr_optab, "ashr", '3');
3863 init_integral_libfuncs (lshr_optab, "lshr", '3');
3864 init_integral_libfuncs (rotl_optab, "rotl", '3');
3865 init_integral_libfuncs (rotr_optab, "rotr", '3');
3866 init_integral_libfuncs (smin_optab, "min", '3');
3867 init_floating_libfuncs (smin_optab, "min", '3');
3868 init_integral_libfuncs (smax_optab, "max", '3');
3869 init_floating_libfuncs (smax_optab, "max", '3');
3870 init_integral_libfuncs (umin_optab, "umin", '3');
3871 init_integral_libfuncs (umax_optab, "umax", '3');
3872 init_integral_libfuncs (neg_optab, "neg", '2');
3873 init_floating_libfuncs (neg_optab, "neg", '2');
3874 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
3875 init_integral_libfuncs (ffs_optab, "ffs", '2');
3877 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3878 init_integral_libfuncs (cmp_optab, "cmp", '2');
3879 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
3880 init_floating_libfuncs (cmp_optab, "cmp", '2');
3882 #ifdef MULSI3_LIBCALL
3883 smul_optab->handlers[(int) SImode].libfunc
3884 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3886 #ifdef MULDI3_LIBCALL
3887 smul_optab->handlers[(int) DImode].libfunc
3888 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3890 #ifdef MULTI3_LIBCALL
3891 smul_optab->handlers[(int) TImode].libfunc
3892 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3895 #ifdef DIVSI3_LIBCALL
3896 sdiv_optab->handlers[(int) SImode].libfunc
3897 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3899 #ifdef DIVDI3_LIBCALL
3900 sdiv_optab->handlers[(int) DImode].libfunc
3901 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3903 #ifdef DIVTI3_LIBCALL
3904 sdiv_optab->handlers[(int) TImode].libfunc
3905 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3908 #ifdef UDIVSI3_LIBCALL
3909 udiv_optab->handlers[(int) SImode].libfunc
3910 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3912 #ifdef UDIVDI3_LIBCALL
3913 udiv_optab->handlers[(int) DImode].libfunc
3914 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3916 #ifdef UDIVTI3_LIBCALL
3917 udiv_optab->handlers[(int) TImode].libfunc
3918 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3922 #ifdef MODSI3_LIBCALL
3923 smod_optab->handlers[(int) SImode].libfunc
3924 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3926 #ifdef MODDI3_LIBCALL
3927 smod_optab->handlers[(int) DImode].libfunc
3928 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3930 #ifdef MODTI3_LIBCALL
3931 smod_optab->handlers[(int) TImode].libfunc
3932 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3936 #ifdef UMODSI3_LIBCALL
3937 umod_optab->handlers[(int) SImode].libfunc
3938 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3940 #ifdef UMODDI3_LIBCALL
3941 umod_optab->handlers[(int) DImode].libfunc
3942 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3944 #ifdef UMODTI3_LIBCALL
3945 umod_optab->handlers[(int) TImode].libfunc
3946 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3949 /* Define library calls for quad FP instructions */
3950 #ifdef ADDTF3_LIBCALL
3951 add_optab->handlers[(int) TFmode].libfunc
3952 = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);
3954 #ifdef SUBTF3_LIBCALL
3955 sub_optab->handlers[(int) TFmode].libfunc
3956 = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);
3958 #ifdef MULTF3_LIBCALL
3959 smul_optab->handlers[(int) TFmode].libfunc
3960 = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);
3962 #ifdef DIVTF3_LIBCALL
3963 flodiv_optab->handlers[(int) TFmode].libfunc
3964 = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);
3966 #ifdef SQRTTF2_LIBCALL
3967 sqrt_optab->handlers[(int) TFmode].libfunc
3968 = gen_rtx (SYMBOL_REF, Pmode, SQRTTF2_LIBCALL);
3971 /* Use cabs for DC complex abs, since systems generally have cabs.
3972 Don't define any libcall for SCmode, so that cabs will be used. */
3973 abs_optab->handlers[(int) DCmode].libfunc
3974 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
3976 /* The ffs function operates on `int'. */
3977 #ifndef INT_TYPE_SIZE
3978 #define INT_TYPE_SIZE BITS_PER_WORD
3980 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
3981 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3983 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3984 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
3985 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
3986 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
3987 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
3989 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3990 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
3991 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
3992 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
3993 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
3995 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3996 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3997 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3998 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
3999 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4000 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4002 eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4003 nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4004 gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4005 gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4006 lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4007 lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4009 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4010 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4011 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4012 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4013 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4014 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4016 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4017 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4018 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4019 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4020 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4021 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4023 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4024 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4025 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4026 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4027 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4028 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4030 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4031 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4032 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4033 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4034 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4035 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4037 /* Define library calls for quad FP instructions */
4038 #ifdef EQTF2_LIBCALL
4039 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);
4041 #ifdef NETF2_LIBCALL
4042 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);
4044 #ifdef GTTF2_LIBCALL
4045 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);
4047 #ifdef GETF2_LIBCALL
4048 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);
4050 #ifdef LTTF2_LIBCALL
4051 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);
4053 #ifdef LETF2_LIBCALL
4054 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);
4057 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4058 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4059 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4061 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4062 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4063 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4065 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4066 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4067 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4069 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4070 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4071 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4073 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4074 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4075 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4077 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4078 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4079 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4081 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4082 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4083 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4085 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4086 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4087 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4089 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4090 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4091 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4093 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4094 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4095 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4097 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4098 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4099 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4101 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4102 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4103 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4105 /* Define library calls for quad FP instructions */
4106 #ifdef TRUNCTFSF2_LIBCALL
4107 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);
4109 #ifdef TRUNCTFDF2_LIBCALL
4110 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);
4112 #ifdef EXTENDSFTF2_LIBCALL
4113 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL);
4115 #ifdef EXTENDDFTF2_LIBCALL
4116 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL);
4118 #ifdef FLOATSITF2_LIBCALL
4119 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);
4121 #ifdef FIX_TRUNCTFSI2_LIBCALL
4122 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);
4124 #ifdef FIXUNS_TRUNCTFSI2_LIBCALL
4125 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL);
4128 #ifdef INIT_TARGET_OPTABS
4129 /* Allow the target to add more libcalls or rename some, etc. */
4136 /* SCO 3.2 apparently has a broken ldexp. */
4149 #endif /* BROKEN_LDEXP */