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"
32 /* Each optab contains info on how this target machine
33 can perform a particular operation
34 for all sizes and kinds of operands.
36 The operation to be performed is often specified
37 by passing one of these optabs as an argument.
39 See expr.h for documentation of these optabs. */
44 optab smul_widen_optab;
45 optab umul_widen_optab;
69 optab movstrict_optab;
80 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
85 /* Tables of patterns for extending one integer mode to another. */
86 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
88 /* Tables of patterns for converting between fixed and floating point. */
89 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
90 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
91 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 /* SYMBOL_REF rtx's for the library functions that are called
94 implicitly and not via optabs. */
96 rtx extendsfdf2_libfunc;
97 rtx extendsfxf2_libfunc;
98 rtx extendsftf2_libfunc;
99 rtx extenddfxf2_libfunc;
100 rtx extenddftf2_libfunc;
102 rtx truncdfsf2_libfunc;
103 rtx truncxfsf2_libfunc;
104 rtx trunctfsf2_libfunc;
105 rtx truncxfdf2_libfunc;
106 rtx trunctfdf2_libfunc;
143 rtx floatsisf_libfunc;
144 rtx floatdisf_libfunc;
145 rtx floattisf_libfunc;
147 rtx floatsidf_libfunc;
148 rtx floatdidf_libfunc;
149 rtx floattidf_libfunc;
151 rtx floatsixf_libfunc;
152 rtx floatdixf_libfunc;
153 rtx floattixf_libfunc;
155 rtx floatsitf_libfunc;
156 rtx floatditf_libfunc;
157 rtx floattitf_libfunc;
175 rtx fixunssfsi_libfunc;
176 rtx fixunssfdi_libfunc;
177 rtx fixunssfti_libfunc;
179 rtx fixunsdfsi_libfunc;
180 rtx fixunsdfdi_libfunc;
181 rtx fixunsdfti_libfunc;
183 rtx fixunsxfsi_libfunc;
184 rtx fixunsxfdi_libfunc;
185 rtx fixunsxfti_libfunc;
187 rtx fixunstfsi_libfunc;
188 rtx fixunstfdi_libfunc;
189 rtx fixunstfti_libfunc;
191 /* from emit-rtl.c */
192 extern rtx gen_highpart ();
194 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
195 gives the gen_function to make a branch to test that condition. */
197 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
199 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
200 gives the insn code to make a store-condition insn
201 to test that condition. */
203 enum insn_code setcc_gen_code[NUM_RTX_CODE];
205 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
206 static void emit_float_lib_cmp PROTO((rtx, rtx, enum rtx_code));
207 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
209 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
211 static rtx ftruncify PROTO((rtx));
212 static optab init_optab PROTO((enum rtx_code));
213 static void init_libfuncs PROTO((optab, int, int, char *, int));
214 static void init_integral_libfuncs PROTO((optab, char *, int));
215 static void init_floating_libfuncs PROTO((optab, char *, int));
216 static void init_complex_libfuncs PROTO((optab, char *, int));
218 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
219 the result of operation CODE applied to OP0 (and OP1 if it is a binary
222 If the last insn does not set TARGET, don't do anything, but return 1.
224 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
225 don't add the REG_EQUAL note but return 0. Our caller can then try
226 again, ensuring that TARGET is not one of the operands. */
229 add_equal_note (seq, target, code, op0, op1)
239 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
240 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
241 || GET_CODE (seq) != SEQUENCE
242 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
243 || GET_CODE (target) == ZERO_EXTRACT
244 || (! rtx_equal_p (SET_DEST (set), target)
245 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
247 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
248 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
252 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
253 besides the last insn. */
254 if (reg_overlap_mentioned_p (target, op0)
255 || (op1 && reg_overlap_mentioned_p (target, op1)))
256 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
257 if (reg_set_p (target, XVECEXP (seq, 0, i)))
260 if (GET_RTX_CLASS (code) == '1')
261 note = gen_rtx (code, GET_MODE (target), op0);
263 note = gen_rtx (code, GET_MODE (target), op0, op1);
265 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
266 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
267 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
272 /* Generate code to perform an operation specified by BINOPTAB
273 on operands OP0 and OP1, with result having machine-mode MODE.
275 UNSIGNEDP is for the case where we have to widen the operands
276 to perform the operation. It says to use zero-extension.
278 If TARGET is nonzero, the value
279 is generated there, if it is convenient to do so.
280 In all cases an rtx is returned for the locus of the value;
281 this may or may not be TARGET. */
284 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
285 enum machine_mode mode;
290 enum optab_methods methods;
292 enum mode_class class;
293 enum machine_mode wider_mode;
295 int commutative_op = 0;
296 int shift_op = (binoptab->code == ASHIFT
297 || binoptab->code == ASHIFTRT
298 || binoptab->code == LSHIFT
299 || binoptab->code == LSHIFTRT
300 || binoptab->code == ROTATE
301 || binoptab->code == ROTATERT);
302 rtx entry_last = get_last_insn ();
305 class = GET_MODE_CLASS (mode);
307 op0 = protect_from_queue (op0, 0);
308 op1 = protect_from_queue (op1, 0);
310 target = protect_from_queue (target, 1);
314 op0 = force_not_mem (op0);
315 op1 = force_not_mem (op1);
318 /* If subtracting an integer constant, convert this into an addition of
319 the negated constant. */
321 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
323 op1 = negate_rtx (mode, op1);
324 binoptab = add_optab;
327 /* If we are inside an appropriately-short loop and one operand is an
328 expensive constant, force it into a register. */
329 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
330 && rtx_cost (op0, binoptab->code) > 2)
331 op0 = force_reg (mode, op0);
333 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
334 && rtx_cost (op1, binoptab->code) > 2)
335 op1 = force_reg (shift_op ? word_mode : mode, op1);
337 /* Record where to delete back to if we backtrack. */
338 last = get_last_insn ();
340 /* If operation is commutative,
341 try to make the first operand a register.
342 Even better, try to make it the same as the target.
343 Also try to make the last operand a constant. */
344 if (GET_RTX_CLASS (binoptab->code) == 'c'
345 || binoptab == smul_widen_optab
346 || binoptab == umul_widen_optab)
350 if (((target == 0 || GET_CODE (target) == REG)
351 ? ((GET_CODE (op1) == REG
352 && GET_CODE (op0) != REG)
354 : rtx_equal_p (op1, target))
355 || GET_CODE (op0) == CONST_INT)
363 /* If we can do it with a three-operand insn, do so. */
365 if (methods != OPTAB_MUST_WIDEN
366 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
368 int icode = (int) binoptab->handlers[(int) mode].insn_code;
369 enum machine_mode mode0 = insn_operand_mode[icode][1];
370 enum machine_mode mode1 = insn_operand_mode[icode][2];
372 rtx xop0 = op0, xop1 = op1;
377 temp = gen_reg_rtx (mode);
379 /* If it is a commutative operator and the modes would match
380 if we would swap the operands, we can save the conversions. */
383 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
384 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
388 tmp = op0; op0 = op1; op1 = tmp;
389 tmp = xop0; xop0 = xop1; xop1 = tmp;
393 /* In case the insn wants input operands in modes different from
394 the result, convert the operands. */
396 if (GET_MODE (op0) != VOIDmode
397 && GET_MODE (op0) != mode0)
398 xop0 = convert_to_mode (mode0, xop0, unsignedp);
400 if (GET_MODE (xop1) != VOIDmode
401 && GET_MODE (xop1) != mode1)
402 xop1 = convert_to_mode (mode1, xop1, unsignedp);
404 /* Now, if insn's predicates don't allow our operands, put them into
407 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
408 xop0 = copy_to_mode_reg (mode0, xop0);
410 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
411 xop1 = copy_to_mode_reg (mode1, xop1);
413 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
414 temp = gen_reg_rtx (mode);
416 pat = GEN_FCN (icode) (temp, xop0, xop1);
419 /* If PAT is a multi-insn sequence, try to add an appropriate
420 REG_EQUAL note to it. If we can't because TEMP conflicts with an
421 operand, call ourselves again, this time without a target. */
422 if (GET_CODE (pat) == SEQUENCE
423 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
425 delete_insns_since (last);
426 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
434 delete_insns_since (last);
437 /* If this is a multiply, see if we can do a widening operation that
438 takes operands of this mode and makes a wider mode. */
440 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
441 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
442 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
443 != CODE_FOR_nothing))
445 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
446 unsignedp ? umul_widen_optab : smul_widen_optab,
447 op0, op1, 0, unsignedp, OPTAB_DIRECT);
449 if (GET_MODE_CLASS (mode) == MODE_INT)
450 return gen_lowpart (mode, temp);
452 return convert_to_mode (mode, temp, unsignedp);
455 /* Look for a wider mode of the same class for which we think we
456 can open-code the operation. Check for a widening multiply at the
457 wider mode as well. */
459 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
460 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
461 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
462 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
464 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
465 || (binoptab == smul_optab
466 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
467 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
468 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
469 != CODE_FOR_nothing)))
471 rtx xop0 = op0, xop1 = op1;
474 /* For certain integer operations, we need not actually extend
475 the narrow operands, as long as we will truncate
476 the results to the same narrowness. Don't do this when
477 WIDER_MODE is wider than a word since a paradoxical SUBREG
478 isn't valid for such modes. */
480 if ((binoptab == ior_optab || binoptab == and_optab
481 || binoptab == xor_optab
482 || binoptab == add_optab || binoptab == sub_optab
483 || binoptab == smul_optab
484 || binoptab == ashl_optab || binoptab == lshl_optab)
486 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
489 /* If an operand is a constant integer, we might as well
490 convert it since that is more efficient than using a SUBREG,
491 unlike the case for other operands. Similarly for
492 SUBREGs that were made due to promoted objects. */
494 if (no_extend && GET_MODE (xop0) != VOIDmode
495 && ! (GET_CODE (xop0) == SUBREG
496 && SUBREG_PROMOTED_VAR_P (xop0)))
497 xop0 = gen_rtx (SUBREG, wider_mode,
498 force_reg (GET_MODE (xop0), xop0), 0);
500 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
502 if (no_extend && GET_MODE (xop1) != VOIDmode
503 && ! (GET_CODE (xop1) == SUBREG
504 && SUBREG_PROMOTED_VAR_P (xop1)))
505 xop1 = gen_rtx (SUBREG, wider_mode,
506 force_reg (GET_MODE (xop1), xop1), 0);
508 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
510 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
511 unsignedp, OPTAB_DIRECT);
514 if (class != MODE_INT)
517 target = gen_reg_rtx (mode);
518 convert_move (target, temp, 0);
522 return gen_lowpart (mode, temp);
525 delete_insns_since (last);
529 /* These can be done a word at a time. */
530 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
532 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
533 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
539 /* If TARGET is the same as one of the operands, the REG_EQUAL note
540 won't be accurate, so use a new target. */
541 if (target == 0 || target == op0 || target == op1)
542 target = gen_reg_rtx (mode);
546 /* Do the actual arithmetic. */
547 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
549 rtx target_piece = operand_subword (target, i, 1, mode);
550 rtx x = expand_binop (word_mode, binoptab,
551 operand_subword_force (op0, i, mode),
552 operand_subword_force (op1, i, mode),
553 target_piece, unsignedp, methods);
554 if (target_piece != x)
555 emit_move_insn (target_piece, x);
558 insns = get_insns ();
561 if (binoptab->code != UNKNOWN)
562 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
566 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
570 /* These can be done a word at a time by propagating carries. */
571 if ((binoptab == add_optab || binoptab == sub_optab)
573 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
574 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
577 rtx carry_tmp = gen_reg_rtx (word_mode);
578 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
579 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
580 rtx carry_in, carry_out;
583 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
584 value is one of those, use it. Otherwise, use 1 since it is the
585 one easiest to get. */
586 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
587 int normalizep = STORE_FLAG_VALUE;
592 /* Prepare the operands. */
593 xop0 = force_reg (mode, op0);
594 xop1 = force_reg (mode, op1);
596 if (target == 0 || GET_CODE (target) != REG
597 || target == xop0 || target == xop1)
598 target = gen_reg_rtx (mode);
600 /* Indicate for flow that the entire target reg is being set. */
601 if (GET_CODE (target) == REG)
602 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
604 /* Do the actual arithmetic. */
605 for (i = 0; i < nwords; i++)
607 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
608 rtx target_piece = operand_subword (target, index, 1, mode);
609 rtx op0_piece = operand_subword_force (xop0, index, mode);
610 rtx op1_piece = operand_subword_force (xop1, index, mode);
613 /* Main add/subtract of the input operands. */
614 x = expand_binop (word_mode, binoptab,
615 op0_piece, op1_piece,
616 target_piece, unsignedp, methods);
622 /* Store carry from main add/subtract. */
623 carry_out = gen_reg_rtx (word_mode);
624 carry_out = emit_store_flag (carry_out,
625 binoptab == add_optab ? LTU : GTU,
627 word_mode, 1, normalizep);
634 /* Add/subtract previous carry to main result. */
635 x = expand_binop (word_mode,
636 normalizep == 1 ? binoptab : otheroptab,
638 target_piece, 1, methods);
639 if (target_piece != x)
640 emit_move_insn (target_piece, x);
644 /* THIS CODE HAS NOT BEEN TESTED. */
645 /* Get out carry from adding/subtracting carry in. */
646 carry_tmp = emit_store_flag (carry_tmp,
647 binoptab == add_optab
650 word_mode, 1, normalizep);
651 /* Logical-ior the two poss. carry together. */
652 carry_out = expand_binop (word_mode, ior_optab,
653 carry_out, carry_tmp,
654 carry_out, 0, methods);
660 carry_in = carry_out;
663 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
667 temp = emit_move_insn (target, target);
668 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
669 gen_rtx (binoptab->code, mode, xop0, xop1),
674 delete_insns_since (last);
677 /* If we want to multiply two two-word values and have normal and widening
678 multiplies of single-word values, we can do this with three smaller
679 multiplications. Note that we do not make a REG_NO_CONFLICT block here
680 because we are not operating on one word at a time.
682 The multiplication proceeds as follows:
683 _______________________
684 [__op0_high_|__op0_low__]
685 _______________________
686 * [__op1_high_|__op1_low__]
687 _______________________________________________
688 _______________________
689 (1) [__op0_low__*__op1_low__]
690 _______________________
691 (2a) [__op0_low__*__op1_high_]
692 _______________________
693 (2b) [__op0_high_*__op1_low__]
694 _______________________
695 (3) [__op0_high_*__op1_high_]
698 This gives a 4-word result. Since we are only interested in the
699 lower 2 words, partial result (3) and the upper words of (2a) and
700 (2b) don't need to be calculated. Hence (2a) and (2b) can be
701 calculated using non-widening multiplication.
703 (1), however, needs to be calculated with an unsigned widening
704 multiplication. If this operation is not directly supported we
705 try using a signed widening multiplication and adjust the result.
706 This adjustment works as follows:
708 If both operands are positive then no adjustment is needed.
710 If the operands have different signs, for example op0_low < 0 and
711 op1_low >= 0, the instruction treats the most significant bit of
712 op0_low as a sign bit instead of a bit with significance
713 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
714 with 2**BITS_PER_WORD - op0_low, and two's complements the
715 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
718 Similarly, if both operands are negative, we need to add
719 (op0_low + op1_low) * 2**BITS_PER_WORD.
721 We use a trick to adjust quickly. We logically shift op0_low right
722 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
723 op0_high (op1_high) before it is used to calculate 2b (2a). If no
724 logical shift exists, we do an arithmetic right shift and subtract
727 if (binoptab == smul_optab
729 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
730 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
731 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
732 && ((umul_widen_optab->handlers[(int) mode].insn_code
734 || (smul_widen_optab->handlers[(int) mode].insn_code
735 != CODE_FOR_nothing)))
737 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
738 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
739 rtx op0_high = operand_subword_force (op0, high, mode);
740 rtx op0_low = operand_subword_force (op0, low, mode);
741 rtx op1_high = operand_subword_force (op1, high, mode);
742 rtx op1_low = operand_subword_force (op1, low, mode);
747 /* If the target is the same as one of the inputs, don't use it. This
748 prevents problems with the REG_EQUAL note. */
749 if (target == op0 || target == op1)
752 /* Multiply the two lower words to get a double-word product.
753 If unsigned widening multiplication is available, use that;
754 otherwise use the signed form and compensate. */
756 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
758 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
759 target, 1, OPTAB_DIRECT);
761 /* If we didn't succeed, delete everything we did so far. */
763 delete_insns_since (last);
765 op0_xhigh = op0_high, op1_xhigh = op1_high;
769 && smul_widen_optab->handlers[(int) mode].insn_code
772 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
773 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
774 target, 1, OPTAB_DIRECT);
775 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
776 NULL_RTX, 1, OPTAB_DIRECT);
778 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
779 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
782 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
783 NULL_RTX, 0, OPTAB_DIRECT);
785 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
786 op0_xhigh, op0_xhigh, 0,
790 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
791 NULL_RTX, 1, OPTAB_DIRECT);
793 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
794 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
797 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
798 NULL_RTX, 0, OPTAB_DIRECT);
800 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
801 op1_xhigh, op1_xhigh, 0,
806 /* If we have been able to directly compute the product of the
807 low-order words of the operands and perform any required adjustments
808 of the operands, we proceed by trying two more multiplications
809 and then computing the appropriate sum.
811 We have checked above that the required addition is provided.
812 Full-word addition will normally always succeed, especially if
813 it is provided at all, so we don't worry about its failure. The
814 multiplication may well fail, however, so we do handle that. */
816 if (product && op0_xhigh && op1_xhigh)
819 rtx product_high = operand_subword (product, high, 1, mode);
820 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
821 NULL_RTX, 0, OPTAB_DIRECT);
825 product_piece = expand_binop (word_mode, add_optab, temp,
826 product_high, product_high,
828 if (product_piece != product_high)
829 emit_move_insn (product_high, product_piece);
831 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
832 NULL_RTX, 0, OPTAB_DIRECT);
834 product_piece = expand_binop (word_mode, add_optab, temp,
835 product_high, product_high,
837 if (product_piece != product_high)
838 emit_move_insn (product_high, product_piece);
840 temp = emit_move_insn (product, product);
841 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
842 gen_rtx (MULT, mode, op0, op1),
849 /* If we get here, we couldn't do it for some reason even though we
850 originally thought we could. Delete anything we've emitted in
853 delete_insns_since (last);
856 /* We need to open-code the complex type operations: '+, -, * and /' */
858 /* At this point we allow operations between two similar complex
859 numbers, and also if one of the operands is not a complex number
860 but rather of MODE_FLOAT or MODE_INT. However, the caller
861 must make sure that the MODE of the non-complex operand matches
862 the SUBMODE of the complex operand. */
864 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
876 /* Find the correct mode for the real and imaginary parts */
877 enum machine_mode submode
878 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
879 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
882 if (submode == BLKmode)
886 target = gen_reg_rtx (mode);
890 realr = gen_realpart (submode, target);
891 imagr = gen_imagpart (submode, target);
893 if (GET_MODE (op0) == mode)
895 real0 = gen_realpart (submode, op0);
896 imag0 = gen_imagpart (submode, op0);
901 if (GET_MODE (op1) == mode)
903 real1 = gen_realpart (submode, op1);
904 imag1 = gen_imagpart (submode, op1);
909 if (! real0 || ! real1 || ! (imag0 || imag1))
912 switch (binoptab->code)
915 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
917 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
918 res = expand_binop (submode, binoptab, real0, real1,
919 realr, unsignedp, methods);
921 emit_move_insn (realr, res);
924 res = expand_binop (submode, binoptab, imag0, imag1,
925 imagr, unsignedp, methods);
928 else if (binoptab->code == MINUS)
929 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
934 emit_move_insn (imagr, res);
938 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
942 /* Don't fetch these from memory more than once. */
943 real0 = force_reg (submode, real0);
944 real1 = force_reg (submode, real1);
945 imag0 = force_reg (submode, imag0);
946 imag1 = force_reg (submode, imag1);
948 res = expand_binop (submode, sub_optab,
949 expand_binop (submode, binoptab, real0,
950 real1, 0, unsignedp, methods),
951 expand_binop (submode, binoptab, imag0,
952 imag1, 0, unsignedp, methods),
953 realr, unsignedp, methods);
956 emit_move_insn (realr, res);
958 res = expand_binop (submode, add_optab,
959 expand_binop (submode, binoptab,
961 0, unsignedp, methods),
962 expand_binop (submode, binoptab,
964 0, unsignedp, methods),
965 imagr, unsignedp, methods);
967 emit_move_insn (imagr, res);
971 /* Don't fetch these from memory more than once. */
972 real0 = force_reg (submode, real0);
973 real1 = force_reg (submode, real1);
975 res = expand_binop (submode, binoptab, real0, real1,
976 realr, unsignedp, methods);
978 emit_move_insn (realr, res);
981 res = expand_binop (submode, binoptab,
982 real1, imag0, imagr, unsignedp, methods);
984 res = expand_binop (submode, binoptab,
985 real0, imag1, imagr, unsignedp, methods);
987 emit_move_insn (imagr, res);
992 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
995 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
997 /* Don't fetch these from memory more than once. */
998 real1 = force_reg (submode, real1);
1000 /* Simply divide the real and imaginary parts by `c' */
1001 res = expand_binop (submode, binoptab, real0, real1,
1002 realr, unsignedp, methods);
1004 emit_move_insn (realr, res);
1006 res = expand_binop (submode, binoptab, imag0, real1,
1007 imagr, unsignedp, methods);
1009 emit_move_insn (imagr, res);
1011 else /* Divisor is of complex type */
1018 optab mulopt = unsignedp ? umul_widen_optab : smul_optab;
1020 /* Don't fetch these from memory more than once. */
1021 real0 = force_reg (submode, real0);
1022 real1 = force_reg (submode, real1);
1024 imag0 = force_reg (submode, imag0);
1025 imag1 = force_reg (submode, imag1);
1027 /* Divisor: c*c + d*d */
1028 divisor = expand_binop (submode, add_optab,
1029 expand_binop (submode, mulopt,
1031 0, unsignedp, methods),
1032 expand_binop (submode, mulopt,
1034 0, unsignedp, methods),
1035 0, unsignedp, methods);
1037 if (! imag0) /* ((a)(c-id))/divisor */
1038 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1039 /* Calculate the dividend */
1040 real_t = expand_binop (submode, mulopt, real0, real1,
1041 0, unsignedp, methods);
1044 = expand_unop (submode, neg_optab,
1045 expand_binop (submode, mulopt, real0, imag1,
1046 0, unsignedp, methods),
1049 else /* ((a+ib)(c-id))/divider */
1051 /* Calculate the dividend */
1052 real_t = expand_binop (submode, add_optab,
1053 expand_binop (submode, mulopt,
1055 0, unsignedp, methods),
1056 expand_binop (submode, mulopt,
1058 0, unsignedp, methods),
1059 0, unsignedp, methods);
1061 imag_t = expand_binop (submode, sub_optab,
1062 expand_binop (submode, mulopt,
1064 0, unsignedp, methods),
1065 expand_binop (submode, mulopt,
1067 0, unsignedp, methods),
1068 0, unsignedp, methods);
1072 res = expand_binop (submode, binoptab, real_t, divisor,
1073 realr, unsignedp, methods);
1075 emit_move_insn (realr, res);
1077 res = expand_binop (submode, binoptab, imag_t, divisor,
1078 imagr, unsignedp, methods);
1080 emit_move_insn (imagr, res);
1091 if (binoptab->code != UNKNOWN)
1092 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
1096 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1101 /* It can't be open-coded in this mode.
1102 Use a library call if one is available and caller says that's ok. */
1104 if (binoptab->handlers[(int) mode].libfunc
1105 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1108 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1110 enum machine_mode op1_mode = mode;
1116 op1_mode = word_mode;
1117 /* Specify unsigned here,
1118 since negative shift counts are meaningless. */
1119 op1x = convert_to_mode (word_mode, op1, 1);
1122 /* Pass 1 for NO_QUEUE so we don't lose any increments
1123 if the libcall is cse'd or moved. */
1124 emit_library_call (binoptab->handlers[(int) mode].libfunc,
1125 1, mode, 2, op0, mode, op1x, op1_mode);
1127 insns = get_insns ();
1130 target = gen_reg_rtx (mode);
1131 emit_libcall_block (insns, target, hard_libcall_value (mode),
1132 gen_rtx (binoptab->code, mode, op0, op1));
1137 delete_insns_since (last);
1139 /* It can't be done in this mode. Can we do it in a wider mode? */
1141 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1142 || methods == OPTAB_MUST_WIDEN))
1144 /* Caller says, don't even try. */
1145 delete_insns_since (entry_last);
1149 /* Compute the value of METHODS to pass to recursive calls.
1150 Don't allow widening to be tried recursively. */
1152 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1154 /* Look for a wider mode of the same class for which it appears we can do
1157 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1159 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1160 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1162 if ((binoptab->handlers[(int) wider_mode].insn_code
1163 != CODE_FOR_nothing)
1164 || (methods == OPTAB_LIB
1165 && binoptab->handlers[(int) wider_mode].libfunc))
1167 rtx xop0 = op0, xop1 = op1;
1170 /* For certain integer operations, we need not actually extend
1171 the narrow operands, as long as we will truncate
1172 the results to the same narrowness. Don't do this when
1173 WIDER_MODE is wider than a word since a paradoxical SUBREG
1174 isn't valid for such modes. */
1176 if ((binoptab == ior_optab || binoptab == and_optab
1177 || binoptab == xor_optab
1178 || binoptab == add_optab || binoptab == sub_optab
1179 || binoptab == smul_optab
1180 || binoptab == ashl_optab || binoptab == lshl_optab)
1181 && class == MODE_INT
1182 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD)
1185 /* If an operand is a constant integer, we might as well
1186 convert it since that is more efficient than using a SUBREG,
1187 unlike the case for other operands. Similarly for
1188 SUBREGs that were made due to promoted objects.*/
1190 if (no_extend && GET_MODE (xop0) != VOIDmode
1191 && ! (GET_CODE (xop0) == SUBREG
1192 && SUBREG_PROMOTED_VAR_P (xop0)))
1193 xop0 = gen_rtx (SUBREG, wider_mode,
1194 force_reg (GET_MODE (xop0), xop0), 0);
1196 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1198 if (no_extend && GET_MODE (xop1) != VOIDmode
1199 && ! (GET_CODE (xop1) == SUBREG
1200 && SUBREG_PROMOTED_VAR_P (xop1)))
1201 xop1 = gen_rtx (SUBREG, wider_mode,
1202 force_reg (GET_MODE (xop1), xop1), 0);
1204 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
1206 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1207 unsignedp, methods);
1210 if (class != MODE_INT)
1213 target = gen_reg_rtx (mode);
1214 convert_move (target, temp, 0);
1218 return gen_lowpart (mode, temp);
1221 delete_insns_since (last);
1226 delete_insns_since (entry_last);
1230 /* Expand a binary operator which has both signed and unsigned forms.
1231 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1234 If we widen unsigned operands, we may use a signed wider operation instead
1235 of an unsigned wider operation, since the result would be the same. */
1238 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1239 enum machine_mode mode;
1240 optab uoptab, soptab;
1241 rtx op0, op1, target;
1243 enum optab_methods methods;
1246 optab direct_optab = unsignedp ? uoptab : soptab;
1247 struct optab wide_soptab;
1249 /* Do it without widening, if possible. */
1250 temp = expand_binop (mode, direct_optab, op0, op1, target,
1251 unsignedp, OPTAB_DIRECT);
1252 if (temp || methods == OPTAB_DIRECT)
1255 /* Try widening to a signed int. Make a fake signed optab that
1256 hides any signed insn for direct use. */
1257 wide_soptab = *soptab;
1258 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1259 wide_soptab.handlers[(int) mode].libfunc = 0;
1261 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1262 unsignedp, OPTAB_WIDEN);
1264 /* For unsigned operands, try widening to an unsigned int. */
1265 if (temp == 0 && unsignedp)
1266 temp = expand_binop (mode, uoptab, op0, op1, target,
1267 unsignedp, OPTAB_WIDEN);
1268 if (temp || methods == OPTAB_WIDEN)
1271 /* Use the right width lib call if that exists. */
1272 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1273 if (temp || methods == OPTAB_LIB)
1276 /* Must widen and use a lib call, use either signed or unsigned. */
1277 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1278 unsignedp, methods);
1282 return expand_binop (mode, uoptab, op0, op1, target,
1283 unsignedp, methods);
1287 /* Generate code to perform an operation specified by BINOPTAB
1288 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1289 We assume that the order of the operands for the instruction
1290 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1291 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1293 Either TARG0 or TARG1 may be zero, but what that means is that
1294 that result is not actually wanted. We will generate it into
1295 a dummy pseudo-reg and discard it. They may not both be zero.
1297 Returns 1 if this operation can be performed; 0 if not. */
1300 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1306 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1307 enum mode_class class;
1308 enum machine_mode wider_mode;
1309 rtx entry_last = get_last_insn ();
1312 class = GET_MODE_CLASS (mode);
1314 op0 = protect_from_queue (op0, 0);
1315 op1 = protect_from_queue (op1, 0);
1319 op0 = force_not_mem (op0);
1320 op1 = force_not_mem (op1);
1323 /* If we are inside an appropriately-short loop and one operand is an
1324 expensive constant, force it into a register. */
1325 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1326 && rtx_cost (op0, binoptab->code) > 2)
1327 op0 = force_reg (mode, op0);
1329 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1330 && rtx_cost (op1, binoptab->code) > 2)
1331 op1 = force_reg (mode, op1);
1334 targ0 = protect_from_queue (targ0, 1);
1336 targ0 = gen_reg_rtx (mode);
1338 targ1 = protect_from_queue (targ1, 1);
1340 targ1 = gen_reg_rtx (mode);
1342 /* Record where to go back to if we fail. */
1343 last = get_last_insn ();
1345 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1347 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1348 enum machine_mode mode0 = insn_operand_mode[icode][1];
1349 enum machine_mode mode1 = insn_operand_mode[icode][2];
1351 rtx xop0 = op0, xop1 = op1;
1353 /* In case this insn wants input operands in modes different from the
1354 result, convert the operands. */
1355 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1356 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1358 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1359 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1361 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1362 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1363 xop0 = copy_to_mode_reg (mode0, xop0);
1365 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1366 xop1 = copy_to_mode_reg (mode1, xop1);
1368 /* We could handle this, but we should always be called with a pseudo
1369 for our targets and all insns should take them as outputs. */
1370 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1371 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1374 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1381 delete_insns_since (last);
1384 /* It can't be done in this mode. Can we do it in a wider mode? */
1386 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1388 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1389 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1391 if (binoptab->handlers[(int) wider_mode].insn_code
1392 != CODE_FOR_nothing)
1394 register rtx t0 = gen_reg_rtx (wider_mode);
1395 register rtx t1 = gen_reg_rtx (wider_mode);
1397 if (expand_twoval_binop (binoptab,
1398 convert_to_mode (wider_mode, op0,
1400 convert_to_mode (wider_mode, op1,
1404 convert_move (targ0, t0, unsignedp);
1405 convert_move (targ1, t1, unsignedp);
1409 delete_insns_since (last);
1414 delete_insns_since (entry_last);
1418 /* Generate code to perform an operation specified by UNOPTAB
1419 on operand OP0, with result having machine-mode MODE.
1421 UNSIGNEDP is for the case where we have to widen the operands
1422 to perform the operation. It says to use zero-extension.
1424 If TARGET is nonzero, the value
1425 is generated there, if it is convenient to do so.
1426 In all cases an rtx is returned for the locus of the value;
1427 this may or may not be TARGET. */
1430 expand_unop (mode, unoptab, op0, target, unsignedp)
1431 enum machine_mode mode;
1437 enum mode_class class;
1438 enum machine_mode wider_mode;
1440 rtx last = get_last_insn ();
1443 class = GET_MODE_CLASS (mode);
1445 op0 = protect_from_queue (op0, 0);
1449 op0 = force_not_mem (op0);
1453 target = protect_from_queue (target, 1);
1455 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1457 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1458 enum machine_mode mode0 = insn_operand_mode[icode][1];
1464 temp = gen_reg_rtx (mode);
1466 if (GET_MODE (xop0) != VOIDmode
1467 && GET_MODE (xop0) != mode0)
1468 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1470 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1472 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1473 xop0 = copy_to_mode_reg (mode0, xop0);
1475 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1476 temp = gen_reg_rtx (mode);
1478 pat = GEN_FCN (icode) (temp, xop0);
1481 if (GET_CODE (pat) == SEQUENCE
1482 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1484 delete_insns_since (last);
1485 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1493 delete_insns_since (last);
1496 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1498 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1499 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1500 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1502 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1506 /* For certain operations, we need not actually extend
1507 the narrow operand, as long as we will truncate the
1508 results to the same narrowness. But it is faster to
1509 convert a SUBREG due to mode promotion. */
1511 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1512 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1513 && class == MODE_INT
1514 && ! (GET_CODE (xop0) == SUBREG
1515 && SUBREG_PROMOTED_VAR_P (xop0)))
1516 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1518 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1520 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1525 if (class != MODE_INT)
1528 target = gen_reg_rtx (mode);
1529 convert_move (target, temp, 0);
1533 return gen_lowpart (mode, temp);
1536 delete_insns_since (last);
1540 /* These can be done a word at a time. */
1541 if (unoptab == one_cmpl_optab
1542 && class == MODE_INT
1543 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1544 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1549 if (target == 0 || target == op0)
1550 target = gen_reg_rtx (mode);
1554 /* Do the actual arithmetic. */
1555 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1557 rtx target_piece = operand_subword (target, i, 1, mode);
1558 rtx x = expand_unop (word_mode, unoptab,
1559 operand_subword_force (op0, i, mode),
1560 target_piece, unsignedp);
1561 if (target_piece != x)
1562 emit_move_insn (target_piece, x);
1565 insns = get_insns ();
1568 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1569 gen_rtx (unoptab->code, mode, op0));
1573 /* Open-code the complex negation operation. */
1574 else if (unoptab == neg_optab
1575 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1581 /* Find the correct mode for the real and imaginary parts */
1582 enum machine_mode submode
1583 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1584 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1587 if (submode == BLKmode)
1591 target = gen_reg_rtx (mode);
1595 target_piece = gen_imagpart (submode, target);
1596 x = expand_unop (submode, unoptab,
1597 gen_imagpart (submode, op0),
1598 target_piece, unsignedp);
1599 if (target_piece != x)
1600 emit_move_insn (target_piece, x);
1602 target_piece = gen_realpart (submode, target);
1603 x = expand_unop (submode, unoptab,
1604 gen_realpart (submode, op0),
1605 target_piece, unsignedp);
1606 if (target_piece != x)
1607 emit_move_insn (target_piece, x);
1612 emit_no_conflict_block (seq, target, op0, 0,
1613 gen_rtx (unoptab->code, mode, op0));
1617 /* Now try a library call in this mode. */
1618 if (unoptab->handlers[(int) mode].libfunc)
1621 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1625 /* Pass 1 for NO_QUEUE so we don't lose any increments
1626 if the libcall is cse'd or moved. */
1627 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1628 1, mode, 1, op0, mode);
1629 insns = get_insns ();
1632 target = gen_reg_rtx (mode);
1633 emit_libcall_block (insns, target, hard_libcall_value (mode),
1634 gen_rtx (unoptab->code, mode, op0));
1639 /* It can't be done in this mode. Can we do it in a wider mode? */
1641 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1643 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1644 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1646 if ((unoptab->handlers[(int) wider_mode].insn_code
1647 != CODE_FOR_nothing)
1648 || unoptab->handlers[(int) wider_mode].libfunc)
1652 /* For certain operations, we need not actually extend
1653 the narrow operand, as long as we will truncate the
1654 results to the same narrowness. */
1656 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1657 && GET_MODE_SIZE (wider_mode) <= UNITS_PER_WORD
1658 && class == MODE_INT
1659 && ! (GET_CODE (xop0) == SUBREG
1660 && SUBREG_PROMOTED_VAR_P (xop0)))
1661 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1663 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1665 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1670 if (class != MODE_INT)
1673 target = gen_reg_rtx (mode);
1674 convert_move (target, temp, 0);
1678 return gen_lowpart (mode, temp);
1681 delete_insns_since (last);
1689 /* Emit code to compute the absolute value of OP0, with result to
1690 TARGET if convenient. (TARGET may be 0.) The return value says
1691 where the result actually is to be found.
1693 MODE is the mode of the operand; the mode of the result is
1694 different but can be deduced from MODE.
1696 UNSIGNEDP is relevant for complex integer modes. */
1699 expand_complex_abs (mode, op0, target, unsignedp)
1700 enum machine_mode mode;
1705 enum mode_class class = GET_MODE_CLASS (mode);
1706 enum machine_mode wider_mode;
1708 rtx entry_last = get_last_insn ();
1712 /* Find the correct mode for the real and imaginary parts. */
1713 enum machine_mode submode
1714 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1715 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1718 if (submode == BLKmode)
1721 op0 = protect_from_queue (op0, 0);
1725 op0 = force_not_mem (op0);
1728 last = get_last_insn ();
1731 target = protect_from_queue (target, 1);
1733 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1735 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
1736 enum machine_mode mode0 = insn_operand_mode[icode][1];
1742 temp = gen_reg_rtx (submode);
1744 if (GET_MODE (xop0) != VOIDmode
1745 && GET_MODE (xop0) != mode0)
1746 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1748 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1750 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1751 xop0 = copy_to_mode_reg (mode0, xop0);
1753 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
1754 temp = gen_reg_rtx (submode);
1756 pat = GEN_FCN (icode) (temp, xop0);
1759 if (GET_CODE (pat) == SEQUENCE
1760 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
1762 delete_insns_since (last);
1763 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
1771 delete_insns_since (last);
1774 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1776 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1777 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1779 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1783 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1784 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1788 if (class != MODE_COMPLEX_INT)
1791 target = gen_reg_rtx (submode);
1792 convert_move (target, temp, 0);
1796 return gen_lowpart (submode, temp);
1799 delete_insns_since (last);
1803 /* Open-code the complex absolute-value operation
1804 if we can open-code sqrt. Otherwise it's not worth while. */
1805 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
1807 rtx real, imag, total;
1809 real = gen_realpart (submode, op0);
1810 imag = gen_imagpart (submode, op0);
1811 /* Square both parts. */
1812 real = expand_mult (mode, real, real, NULL_RTX, 0);
1813 imag = expand_mult (mode, imag, imag, NULL_RTX, 0);
1814 /* Sum the parts. */
1815 total = expand_binop (submode, add_optab, real, imag, 0,
1816 0, OPTAB_LIB_WIDEN);
1817 /* Get sqrt in TARGET. Set TARGET to where the result is. */
1818 target = expand_unop (submode, sqrt_optab, total, target, 0);
1820 delete_insns_since (last);
1825 /* Now try a library call in this mode. */
1826 if (abs_optab->handlers[(int) mode].libfunc)
1829 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
1833 /* Pass 1 for NO_QUEUE so we don't lose any increments
1834 if the libcall is cse'd or moved. */
1835 emit_library_call (abs_optab->handlers[(int) mode].libfunc,
1836 1, mode, 1, op0, mode);
1837 insns = get_insns ();
1840 target = gen_reg_rtx (submode);
1841 emit_libcall_block (insns, target, hard_libcall_value (submode),
1842 gen_rtx (abs_optab->code, mode, op0));
1847 /* It can't be done in this mode. Can we do it in a wider mode? */
1849 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1850 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1852 if ((abs_optab->handlers[(int) wider_mode].insn_code
1853 != CODE_FOR_nothing)
1854 || abs_optab->handlers[(int) wider_mode].libfunc)
1858 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1860 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
1864 if (class != MODE_COMPLEX_INT)
1867 target = gen_reg_rtx (submode);
1868 convert_move (target, temp, 0);
1872 return gen_lowpart (submode, temp);
1875 delete_insns_since (last);
1879 delete_insns_since (entry_last);
1883 /* Generate an instruction whose insn-code is INSN_CODE,
1884 with two operands: an output TARGET and an input OP0.
1885 TARGET *must* be nonzero, and the output is always stored there.
1886 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1887 the value that is stored into TARGET. */
1890 emit_unop_insn (icode, target, op0, code)
1897 enum machine_mode mode0 = insn_operand_mode[icode][1];
1900 temp = target = protect_from_queue (target, 1);
1902 op0 = protect_from_queue (op0, 0);
1905 op0 = force_not_mem (op0);
1907 /* Now, if insn does not accept our operands, put them into pseudos. */
1909 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1910 op0 = copy_to_mode_reg (mode0, op0);
1912 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1913 || (flag_force_mem && GET_CODE (temp) == MEM))
1914 temp = gen_reg_rtx (GET_MODE (temp));
1916 pat = GEN_FCN (icode) (temp, op0);
1918 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1919 add_equal_note (pat, temp, code, op0, NULL_RTX);
1924 emit_move_insn (target, temp);
1927 /* Emit code to perform a series of operations on a multi-word quantity, one
1930 Such a block is preceded by a CLOBBER of the output, consists of multiple
1931 insns, each setting one word of the output, and followed by a SET copying
1932 the output to itself.
1934 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1935 note indicating that it doesn't conflict with the (also multi-word)
1936 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1939 INSNS is a block of code generated to perform the operation, not including
1940 the CLOBBER and final copy. All insns that compute intermediate values
1941 are first emitted, followed by the block as described above. Only
1942 INSNs are allowed in the block; no library calls or jumps may be
1945 TARGET, OP0, and OP1 are the output and inputs of the operations,
1946 respectively. OP1 may be zero for a unary operation.
1948 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1951 If TARGET is not a register, INSNS is simply emitted with no special
1954 The final insn emitted is returned. */
1957 emit_no_conflict_block (insns, target, op0, op1, equiv)
1963 rtx prev, next, first, last, insn;
1965 if (GET_CODE (target) != REG || reload_in_progress)
1966 return emit_insns (insns);
1968 /* First emit all insns that do not store into words of the output and remove
1969 these from the list. */
1970 for (insn = insns; insn; insn = next)
1975 next = NEXT_INSN (insn);
1977 if (GET_CODE (insn) != INSN)
1980 if (GET_CODE (PATTERN (insn)) == SET)
1981 set = PATTERN (insn);
1982 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1984 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1985 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1987 set = XVECEXP (PATTERN (insn), 0, i);
1995 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1997 if (PREV_INSN (insn))
1998 NEXT_INSN (PREV_INSN (insn)) = next;
2003 PREV_INSN (next) = PREV_INSN (insn);
2009 prev = get_last_insn ();
2011 /* Now write the CLOBBER of the output, followed by the setting of each
2012 of the words, followed by the final copy. */
2013 if (target != op0 && target != op1)
2014 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2016 for (insn = insns; insn; insn = next)
2018 next = NEXT_INSN (insn);
2021 if (op1 && GET_CODE (op1) == REG)
2022 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2025 if (op0 && GET_CODE (op0) == REG)
2026 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2030 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2031 != CODE_FOR_nothing)
2033 last = emit_move_insn (target, target);
2036 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2039 last = get_last_insn ();
2042 first = get_insns ();
2044 first = NEXT_INSN (prev);
2046 /* Encapsulate the block so it gets manipulated as a unit. */
2047 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2049 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2054 /* Emit code to make a call to a constant function or a library call.
2056 INSNS is a list containing all insns emitted in the call.
2057 These insns leave the result in RESULT. Our block is to copy RESULT
2058 to TARGET, which is logically equivalent to EQUIV.
2060 We first emit any insns that set a pseudo on the assumption that these are
2061 loading constants into registers; doing so allows them to be safely cse'ed
2062 between blocks. Then we emit all the other insns in the block, followed by
2063 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2064 note with an operand of EQUIV.
2066 Moving assignments to pseudos outside of the block is done to improve
2067 the generated code, but is not required to generate correct code,
2068 hence being unable to move an assignment is not grounds for not making
2069 a libcall block. There are two reasons why it is safe to leave these
2070 insns inside the block: First, we know that these pseudos cannot be
2071 used in generated RTL outside the block since they are created for
2072 temporary purposes within the block. Second, CSE will not record the
2073 values of anything set inside a libcall block, so we know they must
2074 be dead at the end of the block.
2076 Except for the first group of insns (the ones setting pseudos), the
2077 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2080 emit_libcall_block (insns, target, result, equiv)
2086 rtx prev, next, first, last, insn;
2088 /* First emit all insns that set pseudos. Remove them from the list as
2089 we go. Avoid insns that set pseudo which were referenced in previous
2090 insns. These can be generated by move_by_pieces, for example,
2091 to update an address. */
2093 for (insn = insns; insn; insn = next)
2095 rtx set = single_set (insn);
2097 next = NEXT_INSN (insn);
2099 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2100 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2102 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2103 && ! reg_used_between_p (SET_DEST (set), insns, insn))))
2105 if (PREV_INSN (insn))
2106 NEXT_INSN (PREV_INSN (insn)) = next;
2111 PREV_INSN (next) = PREV_INSN (insn);
2117 prev = get_last_insn ();
2119 /* Write the remaining insns followed by the final copy. */
2121 for (insn = insns; insn; insn = next)
2123 next = NEXT_INSN (insn);
2128 last = emit_move_insn (target, result);
2129 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2132 first = get_insns ();
2134 first = NEXT_INSN (prev);
2136 /* Encapsulate the block so it gets manipulated as a unit. */
2137 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2139 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2142 /* Generate code to store zero in X. */
2148 emit_move_insn (x, const0_rtx);
2151 /* Generate code to store 1 in X
2152 assuming it contains zero beforehand. */
2155 emit_0_to_1_insn (x)
2158 emit_move_insn (x, const1_rtx);
2161 /* Generate code to compare X with Y
2162 so that the condition codes are set.
2164 MODE is the mode of the inputs (in case they are const_int).
2165 UNSIGNEDP nonzero says that X and Y are unsigned;
2166 this matters if they need to be widened.
2168 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2169 and ALIGN specifies the known shared alignment of X and Y.
2171 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2172 It is ignored for fixed-point and block comparisons;
2173 it is used only for floating-point comparisons. */
2176 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2178 enum rtx_code comparison;
2180 enum machine_mode mode;
2184 enum mode_class class;
2185 enum machine_mode wider_mode;
2187 class = GET_MODE_CLASS (mode);
2189 /* They could both be VOIDmode if both args are immediate constants,
2190 but we should fold that at an earlier stage.
2191 With no special code here, this will call abort,
2192 reminding the programmer to implement such folding. */
2194 if (mode != BLKmode && flag_force_mem)
2196 x = force_not_mem (x);
2197 y = force_not_mem (y);
2200 /* If we are inside an appropriately-short loop and one operand is an
2201 expensive constant, force it into a register. */
2202 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2203 x = force_reg (mode, x);
2205 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2206 y = force_reg (mode, y);
2208 /* Don't let both operands fail to indicate the mode. */
2209 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2210 x = force_reg (mode, x);
2212 /* Handle all BLKmode compares. */
2214 if (mode == BLKmode)
2217 x = protect_from_queue (x, 0);
2218 y = protect_from_queue (y, 0);
2222 #ifdef HAVE_cmpstrqi
2224 && GET_CODE (size) == CONST_INT
2225 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2227 enum machine_mode result_mode
2228 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2229 rtx result = gen_reg_rtx (result_mode);
2230 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2231 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2236 #ifdef HAVE_cmpstrhi
2238 && GET_CODE (size) == CONST_INT
2239 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2241 enum machine_mode result_mode
2242 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2243 rtx result = gen_reg_rtx (result_mode);
2244 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2245 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2250 #ifdef HAVE_cmpstrsi
2253 enum machine_mode result_mode
2254 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2255 rtx result = gen_reg_rtx (result_mode);
2256 size = protect_from_queue (size, 0);
2257 emit_insn (gen_cmpstrsi (result, x, y,
2258 convert_to_mode (SImode, size, 1),
2260 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2266 #ifdef TARGET_MEM_FUNCTIONS
2267 emit_library_call (memcmp_libfunc, 0,
2268 TYPE_MODE (integer_type_node), 3,
2269 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2272 emit_library_call (bcmp_libfunc, 0,
2273 TYPE_MODE (integer_type_node), 3,
2274 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2277 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2278 const0_rtx, comparison, NULL_RTX,
2279 TYPE_MODE (integer_type_node), 0, 0);
2284 /* Handle some compares against zero. */
2286 if (y == CONST0_RTX (mode)
2287 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2289 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2292 x = protect_from_queue (x, 0);
2293 y = protect_from_queue (y, 0);
2295 /* Now, if insn does accept these operands, put them into pseudos. */
2296 if (! (*insn_operand_predicate[icode][0])
2297 (x, insn_operand_mode[icode][0]))
2298 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2300 emit_insn (GEN_FCN (icode) (x));
2304 /* Handle compares for which there is a directly suitable insn. */
2306 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2308 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2311 x = protect_from_queue (x, 0);
2312 y = protect_from_queue (y, 0);
2314 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2315 if (! (*insn_operand_predicate[icode][0])
2316 (x, insn_operand_mode[icode][0]))
2317 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2319 if (! (*insn_operand_predicate[icode][1])
2320 (y, insn_operand_mode[icode][1]))
2321 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2323 emit_insn (GEN_FCN (icode) (x, y));
2327 /* Try widening if we can find a direct insn that way. */
2329 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2331 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2332 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2334 if (cmp_optab->handlers[(int) wider_mode].insn_code
2335 != CODE_FOR_nothing)
2337 x = protect_from_queue (x, 0);
2338 y = protect_from_queue (y, 0);
2339 x = convert_to_mode (wider_mode, x, unsignedp);
2340 y = convert_to_mode (wider_mode, y, unsignedp);
2341 emit_cmp_insn (x, y, comparison, NULL_RTX,
2342 wider_mode, unsignedp, align);
2348 /* Handle a lib call just for the mode we are using. */
2350 if (cmp_optab->handlers[(int) mode].libfunc
2351 && class != MODE_FLOAT)
2353 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2354 /* If we want unsigned, and this mode has a distinct unsigned
2355 comparison routine, use that. */
2356 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2357 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2359 emit_library_call (libfunc, 1,
2360 word_mode, 2, x, mode, y, mode);
2362 /* Integer comparison returns a result that must be compared against 1,
2363 so that even if we do an unsigned compare afterward,
2364 there is still a value that can represent the result "less than". */
2366 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2367 comparison, NULL_RTX, word_mode, unsignedp, 0);
2371 if (class == MODE_FLOAT)
2372 emit_float_lib_cmp (x, y, comparison);
2378 /* Nonzero if a compare of mode MODE can be done straightforwardly
2379 (without splitting it into pieces). */
2382 can_compare_p (mode)
2383 enum machine_mode mode;
2387 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2389 mode = GET_MODE_WIDER_MODE (mode);
2390 } while (mode != VOIDmode);
2395 /* Emit a library call comparison between floating point X and Y.
2396 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2399 emit_float_lib_cmp (x, y, comparison)
2401 enum rtx_code comparison;
2403 enum machine_mode mode = GET_MODE (x);
2410 libfunc = eqsf2_libfunc;
2414 libfunc = nesf2_libfunc;
2418 libfunc = gtsf2_libfunc;
2422 libfunc = gesf2_libfunc;
2426 libfunc = ltsf2_libfunc;
2430 libfunc = lesf2_libfunc;
2433 else if (mode == DFmode)
2437 libfunc = eqdf2_libfunc;
2441 libfunc = nedf2_libfunc;
2445 libfunc = gtdf2_libfunc;
2449 libfunc = gedf2_libfunc;
2453 libfunc = ltdf2_libfunc;
2457 libfunc = ledf2_libfunc;
2460 else if (mode == XFmode)
2464 libfunc = eqxf2_libfunc;
2468 libfunc = nexf2_libfunc;
2472 libfunc = gtxf2_libfunc;
2476 libfunc = gexf2_libfunc;
2480 libfunc = ltxf2_libfunc;
2484 libfunc = lexf2_libfunc;
2487 else if (mode == TFmode)
2491 libfunc = eqtf2_libfunc;
2495 libfunc = netf2_libfunc;
2499 libfunc = gttf2_libfunc;
2503 libfunc = getf2_libfunc;
2507 libfunc = lttf2_libfunc;
2511 libfunc = letf2_libfunc;
2516 enum machine_mode wider_mode;
2518 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2519 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2521 if ((cmp_optab->handlers[(int) wider_mode].insn_code
2522 != CODE_FOR_nothing)
2523 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
2525 x = protect_from_queue (x, 0);
2526 y = protect_from_queue (y, 0);
2527 x = convert_to_mode (wider_mode, x, 0);
2528 y = convert_to_mode (wider_mode, y, 0);
2529 emit_float_lib_cmp (x, y, comparison);
2536 emit_library_call (libfunc, 1,
2537 word_mode, 2, x, mode, y, mode);
2539 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
2540 NULL_RTX, word_mode, 0, 0);
2543 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2546 emit_indirect_jump (loc)
2549 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
2551 loc = copy_to_mode_reg (Pmode, loc);
2553 emit_jump_insn (gen_indirect_jump (loc));
2557 /* These three functions generate an insn body and return it
2558 rather than emitting the insn.
2560 They do not protect from queued increments,
2561 because they may be used 1) in protect_from_queue itself
2562 and 2) in other passes where there is no queue. */
2564 /* Generate and return an insn body to add Y to X. */
2567 gen_add2_insn (x, y)
2570 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
2572 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2573 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2574 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2577 return (GEN_FCN (icode) (x, x, y));
2581 have_add2_insn (mode)
2582 enum machine_mode mode;
2584 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2587 /* Generate and return an insn body to subtract Y from X. */
2590 gen_sub2_insn (x, y)
2593 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
2595 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
2596 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
2597 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
2600 return (GEN_FCN (icode) (x, x, y));
2604 have_sub2_insn (mode)
2605 enum machine_mode mode;
2607 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
2610 /* Generate the body of an instruction to copy Y into X.
2611 It may be a SEQUENCE, if one insn isn't enough. */
2614 gen_move_insn (x, y)
2617 register enum machine_mode mode = GET_MODE (x);
2618 enum insn_code insn_code;
2621 if (mode == VOIDmode)
2622 mode = GET_MODE (y);
2624 insn_code = mov_optab->handlers[(int) mode].insn_code;
2626 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2627 find a mode to do it in. If we have a movcc, use it. Otherwise,
2628 find the MODE_INT mode of the same width. */
2630 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
2632 enum machine_mode tmode = VOIDmode;
2636 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
2639 for (tmode = QImode; tmode != VOIDmode;
2640 tmode = GET_MODE_WIDER_MODE (tmode))
2641 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
2644 if (tmode == VOIDmode)
2647 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2648 may call change_address which is not appropriate if we were
2649 called when a reload was in progress. We don't have to worry
2650 about changing the address since the size in bytes is supposed to
2651 be the same. Copy the MEM to change the mode and move any
2652 substitutions from the old MEM to the new one. */
2654 if (reload_in_progress)
2656 x = gen_lowpart_common (tmode, x1);
2657 if (x == 0 && GET_CODE (x1) == MEM)
2659 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
2660 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
2661 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
2662 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
2663 copy_replacements (x1, x);
2666 y = gen_lowpart_common (tmode, y1);
2667 if (y == 0 && GET_CODE (y1) == MEM)
2669 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
2670 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
2671 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
2672 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
2673 copy_replacements (y1, y);
2678 x = gen_lowpart (tmode, x);
2679 y = gen_lowpart (tmode, y);
2682 insn_code = mov_optab->handlers[(int) tmode].insn_code;
2683 return (GEN_FCN (insn_code) (x, y));
2687 emit_move_insn_1 (x, y);
2688 seq = gen_sequence ();
2693 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2694 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2695 no such operation exists, CODE_FOR_nothing will be returned. */
2698 can_extend_p (to_mode, from_mode, unsignedp)
2699 enum machine_mode to_mode, from_mode;
2702 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
2705 /* Generate the body of an insn to extend Y (with mode MFROM)
2706 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2709 gen_extend_insn (x, y, mto, mfrom, unsignedp)
2711 enum machine_mode mto, mfrom;
2714 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
2717 /* can_fix_p and can_float_p say whether the target machine
2718 can directly convert a given fixed point type to
2719 a given floating point type, or vice versa.
2720 The returned value is the CODE_FOR_... value to use,
2721 or CODE_FOR_nothing if these modes cannot be directly converted.
2723 *TRUNCP_PTR is set to 1 if it is necessary to output
2724 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2726 static enum insn_code
2727 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2728 enum machine_mode fltmode, fixmode;
2733 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2734 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2736 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2739 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2741 return CODE_FOR_nothing;
2744 static enum insn_code
2745 can_float_p (fltmode, fixmode, unsignedp)
2746 enum machine_mode fixmode, fltmode;
2749 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2752 /* Generate code to convert FROM to floating point
2753 and store in TO. FROM must be fixed point and not VOIDmode.
2754 UNSIGNEDP nonzero means regard FROM as unsigned.
2755 Normally this is done by correcting the final value
2756 if it is negative. */
2759 expand_float (to, from, unsignedp)
2763 enum insn_code icode;
2764 register rtx target = to;
2765 enum machine_mode fmode, imode;
2767 /* Crash now, because we won't be able to decide which mode to use. */
2768 if (GET_MODE (from) == VOIDmode)
2771 /* Look for an insn to do the conversion. Do it in the specified
2772 modes if possible; otherwise convert either input, output or both to
2773 wider mode. If the integer mode is wider than the mode of FROM,
2774 we can do the conversion signed even if the input is unsigned. */
2776 for (imode = GET_MODE (from); imode != VOIDmode;
2777 imode = GET_MODE_WIDER_MODE (imode))
2778 for (fmode = GET_MODE (to); fmode != VOIDmode;
2779 fmode = GET_MODE_WIDER_MODE (fmode))
2781 int doing_unsigned = unsignedp;
2783 icode = can_float_p (fmode, imode, unsignedp);
2784 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2785 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2787 if (icode != CODE_FOR_nothing)
2789 to = protect_from_queue (to, 1);
2790 from = protect_from_queue (from, 0);
2792 if (imode != GET_MODE (from))
2793 from = convert_to_mode (imode, from, unsignedp);
2795 if (fmode != GET_MODE (to))
2796 target = gen_reg_rtx (fmode);
2798 emit_unop_insn (icode, target, from,
2799 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2802 convert_move (to, target, 0);
2807 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2809 /* Unsigned integer, and no way to convert directly.
2810 Convert as signed, then conditionally adjust the result. */
2813 rtx label = gen_label_rtx ();
2815 REAL_VALUE_TYPE offset;
2819 to = protect_from_queue (to, 1);
2820 from = protect_from_queue (from, 0);
2823 from = force_not_mem (from);
2825 /* Look for a usable floating mode FMODE wider than the source and at
2826 least as wide as the target. Using FMODE will avoid rounding woes
2827 with unsigned values greater than the signed maximum value. */
2828 for (fmode = GET_MODE (to); fmode != VOIDmode;
2829 fmode = GET_MODE_WIDER_MODE (fmode))
2830 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
2831 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
2833 if (fmode == VOIDmode)
2835 /* There is no such mode. Pretend the target is wide enough.
2836 This may cause rounding problems, unfortunately. */
2837 fmode = GET_MODE (to);
2840 /* If we are about to do some arithmetic to correct for an
2841 unsigned operand, do it in a pseudo-register. */
2843 if (GET_MODE (to) != fmode
2844 || GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2845 target = gen_reg_rtx (fmode);
2847 /* Convert as signed integer to floating. */
2848 expand_float (target, from, 0);
2850 /* If FROM is negative (and therefore TO is negative),
2851 correct its value by 2**bitwidth. */
2853 do_pending_stack_adjust ();
2854 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
2855 emit_jump_insn (gen_bge (label));
2856 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2857 Rather than setting up a dconst_dot_5, let's hope SCO
2859 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2860 temp = expand_binop (fmode, add_optab, target,
2861 immed_real_const_1 (offset, fmode),
2862 target, 0, OPTAB_LIB_WIDEN);
2864 emit_move_insn (target, temp);
2865 do_pending_stack_adjust ();
2871 /* No hardware instruction available; call a library rotine to convert from
2872 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
2877 to = protect_from_queue (to, 1);
2878 from = protect_from_queue (from, 0);
2880 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2881 from = convert_to_mode (SImode, from, unsignedp);
2884 from = force_not_mem (from);
2886 if (GET_MODE (to) == SFmode)
2888 if (GET_MODE (from) == SImode)
2889 libfcn = floatsisf_libfunc;
2890 else if (GET_MODE (from) == DImode)
2891 libfcn = floatdisf_libfunc;
2892 else if (GET_MODE (from) == TImode)
2893 libfcn = floattisf_libfunc;
2897 else if (GET_MODE (to) == DFmode)
2899 if (GET_MODE (from) == SImode)
2900 libfcn = floatsidf_libfunc;
2901 else if (GET_MODE (from) == DImode)
2902 libfcn = floatdidf_libfunc;
2903 else if (GET_MODE (from) == TImode)
2904 libfcn = floattidf_libfunc;
2908 else if (GET_MODE (to) == XFmode)
2910 if (GET_MODE (from) == SImode)
2911 libfcn = floatsixf_libfunc;
2912 else if (GET_MODE (from) == DImode)
2913 libfcn = floatdixf_libfunc;
2914 else if (GET_MODE (from) == TImode)
2915 libfcn = floattixf_libfunc;
2919 else if (GET_MODE (to) == TFmode)
2921 if (GET_MODE (from) == SImode)
2922 libfcn = floatsitf_libfunc;
2923 else if (GET_MODE (from) == DImode)
2924 libfcn = floatditf_libfunc;
2925 else if (GET_MODE (from) == TImode)
2926 libfcn = floattitf_libfunc;
2935 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2936 insns = get_insns ();
2939 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2940 gen_rtx (FLOAT, GET_MODE (to), from));
2943 /* Copy result to requested destination
2944 if we have been computing in a temp location. */
2948 if (GET_MODE (target) == GET_MODE (to))
2949 emit_move_insn (to, target);
2951 convert_move (to, target, 0);
2955 /* expand_fix: generate code to convert FROM to fixed point
2956 and store in TO. FROM must be floating point. */
2962 rtx temp = gen_reg_rtx (GET_MODE (x));
2963 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2967 expand_fix (to, from, unsignedp)
2968 register rtx to, from;
2971 enum insn_code icode;
2972 register rtx target = to;
2973 enum machine_mode fmode, imode;
2977 /* We first try to find a pair of modes, one real and one integer, at
2978 least as wide as FROM and TO, respectively, in which we can open-code
2979 this conversion. If the integer mode is wider than the mode of TO,
2980 we can do the conversion either signed or unsigned. */
2982 for (imode = GET_MODE (to); imode != VOIDmode;
2983 imode = GET_MODE_WIDER_MODE (imode))
2984 for (fmode = GET_MODE (from); fmode != VOIDmode;
2985 fmode = GET_MODE_WIDER_MODE (fmode))
2987 int doing_unsigned = unsignedp;
2989 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2990 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2991 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
2993 if (icode != CODE_FOR_nothing)
2995 to = protect_from_queue (to, 1);
2996 from = protect_from_queue (from, 0);
2998 if (fmode != GET_MODE (from))
2999 from = convert_to_mode (fmode, from, 0);
3002 from = ftruncify (from);
3004 if (imode != GET_MODE (to))
3005 target = gen_reg_rtx (imode);
3007 emit_unop_insn (icode, target, from,
3008 doing_unsigned ? UNSIGNED_FIX : FIX);
3010 convert_move (to, target, unsignedp);
3015 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3016 /* For an unsigned conversion, there is one more way to do it.
3017 If we have a signed conversion, we generate code that compares
3018 the real value to the largest representable positive number. If if
3019 is smaller, the conversion is done normally. Otherwise, subtract
3020 one plus the highest signed number, convert, and add it back.
3022 We only need to check all real modes, since we know we didn't find
3023 anything with a wider integer mode. */
3025 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3026 for (fmode = GET_MODE (from); fmode != VOIDmode;
3027 fmode = GET_MODE_WIDER_MODE (fmode))
3028 /* Make sure we won't lose significant bits doing this. */
3029 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3030 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3034 REAL_VALUE_TYPE offset;
3035 rtx limit, lab1, lab2, insn;
3037 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3038 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3039 limit = immed_real_const_1 (offset, fmode);
3040 lab1 = gen_label_rtx ();
3041 lab2 = gen_label_rtx ();
3044 to = protect_from_queue (to, 1);
3045 from = protect_from_queue (from, 0);
3048 from = force_not_mem (from);
3050 if (fmode != GET_MODE (from))
3051 from = convert_to_mode (fmode, from, 0);
3053 /* See if we need to do the subtraction. */
3054 do_pending_stack_adjust ();
3055 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3056 emit_jump_insn (gen_bge (lab1));
3058 /* If not, do the signed "fix" and branch around fixup code. */
3059 expand_fix (to, from, 0);
3060 emit_jump_insn (gen_jump (lab2));
3063 /* Otherwise, subtract 2**(N-1), convert to signed number,
3064 then add 2**(N-1). Do the addition using XOR since this
3065 will often generate better code. */
3067 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3068 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3069 expand_fix (to, target, 0);
3070 target = expand_binop (GET_MODE (to), xor_optab, to,
3071 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3072 to, 1, OPTAB_LIB_WIDEN);
3075 emit_move_insn (to, target);
3079 /* Make a place for a REG_NOTE and add it. */
3080 insn = emit_move_insn (to, to);
3081 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3082 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3083 from), REG_NOTES (insn));
3089 /* We can't do it with an insn, so use a library call. But first ensure
3090 that the mode of TO is at least as wide as SImode, since those are the
3091 only library calls we know about. */
3093 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3095 target = gen_reg_rtx (SImode);
3097 expand_fix (target, from, unsignedp);
3099 else if (GET_MODE (from) == SFmode)
3101 if (GET_MODE (to) == SImode)
3102 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3103 else if (GET_MODE (to) == DImode)
3104 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3105 else if (GET_MODE (to) == TImode)
3106 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3110 else if (GET_MODE (from) == DFmode)
3112 if (GET_MODE (to) == SImode)
3113 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3114 else if (GET_MODE (to) == DImode)
3115 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3116 else if (GET_MODE (to) == TImode)
3117 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3121 else if (GET_MODE (from) == XFmode)
3123 if (GET_MODE (to) == SImode)
3124 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3125 else if (GET_MODE (to) == DImode)
3126 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3127 else if (GET_MODE (to) == TImode)
3128 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3132 else if (GET_MODE (from) == TFmode)
3134 if (GET_MODE (to) == SImode)
3135 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3136 else if (GET_MODE (to) == DImode)
3137 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3138 else if (GET_MODE (to) == TImode)
3139 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3150 to = protect_from_queue (to, 1);
3151 from = protect_from_queue (from, 0);
3154 from = force_not_mem (from);
3158 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
3159 insns = get_insns ();
3162 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
3163 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
3164 GET_MODE (to), from));
3167 if (GET_MODE (to) == GET_MODE (target))
3168 emit_move_insn (to, target);
3170 convert_move (to, target, 0);
3178 optab op = (optab) xmalloc (sizeof (struct optab));
3180 for (i = 0; i < NUM_MACHINE_MODES; i++)
3182 op->handlers[i].insn_code = CODE_FOR_nothing;
3183 op->handlers[i].libfunc = 0;
3188 /* Initialize the libfunc fields of an entire group of entries in some
3189 optab. Each entry is set equal to a string consisting of a leading
3190 pair of underscores followed by a generic operation name followed by
3191 a mode name (downshifted to lower case) followed by a single character
3192 representing the number of operands for the given operation (which is
3193 usually one of the characters '2', '3', or '4').
3195 OPTABLE is the table in which libfunc fields are to be initialized.
3196 FIRST_MODE is the first machine mode index in the given optab to
3198 LAST_MODE is the last machine mode index in the given optab to
3200 OPNAME is the generic (string) name of the operation.
3201 SUFFIX is the character which specifies the number of operands for
3202 the given generic operation.
3206 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3207 register optab optable;
3208 register int first_mode;
3209 register int last_mode;
3210 register char *opname;
3211 register char suffix;
3214 register unsigned opname_len = strlen (opname);
3216 for (mode = first_mode; (int) mode <= (int) last_mode;
3217 mode = (enum machine_mode) ((int) mode + 1))
3219 register char *mname = mode_name[(int) mode];
3220 register unsigned mname_len = strlen (mname);
3221 register char *libfunc_name
3222 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3229 for (q = opname; *q; )
3231 for (q = mname; *q; q++)
3232 *p++ = tolower (*q);
3235 optable->handlers[(int) mode].libfunc
3236 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3240 /* Initialize the libfunc fields of an entire group of entries in some
3241 optab which correspond to all integer mode operations. The parameters
3242 have the same meaning as similarly named ones for the `init_libfuncs'
3243 routine. (See above). */
3246 init_integral_libfuncs (optable, opname, suffix)
3247 register optab optable;
3248 register char *opname;
3249 register char suffix;
3251 init_libfuncs (optable, SImode, TImode, opname, suffix);
3254 /* Initialize the libfunc fields of an entire group of entries in some
3255 optab which correspond to all real mode operations. The parameters
3256 have the same meaning as similarly named ones for the `init_libfuncs'
3257 routine. (See above). */
3260 init_floating_libfuncs (optable, opname, suffix)
3261 register optab optable;
3262 register char *opname;
3263 register char suffix;
3265 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3268 /* Initialize the libfunc fields of an entire group of entries in some
3269 optab which correspond to all complex floating modes. The parameters
3270 have the same meaning as similarly named ones for the `init_libfuncs'
3271 routine. (See above). */
3274 init_complex_libfuncs (optable, opname, suffix)
3275 register optab optable;
3276 register char *opname;
3277 register char suffix;
3279 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3282 /* Call this once to initialize the contents of the optabs
3283 appropriately for the current target machine. */
3291 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3293 for (p = fixtab[0][0];
3294 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
3296 *p = CODE_FOR_nothing;
3298 for (p = fixtrunctab[0][0];
3299 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
3301 *p = CODE_FOR_nothing;
3303 for (p = floattab[0][0];
3304 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
3306 *p = CODE_FOR_nothing;
3308 for (p = extendtab[0][0];
3309 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
3311 *p = CODE_FOR_nothing;
3313 for (i = 0; i < NUM_RTX_CODE; i++)
3314 setcc_gen_code[i] = CODE_FOR_nothing;
3316 add_optab = init_optab (PLUS);
3317 sub_optab = init_optab (MINUS);
3318 smul_optab = init_optab (MULT);
3319 smul_widen_optab = init_optab (UNKNOWN);
3320 umul_widen_optab = init_optab (UNKNOWN);
3321 sdiv_optab = init_optab (DIV);
3322 sdivmod_optab = init_optab (UNKNOWN);
3323 udiv_optab = init_optab (UDIV);
3324 udivmod_optab = init_optab (UNKNOWN);
3325 smod_optab = init_optab (MOD);
3326 umod_optab = init_optab (UMOD);
3327 flodiv_optab = init_optab (DIV);
3328 ftrunc_optab = init_optab (UNKNOWN);
3329 and_optab = init_optab (AND);
3330 ior_optab = init_optab (IOR);
3331 xor_optab = init_optab (XOR);
3332 ashl_optab = init_optab (ASHIFT);
3333 ashr_optab = init_optab (ASHIFTRT);
3334 lshl_optab = init_optab (LSHIFT);
3335 lshr_optab = init_optab (LSHIFTRT);
3336 rotl_optab = init_optab (ROTATE);
3337 rotr_optab = init_optab (ROTATERT);
3338 smin_optab = init_optab (SMIN);
3339 smax_optab = init_optab (SMAX);
3340 umin_optab = init_optab (UMIN);
3341 umax_optab = init_optab (UMAX);
3342 mov_optab = init_optab (UNKNOWN);
3343 movstrict_optab = init_optab (UNKNOWN);
3344 cmp_optab = init_optab (UNKNOWN);
3345 ucmp_optab = init_optab (UNKNOWN);
3346 tst_optab = init_optab (UNKNOWN);
3347 neg_optab = init_optab (NEG);
3348 abs_optab = init_optab (ABS);
3349 one_cmpl_optab = init_optab (NOT);
3350 ffs_optab = init_optab (FFS);
3351 sqrt_optab = init_optab (SQRT);
3352 sin_optab = init_optab (UNKNOWN);
3353 cos_optab = init_optab (UNKNOWN);
3354 strlen_optab = init_optab (UNKNOWN);
3356 for (i = 0; i < NUM_MACHINE_MODES; i++)
3358 movstr_optab[i] = CODE_FOR_nothing;
3360 #ifdef HAVE_SECONDARY_RELOADS
3361 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
3365 /* Fill in the optabs with the insns we support. */
3368 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3369 /* This flag says the same insns that convert to a signed fixnum
3370 also convert validly to an unsigned one. */
3371 for (i = 0; i < NUM_MACHINE_MODES; i++)
3372 for (j = 0; j < NUM_MACHINE_MODES; j++)
3373 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
3376 #ifdef EXTRA_CC_MODES
3380 /* Initialize the optabs with the names of the library functions. */
3381 init_integral_libfuncs (add_optab, "add", '3');
3382 init_floating_libfuncs (add_optab, "add", '3');
3383 init_integral_libfuncs (sub_optab, "sub", '3');
3384 init_floating_libfuncs (sub_optab, "sub", '3');
3385 init_integral_libfuncs (smul_optab, "mul", '3');
3386 init_floating_libfuncs (smul_optab, "mul", '3');
3387 init_integral_libfuncs (sdiv_optab, "div", '3');
3388 init_integral_libfuncs (udiv_optab, "udiv", '3');
3389 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
3390 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
3391 init_integral_libfuncs (smod_optab, "mod", '3');
3392 init_integral_libfuncs (umod_optab, "umod", '3');
3393 init_floating_libfuncs (flodiv_optab, "div", '3');
3394 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
3395 init_integral_libfuncs (and_optab, "and", '3');
3396 init_integral_libfuncs (ior_optab, "ior", '3');
3397 init_integral_libfuncs (xor_optab, "xor", '3');
3398 init_integral_libfuncs (ashl_optab, "ashl", '3');
3399 init_integral_libfuncs (ashr_optab, "ashr", '3');
3400 init_integral_libfuncs (lshl_optab, "lshl", '3');
3401 init_integral_libfuncs (lshr_optab, "lshr", '3');
3402 init_integral_libfuncs (rotl_optab, "rotl", '3');
3403 init_integral_libfuncs (rotr_optab, "rotr", '3');
3404 init_integral_libfuncs (smin_optab, "min", '3');
3405 init_floating_libfuncs (smin_optab, "min", '3');
3406 init_integral_libfuncs (smax_optab, "max", '3');
3407 init_floating_libfuncs (smax_optab, "max", '3');
3408 init_integral_libfuncs (umin_optab, "umin", '3');
3409 init_integral_libfuncs (umax_optab, "umax", '3');
3410 init_integral_libfuncs (neg_optab, "neg", '2');
3411 init_floating_libfuncs (neg_optab, "neg", '2');
3412 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
3413 init_integral_libfuncs (ffs_optab, "ffs", '2');
3415 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3416 init_integral_libfuncs (cmp_optab, "cmp", '2');
3417 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
3418 init_floating_libfuncs (cmp_optab, "cmp", '2');
3420 #ifdef MULSI3_LIBCALL
3421 smul_optab->handlers[(int) SImode].libfunc
3422 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
3424 #ifdef MULDI3_LIBCALL
3425 smul_optab->handlers[(int) DImode].libfunc
3426 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
3428 #ifdef MULTI3_LIBCALL
3429 smul_optab->handlers[(int) TImode].libfunc
3430 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
3433 #ifdef DIVSI3_LIBCALL
3434 sdiv_optab->handlers[(int) SImode].libfunc
3435 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3437 #ifdef DIVDI3_LIBCALL
3438 sdiv_optab->handlers[(int) DImode].libfunc
3439 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3441 #ifdef DIVTI3_LIBCALL
3442 sdiv_optab->handlers[(int) TImode].libfunc
3443 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
3446 #ifdef UDIVSI3_LIBCALL
3447 udiv_optab->handlers[(int) SImode].libfunc
3448 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3450 #ifdef UDIVDI3_LIBCALL
3451 udiv_optab->handlers[(int) DImode].libfunc
3452 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3454 #ifdef UDIVTI3_LIBCALL
3455 udiv_optab->handlers[(int) TImode].libfunc
3456 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
3460 #ifdef MODSI3_LIBCALL
3461 smod_optab->handlers[(int) SImode].libfunc
3462 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3464 #ifdef MODDI3_LIBCALL
3465 smod_optab->handlers[(int) DImode].libfunc
3466 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3468 #ifdef MODTI3_LIBCALL
3469 smod_optab->handlers[(int) TImode].libfunc
3470 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
3474 #ifdef UMODSI3_LIBCALL
3475 umod_optab->handlers[(int) SImode].libfunc
3476 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3478 #ifdef UMODDI3_LIBCALL
3479 umod_optab->handlers[(int) DImode].libfunc
3480 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3482 #ifdef UMODTI3_LIBCALL
3483 umod_optab->handlers[(int) TImode].libfunc
3484 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
3487 /* Use cabs for DC complex abs, since systems generally have cabs.
3488 Don't define any libcall for SCmode, so that cabs will be used. */
3489 abs_optab->handlers[(int) DCmode].libfunc
3490 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
3492 ffs_optab->handlers[(int) mode_for_size (BITS_PER_WORD, MODE_INT, 0)] .libfunc
3493 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3495 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3496 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
3497 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
3498 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
3499 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
3501 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3502 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
3503 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
3504 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
3505 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
3507 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3508 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3509 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3510 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
3511 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
3512 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
3514 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
3515 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
3516 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
3517 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
3518 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
3519 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
3521 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
3522 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
3523 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
3524 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
3525 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
3526 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
3528 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
3529 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
3530 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
3531 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
3532 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
3533 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
3535 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
3536 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
3537 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
3538 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
3539 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
3540 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
3542 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
3543 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
3544 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
3546 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
3547 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
3548 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
3550 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
3551 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
3552 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
3554 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
3555 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
3556 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
3558 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
3559 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
3560 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
3562 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
3563 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
3564 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
3566 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
3567 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
3568 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
3570 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
3571 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
3572 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
3574 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
3575 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
3576 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
3578 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
3579 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
3580 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
3582 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
3583 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
3584 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
3586 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
3587 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
3588 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
3593 /* SCO 3.2 apparently has a broken ldexp. */
3606 #endif /* BROKEN_LDEXP */