1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992 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_widen_optab;
46 optab umul_widen_optab;
70 optab movstrict_optab;
81 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
86 /* Tables of patterns for extending one integer mode to another. */
87 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
89 /* Tables of patterns for converting between fixed and floating point. */
90 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
91 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
92 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
94 /* SYMBOL_REF rtx's for the library functions that are called
95 implicitly and not via optabs. */
97 rtx extendsfdf2_libfunc;
98 rtx extendsfxf2_libfunc;
99 rtx extendsftf2_libfunc;
100 rtx extenddfxf2_libfunc;
101 rtx extenddftf2_libfunc;
103 rtx truncdfsf2_libfunc;
104 rtx truncxfsf2_libfunc;
105 rtx trunctfsf2_libfunc;
106 rtx truncxfdf2_libfunc;
107 rtx trunctfdf2_libfunc;
144 rtx floatsisf_libfunc;
145 rtx floatdisf_libfunc;
146 rtx floattisf_libfunc;
148 rtx floatsidf_libfunc;
149 rtx floatdidf_libfunc;
150 rtx floattidf_libfunc;
152 rtx floatsixf_libfunc;
153 rtx floatdixf_libfunc;
154 rtx floattixf_libfunc;
156 rtx floatsitf_libfunc;
157 rtx floatditf_libfunc;
158 rtx floattitf_libfunc;
176 rtx fixunssfsi_libfunc;
177 rtx fixunssfdi_libfunc;
178 rtx fixunssfti_libfunc;
180 rtx fixunsdfsi_libfunc;
181 rtx fixunsdfdi_libfunc;
182 rtx fixunsdfti_libfunc;
184 rtx fixunsxfsi_libfunc;
185 rtx fixunsxfdi_libfunc;
186 rtx fixunsxfti_libfunc;
188 rtx fixunstfsi_libfunc;
189 rtx fixunstfdi_libfunc;
190 rtx fixunstfti_libfunc;
192 /* from emit-rtl.c */
193 extern rtx gen_highpart ();
195 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
196 gives the gen_function to make a branch to test that condition. */
198 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
200 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
201 gives the insn code to make a store-condition insn
202 to test that condition. */
204 enum insn_code setcc_gen_code[NUM_RTX_CODE];
206 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
207 static void emit_float_lib_cmp PROTO((rtx, rtx, enum rtx_code));
208 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
210 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
212 static rtx ftruncify PROTO((rtx));
213 static optab init_optab PROTO((enum rtx_code));
214 static void init_libfuncs PROTO((optab, int, int, char *, int));
215 static void init_integral_libfuncs PROTO((optab, char *, int));
216 static void init_floating_libfuncs PROTO((optab, char *, int));
217 static void init_complex_libfuncs PROTO((optab, char *, int));
219 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
220 the result of operation CODE applied to OP0 (and OP1 if it is a binary
223 If the last insn does not set TARGET, don't do anything, but return 1.
225 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
226 don't add the REG_EQUAL note but return 0. Our caller can then try
227 again, ensuring that TARGET is not one of the operands. */
230 add_equal_note (seq, target, code, op0, op1)
240 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
241 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
242 || GET_CODE (seq) != SEQUENCE
243 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
244 || GET_CODE (target) == ZERO_EXTRACT
245 || (! rtx_equal_p (SET_DEST (set), target)
246 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
248 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
249 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
253 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
254 besides the last insn. */
255 if (reg_overlap_mentioned_p (target, op0)
256 || (op1 && reg_overlap_mentioned_p (target, op1)))
257 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
258 if (reg_set_p (target, XVECEXP (seq, 0, i)))
261 if (GET_RTX_CLASS (code) == '1')
262 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
264 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
266 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
267 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
268 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
273 /* Generate code to perform an operation specified by BINOPTAB
274 on operands OP0 and OP1, with result having machine-mode MODE.
276 UNSIGNEDP is for the case where we have to widen the operands
277 to perform the operation. It says to use zero-extension.
279 If TARGET is nonzero, the value
280 is generated there, if it is convenient to do so.
281 In all cases an rtx is returned for the locus of the value;
282 this may or may not be TARGET. */
285 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
286 enum machine_mode mode;
291 enum optab_methods methods;
293 enum mode_class class;
294 enum machine_mode wider_mode;
296 int commutative_op = 0;
297 int shift_op = (binoptab->code == ASHIFT
298 || binoptab->code == ASHIFTRT
299 || binoptab->code == LSHIFT
300 || binoptab->code == LSHIFTRT
301 || binoptab->code == ROTATE
302 || binoptab->code == ROTATERT);
303 rtx entry_last = get_last_insn ();
306 class = GET_MODE_CLASS (mode);
308 op0 = protect_from_queue (op0, 0);
309 op1 = protect_from_queue (op1, 0);
311 target = protect_from_queue (target, 1);
315 op0 = force_not_mem (op0);
316 op1 = force_not_mem (op1);
319 /* If subtracting an integer constant, convert this into an addition of
320 the negated constant. */
322 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
324 op1 = negate_rtx (mode, op1);
325 binoptab = add_optab;
328 /* If we are inside an appropriately-short loop and one operand is an
329 expensive constant, force it into a register. */
330 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
331 && rtx_cost (op0, binoptab->code) > 2)
332 op0 = force_reg (mode, op0);
334 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
335 && rtx_cost (op1, binoptab->code) > 2)
336 op1 = force_reg (shift_op ? word_mode : mode, op1);
338 /* Record where to delete back to if we backtrack. */
339 last = get_last_insn ();
341 /* If operation is commutative,
342 try to make the first operand a register.
343 Even better, try to make it the same as the target.
344 Also try to make the last operand a constant. */
345 if (GET_RTX_CLASS (binoptab->code) == 'c'
346 || binoptab == smul_widen_optab
347 || binoptab == umul_widen_optab)
351 if (((target == 0 || GET_CODE (target) == REG)
352 ? ((GET_CODE (op1) == REG
353 && GET_CODE (op0) != REG)
355 : rtx_equal_p (op1, target))
356 || GET_CODE (op0) == CONST_INT)
364 /* If we can do it with a three-operand insn, do so. */
366 if (methods != OPTAB_MUST_WIDEN
367 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
369 int icode = (int) binoptab->handlers[(int) mode].insn_code;
370 enum machine_mode mode0 = insn_operand_mode[icode][1];
371 enum machine_mode mode1 = insn_operand_mode[icode][2];
373 rtx xop0 = op0, xop1 = op1;
378 temp = gen_reg_rtx (mode);
380 /* If it is a commutative operator and the modes would match
381 if we would swap the operands, we can save the conversions. */
384 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
385 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
389 tmp = op0; op0 = op1; op1 = tmp;
390 tmp = xop0; xop0 = xop1; xop1 = tmp;
394 /* In case the insn wants input operands in modes different from
395 the result, convert the operands. */
397 if (GET_MODE (op0) != VOIDmode
398 && GET_MODE (op0) != mode0)
399 xop0 = convert_to_mode (mode0, xop0, unsignedp);
401 if (GET_MODE (xop1) != VOIDmode
402 && GET_MODE (xop1) != mode1)
403 xop1 = convert_to_mode (mode1, xop1, unsignedp);
405 /* Now, if insn's predicates don't allow our operands, put them into
408 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
409 xop0 = copy_to_mode_reg (mode0, xop0);
411 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
412 xop1 = copy_to_mode_reg (mode1, xop1);
414 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
415 temp = gen_reg_rtx (mode);
417 pat = GEN_FCN (icode) (temp, xop0, xop1);
420 /* If PAT is a multi-insn sequence, try to add an appropriate
421 REG_EQUAL note to it. If we can't because TEMP conflicts with an
422 operand, call ourselves again, this time without a target. */
423 if (GET_CODE (pat) == SEQUENCE
424 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
426 delete_insns_since (last);
427 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
435 delete_insns_since (last);
438 /* If this is a multiply, see if we can do a widening operation that
439 takes operands of this mode and makes a wider mode. */
441 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
442 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
443 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
444 != CODE_FOR_nothing))
446 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
447 unsignedp ? umul_widen_optab : smul_widen_optab,
448 op0, op1, 0, unsignedp, OPTAB_DIRECT);
450 if (GET_MODE_CLASS (mode) == MODE_INT)
451 return gen_lowpart (mode, temp);
453 return convert_to_mode (mode, temp, unsignedp);
456 /* Look for a wider mode of the same class for which we think we
457 can open-code the operation. Check for a widening multiply at the
458 wider mode as well. */
460 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
461 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
462 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
463 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
465 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
466 || (binoptab == smul_optab
467 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
468 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
469 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
470 != CODE_FOR_nothing)))
472 rtx xop0 = op0, xop1 = op1;
475 /* For certain integer operations, we need not actually extend
476 the narrow operands, as long as we will truncate
477 the results to the same narrowness. Don't do this when
478 WIDER_MODE is wider than a word since a paradoxical SUBREG
479 isn't valid for such modes. */
481 if ((binoptab == ior_optab || binoptab == and_optab
482 || binoptab == xor_optab
483 || binoptab == add_optab || binoptab == sub_optab
484 || binoptab == smul_optab
485 || binoptab == ashl_optab || binoptab == lshl_optab)
487 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
490 /* If an operand is a constant integer, we might as well
491 convert it since that is more efficient than using a SUBREG,
492 unlike the case for other operands. Similarly for
493 SUBREGs that were made due to promoted objects. */
495 if (no_extend && GET_MODE (xop0) != VOIDmode
496 && ! (GET_CODE (xop0) == SUBREG
497 && SUBREG_PROMOTED_VAR_P (xop0)))
498 xop0 = gen_rtx (SUBREG, wider_mode,
499 force_reg (GET_MODE (xop0), xop0), 0);
501 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
503 if (no_extend && GET_MODE (xop1) != VOIDmode
504 && ! (GET_CODE (xop1) == SUBREG
505 && SUBREG_PROMOTED_VAR_P (xop1)))
506 xop1 = gen_rtx (SUBREG, wider_mode,
507 force_reg (GET_MODE (xop1), xop1), 0);
509 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
511 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
512 unsignedp, OPTAB_DIRECT);
515 if (class != MODE_INT)
518 target = gen_reg_rtx (mode);
519 convert_move (target, temp, 0);
523 return gen_lowpart (mode, temp);
526 delete_insns_since (last);
530 /* These can be done a word at a time. */
531 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
533 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
534 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
540 /* If TARGET is the same as one of the operands, the REG_EQUAL note
541 won't be accurate, so use a new target. */
542 if (target == 0 || target == op0 || target == op1)
543 target = gen_reg_rtx (mode);
547 /* Do the actual arithmetic. */
548 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
550 rtx target_piece = operand_subword (target, i, 1, mode);
551 rtx x = expand_binop (word_mode, binoptab,
552 operand_subword_force (op0, i, mode),
553 operand_subword_force (op1, i, mode),
554 target_piece, unsignedp, methods);
555 if (target_piece != x)
556 emit_move_insn (target_piece, x);
559 insns = get_insns ();
562 if (binoptab->code != UNKNOWN)
564 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
568 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
572 /* These can be done a word at a time by propagating carries. */
573 if ((binoptab == add_optab || binoptab == sub_optab)
575 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
576 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
579 rtx carry_tmp = gen_reg_rtx (word_mode);
580 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
581 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
582 rtx carry_in, carry_out;
585 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
586 value is one of those, use it. Otherwise, use 1 since it is the
587 one easiest to get. */
588 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
589 int normalizep = STORE_FLAG_VALUE;
594 /* Prepare the operands. */
595 xop0 = force_reg (mode, op0);
596 xop1 = force_reg (mode, op1);
598 if (target == 0 || GET_CODE (target) != REG
599 || target == xop0 || target == xop1)
600 target = gen_reg_rtx (mode);
602 /* Indicate for flow that the entire target reg is being set. */
603 if (GET_CODE (target) == REG)
604 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
606 /* Do the actual arithmetic. */
607 for (i = 0; i < nwords; i++)
609 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
610 rtx target_piece = operand_subword (target, index, 1, mode);
611 rtx op0_piece = operand_subword_force (xop0, index, mode);
612 rtx op1_piece = operand_subword_force (xop1, index, mode);
615 /* Main add/subtract of the input operands. */
616 x = expand_binop (word_mode, binoptab,
617 op0_piece, op1_piece,
618 target_piece, unsignedp, methods);
624 /* Store carry from main add/subtract. */
625 carry_out = gen_reg_rtx (word_mode);
626 carry_out = emit_store_flag (carry_out,
627 binoptab == add_optab ? LTU : GTU,
629 word_mode, 1, normalizep);
636 /* Add/subtract previous carry to main result. */
637 x = expand_binop (word_mode,
638 normalizep == 1 ? binoptab : otheroptab,
640 target_piece, 1, methods);
641 if (target_piece != x)
642 emit_move_insn (target_piece, x);
646 /* THIS CODE HAS NOT BEEN TESTED. */
647 /* Get out carry from adding/subtracting carry in. */
648 carry_tmp = emit_store_flag (carry_tmp,
649 binoptab == add_optab
652 word_mode, 1, normalizep);
653 /* Logical-ior the two poss. carry together. */
654 carry_out = expand_binop (word_mode, ior_optab,
655 carry_out, carry_tmp,
656 carry_out, 0, methods);
662 carry_in = carry_out;
665 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
669 temp = emit_move_insn (target, target);
670 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
671 gen_rtx (binoptab->code, mode,
678 delete_insns_since (last);
681 /* If we want to multiply two two-word values and have normal and widening
682 multiplies of single-word values, we can do this with three smaller
683 multiplications. Note that we do not make a REG_NO_CONFLICT block here
684 because we are not operating on one word at a time.
686 The multiplication proceeds as follows:
687 _______________________
688 [__op0_high_|__op0_low__]
689 _______________________
690 * [__op1_high_|__op1_low__]
691 _______________________________________________
692 _______________________
693 (1) [__op0_low__*__op1_low__]
694 _______________________
695 (2a) [__op0_low__*__op1_high_]
696 _______________________
697 (2b) [__op0_high_*__op1_low__]
698 _______________________
699 (3) [__op0_high_*__op1_high_]
702 This gives a 4-word result. Since we are only interested in the
703 lower 2 words, partial result (3) and the upper words of (2a) and
704 (2b) don't need to be calculated. Hence (2a) and (2b) can be
705 calculated using non-widening multiplication.
707 (1), however, needs to be calculated with an unsigned widening
708 multiplication. If this operation is not directly supported we
709 try using a signed widening multiplication and adjust the result.
710 This adjustment works as follows:
712 If both operands are positive then no adjustment is needed.
714 If the operands have different signs, for example op0_low < 0 and
715 op1_low >= 0, the instruction treats the most significant bit of
716 op0_low as a sign bit instead of a bit with significance
717 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
718 with 2**BITS_PER_WORD - op0_low, and two's complements the
719 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
722 Similarly, if both operands are negative, we need to add
723 (op0_low + op1_low) * 2**BITS_PER_WORD.
725 We use a trick to adjust quickly. We logically shift op0_low right
726 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
727 op0_high (op1_high) before it is used to calculate 2b (2a). If no
728 logical shift exists, we do an arithmetic right shift and subtract
731 if (binoptab == smul_optab
733 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
734 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
735 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
736 && ((umul_widen_optab->handlers[(int) mode].insn_code
738 || (smul_widen_optab->handlers[(int) mode].insn_code
739 != CODE_FOR_nothing)))
741 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
742 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
743 rtx op0_high = operand_subword_force (op0, high, mode);
744 rtx op0_low = operand_subword_force (op0, low, mode);
745 rtx op1_high = operand_subword_force (op1, high, mode);
746 rtx op1_low = operand_subword_force (op1, low, mode);
751 /* If the target is the same as one of the inputs, don't use it. This
752 prevents problems with the REG_EQUAL note. */
753 if (target == op0 || target == op1)
756 /* Multiply the two lower words to get a double-word product.
757 If unsigned widening multiplication is available, use that;
758 otherwise use the signed form and compensate. */
760 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
762 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
763 target, 1, OPTAB_DIRECT);
765 /* If we didn't succeed, delete everything we did so far. */
767 delete_insns_since (last);
769 op0_xhigh = op0_high, op1_xhigh = op1_high;
773 && smul_widen_optab->handlers[(int) mode].insn_code
776 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
777 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
778 target, 1, OPTAB_DIRECT);
779 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
780 NULL_RTX, 1, OPTAB_DIRECT);
782 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
783 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
786 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
787 NULL_RTX, 0, OPTAB_DIRECT);
789 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
790 op0_xhigh, op0_xhigh, 0,
794 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
795 NULL_RTX, 1, OPTAB_DIRECT);
797 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
798 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
801 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
802 NULL_RTX, 0, OPTAB_DIRECT);
804 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
805 op1_xhigh, op1_xhigh, 0,
810 /* If we have been able to directly compute the product of the
811 low-order words of the operands and perform any required adjustments
812 of the operands, we proceed by trying two more multiplications
813 and then computing the appropriate sum.
815 We have checked above that the required addition is provided.
816 Full-word addition will normally always succeed, especially if
817 it is provided at all, so we don't worry about its failure. The
818 multiplication may well fail, however, so we do handle that. */
820 if (product && op0_xhigh && op1_xhigh)
823 rtx product_high = operand_subword (product, high, 1, mode);
824 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
825 NULL_RTX, 0, OPTAB_DIRECT);
829 product_piece = expand_binop (word_mode, add_optab, temp,
830 product_high, product_high,
832 if (product_piece != product_high)
833 emit_move_insn (product_high, product_piece);
835 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
836 NULL_RTX, 0, OPTAB_DIRECT);
838 product_piece = expand_binop (word_mode, add_optab, temp,
839 product_high, product_high,
841 if (product_piece != product_high)
842 emit_move_insn (product_high, product_piece);
844 temp = emit_move_insn (product, product);
845 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
846 gen_rtx (MULT, mode, copy_rtx (op0),
854 /* If we get here, we couldn't do it for some reason even though we
855 originally thought we could. Delete anything we've emitted in
858 delete_insns_since (last);
861 /* We need to open-code the complex type operations: '+, -, * and /' */
863 /* At this point we allow operations between two similar complex
864 numbers, and also if one of the operands is not a complex number
865 but rather of MODE_FLOAT or MODE_INT. However, the caller
866 must make sure that the MODE of the non-complex operand matches
867 the SUBMODE of the complex operand. */
869 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
881 /* Find the correct mode for the real and imaginary parts */
882 enum machine_mode submode
883 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
884 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
887 if (submode == BLKmode)
891 target = gen_reg_rtx (mode);
895 realr = gen_realpart (submode, target);
896 imagr = gen_imagpart (submode, target);
898 if (GET_MODE (op0) == mode)
900 real0 = gen_realpart (submode, op0);
901 imag0 = gen_imagpart (submode, op0);
906 if (GET_MODE (op1) == mode)
908 real1 = gen_realpart (submode, op1);
909 imag1 = gen_imagpart (submode, op1);
914 if (! real0 || ! real1 || ! (imag0 || imag1))
917 switch (binoptab->code)
920 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
922 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
923 res = expand_binop (submode, binoptab, real0, real1,
924 realr, unsignedp, methods);
926 emit_move_insn (realr, res);
929 res = expand_binop (submode, binoptab, imag0, imag1,
930 imagr, unsignedp, methods);
933 else if (binoptab->code == MINUS)
934 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
939 emit_move_insn (imagr, res);
943 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
947 /* Don't fetch these from memory more than once. */
948 real0 = force_reg (submode, real0);
949 real1 = force_reg (submode, real1);
950 imag0 = force_reg (submode, imag0);
951 imag1 = force_reg (submode, imag1);
953 res = expand_binop (submode, sub_optab,
954 expand_binop (submode, binoptab, real0,
955 real1, 0, unsignedp, methods),
956 expand_binop (submode, binoptab, imag0,
957 imag1, 0, unsignedp, methods),
958 realr, unsignedp, methods);
961 emit_move_insn (realr, res);
963 res = expand_binop (submode, add_optab,
964 expand_binop (submode, binoptab,
966 0, unsignedp, methods),
967 expand_binop (submode, binoptab,
969 0, unsignedp, methods),
970 imagr, unsignedp, methods);
972 emit_move_insn (imagr, res);
976 /* Don't fetch these from memory more than once. */
977 real0 = force_reg (submode, real0);
978 real1 = force_reg (submode, real1);
980 res = expand_binop (submode, binoptab, real0, real1,
981 realr, unsignedp, methods);
983 emit_move_insn (realr, res);
986 res = expand_binop (submode, binoptab,
987 real1, imag0, imagr, unsignedp, methods);
989 res = expand_binop (submode, binoptab,
990 real0, imag1, imagr, unsignedp, methods);
992 emit_move_insn (imagr, res);
997 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1000 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1002 /* Don't fetch these from memory more than once. */
1003 real1 = force_reg (submode, real1);
1005 /* Simply divide the real and imaginary parts by `c' */
1006 res = expand_binop (submode, binoptab, real0, real1,
1007 realr, unsignedp, methods);
1009 emit_move_insn (realr, res);
1011 res = expand_binop (submode, binoptab, imag0, real1,
1012 imagr, unsignedp, methods);
1014 emit_move_insn (imagr, res);
1016 else /* Divisor is of complex type */
1023 optab mulopt = unsignedp ? umul_widen_optab : smul_optab;
1025 /* Don't fetch these from memory more than once. */
1026 real0 = force_reg (submode, real0);
1027 real1 = force_reg (submode, real1);
1029 imag0 = force_reg (submode, imag0);
1030 imag1 = force_reg (submode, imag1);
1032 /* Divisor: c*c + d*d */
1033 divisor = expand_binop (submode, add_optab,
1034 expand_binop (submode, mulopt,
1036 0, unsignedp, methods),
1037 expand_binop (submode, mulopt,
1039 0, unsignedp, methods),
1040 0, unsignedp, methods);
1042 if (! imag0) /* ((a)(c-id))/divisor */
1043 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1044 /* Calculate the dividend */
1045 real_t = expand_binop (submode, mulopt, real0, real1,
1046 0, unsignedp, methods);
1049 = expand_unop (submode, neg_optab,
1050 expand_binop (submode, mulopt, real0, imag1,
1051 0, unsignedp, methods),
1054 else /* ((a+ib)(c-id))/divider */
1056 /* Calculate the dividend */
1057 real_t = expand_binop (submode, add_optab,
1058 expand_binop (submode, mulopt,
1060 0, unsignedp, methods),
1061 expand_binop (submode, mulopt,
1063 0, unsignedp, methods),
1064 0, unsignedp, methods);
1066 imag_t = expand_binop (submode, sub_optab,
1067 expand_binop (submode, mulopt,
1069 0, unsignedp, methods),
1070 expand_binop (submode, mulopt,
1072 0, unsignedp, methods),
1073 0, unsignedp, methods);
1077 res = expand_binop (submode, binoptab, real_t, divisor,
1078 realr, unsignedp, methods);
1080 emit_move_insn (realr, res);
1082 res = expand_binop (submode, binoptab, imag_t, divisor,
1083 imagr, unsignedp, methods);
1085 emit_move_insn (imagr, res);
1096 if (binoptab->code != UNKNOWN)
1098 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1102 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1107 /* It can't be open-coded in this mode.
1108 Use a library call if one is available and caller says that's ok. */
1110 if (binoptab->handlers[(int) mode].libfunc
1111 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1114 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1116 enum machine_mode op1_mode = mode;
1122 op1_mode = word_mode;
1123 /* Specify unsigned here,
1124 since negative shift counts are meaningless. */
1125 op1x = convert_to_mode (word_mode, op1, 1);
1128 /* Pass 1 for NO_QUEUE so we don't lose any increments
1129 if the libcall is cse'd or moved. */
1130 emit_library_call (binoptab->handlers[(int) mode].libfunc,
1131 1, mode, 2, op0, mode, op1x, op1_mode);
1133 insns = get_insns ();
1136 target = gen_reg_rtx (mode);
1137 emit_libcall_block (insns, target, hard_libcall_value (mode),
1138 gen_rtx (binoptab->code, mode, op0, op1));
1143 delete_insns_since (last);
1145 /* It can't be done in this mode. Can we do it in a wider mode? */
1147 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1148 || methods == OPTAB_MUST_WIDEN))
1150 /* Caller says, don't even try. */
1151 delete_insns_since (entry_last);
1155 /* Compute the value of METHODS to pass to recursive calls.
1156 Don't allow widening to be tried recursively. */
1158 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1160 /* Look for a wider mode of the same class for which it appears we can do
1163 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1165 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1166 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1168 if ((binoptab->handlers[(int) wider_mode].insn_code
1169 != CODE_FOR_nothing)
1170 || (methods == OPTAB_LIB
1171 && binoptab->handlers[(int) wider_mode].libfunc))
1173 rtx xop0 = op0, xop1 = op1;
1176 /* For certain integer operations, we need not actually extend
1177 the narrow operands, as long as we will truncate
1178 the results to the same narrowness. Don't do this when
1179 WIDER_MODE is wider than a word since a paradoxical SUBREG
1180 isn't valid for such modes. */
1182 if ((binoptab == ior_optab || binoptab == and_optab
1183 || binoptab == xor_optab
1184 || binoptab == add_optab || binoptab == sub_optab
1185 || binoptab == smul_optab
1186 || binoptab == ashl_optab || binoptab == lshl_optab)
1187 && class == MODE_INT
1188 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
1191 /* If an operand is a constant integer, we might as well
1192 convert it since that is more efficient than using a SUBREG,
1193 unlike the case for other operands. Similarly for
1194 SUBREGs that were made due to promoted objects.*/
1196 if (no_extend && GET_MODE (xop0) != VOIDmode
1197 && ! (GET_CODE (xop0) == SUBREG
1198 && SUBREG_PROMOTED_VAR_P (xop0)))
1199 xop0 = gen_rtx (SUBREG, wider_mode,
1200 force_reg (GET_MODE (xop0), xop0), 0);
1202 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1204 if (no_extend && GET_MODE (xop1) != VOIDmode
1205 && ! (GET_CODE (xop1) == SUBREG
1206 && SUBREG_PROMOTED_VAR_P (xop1)))
1207 xop1 = gen_rtx (SUBREG, wider_mode,
1208 force_reg (GET_MODE (xop1), xop1), 0);
1210 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
1212 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1213 unsignedp, methods);
1216 if (class != MODE_INT)
1219 target = gen_reg_rtx (mode);
1220 convert_move (target, temp, 0);
1224 return gen_lowpart (mode, temp);
1227 delete_insns_since (last);
1232 delete_insns_since (entry_last);
1236 /* Expand a binary operator which has both signed and unsigned forms.
1237 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1240 If we widen unsigned operands, we may use a signed wider operation instead
1241 of an unsigned wider operation, since the result would be the same. */
1244 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1245 enum machine_mode mode;
1246 optab uoptab, soptab;
1247 rtx op0, op1, target;
1249 enum optab_methods methods;
1252 optab direct_optab = unsignedp ? uoptab : soptab;
1253 struct optab wide_soptab;
1255 /* Do it without widening, if possible. */
1256 temp = expand_binop (mode, direct_optab, op0, op1, target,
1257 unsignedp, OPTAB_DIRECT);
1258 if (temp || methods == OPTAB_DIRECT)
1261 /* Try widening to a signed int. Make a fake signed optab that
1262 hides any signed insn for direct use. */
1263 wide_soptab = *soptab;
1264 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1265 wide_soptab.handlers[(int) mode].libfunc = 0;
1267 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1268 unsignedp, OPTAB_WIDEN);
1270 /* For unsigned operands, try widening to an unsigned int. */
1271 if (temp == 0 && unsignedp)
1272 temp = expand_binop (mode, uoptab, op0, op1, target,
1273 unsignedp, OPTAB_WIDEN);
1274 if (temp || methods == OPTAB_WIDEN)
1277 /* Use the right width lib call if that exists. */
1278 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1279 if (temp || methods == OPTAB_LIB)
1282 /* Must widen and use a lib call, use either signed or unsigned. */
1283 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1284 unsignedp, methods);
1288 return expand_binop (mode, uoptab, op0, op1, target,
1289 unsignedp, methods);
1293 /* Generate code to perform an operation specified by BINOPTAB
1294 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1295 We assume that the order of the operands for the instruction
1296 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1297 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1299 Either TARG0 or TARG1 may be zero, but what that means is that
1300 that result is not actually wanted. We will generate it into
1301 a dummy pseudo-reg and discard it. They may not both be zero.
1303 Returns 1 if this operation can be performed; 0 if not. */
1306 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1312 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1313 enum mode_class class;
1314 enum machine_mode wider_mode;
1315 rtx entry_last = get_last_insn ();
1318 class = GET_MODE_CLASS (mode);
1320 op0 = protect_from_queue (op0, 0);
1321 op1 = protect_from_queue (op1, 0);
1325 op0 = force_not_mem (op0);
1326 op1 = force_not_mem (op1);
1329 /* If we are inside an appropriately-short loop and one operand is an
1330 expensive constant, force it into a register. */
1331 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1332 && rtx_cost (op0, binoptab->code) > 2)
1333 op0 = force_reg (mode, op0);
1335 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1336 && rtx_cost (op1, binoptab->code) > 2)
1337 op1 = force_reg (mode, op1);
1340 targ0 = protect_from_queue (targ0, 1);
1342 targ0 = gen_reg_rtx (mode);
1344 targ1 = protect_from_queue (targ1, 1);
1346 targ1 = gen_reg_rtx (mode);
1348 /* Record where to go back to if we fail. */
1349 last = get_last_insn ();
1351 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1353 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1354 enum machine_mode mode0 = insn_operand_mode[icode][1];
1355 enum machine_mode mode1 = insn_operand_mode[icode][2];
1357 rtx xop0 = op0, xop1 = op1;
1359 /* In case this insn wants input operands in modes different from the
1360 result, convert the operands. */
1361 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1362 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1364 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1365 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1367 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1368 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1369 xop0 = copy_to_mode_reg (mode0, xop0);
1371 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1372 xop1 = copy_to_mode_reg (mode1, xop1);
1374 /* We could handle this, but we should always be called with a pseudo
1375 for our targets and all insns should take them as outputs. */
1376 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1377 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1380 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1387 delete_insns_since (last);
1390 /* It can't be done in this mode. Can we do it in a wider mode? */
1392 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1394 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1395 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1397 if (binoptab->handlers[(int) wider_mode].insn_code
1398 != CODE_FOR_nothing)
1400 register rtx t0 = gen_reg_rtx (wider_mode);
1401 register rtx t1 = gen_reg_rtx (wider_mode);
1403 if (expand_twoval_binop (binoptab,
1404 convert_to_mode (wider_mode, op0,
1406 convert_to_mode (wider_mode, op1,
1410 convert_move (targ0, t0, unsignedp);
1411 convert_move (targ1, t1, unsignedp);
1415 delete_insns_since (last);
1420 delete_insns_since (entry_last);
1424 /* Generate code to perform an operation specified by UNOPTAB
1425 on operand OP0, with result having machine-mode MODE.
1427 UNSIGNEDP is for the case where we have to widen the operands
1428 to perform the operation. It says to use zero-extension.
1430 If TARGET is nonzero, the value
1431 is generated there, if it is convenient to do so.
1432 In all cases an rtx is returned for the locus of the value;
1433 this may or may not be TARGET. */
1436 expand_unop (mode, unoptab, op0, target, unsignedp)
1437 enum machine_mode mode;
1443 enum mode_class class;
1444 enum machine_mode wider_mode;
1446 rtx last = get_last_insn ();
1449 class = GET_MODE_CLASS (mode);
1451 op0 = protect_from_queue (op0, 0);
1455 op0 = force_not_mem (op0);
1459 target = protect_from_queue (target, 1);
1461 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1463 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1464 enum machine_mode mode0 = insn_operand_mode[icode][1];
1470 temp = gen_reg_rtx (mode);
1472 if (GET_MODE (xop0) != VOIDmode
1473 && GET_MODE (xop0) != mode0)
1474 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1476 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1478 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1479 xop0 = copy_to_mode_reg (mode0, xop0);
1481 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1482 temp = gen_reg_rtx (mode);
1484 pat = GEN_FCN (icode) (temp, xop0);
1487 if (GET_CODE (pat) == SEQUENCE
1488 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1490 delete_insns_since (last);
1491 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1499 delete_insns_since (last);
1502 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1504 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1505 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1506 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1508 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1512 /* For certain operations, we need not actually extend
1513 the narrow operand, as long as we will truncate the
1514 results to the same narrowness. But it is faster to
1515 convert a SUBREG due to mode promotion. */
1517 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1518 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1519 && class == MODE_INT
1520 && ! (GET_CODE (xop0) == SUBREG
1521 && SUBREG_PROMOTED_VAR_P (xop0)))
1522 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1524 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1526 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1531 if (class != MODE_INT)
1534 target = gen_reg_rtx (mode);
1535 convert_move (target, temp, 0);
1539 return gen_lowpart (mode, temp);
1542 delete_insns_since (last);
1546 /* These can be done a word at a time. */
1547 if (unoptab == one_cmpl_optab
1548 && class == MODE_INT
1549 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1550 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1555 if (target == 0 || target == op0)
1556 target = gen_reg_rtx (mode);
1560 /* Do the actual arithmetic. */
1561 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1563 rtx target_piece = operand_subword (target, i, 1, mode);
1564 rtx x = expand_unop (word_mode, unoptab,
1565 operand_subword_force (op0, i, mode),
1566 target_piece, unsignedp);
1567 if (target_piece != x)
1568 emit_move_insn (target_piece, x);
1571 insns = get_insns ();
1574 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1575 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1579 /* Open-code the complex negation operation. */
1580 else if (unoptab == neg_optab
1581 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1587 /* Find the correct mode for the real and imaginary parts */
1588 enum machine_mode submode
1589 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1590 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1593 if (submode == BLKmode)
1597 target = gen_reg_rtx (mode);
1601 target_piece = gen_imagpart (submode, target);
1602 x = expand_unop (submode, unoptab,
1603 gen_imagpart (submode, op0),
1604 target_piece, unsignedp);
1605 if (target_piece != x)
1606 emit_move_insn (target_piece, x);
1608 target_piece = gen_realpart (submode, target);
1609 x = expand_unop (submode, unoptab,
1610 gen_realpart (submode, op0),
1611 target_piece, unsignedp);
1612 if (target_piece != x)
1613 emit_move_insn (target_piece, x);
1618 emit_no_conflict_block (seq, target, op0, 0,
1619 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1623 /* Now try a library call in this mode. */
1624 if (unoptab->handlers[(int) mode].libfunc)
1627 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1631 /* Pass 1 for NO_QUEUE so we don't lose any increments
1632 if the libcall is cse'd or moved. */
1633 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1634 1, mode, 1, op0, mode);
1635 insns = get_insns ();
1638 target = gen_reg_rtx (mode);
1639 emit_libcall_block (insns, target, hard_libcall_value (mode),
1640 gen_rtx (unoptab->code, mode, op0));
1645 /* It can't be done in this mode. Can we do it in a wider mode? */
1647 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1649 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1650 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1652 if ((unoptab->handlers[(int) wider_mode].insn_code
1653 != CODE_FOR_nothing)
1654 || unoptab->handlers[(int) wider_mode].libfunc)
1658 /* For certain operations, we need not actually extend
1659 the narrow operand, as long as we will truncate the
1660 results to the same narrowness. */
1662 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1663 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1664 && class == MODE_INT
1665 && ! (GET_CODE (xop0) == SUBREG
1666 && SUBREG_PROMOTED_VAR_P (xop0)))
1667 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1669 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1671 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1676 if (class != MODE_INT)
1679 target = gen_reg_rtx (mode);
1680 convert_move (target, temp, 0);
1684 return gen_lowpart (mode, temp);
1687 delete_insns_since (last);
1695 /* Emit code to compute the absolute value of OP0, with result to
1696 TARGET if convenient. (TARGET may be 0.) The return value says
1697 where the result actually is to be found.
1699 MODE is the mode of the operand; the mode of the result is
1700 different but can be deduced from MODE.
1702 UNSIGNEDP is relevant for complex integer modes. */
1705 expand_complex_abs (mode, op0, target, unsignedp)
1706 enum machine_mode mode;
1711 enum mode_class class = GET_MODE_CLASS (mode);
1712 enum machine_mode wider_mode;
1714 rtx entry_last = get_last_insn ();
1718 /* Find the correct mode for the real and imaginary parts. */
1719 enum machine_mode submode
1720 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1721 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1724 if (submode == BLKmode)
1727 op0 = protect_from_queue (op0, 0);
1731 op0 = force_not_mem (op0);
1734 last = get_last_insn ();
1737 target = protect_from_queue (target, 1);
1739 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1741 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1742 enum machine_mode mode0 = insn_operand_mode[icode][1];
1748 temp = gen_reg_rtx (submode);
1750 if (GET_MODE (xop0) != VOIDmode
1751 && GET_MODE (xop0) != mode0)
1752 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1754 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1756 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1757 xop0 = copy_to_mode_reg (mode0, xop0);
1759 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1760 temp = gen_reg_rtx (submode);
1762 pat = GEN_FCN (icode) (temp, xop0);
1765 if (GET_CODE (pat) == SEQUENCE
1766 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
1768 delete_insns_since (last);
1769 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
1777 delete_insns_since (last);
1780 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1782 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1783 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1785 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1789 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1790 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1794 if (class != MODE_COMPLEX_INT)
1797 target = gen_reg_rtx (submode);
1798 convert_move (target, temp, 0);
1802 return gen_lowpart (submode, temp);
1805 delete_insns_since (last);
1809 /* Open-code the complex absolute-value operation
1810 if we can open-code sqrt. Otherwise it's not worth while. */
1811 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
1813 rtx real, imag, total;
1815 real = gen_realpart (submode, op0);
1816 imag = gen_imagpart (submode, op0);
1817 /* Square both parts. */
1818 real = expand_mult (mode, real, real, NULL_RTX, 0);
1819 imag = expand_mult (mode, imag, imag, NULL_RTX, 0);
1820 /* Sum the parts. */
1821 total = expand_binop (submode, add_optab, real, imag, 0,
1822 0, OPTAB_LIB_WIDEN);
1823 /* Get sqrt in TARGET. Set TARGET to where the result is. */
1824 target = expand_unop (submode, sqrt_optab, total, target, 0);
1826 delete_insns_since (last);
1831 /* Now try a library call in this mode. */
1832 if (abs_optab->handlers[(int) mode].libfunc)
1835 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
1839 /* Pass 1 for NO_QUEUE so we don't lose any increments
1840 if the libcall is cse'd or moved. */
1841 emit_library_call (abs_optab->handlers[(int) mode].libfunc,
1842 1, mode, 1, op0, mode);
1843 insns = get_insns ();
1846 target = gen_reg_rtx (submode);
1847 emit_libcall_block (insns, target, hard_libcall_value (submode),
1848 gen_rtx (abs_optab->code, mode, op0));
1853 /* It can't be done in this mode. Can we do it in a wider mode? */
1855 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1856 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1858 if ((abs_optab->handlers[(int) wider_mode].insn_code
1859 != CODE_FOR_nothing)
1860 || abs_optab->handlers[(int) wider_mode].libfunc)
1864 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1866 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1870 if (class != MODE_COMPLEX_INT)
1873 target = gen_reg_rtx (submode);
1874 convert_move (target, temp, 0);
1878 return gen_lowpart (submode, temp);
1881 delete_insns_since (last);
1885 delete_insns_since (entry_last);
1889 /* Generate an instruction whose insn-code is INSN_CODE,
1890 with two operands: an output TARGET and an input OP0.
1891 TARGET *must* be nonzero, and the output is always stored there.
1892 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1893 the value that is stored into TARGET. */
1896 emit_unop_insn (icode, target, op0, code)
1903 enum machine_mode mode0 = insn_operand_mode[icode][1];
1906 temp = target = protect_from_queue (target, 1);
1908 op0 = protect_from_queue (op0, 0);
1911 op0 = force_not_mem (op0);
1913 /* Now, if insn does not accept our operands, put them into pseudos. */
1915 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1916 op0 = copy_to_mode_reg (mode0, op0);
1918 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1919 || (flag_force_mem && GET_CODE (temp) == MEM))
1920 temp = gen_reg_rtx (GET_MODE (temp));
1922 pat = GEN_FCN (icode) (temp, op0);
1924 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1925 add_equal_note (pat, temp, code, op0, NULL_RTX);
1930 emit_move_insn (target, temp);
1933 /* Emit code to perform a series of operations on a multi-word quantity, one
1936 Such a block is preceded by a CLOBBER of the output, consists of multiple
1937 insns, each setting one word of the output, and followed by a SET copying
1938 the output to itself.
1940 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1941 note indicating that it doesn't conflict with the (also multi-word)
1942 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1945 INSNS is a block of code generated to perform the operation, not including
1946 the CLOBBER and final copy. All insns that compute intermediate values
1947 are first emitted, followed by the block as described above. Only
1948 INSNs are allowed in the block; no library calls or jumps may be
1951 TARGET, OP0, and OP1 are the output and inputs of the operations,
1952 respectively. OP1 may be zero for a unary operation.
1954 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1957 If TARGET is not a register, INSNS is simply emitted with no special
1960 The final insn emitted is returned. */
1963 emit_no_conflict_block (insns, target, op0, op1, equiv)
1969 rtx prev, next, first, last, insn;
1971 if (GET_CODE (target) != REG || reload_in_progress)
1972 return emit_insns (insns);
1974 /* First emit all insns that do not store into words of the output and remove
1975 these from the list. */
1976 for (insn = insns; insn; insn = next)
1981 next = NEXT_INSN (insn);
1983 if (GET_CODE (insn) != INSN)
1986 if (GET_CODE (PATTERN (insn)) == SET)
1987 set = PATTERN (insn);
1988 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1990 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1991 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1993 set = XVECEXP (PATTERN (insn), 0, i);
2001 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2003 if (PREV_INSN (insn))
2004 NEXT_INSN (PREV_INSN (insn)) = next;
2009 PREV_INSN (next) = PREV_INSN (insn);
2015 prev = get_last_insn ();
2017 /* Now write the CLOBBER of the output, followed by the setting of each
2018 of the words, followed by the final copy. */
2019 if (target != op0 && target != op1)
2020 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2022 for (insn = insns; insn; insn = next)
2024 next = NEXT_INSN (insn);
2027 if (op1 && GET_CODE (op1) == REG)
2028 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2031 if (op0 && GET_CODE (op0) == REG)
2032 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2036 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2037 != CODE_FOR_nothing)
2039 last = emit_move_insn (target, target);
2042 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2045 last = get_last_insn ();
2048 first = get_insns ();
2050 first = NEXT_INSN (prev);
2052 /* Encapsulate the block so it gets manipulated as a unit. */
2053 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2055 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2060 /* Emit code to make a call to a constant function or a library call.
2062 INSNS is a list containing all insns emitted in the call.
2063 These insns leave the result in RESULT. Our block is to copy RESULT
2064 to TARGET, which is logically equivalent to EQUIV.
2066 We first emit any insns that set a pseudo on the assumption that these are
2067 loading constants into registers; doing so allows them to be safely cse'ed
2068 between blocks. Then we emit all the other insns in the block, followed by
2069 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2070 note with an operand of EQUIV.
2072 Moving assignments to pseudos outside of the block is done to improve
2073 the generated code, but is not required to generate correct code,
2074 hence being unable to move an assignment is not grounds for not making
2075 a libcall block. There are two reasons why it is safe to leave these
2076 insns inside the block: First, we know that these pseudos cannot be
2077 used in generated RTL outside the block since they are created for
2078 temporary purposes within the block. Second, CSE will not record the
2079 values of anything set inside a libcall block, so we know they must
2080 be dead at the end of the block.
2082 Except for the first group of insns (the ones setting pseudos), the
2083 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2086 emit_libcall_block (insns, target, result, equiv)
2092 rtx prev, next, first, last, insn;
2094 /* First emit all insns that set pseudos. Remove them from the list as
2095 we go. Avoid insns that set pseudo which were referenced in previous
2096 insns. These can be generated by move_by_pieces, for example,
2097 to update an address. */
2099 for (insn = insns; insn; insn = next)
2101 rtx set = single_set (insn);
2103 next = NEXT_INSN (insn);
2105 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2106 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2108 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2109 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
2111 if (PREV_INSN (insn))
2112 NEXT_INSN (PREV_INSN (insn)) = next;
2117 PREV_INSN (next) = PREV_INSN (insn);
2123 prev = get_last_insn ();
2125 /* Write the remaining insns followed by the final copy. */
2127 for (insn = insns; insn; insn = next)
2129 next = NEXT_INSN (insn);
2134 last = emit_move_insn (target, result);
2135 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2136 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2139 first = get_insns ();
2141 first = NEXT_INSN (prev);
2143 /* Encapsulate the block so it gets manipulated as a unit. */
2144 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2146 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2149 /* Generate code to store zero in X. */
2155 emit_move_insn (x, const0_rtx);
2158 /* Generate code to store 1 in X
2159 assuming it contains zero beforehand. */
2162 emit_0_to_1_insn (x)
2165 emit_move_insn (x, const1_rtx);
2168 /* Generate code to compare X with Y
2169 so that the condition codes are set.
2171 MODE is the mode of the inputs (in case they are const_int).
2172 UNSIGNEDP nonzero says that X and Y are unsigned;
2173 this matters if they need to be widened.
2175 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2176 and ALIGN specifies the known shared alignment of X and Y.
2178 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2179 It is ignored for fixed-point and block comparisons;
2180 it is used only for floating-point comparisons. */
2183 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2185 enum rtx_code comparison;
2187 enum machine_mode mode;
2191 enum mode_class class;
2192 enum machine_mode wider_mode;
2194 class = GET_MODE_CLASS (mode);
2196 /* They could both be VOIDmode if both args are immediate constants,
2197 but we should fold that at an earlier stage.
2198 With no special code here, this will call abort,
2199 reminding the programmer to implement such folding. */
2201 if (mode != BLKmode && flag_force_mem)
2203 x = force_not_mem (x);
2204 y = force_not_mem (y);
2207 /* If we are inside an appropriately-short loop and one operand is an
2208 expensive constant, force it into a register. */
2209 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2210 x = force_reg (mode, x);
2212 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2213 y = force_reg (mode, y);
2215 /* Don't let both operands fail to indicate the mode. */
2216 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2217 x = force_reg (mode, x);
2219 /* Handle all BLKmode compares. */
2221 if (mode == BLKmode)
2224 x = protect_from_queue (x, 0);
2225 y = protect_from_queue (y, 0);
2229 #ifdef HAVE_cmpstrqi
2231 && GET_CODE (size) == CONST_INT
2232 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2234 enum machine_mode result_mode
2235 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2236 rtx result = gen_reg_rtx (result_mode);
2237 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2238 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2243 #ifdef HAVE_cmpstrhi
2245 && GET_CODE (size) == CONST_INT
2246 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2248 enum machine_mode result_mode
2249 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2250 rtx result = gen_reg_rtx (result_mode);
2251 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2252 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2257 #ifdef HAVE_cmpstrsi
2260 enum machine_mode result_mode
2261 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2262 rtx result = gen_reg_rtx (result_mode);
2263 size = protect_from_queue (size, 0);
2264 emit_insn (gen_cmpstrsi (result, x, y,
2265 convert_to_mode (SImode, size, 1),
2267 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2273 #ifdef TARGET_MEM_FUNCTIONS
2274 emit_library_call (memcmp_libfunc, 0,
2275 TYPE_MODE (integer_type_node), 3,
2276 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2279 emit_library_call (bcmp_libfunc, 0,
2280 TYPE_MODE (integer_type_node), 3,
2281 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2284 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2285 const0_rtx, comparison, NULL_RTX,
2286 TYPE_MODE (integer_type_node), 0, 0);
2291 /* Handle some compares against zero. */
2293 if (y == CONST0_RTX (mode)
2294 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2296 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2299 x = protect_from_queue (x, 0);
2300 y = protect_from_queue (y, 0);
2302 /* Now, if insn does accept these operands, put them into pseudos. */
2303 if (! (*insn_operand_predicate[icode][0])
2304 (x, insn_operand_mode[icode][0]))
2305 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2307 emit_insn (GEN_FCN (icode) (x));
2311 /* Handle compares for which there is a directly suitable insn. */
2313 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2315 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2318 x = protect_from_queue (x, 0);
2319 y = protect_from_queue (y, 0);
2321 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2322 if (! (*insn_operand_predicate[icode][0])
2323 (x, insn_operand_mode[icode][0]))
2324 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2326 if (! (*insn_operand_predicate[icode][1])
2327 (y, insn_operand_mode[icode][1]))
2328 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2330 emit_insn (GEN_FCN (icode) (x, y));
2334 /* Try widening if we can find a direct insn that way. */
2336 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2338 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2339 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2341 if (cmp_optab->handlers[(int) wider_mode].insn_code
2342 != CODE_FOR_nothing)
2344 x = protect_from_queue (x, 0);
2345 y = protect_from_queue (y, 0);
2346 x = convert_to_mode (wider_mode, x, unsignedp);
2347 y = convert_to_mode (wider_mode, y, unsignedp);
2348 emit_cmp_insn (x, y, comparison, NULL_RTX,
2349 wider_mode, unsignedp, align);
2355 /* Handle a lib call just for the mode we are using. */
2357 if (cmp_optab->handlers[(int) mode].libfunc
2358 && class != MODE_FLOAT)
2360 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2361 /* If we want unsigned, and this mode has a distinct unsigned
2362 comparison routine, use that. */
2363 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2364 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2366 emit_library_call (libfunc, 1,
2367 word_mode, 2, x, mode, y, mode);
2369 /* Integer comparison returns a result that must be compared against 1,
2370 so that even if we do an unsigned compare afterward,
2371 there is still a value that can represent the result "less than". */
2373 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2374 comparison, NULL_RTX, word_mode, unsignedp, 0);
2378 if (class == MODE_FLOAT)
2379 emit_float_lib_cmp (x, y, comparison);
2385 /* Nonzero if a compare of mode MODE can be done straightforwardly
2386 (without splitting it into pieces). */
2389 can_compare_p (mode)
2390 enum machine_mode mode;
2394 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2396 mode = GET_MODE_WIDER_MODE (mode);
2397 } while (mode != VOIDmode);
2402 /* Emit a library call comparison between floating point X and Y.
2403 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2406 emit_float_lib_cmp (x, y, comparison)
2408 enum rtx_code comparison;
2410 enum machine_mode mode = GET_MODE (x);
2417 libfunc = eqsf2_libfunc;
2421 libfunc = nesf2_libfunc;
2425 libfunc = gtsf2_libfunc;
2429 libfunc = gesf2_libfunc;
2433 libfunc = ltsf2_libfunc;
2437 libfunc = lesf2_libfunc;
2440 else if (mode == DFmode)
2444 libfunc = eqdf2_libfunc;
2448 libfunc = nedf2_libfunc;
2452 libfunc = gtdf2_libfunc;
2456 libfunc = gedf2_libfunc;
2460 libfunc = ltdf2_libfunc;
2464 libfunc = ledf2_libfunc;
2467 else if (mode == XFmode)
2471 libfunc = eqxf2_libfunc;
2475 libfunc = nexf2_libfunc;
2479 libfunc = gtxf2_libfunc;
2483 libfunc = gexf2_libfunc;
2487 libfunc = ltxf2_libfunc;
2491 libfunc = lexf2_libfunc;
2494 else if (mode == TFmode)
2498 libfunc = eqtf2_libfunc;
2502 libfunc = netf2_libfunc;
2506 libfunc = gttf2_libfunc;
2510 libfunc = getf2_libfunc;
2514 libfunc = lttf2_libfunc;
2518 libfunc = letf2_libfunc;
2523 enum machine_mode wider_mode;
2525 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2526 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2528 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2529 != CODE_FOR_nothing)
2530 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2532 x = protect_from_queue (x, 0);
2533 y = protect_from_queue (y, 0);
2534 x = convert_to_mode (wider_mode, x, 0);
2535 y = convert_to_mode (wider_mode, y, 0);
2536 emit_float_lib_cmp (x, y, comparison);
2543 emit_library_call (libfunc, 1,
2544 word_mode, 2, x, mode, y, mode);
2546 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
2547 NULL_RTX, word_mode, 0, 0);
2550 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2553 emit_indirect_jump (loc)
2556 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2558 loc = copy_to_mode_reg (Pmode, loc);
2560 emit_jump_insn (gen_indirect_jump (loc));
2564 /* These three functions generate an insn body and return it
2565 rather than emitting the insn.
2567 They do not protect from queued increments,
2568 because they may be used 1) in protect_from_queue itself
2569 and 2) in other passes where there is no queue. */
2571 /* Generate and return an insn body to add Y to X. */
2574 gen_add2_insn (x, y)
2577 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2579 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2580 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2581 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2584 return (GEN_FCN (icode) (x, x, y));
2588 have_add2_insn (mode)
2589 enum machine_mode mode;
2591 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2594 /* Generate and return an insn body to subtract Y from X. */
2597 gen_sub2_insn (x, y)
2600 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2602 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2603 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2604 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2607 return (GEN_FCN (icode) (x, x, y));
2611 have_sub2_insn (mode)
2612 enum machine_mode mode;
2614 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2617 /* Generate the body of an instruction to copy Y into X.
2618 It may be a SEQUENCE, if one insn isn't enough. */
2621 gen_move_insn (x, y)
2624 register enum machine_mode mode = GET_MODE (x);
2625 enum insn_code insn_code;
2628 if (mode == VOIDmode)
2629 mode = GET_MODE (y);
2631 insn_code = mov_optab->handlers[(int) mode].insn_code;
2633 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2634 find a mode to do it in. If we have a movcc, use it. Otherwise,
2635 find the MODE_INT mode of the same width. */
2637 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
2639 enum machine_mode tmode = VOIDmode;
2643 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2646 for (tmode = QImode; tmode != VOIDmode;
2647 tmode = GET_MODE_WIDER_MODE (tmode))
2648 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2651 if (tmode == VOIDmode)
2654 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2655 may call change_address which is not appropriate if we were
2656 called when a reload was in progress. We don't have to worry
2657 about changing the address since the size in bytes is supposed to
2658 be the same. Copy the MEM to change the mode and move any
2659 substitutions from the old MEM to the new one. */
2661 if (reload_in_progress)
2663 x = gen_lowpart_common (tmode, x1);
2664 if (x == 0 && GET_CODE (x1) == MEM)
2666 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2667 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2668 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2669 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2670 copy_replacements (x1, x);
2673 y = gen_lowpart_common (tmode, y1);
2674 if (y == 0 && GET_CODE (y1) == MEM)
2676 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2677 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2678 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2679 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2680 copy_replacements (y1, y);
2685 x = gen_lowpart (tmode, x);
2686 y = gen_lowpart (tmode, y);
2689 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2690 return (GEN_FCN (insn_code) (x, y));
2694 emit_move_insn_1 (x, y);
2695 seq = gen_sequence ();
2700 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2701 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2702 no such operation exists, CODE_FOR_nothing will be returned. */
2705 can_extend_p (to_mode, from_mode, unsignedp)
2706 enum machine_mode to_mode, from_mode;
2709 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2712 /* Generate the body of an insn to extend Y (with mode MFROM)
2713 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2716 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2718 enum machine_mode mto, mfrom;
2721 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2724 /* can_fix_p and can_float_p say whether the target machine
2725 can directly convert a given fixed point type to
2726 a given floating point type, or vice versa.
2727 The returned value is the CODE_FOR_... value to use,
2728 or CODE_FOR_nothing if these modes cannot be directly converted.
2730 *TRUNCP_PTR is set to 1 if it is necessary to output
2731 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2733 static enum insn_code
2734 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2735 enum machine_mode fltmode, fixmode;
2740 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2741 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2743 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2746 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2748 return CODE_FOR_nothing;
2751 static enum insn_code
2752 can_float_p (fltmode, fixmode, unsignedp)
2753 enum machine_mode fixmode, fltmode;
2756 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2759 /* Generate code to convert FROM to floating point
2760 and store in TO. FROM must be fixed point and not VOIDmode.
2761 UNSIGNEDP nonzero means regard FROM as unsigned.
2762 Normally this is done by correcting the final value
2763 if it is negative. */
2766 expand_float (to, from, unsignedp)
2770 enum insn_code icode;
2771 register rtx target = to;
2772 enum machine_mode fmode, imode;
2774 /* Crash now, because we won't be able to decide which mode to use. */
2775 if (GET_MODE (from) == VOIDmode)
2778 /* Look for an insn to do the conversion. Do it in the specified
2779 modes if possible; otherwise convert either input, output or both to
2780 wider mode. If the integer mode is wider than the mode of FROM,
2781 we can do the conversion signed even if the input is unsigned. */
2783 for (imode = GET_MODE (from); imode != VOIDmode;
2784 imode = GET_MODE_WIDER_MODE (imode))
2785 for (fmode = GET_MODE (to); fmode != VOIDmode;
2786 fmode = GET_MODE_WIDER_MODE (fmode))
2788 int doing_unsigned = unsignedp;
2790 icode = can_float_p (fmode, imode, unsignedp);
2791 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2792 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2794 if (icode != CODE_FOR_nothing)
2796 to = protect_from_queue (to, 1);
2797 from = protect_from_queue (from, 0);
2799 if (imode != GET_MODE (from))
2800 from = convert_to_mode (imode, from, unsignedp);
2802 if (fmode != GET_MODE (to))
2803 target = gen_reg_rtx (fmode);
2805 emit_unop_insn (icode, target, from,
2806 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2809 convert_move (to, target, 0);
2814 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2816 /* Unsigned integer, and no way to convert directly.
2817 Convert as signed, then conditionally adjust the result. */
2820 rtx label = gen_label_rtx ();
2822 REAL_VALUE_TYPE offset;
2826 to = protect_from_queue (to, 1);
2827 from = protect_from_queue (from, 0);
2830 from = force_not_mem (from);
2832 /* Look for a usable floating mode FMODE wider than the source and at
2833 least as wide as the target. Using FMODE will avoid rounding woes
2834 with unsigned values greater than the signed maximum value. */
2835 for (fmode = GET_MODE (to); fmode != VOIDmode;
2836 fmode = GET_MODE_WIDER_MODE (fmode))
2837 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
2838 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
2840 if (fmode == VOIDmode)
2842 /* There is no such mode. Pretend the target is wide enough.
2843 This may cause rounding problems, unfortunately. */
2844 fmode = GET_MODE (to);
2847 /* If we are about to do some arithmetic to correct for an
2848 unsigned operand, do it in a pseudo-register. */
2850 if (GET_MODE (to) != fmode
2851 || GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2852 target = gen_reg_rtx (fmode);
2854 /* Convert as signed integer to floating. */
2855 expand_float (target, from, 0);
2857 /* If FROM is negative (and therefore TO is negative),
2858 correct its value by 2**bitwidth. */
2860 do_pending_stack_adjust ();
2861 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
2862 emit_jump_insn (gen_bge (label));
2863 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2864 Rather than setting up a dconst_dot_5, let's hope SCO
2866 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2867 temp = expand_binop (fmode, add_optab, target,
2868 immed_real_const_1 (offset, fmode),
2869 target, 0, OPTAB_LIB_WIDEN);
2871 emit_move_insn (target, temp);
2872 do_pending_stack_adjust ();
2878 /* No hardware instruction available; call a library rotine to convert from
2879 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
2884 to = protect_from_queue (to, 1);
2885 from = protect_from_queue (from, 0);
2887 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2888 from = convert_to_mode (SImode, from, unsignedp);
2891 from = force_not_mem (from);
2893 if (GET_MODE (to) == SFmode)
2895 if (GET_MODE (from) == SImode)
2896 libfcn = floatsisf_libfunc;
2897 else if (GET_MODE (from) == DImode)
2898 libfcn = floatdisf_libfunc;
2899 else if (GET_MODE (from) == TImode)
2900 libfcn = floattisf_libfunc;
2904 else if (GET_MODE (to) == DFmode)
2906 if (GET_MODE (from) == SImode)
2907 libfcn = floatsidf_libfunc;
2908 else if (GET_MODE (from) == DImode)
2909 libfcn = floatdidf_libfunc;
2910 else if (GET_MODE (from) == TImode)
2911 libfcn = floattidf_libfunc;
2915 else if (GET_MODE (to) == XFmode)
2917 if (GET_MODE (from) == SImode)
2918 libfcn = floatsixf_libfunc;
2919 else if (GET_MODE (from) == DImode)
2920 libfcn = floatdixf_libfunc;
2921 else if (GET_MODE (from) == TImode)
2922 libfcn = floattixf_libfunc;
2926 else if (GET_MODE (to) == TFmode)
2928 if (GET_MODE (from) == SImode)
2929 libfcn = floatsitf_libfunc;
2930 else if (GET_MODE (from) == DImode)
2931 libfcn = floatditf_libfunc;
2932 else if (GET_MODE (from) == TImode)
2933 libfcn = floattitf_libfunc;
2942 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2943 insns = get_insns ();
2946 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2947 gen_rtx (FLOAT, GET_MODE (to), from));
2950 /* Copy result to requested destination
2951 if we have been computing in a temp location. */
2955 if (GET_MODE (target) == GET_MODE (to))
2956 emit_move_insn (to, target);
2958 convert_move (to, target, 0);
2962 /* expand_fix: generate code to convert FROM to fixed point
2963 and store in TO. FROM must be floating point. */
2969 rtx temp = gen_reg_rtx (GET_MODE (x));
2970 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2974 expand_fix (to, from, unsignedp)
2975 register rtx to, from;
2978 enum insn_code icode;
2979 register rtx target = to;
2980 enum machine_mode fmode, imode;
2984 /* We first try to find a pair of modes, one real and one integer, at
2985 least as wide as FROM and TO, respectively, in which we can open-code
2986 this conversion. If the integer mode is wider than the mode of TO,
2987 we can do the conversion either signed or unsigned. */
2989 for (imode = GET_MODE (to); imode != VOIDmode;
2990 imode = GET_MODE_WIDER_MODE (imode))
2991 for (fmode = GET_MODE (from); fmode != VOIDmode;
2992 fmode = GET_MODE_WIDER_MODE (fmode))
2994 int doing_unsigned = unsignedp;
2996 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2997 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2998 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3000 if (icode != CODE_FOR_nothing)
3002 to = protect_from_queue (to, 1);
3003 from = protect_from_queue (from, 0);
3005 if (fmode != GET_MODE (from))
3006 from = convert_to_mode (fmode, from, 0);
3009 from = ftruncify (from);
3011 if (imode != GET_MODE (to))
3012 target = gen_reg_rtx (imode);
3014 emit_unop_insn (icode, target, from,
3015 doing_unsigned ? UNSIGNED_FIX : FIX);
3017 convert_move (to, target, unsignedp);
3022 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3023 /* For an unsigned conversion, there is one more way to do it.
3024 If we have a signed conversion, we generate code that compares
3025 the real value to the largest representable positive number. If if
3026 is smaller, the conversion is done normally. Otherwise, subtract
3027 one plus the highest signed number, convert, and add it back.
3029 We only need to check all real modes, since we know we didn't find
3030 anything with a wider integer mode. */
3032 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3033 for (fmode = GET_MODE (from); fmode != VOIDmode;
3034 fmode = GET_MODE_WIDER_MODE (fmode))
3035 /* Make sure we won't lose significant bits doing this. */
3036 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3037 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3041 REAL_VALUE_TYPE offset;
3042 rtx limit, lab1, lab2, insn;
3044 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3045 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3046 limit = immed_real_const_1 (offset, fmode);
3047 lab1 = gen_label_rtx ();
3048 lab2 = gen_label_rtx ();
3051 to = protect_from_queue (to, 1);
3052 from = protect_from_queue (from, 0);
3055 from = force_not_mem (from);
3057 if (fmode != GET_MODE (from))
3058 from = convert_to_mode (fmode, from, 0);
3060 /* See if we need to do the subtraction. */
3061 do_pending_stack_adjust ();
3062 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3063 emit_jump_insn (gen_bge (lab1));
3065 /* If not, do the signed "fix" and branch around fixup code. */
3066 expand_fix (to, from, 0);
3067 emit_jump_insn (gen_jump (lab2));
3070 /* Otherwise, subtract 2**(N-1), convert to signed number,
3071 then add 2**(N-1). Do the addition using XOR since this
3072 will often generate better code. */
3074 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3075 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3076 expand_fix (to, target, 0);
3077 target = expand_binop (GET_MODE (to), xor_optab, to,
3078 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3079 to, 1, OPTAB_LIB_WIDEN);
3082 emit_move_insn (to, target);
3086 /* Make a place for a REG_NOTE and add it. */
3087 insn = emit_move_insn (to, to);
3088 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3089 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3097 /* We can't do it with an insn, so use a library call. But first ensure
3098 that the mode of TO is at least as wide as SImode, since those are the
3099 only library calls we know about. */
3101 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3103 target = gen_reg_rtx (SImode);
3105 expand_fix (target, from, unsignedp);
3107 else if (GET_MODE (from) == SFmode)
3109 if (GET_MODE (to) == SImode)
3110 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3111 else if (GET_MODE (to) == DImode)
3112 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3113 else if (GET_MODE (to) == TImode)
3114 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3118 else if (GET_MODE (from) == DFmode)
3120 if (GET_MODE (to) == SImode)
3121 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3122 else if (GET_MODE (to) == DImode)
3123 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3124 else if (GET_MODE (to) == TImode)
3125 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3129 else if (GET_MODE (from) == XFmode)
3131 if (GET_MODE (to) == SImode)
3132 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3133 else if (GET_MODE (to) == DImode)
3134 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3135 else if (GET_MODE (to) == TImode)
3136 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3140 else if (GET_MODE (from) == TFmode)
3142 if (GET_MODE (to) == SImode)
3143 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3144 else if (GET_MODE (to) == DImode)
3145 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3146 else if (GET_MODE (to) == TImode)
3147 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3158 to = protect_from_queue (to, 1);
3159 from = protect_from_queue (from, 0);
3162 from = force_not_mem (from);
3166 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3167 insns = get_insns ();
3170 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3171 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3172 GET_MODE (to), from));
3175 if (GET_MODE (to) == GET_MODE (target))
3176 emit_move_insn (to, target);
3178 convert_move (to, target, 0);
3186 optab op = (optab) xmalloc (sizeof (struct optab));
3188 for (i = 0; i < NUM_MACHINE_MODES; i++)
3190 op->handlers[i].insn_code = CODE_FOR_nothing;
3191 op->handlers[i].libfunc = 0;
3196 /* Initialize the libfunc fields of an entire group of entries in some
3197 optab. Each entry is set equal to a string consisting of a leading
3198 pair of underscores followed by a generic operation name followed by
3199 a mode name (downshifted to lower case) followed by a single character
3200 representing the number of operands for the given operation (which is
3201 usually one of the characters '2', '3', or '4').
3203 OPTABLE is the table in which libfunc fields are to be initialized.
3204 FIRST_MODE is the first machine mode index in the given optab to
3206 LAST_MODE is the last machine mode index in the given optab to
3208 OPNAME is the generic (string) name of the operation.
3209 SUFFIX is the character which specifies the number of operands for
3210 the given generic operation.
3214 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3215 register optab optable;
3216 register int first_mode;
3217 register int last_mode;
3218 register char *opname;
3219 register char suffix;
3222 register unsigned opname_len = strlen (opname);
3224 for (mode = first_mode; (int) mode <= (int) last_mode;
3225 mode = (enum machine_mode) ((int) mode + 1))
3227 register char *mname = mode_name[(int) mode];
3228 register unsigned mname_len = strlen (mname);
3229 register char *libfunc_name
3230 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3237 for (q = opname; *q; )
3239 for (q = mname; *q; q++)
3240 *p++ = tolower (*q);
3243 optable->handlers[(int) mode].libfunc
3244 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3248 /* Initialize the libfunc fields of an entire group of entries in some
3249 optab which correspond to all integer mode operations. The parameters
3250 have the same meaning as similarly named ones for the `init_libfuncs'
3251 routine. (See above). */
3254 init_integral_libfuncs (optable, opname, suffix)
3255 register optab optable;
3256 register char *opname;
3257 register char suffix;
3259 init_libfuncs (optable, SImode, TImode, opname, suffix);
3262 /* Initialize the libfunc fields of an entire group of entries in some
3263 optab which correspond to all real mode operations. The parameters
3264 have the same meaning as similarly named ones for the `init_libfuncs'
3265 routine. (See above). */
3268 init_floating_libfuncs (optable, opname, suffix)
3269 register optab optable;
3270 register char *opname;
3271 register char suffix;
3273 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3276 /* Initialize the libfunc fields of an entire group of entries in some
3277 optab which correspond to all complex floating modes. The parameters
3278 have the same meaning as similarly named ones for the `init_libfuncs'
3279 routine. (See above). */
3282 init_complex_libfuncs (optable, opname, suffix)
3283 register optab optable;
3284 register char *opname;
3285 register char suffix;
3287 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3290 /* Call this once to initialize the contents of the optabs
3291 appropriately for the current target machine. */
3299 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3301 for (p = fixtab[0][0];
3302 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
3304 *p = CODE_FOR_nothing;
3306 for (p = fixtrunctab[0][0];
3307 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
3309 *p = CODE_FOR_nothing;
3311 for (p = floattab[0][0];
3312 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3314 *p = CODE_FOR_nothing;
3316 for (p = extendtab[0][0];
3317 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
3319 *p = CODE_FOR_nothing;
3321 for (i = 0; i < NUM_RTX_CODE; i++)
3322 setcc_gen_code[i] = CODE_FOR_nothing;
3324 add_optab = init_optab (PLUS);
3325 sub_optab = init_optab (MINUS);
3326 smul_optab = init_optab (MULT);
3327 smul_widen_optab = init_optab (UNKNOWN);
3328 umul_widen_optab = init_optab (UNKNOWN);
3329 sdiv_optab = init_optab (DIV);
3330 sdivmod_optab = init_optab (UNKNOWN);
3331 udiv_optab = init_optab (UDIV);
3332 udivmod_optab = init_optab (UNKNOWN);
3333 smod_optab = init_optab (MOD);
3334 umod_optab = init_optab (UMOD);
3335 flodiv_optab = init_optab (DIV);
3336 ftrunc_optab = init_optab (UNKNOWN);
3337 and_optab = init_optab (AND);
3338 ior_optab = init_optab (IOR);
3339 xor_optab = init_optab (XOR);
3340 ashl_optab = init_optab (ASHIFT);
3341 ashr_optab = init_optab (ASHIFTRT);
3342 lshl_optab = init_optab (LSHIFT);
3343 lshr_optab = init_optab (LSHIFTRT);
3344 rotl_optab = init_optab (ROTATE);
3345 rotr_optab = init_optab (ROTATERT);
3346 smin_optab = init_optab (SMIN);
3347 smax_optab = init_optab (SMAX);
3348 umin_optab = init_optab (UMIN);
3349 umax_optab = init_optab (UMAX);
3350 mov_optab = init_optab (UNKNOWN);
3351 movstrict_optab = init_optab (UNKNOWN);
3352 cmp_optab = init_optab (UNKNOWN);
3353 ucmp_optab = init_optab (UNKNOWN);
3354 tst_optab = init_optab (UNKNOWN);
3355 neg_optab = init_optab (NEG);
3356 abs_optab = init_optab (ABS);
3357 one_cmpl_optab = init_optab (NOT);
3358 ffs_optab = init_optab (FFS);
3359 sqrt_optab = init_optab (SQRT);
3360 sin_optab = init_optab (UNKNOWN);
3361 cos_optab = init_optab (UNKNOWN);
3362 strlen_optab = init_optab (UNKNOWN);
3364 for (i = 0; i < NUM_MACHINE_MODES; i++)
3366 movstr_optab[i] = CODE_FOR_nothing;
3368 #ifdef HAVE_SECONDARY_RELOADS
3369 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
3373 /* Fill in the optabs with the insns we support. */
3376 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3377 /* This flag says the same insns that convert to a signed fixnum
3378 also convert validly to an unsigned one. */
3379 for (i = 0; i < NUM_MACHINE_MODES; i++)
3380 for (j = 0; j < NUM_MACHINE_MODES; j++)
3381 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3384 #ifdef EXTRA_CC_MODES
3388 /* Initialize the optabs with the names of the library functions. */
3389 init_integral_libfuncs (add_optab, "add", '3');
3390 init_floating_libfuncs (add_optab, "add", '3');
3391 init_integral_libfuncs (sub_optab, "sub", '3');
3392 init_floating_libfuncs (sub_optab, "sub", '3');
3393 init_integral_libfuncs (smul_optab, "mul", '3');
3394 init_floating_libfuncs (smul_optab, "mul", '3');
3395 init_integral_libfuncs (sdiv_optab, "div", '3');
3396 init_integral_libfuncs (udiv_optab, "udiv", '3');
3397 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3398 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3399 init_integral_libfuncs (smod_optab, "mod", '3');
3400 init_integral_libfuncs (umod_optab, "umod", '3');
3401 init_floating_libfuncs (flodiv_optab, "div", '3');
3402 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3403 init_integral_libfuncs (and_optab, "and", '3');
3404 init_integral_libfuncs (ior_optab, "ior", '3');
3405 init_integral_libfuncs (xor_optab, "xor", '3');
3406 init_integral_libfuncs (ashl_optab, "ashl", '3');
3407 init_integral_libfuncs (ashr_optab, "ashr", '3');
3408 init_integral_libfuncs (lshl_optab, "lshl", '3');
3409 init_integral_libfuncs (lshr_optab, "lshr", '3');
3410 init_integral_libfuncs (rotl_optab, "rotl", '3');
3411 init_integral_libfuncs (rotr_optab, "rotr", '3');
3412 init_integral_libfuncs (smin_optab, "min", '3');
3413 init_floating_libfuncs (smin_optab, "min", '3');
3414 init_integral_libfuncs (smax_optab, "max", '3');
3415 init_floating_libfuncs (smax_optab, "max", '3');
3416 init_integral_libfuncs (umin_optab, "umin", '3');
3417 init_integral_libfuncs (umax_optab, "umax", '3');
3418 init_integral_libfuncs (neg_optab, "neg", '2');
3419 init_floating_libfuncs (neg_optab, "neg", '2');
3420 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
3421 init_integral_libfuncs (ffs_optab, "ffs", '2');
3423 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3424 init_integral_libfuncs (cmp_optab, "cmp", '2');
3425 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
3426 init_floating_libfuncs (cmp_optab, "cmp", '2');
3428 #ifdef MULSI3_LIBCALL
3429 smul_optab->handlers[(int) SImode].libfunc
3430 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3432 #ifdef MULDI3_LIBCALL
3433 smul_optab->handlers[(int) DImode].libfunc
3434 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3436 #ifdef MULTI3_LIBCALL
3437 smul_optab->handlers[(int) TImode].libfunc
3438 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3441 #ifdef DIVSI3_LIBCALL
3442 sdiv_optab->handlers[(int) SImode].libfunc
3443 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3445 #ifdef DIVDI3_LIBCALL
3446 sdiv_optab->handlers[(int) DImode].libfunc
3447 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3449 #ifdef DIVTI3_LIBCALL
3450 sdiv_optab->handlers[(int) TImode].libfunc
3451 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3454 #ifdef UDIVSI3_LIBCALL
3455 udiv_optab->handlers[(int) SImode].libfunc
3456 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3458 #ifdef UDIVDI3_LIBCALL
3459 udiv_optab->handlers[(int) DImode].libfunc
3460 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3462 #ifdef UDIVTI3_LIBCALL
3463 udiv_optab->handlers[(int) TImode].libfunc
3464 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3468 #ifdef MODSI3_LIBCALL
3469 smod_optab->handlers[(int) SImode].libfunc
3470 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3472 #ifdef MODDI3_LIBCALL
3473 smod_optab->handlers[(int) DImode].libfunc
3474 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3476 #ifdef MODTI3_LIBCALL
3477 smod_optab->handlers[(int) TImode].libfunc
3478 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3482 #ifdef UMODSI3_LIBCALL
3483 umod_optab->handlers[(int) SImode].libfunc
3484 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3486 #ifdef UMODDI3_LIBCALL
3487 umod_optab->handlers[(int) DImode].libfunc
3488 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3490 #ifdef UMODTI3_LIBCALL
3491 umod_optab->handlers[(int) TImode].libfunc
3492 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3495 /* Use cabs for DC complex abs, since systems generally have cabs.
3496 Don't define any libcall for SCmode, so that cabs will be used. */
3497 abs_optab->handlers[(int) DCmode].libfunc
3498 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
3500 ffs_optab->handlers[(int) mode_for_size (BITS_PER_WORD, MODE_INT, 0)] .libfunc
3501 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3503 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3504 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
3505 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
3506 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
3507 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
3509 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3510 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
3511 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
3512 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
3513 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
3515 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3516 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3517 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3518 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
3519 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
3520 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
3522 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
3523 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
3524 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
3525 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
3526 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
3527 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
3529 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
3530 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
3531 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
3532 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
3533 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
3534 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
3536 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
3537 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
3538 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
3539 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
3540 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
3541 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
3543 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
3544 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
3545 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
3546 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
3547 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
3548 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
3550 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
3551 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
3552 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
3554 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
3555 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
3556 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
3558 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
3559 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
3560 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
3562 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
3563 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
3564 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
3566 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
3567 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
3568 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
3570 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
3571 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
3572 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
3574 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
3575 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
3576 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
3578 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
3579 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
3580 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
3582 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
3583 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
3584 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
3586 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
3587 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
3588 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
3590 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
3591 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
3592 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
3594 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
3595 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
3596 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
3601 /* SCO 3.2 apparently has a broken ldexp. */
3614 #endif /* BROKEN_LDEXP */