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"
31 /* Each optab contains info on how this target machine
32 can perform a particular operation
33 for all sizes and kinds of operands.
35 The operation to be performed is often specified
36 by passing one of these optabs as an argument.
38 See expr.h for documentation of these optabs. */
43 optab smul_widen_optab;
44 optab umul_widen_optab;
68 optab movstrict_optab;
77 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
82 /* SYMBOL_REF rtx's for the library functions that are called
83 implicitly and not via optabs. */
85 rtx extendsfdf2_libfunc;
86 rtx truncdfsf2_libfunc;
105 rtx floatdisf_libfunc;
106 rtx floatsisf_libfunc;
107 rtx floatdidf_libfunc;
108 rtx floatsidf_libfunc;
113 rtx fixunssfsi_libfunc;
114 rtx fixunssfdi_libfunc;
115 rtx fixunsdfsi_libfunc;
116 rtx fixunsdfdi_libfunc;
118 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
119 gives the gen_function to make a branch to test that condition. */
121 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
123 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
124 gives the insn code to make a store-condition insn
125 to test that condition. */
127 enum insn_code setcc_gen_code[NUM_RTX_CODE];
129 static void emit_float_lib_cmp ();
131 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
132 the result of operation CODE applied to OP0 (and OP1 if it is a binary
135 If the last insn does not set TARGET, don't do anything, but return 1.
137 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
138 don't add the REG_EQUAL note but return 0. Our caller can then try
139 again, ensuring that TARGET is not one of the operands. */
142 add_equal_note (seq, target, code, op0, op1)
152 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
153 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
154 || GET_CODE (seq) != SEQUENCE
155 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
156 || GET_CODE (target) == ZERO_EXTRACT
157 || (! rtx_equal_p (SET_DEST (set), target)
158 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
160 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
161 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
165 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
166 besides the last insn. */
167 if (reg_overlap_mentioned_p (target, op0)
168 || (op1 && reg_overlap_mentioned_p (target, op1)))
169 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
170 if (reg_set_p (target, XVECEXP (seq, 0, i)))
173 if (GET_RTX_CLASS (code) == '1')
174 note = gen_rtx (code, GET_MODE (target), op0);
176 note = gen_rtx (code, GET_MODE (target), op0, op1);
178 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
179 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
180 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
185 /* Generate code to perform an operation specified by BINOPTAB
186 on operands OP0 and OP1, with result having machine-mode MODE.
188 UNSIGNEDP is for the case where we have to widen the operands
189 to perform the operation. It says to use zero-extension.
191 If TARGET is nonzero, the value
192 is generated there, if it is convenient to do so.
193 In all cases an rtx is returned for the locus of the value;
194 this may or may not be TARGET. */
197 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
198 enum machine_mode mode;
203 enum optab_methods methods;
205 enum mode_class class;
206 enum machine_mode wider_mode;
208 int commutative_op = 0;
209 int shift_op = (binoptab->code == ASHIFT
210 || binoptab->code == ASHIFTRT
211 || binoptab->code == LSHIFT
212 || binoptab->code == LSHIFTRT
213 || binoptab->code == ROTATE
214 || binoptab->code == ROTATERT);
217 class = GET_MODE_CLASS (mode);
219 op0 = protect_from_queue (op0, 0);
220 op1 = protect_from_queue (op1, 0);
222 target = protect_from_queue (target, 1);
226 op0 = force_not_mem (op0);
227 op1 = force_not_mem (op1);
230 /* If we are inside an appropriately-short loop and one operand is an
231 expensive constant, force it into a register. */
232 if (CONSTANT_P (op0) && preserve_subexpressions_p () && rtx_cost (op0) > 2)
233 op0 = force_reg (mode, op0);
235 if (CONSTANT_P (op1) && preserve_subexpressions_p () && rtx_cost (op1) > 2)
236 op1 = force_reg (shift_op ? word_mode : mode, op1);
238 #if 0 /* Turned off because it seems to be a kludgy method. */
239 /* If subtracting integer from pointer, and the pointer has a special mode,
240 then change it to an add. We use the add insn of Pmode for combining
241 integers with pointers, and the sub insn to subtract two pointers. */
243 if (binoptab == sub_optab
244 && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
246 op1 = negate_rtx (GET_MODE(op1), op1);
247 binoptab = add_optab;
251 /* Record where to delete back to if we backtrack. */
252 last = get_last_insn ();
254 /* If operation is commutative,
255 try to make the first operand a register.
256 Even better, try to make it the same as the target.
257 Also try to make the last operand a constant. */
258 if (GET_RTX_CLASS (binoptab->code) == 'c'
259 || binoptab == smul_widen_optab
260 || binoptab == umul_widen_optab)
264 if (((target == 0 || GET_CODE (target) == REG)
265 ? ((GET_CODE (op1) == REG
266 && GET_CODE (op0) != REG)
268 : rtx_equal_p (op1, target))
269 || GET_CODE (op0) == CONST_INT)
277 /* If we can do it with a three-operand insn, do so. */
279 if (methods != OPTAB_MUST_WIDEN
280 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
282 int icode = (int) binoptab->handlers[(int) mode].insn_code;
283 enum machine_mode mode0 = insn_operand_mode[icode][1];
284 enum machine_mode mode1 = insn_operand_mode[icode][2];
286 rtx xop0 = op0, xop1 = op1;
291 temp = gen_reg_rtx (mode);
293 /* If it is a commutative operator and the modes would match
294 if we would swap the operands, we can save the conversions. */
297 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
298 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
302 tmp = op0; op0 = op1; op1 = tmp;
303 tmp = xop0; xop0 = xop1; xop1 = tmp;
307 /* In case the insn wants input operands in modes different from
308 the result, convert the operands. */
310 if (GET_MODE (op0) != VOIDmode
311 && GET_MODE (op0) != mode0)
312 xop0 = convert_to_mode (mode0, xop0, unsignedp);
314 if (GET_MODE (xop1) != VOIDmode
315 && GET_MODE (xop1) != mode1)
316 xop1 = convert_to_mode (mode1, xop1, unsignedp);
318 /* Now, if insn's predicates don't allow our operands, put them into
321 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
322 xop0 = copy_to_mode_reg (mode0, xop0);
324 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
325 xop1 = copy_to_mode_reg (mode1, xop1);
327 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
328 temp = gen_reg_rtx (mode);
330 pat = GEN_FCN (icode) (temp, xop0, xop1);
333 /* If PAT is a multi-insn sequence, try to add an appropriate
334 REG_EQUAL note to it. If we can't because TEMP conflicts with an
335 operand, call ourselves again, this time without a target. */
336 if (GET_CODE (pat) == SEQUENCE
337 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
339 delete_insns_since (last);
340 return expand_binop (mode, binoptab, op0, op1, 0, unsignedp,
348 delete_insns_since (last);
351 /* These can be done a word at a time. */
352 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
354 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
355 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
361 /* If TARGET is the same as one of the operands, the REG_EQUAL note
362 won't be accurate, so use a new target. */
363 if (target == 0 || target == op0 || target == op1)
364 target = gen_reg_rtx (mode);
368 /* Do the actual arithmetic. */
369 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
371 rtx target_piece = operand_subword (target, i, 1, mode);
372 rtx x = expand_binop (word_mode, binoptab,
373 operand_subword_force (op0, i, mode),
374 operand_subword_force (op1, i, mode),
375 target_piece, unsignedp, methods);
376 if (target_piece != x)
377 emit_move_insn (target_piece, x);
380 insns = get_insns ();
383 if (binoptab->code != UNKNOWN)
384 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
388 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
392 /* These can be done a word at a time by propagating carries. */
393 if ((binoptab == add_optab || binoptab == sub_optab)
395 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
396 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
399 rtx carry_tmp = gen_reg_rtx (word_mode);
400 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
401 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
402 rtx carry_in, carry_out;
404 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
405 value is one of those, use it. Otherwise, use 1 since it is the
406 one easiest to get. */
407 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
408 int normalizep = STORE_FLAG_VALUE;
413 /* Prepare the operands. */
414 op0 = force_reg (mode, op0);
415 op1 = force_reg (mode, op1);
417 if (target == 0 || GET_CODE (target) != REG
418 || target == op0 || target == op1)
419 target = gen_reg_rtx (mode);
421 /* Do the actual arithmetic. */
422 for (i = 0; i < nwords; i++)
424 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
425 rtx target_piece = operand_subword (target, index, 1, mode);
426 rtx op0_piece = operand_subword_force (op0, index, mode);
427 rtx op1_piece = operand_subword_force (op1, index, mode);
430 /* Main add/subtract of the input operands. */
431 x = expand_binop (word_mode, binoptab,
432 op0_piece, op1_piece,
433 target_piece, unsignedp, methods);
439 /* Store carry from main add/subtract. */
440 carry_out = gen_reg_rtx (word_mode);
441 carry_out = emit_store_flag (carry_out,
442 binoptab == add_optab ? LTU : GTU,
444 word_mode, 1, normalizep);
451 /* Add/subtract previous carry to main result. */
452 x = expand_binop (word_mode,
453 normalizep == 1 ? binoptab : otheroptab,
455 target_piece, 1, methods);
456 if (target_piece != x)
457 emit_move_insn (target_piece, x);
461 /* THIS CODE HAS NOT BEEN TESTED. */
462 /* Get out carry from adding/subtracting carry in. */
463 carry_tmp = emit_store_flag (carry_tmp,
464 binoptab == add_optab
467 word_mode, 1, normalizep);
468 /* Logical-ior the two poss. carry together. */
469 carry_out = expand_binop (word_mode, ior_optab,
470 carry_out, carry_tmp,
471 carry_out, 0, methods);
477 carry_in = carry_out;
480 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
484 temp = emit_move_insn (target, target);
485 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
486 gen_rtx (binoptab->code, mode, op0, op1),
491 delete_insns_since (last);
494 /* If we want to multiply two two-word values and have normal and widening
495 multiplies of single-word values, we can do this with three smaller
496 multiplications. Note that we do not make a REG_NO_CONFLICT block here
497 because we are not operating on one word at a time.
499 The multiplication proceeds as follows:
500 _______________________
501 [__op0_high_|__op0_low__]
502 _______________________
503 * [__op1_high_|__op1_low__]
504 _______________________________________________
505 _______________________
506 (1) [__op0_low__*__op1_low__]
507 _______________________
508 (2a) [__op0_low__*__op1_high_]
509 _______________________
510 (2b) [__op0_high_*__op1_low__]
511 _______________________
512 (3) [__op0_high_*__op1_high_]
515 This gives a 4-word result. Since we are only interested in the
516 lower 2 words, partial result (3) and the upper words of (2a) and
517 (2b) don't need to be calculated. Hence (2a) and (2b) can be
518 calculated using non-widening multiplication.
520 (1), however, needs to be calculated with an unsigned widening
521 multiplication. If this operation is not directly supported we
522 try using a signed widening multiplication and adjust the result.
523 This adjustment works as follows:
525 If both operands are positive then no adjustment is needed.
527 If the operands have different signs, for example op0_low < 0 and
528 op1_low >= 0, the instruction treats the most significant bit of
529 op0_low as a sign bit instead of a bit with significance
530 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
531 with 2**BITS_PER_WORD - op0_low, and two's complements the
532 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
535 Similarly, if both operands are negative, we need to add
536 (op0_low + op1_low) * 2**BITS_PER_WORD.
538 We use a trick to adjust quickly. We logically shift op0_low right
539 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
540 op0_high (op1_high) before it is used to calculate 2b (2a). If no
541 logical shift exists, we do an arithmetic right shift and subtract
544 if (binoptab == smul_optab
546 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
547 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
548 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
549 && ((umul_widen_optab->handlers[(int) mode].insn_code
551 || (smul_widen_optab->handlers[(int) mode].insn_code
552 != CODE_FOR_nothing)))
554 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
555 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
556 rtx op0_high = operand_subword_force (op0, high, mode);
557 rtx op0_low = operand_subword_force (op0, low, mode);
558 rtx op1_high = operand_subword_force (op1, high, mode);
559 rtx op1_low = operand_subword_force (op1, low, mode);
564 /* If the target is the same as one of the inputs, don't use it. This
565 prevents problems with the REG_EQUAL note. */
566 if (target == op0 || target == op1)
569 /* Multiply the two lower words to get a double-word product.
570 If unsigned widening multiplication is available, use that;
571 otherwise use the signed form and compensate. */
573 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
575 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
576 target, 1, OPTAB_DIRECT);
578 /* If we didn't succeed, delete everything we did so far. */
580 delete_insns_since (last);
582 op0_xhigh = op0_high, op1_xhigh = op1_high;
586 && smul_widen_optab->handlers[(int) mode].insn_code
589 rtx wordm1 = gen_rtx (CONST_INT, VOIDmode, BITS_PER_WORD - 1);
590 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
591 target, 1, OPTAB_DIRECT);
592 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
595 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
596 op0_xhigh, op0_xhigh, 0, OPTAB_DIRECT);
599 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
602 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
603 op0_xhigh, op0_xhigh, 0,
607 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
610 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
611 op1_xhigh, op1_xhigh, 0, OPTAB_DIRECT);
614 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
617 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
618 op1_xhigh, op1_xhigh, 0,
623 /* If we have been able to directly compute the product of the
624 low-order words of the operands and perform any required adjustments
625 of the operands, we proceed by trying two more multiplications
626 and then computing the appropriate sum.
628 We have checked above that the required addition is provided.
629 Full-word addition will normally always succeed, especially if
630 it is provided at all, so we don't worry about its failure. The
631 multiplication may well fail, however, so we do handle that. */
633 if (product && op0_xhigh && op1_xhigh)
636 rtx product_high = operand_subword (product, high, 1, mode);
637 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh, 0,
642 product_piece = expand_binop (word_mode, add_optab, temp,
643 product_high, product_high,
645 if (product_piece != product_high)
646 emit_move_insn (product_high, product_piece);
648 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh, 0,
651 product_piece = expand_binop (word_mode, add_optab, temp,
652 product_high, product_high,
654 if (product_piece != product_high)
655 emit_move_insn (product_high, product_piece);
657 temp = emit_move_insn (product, product);
658 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
659 gen_rtx (MULT, mode, op0, op1),
666 /* If we get here, we couldn't do it for some reason even though we
667 originally thought we could. Delete anything we've emitted in
670 delete_insns_since (last);
673 /* It can't be open-coded in this mode.
674 Use a library call if one is available and caller says that's ok. */
676 if (binoptab->handlers[(int) mode].libfunc
677 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
680 rtx funexp = binoptab->handlers[(int) mode].libfunc;
684 /* Pass 1 for NO_QUEUE so we don't lose any increments
685 if the libcall is cse'd or moved. */
686 emit_library_call (binoptab->handlers[(int) mode].libfunc,
687 1, mode, 2, op0, mode, op1,
688 (shift_op ? word_mode : mode));
690 insns = get_insns ();
693 target = gen_reg_rtx (mode);
694 emit_libcall_block (insns, target, hard_libcall_value (mode),
695 gen_rtx (binoptab->code, mode, op0, op1));
700 delete_insns_since (last);
702 /* It can't be done in this mode. Can we do it in a wider mode? */
704 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
705 || methods == OPTAB_MUST_WIDEN))
706 return 0; /* Caller says, don't even try. */
708 /* Compute the value of METHODS to pass to recursive calls.
709 Don't allow widening to be tried recursively. */
711 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
713 /* Look for a wider mode of the same class for which it appears we can do
716 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
718 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
719 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
721 if ((binoptab->handlers[(int) wider_mode].insn_code
723 || (methods == OPTAB_LIB
724 && binoptab->handlers[(int) wider_mode].libfunc))
726 rtx xop0 = op0, xop1 = op1;
729 /* For certain integer operations, we need not actually extend
730 the narrow operands, as long as we will truncate
731 the results to the same narrowness. */
733 if ((binoptab == ior_optab || binoptab == and_optab
734 || binoptab == xor_optab
735 || binoptab == add_optab || binoptab == sub_optab
736 || binoptab == smul_optab
737 || binoptab == ashl_optab || binoptab == lshl_optab)
738 && class == MODE_INT)
741 /* If an operand is a constant integer, we might as well
742 convert it since that is more efficient than using a SUBREG,
743 unlike the case for other operands. */
745 if (no_extend && GET_MODE (xop0) != VOIDmode)
746 xop0 = gen_rtx (SUBREG, wider_mode,
747 force_reg (GET_MODE (xop0), xop0), 0);
749 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
751 if (no_extend && GET_MODE (xop1) != VOIDmode)
752 xop1 = gen_rtx (SUBREG, wider_mode,
753 force_reg (GET_MODE (xop1), xop1), 0);
755 xop1 = convert_to_mode (wider_mode, xop1, unsignedp);
757 temp = expand_binop (wider_mode, binoptab, xop0, xop1, 0,
761 if (class != MODE_INT)
764 target = gen_reg_rtx (mode);
765 convert_move (target, temp, 0);
769 return gen_lowpart (mode, temp);
772 delete_insns_since (last);
780 /* Expand a binary operator which has both signed and unsigned forms.
781 UOPTAB is the optab for unsigned operations, and SOPTAB is for
784 If we widen unsigned operands, we may use a signed wider operation instead
785 of an unsigned wider operation, since the result would be the same. */
788 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
789 enum machine_mode mode;
790 optab uoptab, soptab;
791 rtx op0, op1, target;
793 enum optab_methods methods;
796 optab direct_optab = unsignedp ? uoptab : soptab;
797 struct optab wide_soptab;
799 /* Do it without widening, if possible. */
800 temp = expand_binop (mode, direct_optab, op0, op1, target,
801 unsignedp, OPTAB_DIRECT);
802 if (temp || methods == OPTAB_DIRECT)
805 /* Try widening to a signed int. Make a fake signed optab that
806 hides any signed insn for direct use. */
807 wide_soptab = *soptab;
808 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
809 wide_soptab.handlers[(int) mode].libfunc = 0;
811 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
812 unsignedp, OPTAB_WIDEN);
814 /* For unsigned operands, try widening to an unsigned int. */
815 if (temp == 0 && unsignedp)
816 temp = expand_binop (mode, uoptab, op0, op1, target,
817 unsignedp, OPTAB_WIDEN);
818 if (temp || methods == OPTAB_WIDEN)
821 /* Use the right width lib call if that exists. */
822 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
823 if (temp || methods == OPTAB_LIB)
826 /* Must widen and use a lib call, use either signed or unsigned. */
827 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
832 return expand_binop (mode, uoptab, op0, op1, target,
837 /* Generate code to perform an operation specified by BINOPTAB
838 on operands OP0 and OP1, with two results to TARG1 and TARG2.
839 We assume that the order of the operands for the instruction
840 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
841 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
843 Either TARG0 or TARG1 may be zero, but what that means is that
844 that result is not actually wanted. We will generate it into
845 a dummy pseudo-reg and discard it. They may not both be zero.
847 Returns 1 if this operation can be performed; 0 if not. */
850 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
856 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
857 enum mode_class class;
858 enum machine_mode wider_mode;
861 class = GET_MODE_CLASS (mode);
863 op0 = protect_from_queue (op0, 0);
864 op1 = protect_from_queue (op1, 0);
868 op0 = force_not_mem (op0);
869 op1 = force_not_mem (op1);
872 /* If we are inside an appropriately-short loop and one operand is an
873 expensive constant, force it into a register. */
874 if (CONSTANT_P (op0) && preserve_subexpressions_p () && rtx_cost (op0) > 2)
875 op0 = force_reg (mode, op0);
877 if (CONSTANT_P (op1) && preserve_subexpressions_p () && rtx_cost (op1) > 2)
878 op1 = force_reg (mode, op1);
881 targ0 = protect_from_queue (targ0, 1);
883 targ0 = gen_reg_rtx (mode);
885 targ1 = protect_from_queue (targ1, 1);
887 targ1 = gen_reg_rtx (mode);
889 /* Record where to go back to if we fail. */
890 last = get_last_insn ();
892 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
894 int icode = (int) binoptab->handlers[(int) mode].insn_code;
895 enum machine_mode mode0 = insn_operand_mode[icode][1];
896 enum machine_mode mode1 = insn_operand_mode[icode][2];
898 rtx xop0 = op0, xop1 = op1;
900 /* In case this insn wants input operands in modes different from the
901 result, convert the operands. */
902 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
903 xop0 = convert_to_mode (mode0, xop0, unsignedp);
905 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
906 xop1 = convert_to_mode (mode1, xop1, unsignedp);
908 /* Now, if insn doesn't accept these operands, put them into pseudos. */
909 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
910 xop0 = copy_to_mode_reg (mode0, xop0);
912 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
913 xop1 = copy_to_mode_reg (mode1, xop1);
915 /* We could handle this, but we should always be called with a pseudo
916 for our targets and all insns should take them as outputs. */
917 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
918 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
921 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
928 delete_insns_since (last);
931 /* It can't be done in this mode. Can we do it in a wider mode? */
933 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
935 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
936 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
938 if (binoptab->handlers[(int) wider_mode].insn_code
941 register rtx t0 = gen_reg_rtx (wider_mode);
942 register rtx t1 = gen_reg_rtx (wider_mode);
944 if (expand_twoval_binop (binoptab,
945 convert_to_mode (wider_mode, op0,
947 convert_to_mode (wider_mode, op1,
951 convert_move (targ0, t0, unsignedp);
952 convert_move (targ1, t1, unsignedp);
956 delete_insns_since (last);
964 /* Generate code to perform an operation specified by UNOPTAB
965 on operand OP0, with result having machine-mode MODE.
967 UNSIGNEDP is for the case where we have to widen the operands
968 to perform the operation. It says to use zero-extension.
970 If TARGET is nonzero, the value
971 is generated there, if it is convenient to do so.
972 In all cases an rtx is returned for the locus of the value;
973 this may or may not be TARGET. */
976 expand_unop (mode, unoptab, op0, target, unsignedp)
977 enum machine_mode mode;
983 enum mode_class class;
984 enum machine_mode wider_mode;
986 rtx last = get_last_insn ();
989 class = GET_MODE_CLASS (mode);
991 op0 = protect_from_queue (op0, 0);
995 op0 = force_not_mem (op0);
999 target = protect_from_queue (target, 1);
1001 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1003 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1004 enum machine_mode mode0 = insn_operand_mode[icode][1];
1010 temp = gen_reg_rtx (mode);
1012 if (GET_MODE (xop0) != VOIDmode
1013 && GET_MODE (xop0) != mode0)
1014 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1016 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1018 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1019 xop0 = copy_to_mode_reg (mode0, xop0);
1021 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1022 temp = gen_reg_rtx (mode);
1024 pat = GEN_FCN (icode) (temp, xop0);
1027 if (GET_CODE (pat) == SEQUENCE
1028 && ! add_equal_note (pat, temp, unoptab->code, xop0, 0))
1030 delete_insns_since (last);
1031 return expand_unop (mode, unoptab, op0, 0, unsignedp);
1039 delete_insns_since (last);
1042 /* These can be done a word at a time. */
1043 if (unoptab == one_cmpl_optab
1044 && class == MODE_INT
1045 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1046 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1051 if (target == 0 || target == op0)
1052 target = gen_reg_rtx (mode);
1056 /* Do the actual arithmetic. */
1057 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1059 rtx target_piece = operand_subword (target, i, 1, mode);
1060 rtx x = expand_unop (word_mode, unoptab,
1061 operand_subword_force (op0, i, mode),
1062 target_piece, unsignedp);
1063 if (target_piece != x)
1064 emit_move_insn (target_piece, x);
1067 insns = get_insns ();
1070 emit_no_conflict_block (insns, target, op0, 0,
1071 gen_rtx (unoptab->code, mode, op0));
1075 if (unoptab->handlers[(int) mode].libfunc)
1078 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1082 /* Pass 1 for NO_QUEUE so we don't lose any increments
1083 if the libcall is cse'd or moved. */
1084 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1085 1, mode, 1, op0, mode);
1086 insns = get_insns ();
1089 target = gen_reg_rtx (mode);
1090 emit_libcall_block (insns, target, hard_libcall_value (mode),
1091 gen_rtx (unoptab->code, mode, op0));
1096 /* It can't be done in this mode. Can we do it in a wider mode? */
1098 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1100 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1101 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1103 if ((unoptab->handlers[(int) wider_mode].insn_code
1104 != CODE_FOR_nothing)
1105 || unoptab->handlers[(int) wider_mode].libfunc)
1109 /* For certain operations, we need not actually extend
1110 the narrow operand, as long as we will truncate the
1111 results to the same narrowness. */
1113 if ((unoptab == neg_optab || unoptab == one_cmpl_optab)
1114 && class == MODE_INT)
1115 xop0 = gen_rtx (SUBREG, wider_mode, force_reg (mode, xop0), 0);
1117 xop0 = convert_to_mode (wider_mode, xop0, unsignedp);
1119 temp = expand_unop (wider_mode, unoptab, xop0, 0, unsignedp);
1123 if (class != MODE_INT)
1126 target = gen_reg_rtx (mode);
1127 convert_move (target, temp, 0);
1131 return gen_lowpart (mode, temp);
1134 delete_insns_since (last);
1142 /* Generate an instruction whose insn-code is INSN_CODE,
1143 with two operands: an output TARGET and an input OP0.
1144 TARGET *must* be nonzero, and the output is always stored there.
1145 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1146 the value that is stored into TARGET. */
1149 emit_unop_insn (icode, target, op0, code)
1156 enum machine_mode mode0 = insn_operand_mode[icode][1];
1159 temp = target = protect_from_queue (target, 1);
1161 op0 = protect_from_queue (op0, 0);
1164 op0 = force_not_mem (op0);
1166 /* Now, if insn does not accept our operands, put them into pseudos. */
1168 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1169 op0 = copy_to_mode_reg (mode0, op0);
1171 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1172 || (flag_force_mem && GET_CODE (temp) == MEM))
1173 temp = gen_reg_rtx (GET_MODE (temp));
1175 pat = GEN_FCN (icode) (temp, op0);
1177 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1178 add_equal_note (pat, temp, code, op0, 0);
1183 emit_move_insn (target, temp);
1186 /* Emit code to perform a series of operations on a multi-word quantity, one
1189 Such a block is preceded by a CLOBBER of the output, consists of multiple
1190 insns, each setting one word of the output, and followed by a SET copying
1191 the output to itself.
1193 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1194 note indicating that it doesn't conflict with the (also multi-word)
1195 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1198 INSNS is a block of code generated to perform the operation, not including
1199 the CLOBBER and final copy. All insns that compute intermediate values
1200 are first emitted, followed by the block as described above. Only
1201 INSNs are allowed in the block; no library calls or jumps may be
1204 TARGET, OP0, and OP1 are the output and inputs of the operations,
1205 respectively. OP1 may be zero for a unary operation.
1207 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1210 If TARGET is not a register, INSNS is simply emitted with no special
1213 The final insn emitted is returned. */
1216 emit_no_conflict_block (insns, target, op0, op1, equiv)
1222 rtx prev, next, first, last, insn;
1224 if (GET_CODE (target) != REG || reload_in_progress)
1225 return emit_insns (insns);
1227 /* First emit all insns that do not store into words of the output and remove
1228 these from the list. */
1229 for (insn = insns; insn; insn = next)
1234 next = NEXT_INSN (insn);
1236 if (GET_CODE (insn) != INSN)
1239 if (GET_CODE (PATTERN (insn)) == SET)
1240 set = PATTERN (insn);
1241 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1243 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1244 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1246 set = XVECEXP (PATTERN (insn), 0, i);
1254 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1256 if (PREV_INSN (insn))
1257 NEXT_INSN (PREV_INSN (insn)) = next;
1262 PREV_INSN (next) = PREV_INSN (insn);
1268 prev = get_last_insn ();
1270 /* Now write the CLOBBER of the output, followed by the setting of each
1271 of the words, followed by the final copy. */
1272 if (target != op0 && target != op1)
1273 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1275 for (insn = insns; insn; insn = next)
1277 next = NEXT_INSN (insn);
1280 if (op1 && GET_CODE (op1) == REG)
1281 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1284 if (op0 && GET_CODE (op0) == REG)
1285 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1289 last = emit_move_insn (target, target);
1291 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1294 first = get_insns ();
1296 first = NEXT_INSN (prev);
1298 /* Encapsulate the block so it gets manipulated as a unit. */
1299 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1301 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1306 /* Emit code to make a call to a constant function or a library call.
1308 INSNS is a list containing all insns emitted in the call.
1309 These insns leave the result in RESULT. Our block is to copy RESULT
1310 to TARGET, which is logically equivalent to EQUIV.
1312 We first emit any insns that set a pseudo on the assumption that these are
1313 loading constants into registers; doing so allows them to be safely cse'ed
1314 between blocks. Then we emit all the other insns in the block, followed by
1315 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1316 note with an operand of EQUIV.
1318 Moving assignments to pseudos outside of the block is done to improve
1319 the generated code, but is not required to generate correct code,
1320 hence being unable to move an assignment is not grounds for not making
1321 a libcall block. There are two reasons why it is safe to leave these
1322 insns inside the block: First, we know that these pseudos cannot be
1323 used in generated RTL outside the block since they are created for
1324 temporary purposes within the block. Second, CSE will not record the
1325 values of anything set inside a libcall block, so we know they must
1326 be dead at the end of the block.
1328 Except for the first group of insns (the ones setting pseudos), the
1329 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1332 emit_libcall_block (insns, target, result, equiv)
1338 rtx prev, next, first, last, insn;
1340 /* First emit all insns that set pseudos. Remove them from the list as
1341 we go. Avoid insns that set pseudo which were referenced in previous
1342 insns. These can be generated by move_by_pieces, for example,
1343 to update an address. */
1345 for (insn = insns; insn; insn = next)
1347 rtx set = single_set (insn);
1349 next = NEXT_INSN (insn);
1351 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1352 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
1353 && ! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
1354 && ! reg_used_between_p (SET_DEST (set), insns, insn))
1356 if (PREV_INSN (insn))
1357 NEXT_INSN (PREV_INSN (insn)) = next;
1362 PREV_INSN (next) = PREV_INSN (insn);
1368 prev = get_last_insn ();
1370 /* Write the remaining insns followed by the final copy. */
1372 for (insn = insns; insn; insn = next)
1374 next = NEXT_INSN (insn);
1379 last = emit_move_insn (target, result);
1380 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1383 first = get_insns ();
1385 first = NEXT_INSN (prev);
1387 /* Encapsulate the block so it gets manipulated as a unit. */
1388 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1390 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1393 /* Generate code to store zero in X. */
1399 emit_move_insn (x, const0_rtx);
1402 /* Generate code to store 1 in X
1403 assuming it contains zero beforehand. */
1406 emit_0_to_1_insn (x)
1409 emit_move_insn (x, const1_rtx);
1412 /* Generate code to compare X with Y
1413 so that the condition codes are set.
1415 MODE is the mode of the inputs (in case they are const_int).
1416 UNSIGNEDP nonzero says that X and Y are unsigned;
1417 this matters if they need to be widened.
1419 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1420 and ALIGN specifies the known shared alignment of X and Y.
1422 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1423 It is ignored for fixed-point and block comparisons;
1424 it is used only for floating-point comparisons. */
1427 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1429 enum rtx_code comparison;
1431 enum machine_mode mode;
1435 enum mode_class class;
1436 enum machine_mode wider_mode;
1438 class = GET_MODE_CLASS (mode);
1440 /* They could both be VOIDmode if both args are immediate constants,
1441 but we should fold that at an earlier stage.
1442 With no special code here, this will call abort,
1443 reminding the programmer to implement such folding. */
1445 if (mode != BLKmode && flag_force_mem)
1447 x = force_not_mem (x);
1448 y = force_not_mem (y);
1451 /* If we are inside an appropriately-short loop and one operand is an
1452 expensive constant, force it into a register. */
1453 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x) > 2)
1454 x = force_reg (mode, x);
1456 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y) > 2)
1457 y = force_reg (mode, y);
1459 /* Don't let both operands fail to indicate the mode. */
1460 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1461 x = force_reg (mode, x);
1463 /* Handle all BLKmode compares. */
1465 if (mode == BLKmode)
1468 x = protect_from_queue (x, 0);
1469 y = protect_from_queue (y, 0);
1473 #ifdef HAVE_cmpstrqi
1475 && GET_CODE (size) == CONST_INT
1476 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1478 enum machine_mode result_mode
1479 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1480 rtx result = gen_reg_rtx (result_mode);
1481 emit_insn (gen_cmpstrqi (result, x, y, size,
1482 gen_rtx (CONST_INT, VOIDmode, align)));
1483 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1487 #ifdef HAVE_cmpstrhi
1489 && GET_CODE (size) == CONST_INT
1490 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1492 enum machine_mode result_mode
1493 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1494 rtx result = gen_reg_rtx (result_mode);
1495 emit_insn (gen_cmpstrhi (result, x, y, size,
1496 gen_rtx (CONST_INT, VOIDmode, align)));
1497 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1501 #ifdef HAVE_cmpstrsi
1504 enum machine_mode result_mode
1505 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1506 rtx result = gen_reg_rtx (result_mode);
1507 emit_insn (gen_cmpstrsi (result, x, y,
1508 convert_to_mode (SImode, size, 1),
1509 gen_rtx (CONST_INT, VOIDmode, align)));
1510 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1515 #ifdef TARGET_MEM_FUNCTIONS
1516 emit_library_call (memcmp_libfunc, 1,
1517 TYPE_MODE (integer_type_node), 3,
1518 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1521 emit_library_call (bcmp_libfunc, 1,
1522 TYPE_MODE (integer_type_node), 3,
1523 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1526 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1527 const0_rtx, comparison, 0,
1528 TYPE_MODE (integer_type_node), 0, 0);
1533 /* Handle some compares against zero. */
1535 if (y == CONST0_RTX (mode)
1536 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1538 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1541 x = protect_from_queue (x, 0);
1542 y = protect_from_queue (y, 0);
1544 /* Now, if insn does accept these operands, put them into pseudos. */
1545 if (! (*insn_operand_predicate[icode][0])
1546 (x, insn_operand_mode[icode][0]))
1547 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1549 emit_insn (GEN_FCN (icode) (x));
1553 /* Handle compares for which there is a directly suitable insn. */
1555 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1557 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1560 x = protect_from_queue (x, 0);
1561 y = protect_from_queue (y, 0);
1563 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1564 if (! (*insn_operand_predicate[icode][0])
1565 (x, insn_operand_mode[icode][0]))
1566 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1568 if (! (*insn_operand_predicate[icode][1])
1569 (y, insn_operand_mode[icode][1]))
1570 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1572 emit_insn (GEN_FCN (icode) (x, y));
1576 /* Try widening if we can find a direct insn that way. */
1578 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1580 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1581 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1583 if (cmp_optab->handlers[(int) wider_mode].insn_code
1584 != CODE_FOR_nothing)
1586 x = convert_to_mode (wider_mode, x, unsignedp);
1587 y = convert_to_mode (wider_mode, y, unsignedp);
1588 emit_cmp_insn (x, y, comparison, 0,
1589 wider_mode, unsignedp, align);
1595 /* Handle a lib call just for the mode we are using. */
1597 if (cmp_optab->handlers[(int) mode].libfunc
1598 && class != MODE_FLOAT)
1600 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1601 /* If we want unsigned, and this mode has a distinct unsigned
1602 comparison routine, use that. */
1603 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1604 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1606 emit_library_call (libfunc, 1,
1607 SImode, 2, x, mode, y, mode);
1609 /* Integer comparison returns a result that must be compared against 1,
1610 so that even if we do an unsigned compare afterward,
1611 there is still a value that can represent the result "less than". */
1613 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1614 comparison, 0, SImode, unsignedp, 0);
1618 if (class == MODE_FLOAT)
1619 emit_float_lib_cmp (x, y, comparison);
1625 /* Nonzero if a compare of mode MODE can be done straightforwardly
1626 (without splitting it into pieces). */
1629 can_compare_p (mode)
1630 enum machine_mode mode;
1634 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1636 mode = GET_MODE_WIDER_MODE (mode);
1637 } while (mode != VOIDmode);
1642 /* Emit a library call comparison between floating point X and Y.
1643 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1646 emit_float_lib_cmp (x, y, comparison)
1648 enum rtx_code comparison;
1650 enum machine_mode mode = GET_MODE (x);
1657 libfunc = eqsf2_libfunc;
1661 libfunc = nesf2_libfunc;
1665 libfunc = gtsf2_libfunc;
1669 libfunc = gesf2_libfunc;
1673 libfunc = ltsf2_libfunc;
1677 libfunc = lesf2_libfunc;
1680 else if (mode == DFmode)
1684 libfunc = eqdf2_libfunc;
1688 libfunc = nedf2_libfunc;
1692 libfunc = gtdf2_libfunc;
1696 libfunc = gedf2_libfunc;
1700 libfunc = ltdf2_libfunc;
1704 libfunc = ledf2_libfunc;
1709 enum machine_mode wider_mode;
1711 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1712 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1714 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1715 != CODE_FOR_nothing)
1716 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1718 x = convert_to_mode (wider_mode, x, 0);
1719 y = convert_to_mode (wider_mode, y, 0);
1720 emit_float_lib_cmp (x, y, comparison);
1727 emit_library_call (libfunc, 1,
1728 SImode, 2, x, mode, y, mode);
1730 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1734 /* Generate code to indirectly jump to a location given in the rtx LOC. */
1737 emit_indirect_jump (loc)
1740 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1742 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1745 emit_jump_insn (gen_indirect_jump (loc));
1748 /* These three functions generate an insn body and return it
1749 rather than emitting the insn.
1751 They do not protect from queued increments,
1752 because they may be used 1) in protect_from_queue itself
1753 and 2) in other passes where there is no queue. */
1755 /* Generate and return an insn body to add Y to X. */
1758 gen_add2_insn (x, y)
1761 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1763 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1764 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1765 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1768 return (GEN_FCN (icode) (x, x, y));
1772 have_add2_insn (mode)
1773 enum machine_mode mode;
1775 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1778 /* Generate and return an insn body to subtract Y from X. */
1781 gen_sub2_insn (x, y)
1784 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
1786 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1787 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1788 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1791 return (GEN_FCN (icode) (x, x, y));
1795 have_sub2_insn (mode)
1796 enum machine_mode mode;
1798 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1801 /* Generate the body of an instruction to copy Y into X. */
1804 gen_move_insn (x, y)
1807 register enum machine_mode mode = GET_MODE (x);
1808 enum insn_code insn_code;
1810 if (mode == VOIDmode)
1811 mode = GET_MODE (y);
1813 insn_code = mov_optab->handlers[(int) mode].insn_code;
1815 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
1816 find a mode to do it in. If we have a movcc, use it. Otherwise,
1817 find the MODE_INT mode of the same width. */
1819 if (insn_code == CODE_FOR_nothing)
1821 enum machine_mode tmode = VOIDmode;
1824 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
1825 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
1827 else if (GET_MODE_CLASS (mode) == MODE_CC)
1828 for (tmode = QImode; tmode != VOIDmode;
1829 tmode = GET_MODE_WIDER_MODE (tmode))
1830 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
1833 if (tmode == VOIDmode)
1836 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
1837 may call change_address which is not appropriate if we were
1838 called when a reload was in progress. We don't have to worry
1839 about changing the address since the size in bytes is supposed to
1840 be the same. Copy the MEM to change the mode and move any
1841 substitutions from the old MEM to the new one. */
1843 if (reload_in_progress)
1845 x = gen_lowpart_common (tmode, x1);
1846 if (x == 0 && GET_CODE (x1) == MEM)
1848 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
1849 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
1850 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
1851 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
1852 copy_replacements (x1, x);
1855 y = gen_lowpart_common (tmode, y1);
1856 if (y == 0 && GET_CODE (y1) == MEM)
1858 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
1859 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
1860 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
1861 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
1862 copy_replacements (y1, y);
1867 x = gen_lowpart (tmode, x);
1868 y = gen_lowpart (tmode, y);
1871 insn_code = mov_optab->handlers[(int) tmode].insn_code;
1874 return (GEN_FCN (insn_code) (x, y));
1877 /* Tables of patterns for extending one integer mode to another. */
1878 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
1880 /* Return the insn code used to extend FROM_MODE to TO_MODE.
1881 UNSIGNEDP specifies zero-extension instead of sign-extension. If
1882 no such operation exists, CODE_FOR_nothing will be returned. */
1885 can_extend_p (to_mode, from_mode, unsignedp)
1886 enum machine_mode to_mode, from_mode;
1889 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
1892 /* Generate the body of an insn to extend Y (with mode MFROM)
1893 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
1896 gen_extend_insn (x, y, mto, mfrom, unsignedp)
1898 enum machine_mode mto, mfrom;
1901 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
1909 for (p = extendtab[0][0];
1910 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
1912 *p = CODE_FOR_nothing;
1914 #ifdef HAVE_extendditi2
1915 if (HAVE_extendditi2)
1916 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
1918 #ifdef HAVE_extendsiti2
1919 if (HAVE_extendsiti2)
1920 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
1922 #ifdef HAVE_extendhiti2
1923 if (HAVE_extendhiti2)
1924 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
1926 #ifdef HAVE_extendqiti2
1927 if (HAVE_extendqiti2)
1928 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
1930 #ifdef HAVE_extendsidi2
1931 if (HAVE_extendsidi2)
1932 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
1934 #ifdef HAVE_extendhidi2
1935 if (HAVE_extendhidi2)
1936 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
1938 #ifdef HAVE_extendqidi2
1939 if (HAVE_extendqidi2)
1940 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
1942 #ifdef HAVE_extendhisi2
1943 if (HAVE_extendhisi2)
1944 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
1946 #ifdef HAVE_extendqisi2
1947 if (HAVE_extendqisi2)
1948 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
1950 #ifdef HAVE_extendqihi2
1951 if (HAVE_extendqihi2)
1952 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
1955 #ifdef HAVE_zero_extendditi2
1956 if (HAVE_zero_extendsiti2)
1957 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
1959 #ifdef HAVE_zero_extendsiti2
1960 if (HAVE_zero_extendsiti2)
1961 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
1963 #ifdef HAVE_zero_extendhiti2
1964 if (HAVE_zero_extendhiti2)
1965 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
1967 #ifdef HAVE_zero_extendqiti2
1968 if (HAVE_zero_extendqiti2)
1969 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
1971 #ifdef HAVE_zero_extendsidi2
1972 if (HAVE_zero_extendsidi2)
1973 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
1975 #ifdef HAVE_zero_extendhidi2
1976 if (HAVE_zero_extendhidi2)
1977 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
1979 #ifdef HAVE_zero_extendqidi2
1980 if (HAVE_zero_extendqidi2)
1981 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
1983 #ifdef HAVE_zero_extendhisi2
1984 if (HAVE_zero_extendhisi2)
1985 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
1987 #ifdef HAVE_zero_extendqisi2
1988 if (HAVE_zero_extendqisi2)
1989 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
1991 #ifdef HAVE_zero_extendqihi2
1992 if (HAVE_zero_extendqihi2)
1993 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
1997 /* can_fix_p and can_float_p say whether the target machine
1998 can directly convert a given fixed point type to
1999 a given floating point type, or vice versa.
2000 The returned value is the CODE_FOR_... value to use,
2001 or CODE_FOR_nothing if these modes cannot be directly converted. */
2003 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2004 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2005 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
2007 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2008 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2010 static enum insn_code
2011 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2012 enum machine_mode fltmode, fixmode;
2017 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2018 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2020 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2023 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2025 return CODE_FOR_nothing;
2028 static enum insn_code
2029 can_float_p (fltmode, fixmode, unsignedp)
2030 enum machine_mode fixmode, fltmode;
2033 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2040 for (p = fixtab[0][0];
2041 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2043 *p = CODE_FOR_nothing;
2044 for (p = fixtrunctab[0][0];
2045 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2047 *p = CODE_FOR_nothing;
2049 #ifdef HAVE_fixsfqi2
2051 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2053 #ifdef HAVE_fixsfhi2
2055 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2057 #ifdef HAVE_fixsfsi2
2059 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2061 #ifdef HAVE_fixsfdi2
2063 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2066 #ifdef HAVE_fixdfqi2
2068 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2070 #ifdef HAVE_fixdfhi2
2072 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2074 #ifdef HAVE_fixdfsi2
2076 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2078 #ifdef HAVE_fixdfdi2
2080 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2082 #ifdef HAVE_fixdfti2
2084 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2087 #ifdef HAVE_fixtfqi2
2089 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2091 #ifdef HAVE_fixtfhi2
2093 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2095 #ifdef HAVE_fixtfsi2
2097 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2099 #ifdef HAVE_fixtfdi2
2101 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2103 #ifdef HAVE_fixtfti2
2105 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2108 #ifdef HAVE_fixunssfqi2
2109 if (HAVE_fixunssfqi2)
2110 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2112 #ifdef HAVE_fixunssfhi2
2113 if (HAVE_fixunssfhi2)
2114 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2116 #ifdef HAVE_fixunssfsi2
2117 if (HAVE_fixunssfsi2)
2118 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2120 #ifdef HAVE_fixunssfdi2
2121 if (HAVE_fixunssfdi2)
2122 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2125 #ifdef HAVE_fixunsdfqi2
2126 if (HAVE_fixunsdfqi2)
2127 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2129 #ifdef HAVE_fixunsdfhi2
2130 if (HAVE_fixunsdfhi2)
2131 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2133 #ifdef HAVE_fixunsdfsi2
2134 if (HAVE_fixunsdfsi2)
2135 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2137 #ifdef HAVE_fixunsdfdi2
2138 if (HAVE_fixunsdfdi2)
2139 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2141 #ifdef HAVE_fixunsdfti2
2142 if (HAVE_fixunsdfti2)
2143 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2146 #ifdef HAVE_fixunstfqi2
2147 if (HAVE_fixunstfqi2)
2148 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2150 #ifdef HAVE_fixunstfhi2
2151 if (HAVE_fixunstfhi2)
2152 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2154 #ifdef HAVE_fixunstfsi2
2155 if (HAVE_fixunstfsi2)
2156 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2158 #ifdef HAVE_fixunstfdi2
2159 if (HAVE_fixunstfdi2)
2160 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2162 #ifdef HAVE_fixunstfti2
2163 if (HAVE_fixunstfti2)
2164 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2167 #ifdef HAVE_fix_truncsfqi2
2168 if (HAVE_fix_truncsfqi2)
2169 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2171 #ifdef HAVE_fix_truncsfhi2
2172 if (HAVE_fix_truncsfhi2)
2173 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2175 #ifdef HAVE_fix_truncsfsi2
2176 if (HAVE_fix_truncsfsi2)
2177 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2179 #ifdef HAVE_fix_truncsfdi2
2180 if (HAVE_fix_truncsfdi2)
2181 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2184 #ifdef HAVE_fix_truncdfqi2
2185 if (HAVE_fix_truncdfsi2)
2186 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2188 #ifdef HAVE_fix_truncdfhi2
2189 if (HAVE_fix_truncdfhi2)
2190 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2192 #ifdef HAVE_fix_truncdfsi2
2193 if (HAVE_fix_truncdfsi2)
2194 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2196 #ifdef HAVE_fix_truncdfdi2
2197 if (HAVE_fix_truncdfdi2)
2198 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2200 #ifdef HAVE_fix_truncdfti2
2201 if (HAVE_fix_truncdfti2)
2202 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2205 #ifdef HAVE_fix_trunctfqi2
2206 if (HAVE_fix_trunctfqi2)
2207 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2209 #ifdef HAVE_fix_trunctfhi2
2210 if (HAVE_fix_trunctfhi2)
2211 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2213 #ifdef HAVE_fix_trunctfsi2
2214 if (HAVE_fix_trunctfsi2)
2215 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2217 #ifdef HAVE_fix_trunctfdi2
2218 if (HAVE_fix_trunctfdi2)
2219 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2221 #ifdef HAVE_fix_trunctfti2
2222 if (HAVE_fix_trunctfti2)
2223 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2226 #ifdef HAVE_fixuns_truncsfqi2
2227 if (HAVE_fixuns_truncsfqi2)
2228 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2230 #ifdef HAVE_fixuns_truncsfhi2
2231 if (HAVE_fixuns_truncsfhi2)
2232 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2234 #ifdef HAVE_fixuns_truncsfsi2
2235 if (HAVE_fixuns_truncsfsi2)
2236 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2238 #ifdef HAVE_fixuns_truncsfdi2
2239 if (HAVE_fixuns_truncsfdi2)
2240 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2243 #ifdef HAVE_fixuns_truncdfqi2
2244 if (HAVE_fixuns_truncdfqi2)
2245 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2247 #ifdef HAVE_fixuns_truncdfhi2
2248 if (HAVE_fixuns_truncdfhi2)
2249 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2251 #ifdef HAVE_fixuns_truncdfsi2
2252 if (HAVE_fixuns_truncdfsi2)
2253 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2255 #ifdef HAVE_fixuns_truncdfdi2
2256 if (HAVE_fixuns_truncdfdi2)
2257 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2259 #ifdef HAVE_fixuns_truncdfti2
2260 if (HAVE_fixuns_truncdfti2)
2261 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2264 #ifdef HAVE_fixuns_trunctfqi2
2265 if (HAVE_fixuns_trunctfqi2)
2266 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2268 #ifdef HAVE_fixuns_trunctfhi2
2269 if (HAVE_fixuns_trunctfhi2)
2270 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2272 #ifdef HAVE_fixuns_trunctfsi2
2273 if (HAVE_fixuns_trunctfsi2)
2274 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2276 #ifdef HAVE_fixuns_trunctfdi2
2277 if (HAVE_fixuns_trunctfdi2)
2278 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2280 #ifdef HAVE_fixuns_trunctfti2
2281 if (HAVE_fixuns_trunctfti2)
2282 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2285 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2286 /* This flag says the same insns that convert to a signed fixnum
2287 also convert validly to an unsigned one. */
2291 for (i = 0; i < NUM_MACHINE_MODES; i++)
2292 for (j = 0; j < NUM_MACHINE_MODES; j++)
2293 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2302 for (p = floattab[0][0];
2303 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2305 *p = CODE_FOR_nothing;
2307 #ifdef HAVE_floatqisf2
2308 if (HAVE_floatqisf2)
2309 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2311 #ifdef HAVE_floathisf2
2312 if (HAVE_floathisf2)
2313 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2315 #ifdef HAVE_floatsisf2
2316 if (HAVE_floatsisf2)
2317 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2319 #ifdef HAVE_floatdisf2
2320 if (HAVE_floatdisf2)
2321 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2323 #ifdef HAVE_floattisf2
2324 if (HAVE_floattisf2)
2325 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2328 #ifdef HAVE_floatqidf2
2329 if (HAVE_floatqidf2)
2330 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2332 #ifdef HAVE_floathidf2
2333 if (HAVE_floathidf2)
2334 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2336 #ifdef HAVE_floatsidf2
2337 if (HAVE_floatsidf2)
2338 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2340 #ifdef HAVE_floatdidf2
2341 if (HAVE_floatdidf2)
2342 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2344 #ifdef HAVE_floattidf2
2345 if (HAVE_floattidf2)
2346 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2349 #ifdef HAVE_floatqitf2
2350 if (HAVE_floatqitf2)
2351 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2353 #ifdef HAVE_floathitf2
2354 if (HAVE_floathitf2)
2355 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2357 #ifdef HAVE_floatsitf2
2358 if (HAVE_floatsitf2)
2359 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2361 #ifdef HAVE_floatditf2
2362 if (HAVE_floatditf2)
2363 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2365 #ifdef HAVE_floattitf2
2366 if (HAVE_floattitf2)
2367 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2370 #ifdef HAVE_floatunsqisf2
2371 if (HAVE_floatunsqisf2)
2372 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2374 #ifdef HAVE_floatunshisf2
2375 if (HAVE_floatunshisf2)
2376 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2378 #ifdef HAVE_floatunssisf2
2379 if (HAVE_floatunssisf2)
2380 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2382 #ifdef HAVE_floatunsdisf2
2383 if (HAVE_floatunsdisf2)
2384 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2386 #ifdef HAVE_floatunstisf2
2387 if (HAVE_floatunstisf2)
2388 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2391 #ifdef HAVE_floatunsqidf2
2392 if (HAVE_floatunsqidf2)
2393 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2395 #ifdef HAVE_floatunshidf2
2396 if (HAVE_floatunshidf2)
2397 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2399 #ifdef HAVE_floatunssidf2
2400 if (HAVE_floatunssidf2)
2401 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2403 #ifdef HAVE_floatunsdidf2
2404 if (HAVE_floatunsdidf2)
2405 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2407 #ifdef HAVE_floatunstidf2
2408 if (HAVE_floatunstidf2)
2409 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2412 #ifdef HAVE_floatunsqitf2
2413 if (HAVE_floatunsqitf2)
2414 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2416 #ifdef HAVE_floatunshitf2
2417 if (HAVE_floatunshitf2)
2418 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2420 #ifdef HAVE_floatunssitf2
2421 if (HAVE_floatunssitf2)
2422 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2424 #ifdef HAVE_floatunsditf2
2425 if (HAVE_floatunsditf2)
2426 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2428 #ifdef HAVE_floatunstitf2
2429 if (HAVE_floatunstitf2)
2430 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2434 /* Generate code to convert FROM to floating point
2435 and store in TO. FROM must be fixed point and not VOIDmode.
2436 UNSIGNEDP nonzero means regard FROM as unsigned.
2437 Normally this is done by correcting the final value
2438 if it is negative. */
2441 expand_float (to, from, unsignedp)
2445 enum insn_code icode;
2446 register rtx target = to;
2447 enum machine_mode fmode, imode;
2449 /* Crash now, because we won't be able to decide which mode to use. */
2450 if (GET_MODE (from) == VOIDmode)
2453 /* Look for an insn to do the conversion. Do it in the specified
2454 modes if possible; otherwise convert either input, output or both to
2455 wider mode. If the integer mode is wider than the mode of FROM,
2456 we can do the conversion signed even if the input is unsigned. */
2458 for (imode = GET_MODE (from); imode != VOIDmode;
2459 imode = GET_MODE_WIDER_MODE (imode))
2460 for (fmode = GET_MODE (to); fmode != VOIDmode;
2461 fmode = GET_MODE_WIDER_MODE (fmode))
2463 int doing_unsigned = unsignedp;
2465 icode = can_float_p (fmode, imode, unsignedp);
2466 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2467 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2469 if (icode != CODE_FOR_nothing)
2471 to = protect_from_queue (to, 1);
2473 if (imode != GET_MODE (from))
2474 from = convert_to_mode (imode, from, unsignedp);
2476 from = protect_from_queue (from, 0);
2478 if (fmode != GET_MODE (to))
2479 target = gen_reg_rtx (fmode);
2481 emit_unop_insn (icode, target, from,
2482 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2485 convert_move (to, target, 0);
2490 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2492 /* Unsigned integer, and no way to convert directly.
2493 Convert as signed, then conditionally adjust the result. */
2496 rtx label = gen_label_rtx ();
2498 REAL_VALUE_TYPE offset;
2502 to = protect_from_queue (to, 1);
2503 from = protect_from_queue (from, 0);
2506 from = force_not_mem (from);
2508 /* If we are about to do some arithmetic to correct for an
2509 unsigned operand, do it in a pseudo-register. */
2511 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2512 target = gen_reg_rtx (GET_MODE (to));
2514 /* Convert as signed integer to floating. */
2515 expand_float (target, from, 0);
2517 /* If FROM is negative (and therefore TO is negative),
2518 correct its value by 2**bitwidth. */
2520 do_pending_stack_adjust ();
2521 emit_cmp_insn (from, const0_rtx, GE, 0, GET_MODE (from), 0, 0);
2522 emit_jump_insn (gen_bge (label));
2523 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2524 Rather than setting up a dconst_dot_5, let's hope SCO
2526 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2527 temp = expand_binop (GET_MODE (to), add_optab, target,
2528 immed_real_const_1 (offset, GET_MODE (to)),
2529 target, 0, OPTAB_LIB_WIDEN);
2531 emit_move_insn (target, temp);
2532 do_pending_stack_adjust ();
2538 /* No hardware instruction available; call a library
2539 to convert from SImode or DImode into SFmode or DFmode. */
2544 to = protect_from_queue (to, 1);
2546 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2547 from = convert_to_mode (SImode, from, unsignedp);
2549 from = protect_from_queue (from, 0);
2552 from = force_not_mem (from);
2554 if (GET_MODE (to) == SFmode)
2556 if (GET_MODE (from) == SImode)
2557 libfcn = floatsisf_libfunc;
2558 else if (GET_MODE (from) == DImode)
2559 libfcn = floatdisf_libfunc;
2563 else if (GET_MODE (to) == DFmode)
2565 if (GET_MODE (from) == SImode)
2566 libfcn = floatsidf_libfunc;
2567 else if (GET_MODE (from) == DImode)
2568 libfcn = floatdidf_libfunc;
2577 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2578 insns = get_insns ();
2581 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2582 gen_rtx (FLOAT, GET_MODE (to), from));
2585 /* Copy result to requested destination
2586 if we have been computing in a temp location. */
2590 if (GET_MODE (target) == GET_MODE (to))
2591 emit_move_insn (to, target);
2593 convert_move (to, target, 0);
2597 /* expand_fix: generate code to convert FROM to fixed point
2598 and store in TO. FROM must be floating point. */
2604 rtx temp = gen_reg_rtx (GET_MODE (x));
2605 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2609 expand_fix (to, from, unsignedp)
2610 register rtx to, from;
2613 enum insn_code icode;
2614 register rtx target = to;
2615 enum machine_mode fmode, imode;
2619 /* We first try to find a pair of modes, one real and one integer, at
2620 least as wide as FROM and TO, respectively, in which we can open-code
2621 this conversion. If the integer mode is wider than the mode of TO,
2622 we can do the conversion either signed or unsigned. */
2624 for (imode = GET_MODE (to); imode != VOIDmode;
2625 imode = GET_MODE_WIDER_MODE (imode))
2626 for (fmode = GET_MODE (from); fmode != VOIDmode;
2627 fmode = GET_MODE_WIDER_MODE (fmode))
2629 int doing_unsigned = unsignedp;
2631 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2632 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2633 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
2635 if (icode != CODE_FOR_nothing)
2637 to = protect_from_queue (to, 1);
2639 if (fmode != GET_MODE (from))
2640 from = convert_to_mode (fmode, from, 0);
2642 from = protect_from_queue (from, 0);
2645 from = ftruncify (from);
2647 if (imode != GET_MODE (to))
2648 target = gen_reg_rtx (imode);
2650 emit_unop_insn (icode, target, from,
2651 doing_unsigned ? UNSIGNED_FIX : FIX);
2653 convert_move (to, target, unsignedp);
2658 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2659 /* For an unsigned conversion, there is one more way to do it.
2660 If we have a signed conversion, we generate code that compares
2661 the real value to the largest representable positive number. If if
2662 is smaller, the conversion is done normally. Otherwise, subtract
2663 one plus the highest signed number, convert, and add it back.
2665 We only need to check all real modes, since we know we didn't find
2666 anything with a wider inetger mode. */
2668 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT)
2669 for (fmode = GET_MODE (from); fmode != VOIDmode;
2670 fmode = GET_MODE_WIDER_MODE (fmode))
2671 /* Make sure we won't lose significant bits doing this. */
2672 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
2673 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
2676 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
2677 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
2678 rtx limit = immed_real_const_1 (offset, fmode);
2679 rtx lab1 = gen_label_rtx ();
2680 rtx lab2 = gen_label_rtx ();
2684 to = protect_from_queue (to, 1);
2685 from = protect_from_queue (from, 0);
2688 from = force_not_mem (from);
2690 if (fmode != GET_MODE (from))
2691 from = convert_to_mode (fmode, from, 0);
2693 /* See if we need to do the subtraction. */
2694 do_pending_stack_adjust ();
2695 emit_cmp_insn (from, limit, GE, 0, GET_MODE (from), 0, 0);
2696 emit_jump_insn (gen_bge (lab1));
2698 /* If not, do the signed "fix" and branch around fixup code. */
2699 expand_fix (to, from, 0);
2700 emit_jump_insn (gen_jump (lab2));
2703 /* Otherwise, subtract 2**(N-1), convert to signed number,
2704 then add 2**(N-1). Do the addition using XOR since this
2705 will often generate better code. */
2707 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
2708 0, 0, OPTAB_LIB_WIDEN);
2709 expand_fix (to, target, 0);
2710 target = expand_binop (GET_MODE (to), xor_optab, to,
2711 gen_rtx (CONST_INT, VOIDmode,
2712 1 << (bitsize - 1)),
2713 to, 1, OPTAB_LIB_WIDEN);
2716 emit_move_insn (to, target);
2720 /* Make a place for a REG_NOTE and add it. */
2721 insn = emit_move_insn (to, to);
2722 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
2723 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
2724 from), REG_NOTES (insn));
2730 /* We can't do it with an insn, so use a library call. But first ensure
2731 that the mode of TO is at least as wide as SImode, since those are the
2732 only library calls we know about. */
2734 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
2736 target = gen_reg_rtx (SImode);
2738 expand_fix (target, from, unsignedp);
2740 else if (GET_MODE (from) == SFmode)
2742 if (GET_MODE (to) == SImode)
2743 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
2744 else if (GET_MODE (to) == DImode)
2745 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
2749 else if (GET_MODE (from) == DFmode)
2751 if (GET_MODE (to) == SImode)
2752 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
2753 else if (GET_MODE (to) == DImode)
2754 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
2765 to = protect_from_queue (to, 1);
2766 from = protect_from_queue (from, 0);
2769 from = force_not_mem (from);
2773 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2774 insns = get_insns ();
2777 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2778 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
2779 GET_MODE (to), from));
2782 if (GET_MODE (to) == GET_MODE (target))
2783 emit_move_insn (to, target);
2785 convert_move (to, target, 0);
2793 optab op = (optab) xmalloc (sizeof (struct optab));
2795 for (i = 0; i < NUM_MACHINE_MODES; i++)
2797 op->handlers[i].insn_code = CODE_FOR_nothing;
2798 op->handlers[i].libfunc = 0;
2803 /* Call this once to initialize the contents of the optabs
2804 appropriately for the current target machine. */
2815 add_optab = init_optab (PLUS);
2816 sub_optab = init_optab (MINUS);
2817 smul_optab = init_optab (MULT);
2818 smul_widen_optab = init_optab (UNKNOWN);
2819 umul_widen_optab = init_optab (UNKNOWN);
2820 sdiv_optab = init_optab (DIV);
2821 sdivmod_optab = init_optab (UNKNOWN);
2822 udiv_optab = init_optab (UDIV);
2823 udivmod_optab = init_optab (UNKNOWN);
2824 smod_optab = init_optab (MOD);
2825 umod_optab = init_optab (UMOD);
2826 flodiv_optab = init_optab (DIV);
2827 ftrunc_optab = init_optab (UNKNOWN);
2828 and_optab = init_optab (AND);
2829 ior_optab = init_optab (IOR);
2830 xor_optab = init_optab (XOR);
2831 ashl_optab = init_optab (ASHIFT);
2832 ashr_optab = init_optab (ASHIFTRT);
2833 lshl_optab = init_optab (LSHIFT);
2834 lshr_optab = init_optab (LSHIFTRT);
2835 rotl_optab = init_optab (ROTATE);
2836 rotr_optab = init_optab (ROTATERT);
2837 smin_optab = init_optab (SMIN);
2838 smax_optab = init_optab (SMAX);
2839 umin_optab = init_optab (UMIN);
2840 umax_optab = init_optab (UMAX);
2841 mov_optab = init_optab (UNKNOWN);
2842 movstrict_optab = init_optab (UNKNOWN);
2843 cmp_optab = init_optab (UNKNOWN);
2844 ucmp_optab = init_optab (UNKNOWN);
2845 tst_optab = init_optab (UNKNOWN);
2846 neg_optab = init_optab (NEG);
2847 abs_optab = init_optab (ABS);
2848 one_cmpl_optab = init_optab (NOT);
2849 ffs_optab = init_optab (FFS);
2850 sqrt_optab = init_optab (SQRT);
2851 strlen_optab = init_optab (UNKNOWN);
2855 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
2859 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
2863 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
2867 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
2871 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
2875 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
2879 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
2883 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
2887 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
2889 add_optab->handlers[(int) SFmode].libfunc
2890 = gen_rtx (SYMBOL_REF, Pmode, "__addsf3");
2891 add_optab->handlers[(int) DFmode].libfunc
2892 = gen_rtx (SYMBOL_REF, Pmode, "__adddf3");
2896 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
2900 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
2904 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
2908 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
2912 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
2916 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
2920 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
2924 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
2928 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
2930 sub_optab->handlers[(int) SFmode].libfunc
2931 = gen_rtx (SYMBOL_REF, Pmode, "__subsf3");
2932 sub_optab->handlers[(int) DFmode].libfunc
2933 = gen_rtx (SYMBOL_REF, Pmode, "__subdf3");
2937 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
2941 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
2945 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
2949 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
2953 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
2957 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
2961 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
2965 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
2969 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
2972 #ifdef MULSI3_LIBCALL
2973 smul_optab->handlers[(int) SImode].libfunc
2974 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
2976 smul_optab->handlers[(int) SImode].libfunc
2977 = gen_rtx (SYMBOL_REF, Pmode, "__mulsi3");
2979 #ifdef MULDI3_LIBCALL
2980 smul_optab->handlers[(int) DImode].libfunc
2981 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
2983 smul_optab->handlers[(int) DImode].libfunc
2984 = gen_rtx (SYMBOL_REF, Pmode, "__muldi3");
2986 smul_optab->handlers[(int) SFmode].libfunc
2987 = gen_rtx (SYMBOL_REF, Pmode, "__mulsf3");
2988 smul_optab->handlers[(int) DFmode].libfunc
2989 = gen_rtx (SYMBOL_REF, Pmode, "__muldf3");
2991 #ifdef HAVE_mulqihi3
2993 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
2995 #ifdef HAVE_mulhisi3
2997 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
2999 #ifdef HAVE_mulsidi3
3001 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
3003 #ifdef HAVE_mulditi3
3005 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
3008 #ifdef HAVE_umulqihi3
3010 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
3012 #ifdef HAVE_umulhisi3
3014 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3016 #ifdef HAVE_umulsidi3
3018 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3020 #ifdef HAVE_umulditi3
3022 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3027 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3031 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3035 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3039 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3043 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3047 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3050 #ifdef DIVSI3_LIBCALL
3051 sdiv_optab->handlers[(int) SImode].libfunc
3052 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3054 sdiv_optab->handlers[(int) SImode].libfunc
3055 = gen_rtx (SYMBOL_REF, Pmode, "__divsi3");
3057 #ifdef DIVDI3_LIBCALL
3058 sdiv_optab->handlers[(int) DImode].libfunc
3059 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3061 sdiv_optab->handlers[(int) DImode].libfunc
3062 = gen_rtx (SYMBOL_REF, Pmode, "__divdi3");
3067 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3071 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3073 #ifdef HAVE_udivpsi3
3075 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3079 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3083 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3087 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3090 #ifdef UDIVSI3_LIBCALL
3091 udiv_optab->handlers[(int) SImode].libfunc
3092 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3094 udiv_optab->handlers[(int) SImode].libfunc
3095 = gen_rtx (SYMBOL_REF, Pmode, "__udivsi3");
3097 #ifdef UDIVDI3_LIBCALL
3098 udiv_optab->handlers[(int) DImode].libfunc
3099 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3101 udiv_optab->handlers[(int) DImode].libfunc
3102 = gen_rtx (SYMBOL_REF, Pmode, "__udivdi3");
3105 #ifdef HAVE_divmodqi4
3107 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3109 #ifdef HAVE_divmodhi4
3111 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3113 #ifdef HAVE_divmodsi4
3115 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3117 #ifdef HAVE_divmoddi4
3119 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3121 #ifdef HAVE_divmodti4
3123 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3126 #ifdef HAVE_udivmodqi4
3127 if (HAVE_udivmodqi4)
3128 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3130 #ifdef HAVE_udivmodhi4
3131 if (HAVE_udivmodhi4)
3132 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3134 #ifdef HAVE_udivmodsi4
3135 if (HAVE_udivmodsi4)
3136 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3138 #ifdef HAVE_udivmoddi4
3139 if (HAVE_udivmoddi4)
3140 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3142 #ifdef HAVE_udivmodti4
3143 if (HAVE_udivmodti4)
3144 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3149 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3153 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3157 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3161 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3165 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3169 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3172 #ifdef MODSI3_LIBCALL
3173 smod_optab->handlers[(int) SImode].libfunc
3174 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3176 smod_optab->handlers[(int) SImode].libfunc
3177 = gen_rtx (SYMBOL_REF, Pmode, "__modsi3");
3179 #ifdef MODDI3_LIBCALL
3180 smod_optab->handlers[(int) DImode].libfunc
3181 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3183 smod_optab->handlers[(int) DImode].libfunc
3184 = gen_rtx (SYMBOL_REF, Pmode, "__moddi3");
3189 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3193 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3195 #ifdef HAVE_umodpsi3
3197 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3201 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3205 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3209 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3212 #ifdef UMODSI3_LIBCALL
3213 umod_optab->handlers[(int) SImode].libfunc
3214 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3216 umod_optab->handlers[(int) SImode].libfunc
3217 = gen_rtx (SYMBOL_REF, Pmode, "__umodsi3");
3219 #ifdef UMODDI3_LIBCALL
3220 umod_optab->handlers[(int) DImode].libfunc
3221 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3223 umod_optab->handlers[(int) DImode].libfunc
3224 = gen_rtx (SYMBOL_REF, Pmode, "__umoddi3");
3229 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3233 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3237 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3239 flodiv_optab->handlers[(int) SFmode].libfunc
3240 = gen_rtx (SYMBOL_REF, Pmode, "__divsf3");
3241 flodiv_optab->handlers[(int) DFmode].libfunc
3242 = gen_rtx (SYMBOL_REF, Pmode, "__divdf3");
3244 #ifdef HAVE_ftruncsf2
3246 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3248 #ifdef HAVE_ftruncdf2
3250 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3252 #ifdef HAVE_ftrunctf2
3254 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3259 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3263 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3267 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3271 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3275 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3279 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3284 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3288 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3292 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3296 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3300 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3304 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3309 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3313 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3317 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3321 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3325 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3329 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3334 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3338 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3340 #ifdef HAVE_ashlpsi3
3342 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3346 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3350 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3354 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3356 ashl_optab->handlers[(int) SImode].libfunc
3357 = gen_rtx (SYMBOL_REF, Pmode, "__ashlsi3");
3358 ashl_optab->handlers[(int) DImode].libfunc
3359 = gen_rtx (SYMBOL_REF, Pmode, "__ashldi3");
3363 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3367 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3369 #ifdef HAVE_ashrpsi3
3371 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3375 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3379 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3383 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3385 ashr_optab->handlers[(int) SImode].libfunc
3386 = gen_rtx (SYMBOL_REF, Pmode, "__ashrsi3");
3387 ashr_optab->handlers[(int) DImode].libfunc
3388 = gen_rtx (SYMBOL_REF, Pmode, "__ashrdi3");
3392 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3396 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3398 #ifdef HAVE_lshlpsi3
3400 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3404 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3408 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3412 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3414 lshl_optab->handlers[(int) SImode].libfunc
3415 = gen_rtx (SYMBOL_REF, Pmode, "__lshlsi3");
3416 lshl_optab->handlers[(int) DImode].libfunc
3417 = gen_rtx (SYMBOL_REF, Pmode, "__lshldi3");
3421 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3425 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3427 #ifdef HAVE_lshrpsi3
3429 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3433 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3437 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3441 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3443 lshr_optab->handlers[(int) SImode].libfunc
3444 = gen_rtx (SYMBOL_REF, Pmode, "__lshrsi3");
3445 lshr_optab->handlers[(int) DImode].libfunc
3446 = gen_rtx (SYMBOL_REF, Pmode, "__lshrdi3");
3450 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3454 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3456 #ifdef HAVE_rotlpsi3
3458 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3462 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3466 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3470 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3472 rotl_optab->handlers[(int) SImode].libfunc
3473 = gen_rtx (SYMBOL_REF, Pmode, "__rotlsi3");
3474 rotl_optab->handlers[(int) DImode].libfunc
3475 = gen_rtx (SYMBOL_REF, Pmode, "__rotldi3");
3479 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3483 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3485 #ifdef HAVE_rotrpsi3
3487 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3491 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3495 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3499 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3501 rotr_optab->handlers[(int) SImode].libfunc
3502 = gen_rtx (SYMBOL_REF, Pmode, "__rotrsi3");
3503 rotr_optab->handlers[(int) DImode].libfunc
3504 = gen_rtx (SYMBOL_REF, Pmode, "__rotrdi3");
3508 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3512 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3516 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3520 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
3524 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
3528 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sminsf3;
3532 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smindf3;
3536 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smintf3;
3541 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
3545 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
3549 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
3553 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
3557 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
3561 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_smaxsf3;
3565 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smaxdf3;
3569 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smaxtf3;
3574 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
3578 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
3582 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
3586 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
3590 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
3595 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
3599 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
3603 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
3607 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
3611 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
3616 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
3620 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
3624 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
3628 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
3632 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
3636 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
3640 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
3644 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
3648 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
3650 neg_optab->handlers[(int) SImode].libfunc
3651 = gen_rtx (SYMBOL_REF, Pmode, "__negsi2");
3652 neg_optab->handlers[(int) DImode].libfunc
3653 = gen_rtx (SYMBOL_REF, Pmode, "__negdi2");
3654 neg_optab->handlers[(int) SFmode].libfunc
3655 = gen_rtx (SYMBOL_REF, Pmode, "__negsf2");
3656 neg_optab->handlers[(int) DFmode].libfunc
3657 = gen_rtx (SYMBOL_REF, Pmode, "__negdf2");
3661 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
3665 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
3669 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
3673 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
3677 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
3681 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
3685 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
3689 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
3693 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
3695 /* No library calls here! If there is no abs instruction,
3696 expand_expr will generate a conditional negation. */
3700 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
3704 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
3706 #ifdef HAVE_sqrtpsi2
3708 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
3712 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
3716 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
3720 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
3724 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
3728 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
3732 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
3734 /* No library calls here! If there is no sqrt instruction expand_builtin
3735 should force the library call. */
3737 #ifdef HAVE_strlenqi
3739 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
3741 #ifdef HAVE_strlenhi
3743 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
3745 #ifdef HAVE_strlenpsi
3747 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
3749 #ifdef HAVE_strlensi
3751 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
3753 #ifdef HAVE_strlendi
3755 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
3757 #ifdef HAVE_strlenti
3759 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
3761 /* No library calls here! If there is no strlen instruction expand_builtin
3762 should force the library call. */
3764 #ifdef HAVE_one_cmplqi2
3765 if (HAVE_one_cmplqi2)
3766 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
3768 #ifdef HAVE_one_cmplhi2
3769 if (HAVE_one_cmplhi2)
3770 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
3772 #ifdef HAVE_one_cmplpsi2
3773 if (HAVE_one_cmplpsi2)
3774 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
3776 #ifdef HAVE_one_cmplsi2
3777 if (HAVE_one_cmplsi2)
3778 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
3780 #ifdef HAVE_one_cmpldi2
3781 if (HAVE_one_cmpldi2)
3782 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
3784 #ifdef HAVE_one_cmplti2
3785 if (HAVE_one_cmplti2)
3786 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
3788 one_cmpl_optab->handlers[(int) SImode].libfunc
3789 = gen_rtx (SYMBOL_REF, Pmode, "__one_cmplsi2");
3793 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
3797 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
3801 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
3805 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
3809 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
3813 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
3815 ffs_optab->handlers[(int) SImode].libfunc
3816 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3820 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
3824 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
3828 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
3832 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
3836 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
3840 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
3844 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
3848 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
3852 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
3856 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
3859 #ifdef EXTRA_CC_MODES
3863 #ifdef HAVE_movstrictqi
3864 if (HAVE_movstrictqi)
3865 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
3867 #ifdef HAVE_movstricthi
3868 if (HAVE_movstricthi)
3869 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
3871 #ifdef HAVE_movstrictpsi
3872 if (HAVE_movstrictpsi)
3873 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
3875 #ifdef HAVE_movstrictsi
3876 if (HAVE_movstrictsi)
3877 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
3879 #ifdef HAVE_movstrictdi
3880 if (HAVE_movstrictdi)
3881 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
3883 #ifdef HAVE_movstrictti
3884 if (HAVE_movstrictti)
3885 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
3890 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
3894 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
3898 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
3902 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
3906 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
3910 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
3914 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
3918 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
3922 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
3926 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
3930 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
3934 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
3938 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
3942 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
3946 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
3950 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
3954 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
3958 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
3960 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3961 cmp_optab->handlers[(int) DImode].libfunc
3962 = gen_rtx (SYMBOL_REF, Pmode, "__cmpdi2");
3963 ucmp_optab->handlers[(int) DImode].libfunc
3964 = gen_rtx (SYMBOL_REF, Pmode, "__ucmpdi2");
3968 bcc_gen_fctn[(int) EQ] = gen_beq;
3972 bcc_gen_fctn[(int) NE] = gen_bne;
3976 bcc_gen_fctn[(int) GT] = gen_bgt;
3980 bcc_gen_fctn[(int) GE] = gen_bge;
3984 bcc_gen_fctn[(int) GTU] = gen_bgtu;
3988 bcc_gen_fctn[(int) GEU] = gen_bgeu;
3992 bcc_gen_fctn[(int) LT] = gen_blt;
3996 bcc_gen_fctn[(int) LE] = gen_ble;
4000 bcc_gen_fctn[(int) LTU] = gen_bltu;
4004 bcc_gen_fctn[(int) LEU] = gen_bleu;
4007 for (i = 0; i < NUM_RTX_CODE; i++)
4008 setcc_gen_code[i] = CODE_FOR_nothing;
4012 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4016 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4020 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4024 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4028 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4032 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4036 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4040 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4044 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4048 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4051 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4052 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4053 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4054 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4055 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4056 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4057 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4058 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4059 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4060 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4061 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4062 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4063 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4064 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4065 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4066 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4067 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4068 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4069 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4070 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4071 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4072 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4073 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4074 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4075 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4076 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4077 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4078 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4079 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4080 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4081 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4082 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4087 /* SCO 3.2 apparently has a broken ldexp. */
4100 #endif /* BROKEN_LDEXP */