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 Except for the first group of insns (the ones setting pseudos), the
1319 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1322 emit_libcall_block (insns, target, result, equiv)
1328 rtx prev, next, first, last, insn;
1330 /* First emit all insns that set pseudos. Remove them from the list as
1333 for (insn = insns; insn; insn = next)
1335 rtx set = single_set (insn);
1337 next = NEXT_INSN (insn);
1339 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1340 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
1342 if (PREV_INSN (insn))
1343 NEXT_INSN (PREV_INSN (insn)) = next;
1348 PREV_INSN (next) = PREV_INSN (insn);
1354 prev = get_last_insn ();
1356 /* Write the remaining insns followed by the final copy. */
1358 for (insn = insns; insn; insn = next)
1360 next = NEXT_INSN (insn);
1365 last = emit_move_insn (target, result);
1366 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1369 first = get_insns ();
1371 first = NEXT_INSN (prev);
1373 /* Encapsulate the block so it gets manipulated as a unit. */
1374 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1376 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1379 /* Generate code to store zero in X. */
1385 emit_move_insn (x, const0_rtx);
1388 /* Generate code to store 1 in X
1389 assuming it contains zero beforehand. */
1392 emit_0_to_1_insn (x)
1395 emit_move_insn (x, const1_rtx);
1398 /* Generate code to compare X with Y
1399 so that the condition codes are set.
1401 MODE is the mode of the inputs (in case they are const_int).
1402 UNSIGNEDP nonzero says that X and Y are unsigned;
1403 this matters if they need to be widened.
1405 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1406 and ALIGN specifies the known shared alignment of X and Y.
1408 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1409 It is ignored for fixed-point and block comparisons;
1410 it is used only for floating-point comparisons. */
1413 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1415 enum rtx_code comparison;
1420 enum mode_class class;
1421 enum machine_mode wider_mode;
1423 class = GET_MODE_CLASS (mode);
1425 /* They could both be VOIDmode if both args are immediate constants,
1426 but we should fold that at an earlier stage.
1427 With no special code here, this will call abort,
1428 reminding the programmer to implement such folding. */
1430 if (mode != BLKmode && flag_force_mem)
1432 x = force_not_mem (x);
1433 y = force_not_mem (y);
1436 /* If we are inside an appropriately-short loop and one operand is an
1437 expensive constant, force it into a register. */
1438 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x) > 2)
1439 x = force_reg (mode, x);
1441 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y) > 2)
1442 y = force_reg (mode, y);
1444 /* Don't let both operands fail to indicate the mode. */
1445 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1446 x = force_reg (mode, x);
1448 /* Handle all BLKmode compares. */
1450 if (mode == BLKmode)
1453 x = protect_from_queue (x, 0);
1454 y = protect_from_queue (y, 0);
1458 #ifdef HAVE_cmpstrqi
1460 && GET_CODE (size) == CONST_INT
1461 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1463 enum machine_mode result_mode
1464 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1465 rtx result = gen_reg_rtx (result_mode);
1466 emit_insn (gen_cmpstrqi (result, x, y, size,
1467 gen_rtx (CONST_INT, VOIDmode, align)));
1468 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1472 #ifdef HAVE_cmpstrhi
1474 && GET_CODE (size) == CONST_INT
1475 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1477 enum machine_mode result_mode
1478 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1479 rtx result = gen_reg_rtx (result_mode);
1480 emit_insn (gen_cmpstrhi (result, x, y, size,
1481 gen_rtx (CONST_INT, VOIDmode, align)));
1482 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1486 #ifdef HAVE_cmpstrsi
1489 enum machine_mode result_mode
1490 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1491 rtx result = gen_reg_rtx (result_mode);
1492 emit_insn (gen_cmpstrsi (result, x, y,
1493 convert_to_mode (SImode, size, 1),
1494 gen_rtx (CONST_INT, VOIDmode, align)));
1495 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1500 #ifdef TARGET_MEM_FUNCTIONS
1501 emit_library_call (memcmp_libfunc, 1,
1502 TYPE_MODE (integer_type_node), 3,
1503 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1506 emit_library_call (bcmp_libfunc, 1,
1507 TYPE_MODE (integer_type_node), 3,
1508 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1511 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1512 const0_rtx, comparison, 0,
1513 TYPE_MODE (integer_type_node), 0, 0);
1518 /* Handle some compares against zero. */
1520 if (y == CONST0_RTX (mode)
1521 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1523 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1526 x = protect_from_queue (x, 0);
1527 y = protect_from_queue (y, 0);
1529 /* Now, if insn does accept these operands, put them into pseudos. */
1530 if (! (*insn_operand_predicate[icode][0])
1531 (x, insn_operand_mode[icode][0]))
1532 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1534 emit_insn (GEN_FCN (icode) (x));
1538 /* Handle compares for which there is a directly suitable insn. */
1540 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1542 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1545 x = protect_from_queue (x, 0);
1546 y = protect_from_queue (y, 0);
1548 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1549 if (! (*insn_operand_predicate[icode][0])
1550 (x, insn_operand_mode[icode][0]))
1551 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1553 if (! (*insn_operand_predicate[icode][1])
1554 (y, insn_operand_mode[icode][1]))
1555 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1557 emit_insn (GEN_FCN (icode) (x, y));
1561 /* Try widening if we can find a direct insn that way. */
1563 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1565 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1566 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1568 if (cmp_optab->handlers[(int) wider_mode].insn_code
1569 != CODE_FOR_nothing)
1571 x = convert_to_mode (wider_mode, x, unsignedp);
1572 y = convert_to_mode (wider_mode, y, unsignedp);
1573 emit_cmp_insn (x, y, comparison, 0,
1574 wider_mode, unsignedp, align);
1580 /* Handle a lib call just for the mode we are using. */
1582 if (cmp_optab->handlers[(int) mode].libfunc
1583 && class != MODE_FLOAT)
1585 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1586 /* If we want unsigned, and this mode has a distinct unsigned
1587 comparison routine, use that. */
1588 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1589 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1591 emit_library_call (libfunc, 1,
1592 SImode, 2, x, mode, y, mode);
1594 /* Integer comparison returns a result that must be compared against 1,
1595 so that even if we do an unsigned compare afterward,
1596 there is still a value that can represent the result "less than". */
1598 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1599 comparison, 0, SImode, unsignedp, 0);
1603 if (class == MODE_FLOAT)
1604 emit_float_lib_cmp (x, y, comparison);
1610 /* Nonzero if a compare of mode MODE can be done straightforwardly
1611 (without splitting it into pieces). */
1614 can_compare_p (mode)
1615 enum machine_mode mode;
1619 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1621 mode = GET_MODE_WIDER_MODE (mode);
1622 } while (mode != VOIDmode);
1627 /* Emit a library call comparison between floating point X and Y.
1628 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1631 emit_float_lib_cmp (x, y, comparison)
1633 enum rtx_code comparison;
1635 enum machine_mode mode = GET_MODE (x);
1642 libfunc = eqsf2_libfunc;
1646 libfunc = nesf2_libfunc;
1650 libfunc = gtsf2_libfunc;
1654 libfunc = gesf2_libfunc;
1658 libfunc = ltsf2_libfunc;
1662 libfunc = lesf2_libfunc;
1665 else if (mode == DFmode)
1669 libfunc = eqdf2_libfunc;
1673 libfunc = nedf2_libfunc;
1677 libfunc = gtdf2_libfunc;
1681 libfunc = gedf2_libfunc;
1685 libfunc = ltdf2_libfunc;
1689 libfunc = ledf2_libfunc;
1694 enum machine_mode wider_mode;
1696 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1697 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1699 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1700 != CODE_FOR_nothing)
1701 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1703 x = convert_to_mode (wider_mode, x, 0);
1704 y = convert_to_mode (wider_mode, y, 0);
1705 emit_float_lib_cmp (x, y, comparison);
1712 emit_library_call (libfunc, 1,
1713 SImode, 2, x, mode, y, mode);
1715 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1719 /* Generate code to indirectly jump to a location given in the rtx LOC. */
1722 emit_indirect_jump (loc)
1725 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1727 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1730 emit_jump_insn (gen_indirect_jump (loc));
1733 /* These three functions generate an insn body and return it
1734 rather than emitting the insn.
1736 They do not protect from queued increments,
1737 because they may be used 1) in protect_from_queue itself
1738 and 2) in other passes where there is no queue. */
1740 /* Generate and return an insn body to add Y to X. */
1743 gen_add2_insn (x, y)
1746 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1748 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1749 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1750 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1753 return (GEN_FCN (icode) (x, x, y));
1757 have_add2_insn (mode)
1758 enum machine_mode mode;
1760 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1763 /* Generate and return an insn body to subtract Y from X. */
1766 gen_sub2_insn (x, y)
1769 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
1771 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1772 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1773 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1776 return (GEN_FCN (icode) (x, x, y));
1780 have_sub2_insn (mode)
1781 enum machine_mode mode;
1783 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1786 /* Generate the body of an instruction to copy Y into X. */
1789 gen_move_insn (x, y)
1792 register enum machine_mode mode = GET_MODE (x);
1793 enum insn_code insn_code;
1795 if (mode == VOIDmode)
1796 mode = GET_MODE (y);
1798 insn_code = mov_optab->handlers[(int) mode].insn_code;
1800 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
1801 find a mode to do it in. If we have a movcc, use it. Otherwise,
1802 find the MODE_INT mode of the same width. */
1804 if (insn_code == CODE_FOR_nothing)
1806 enum machine_mode tmode = VOIDmode;
1809 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
1810 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
1812 else if (GET_MODE_CLASS (mode) == MODE_CC)
1813 for (tmode = QImode; tmode != VOIDmode;
1814 tmode = GET_MODE_WIDER_MODE (tmode))
1815 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
1818 if (tmode == VOIDmode)
1821 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
1822 may call change_address which is not appropriate if we were
1823 called when a reload was in progress. We don't have to worry
1824 about changing the address since the size in bytes is supposed to
1825 be the same. Copy the MEM to change the mode and move any
1826 substitutions from the old MEM to the new one. */
1828 if (reload_in_progress)
1830 x = gen_lowpart_common (tmode, x1);
1831 if (x == 0 && GET_CODE (x1) == MEM)
1833 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
1834 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
1835 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
1836 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
1837 copy_replacements (x1, x);
1840 y = gen_lowpart_common (tmode, y1);
1841 if (y == 0 && GET_CODE (y1) == MEM)
1843 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
1844 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
1845 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
1846 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
1847 copy_replacements (y1, y);
1852 x = gen_lowpart (tmode, x);
1853 y = gen_lowpart (tmode, y);
1856 insn_code = mov_optab->handlers[(int) tmode].insn_code;
1859 return (GEN_FCN (insn_code) (x, y));
1862 /* Tables of patterns for extending one integer mode to another. */
1863 static enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
1865 /* Return the insn code used to extend FROM_MODE to TO_MODE.
1866 UNSIGNEDP specifies zero-extension instead of sign-extension. If
1867 no such operation exists, CODE_FOR_nothing will be returned. */
1870 can_extend_p (to_mode, from_mode, unsignedp)
1871 enum machine_mode to_mode, from_mode;
1874 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
1877 /* Generate the body of an insn to extend Y (with mode MFROM)
1878 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
1881 gen_extend_insn (x, y, mto, mfrom, unsignedp)
1883 enum machine_mode mto, mfrom;
1886 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
1894 for (p = extendtab[0][0];
1895 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
1897 *p = CODE_FOR_nothing;
1899 #ifdef HAVE_extendditi2
1900 if (HAVE_extendditi2)
1901 extendtab[(int) TImode][(int) DImode][0] = CODE_FOR_extendditi2;
1903 #ifdef HAVE_extendsiti2
1904 if (HAVE_extendsiti2)
1905 extendtab[(int) TImode][(int) SImode][0] = CODE_FOR_extendsiti2;
1907 #ifdef HAVE_extendhiti2
1908 if (HAVE_extendhiti2)
1909 extendtab[(int) TImode][(int) HImode][0] = CODE_FOR_extendhiti2;
1911 #ifdef HAVE_extendqiti2
1912 if (HAVE_extendqiti2)
1913 extendtab[(int) TImode][(int) QImode][0] = CODE_FOR_extendqiti2;
1915 #ifdef HAVE_extendsidi2
1916 if (HAVE_extendsidi2)
1917 extendtab[(int) DImode][(int) SImode][0] = CODE_FOR_extendsidi2;
1919 #ifdef HAVE_extendhidi2
1920 if (HAVE_extendhidi2)
1921 extendtab[(int) DImode][(int) HImode][0] = CODE_FOR_extendhidi2;
1923 #ifdef HAVE_extendqidi2
1924 if (HAVE_extendqidi2)
1925 extendtab[(int) DImode][(int) QImode][0] = CODE_FOR_extendqidi2;
1927 #ifdef HAVE_extendhisi2
1928 if (HAVE_extendhisi2)
1929 extendtab[(int) SImode][(int) HImode][0] = CODE_FOR_extendhisi2;
1931 #ifdef HAVE_extendqisi2
1932 if (HAVE_extendqisi2)
1933 extendtab[(int) SImode][(int) QImode][0] = CODE_FOR_extendqisi2;
1935 #ifdef HAVE_extendqihi2
1936 if (HAVE_extendqihi2)
1937 extendtab[(int) HImode][(int) QImode][0] = CODE_FOR_extendqihi2;
1940 #ifdef HAVE_zero_extendditi2
1941 if (HAVE_zero_extendsiti2)
1942 extendtab[(int) TImode][(int) DImode][1] = CODE_FOR_zero_extendditi2;
1944 #ifdef HAVE_zero_extendsiti2
1945 if (HAVE_zero_extendsiti2)
1946 extendtab[(int) TImode][(int) SImode][1] = CODE_FOR_zero_extendsiti2;
1948 #ifdef HAVE_zero_extendhiti2
1949 if (HAVE_zero_extendhiti2)
1950 extendtab[(int) TImode][(int) HImode][1] = CODE_FOR_zero_extendhiti2;
1952 #ifdef HAVE_zero_extendqiti2
1953 if (HAVE_zero_extendqiti2)
1954 extendtab[(int) TImode][(int) QImode][1] = CODE_FOR_zero_extendqiti2;
1956 #ifdef HAVE_zero_extendsidi2
1957 if (HAVE_zero_extendsidi2)
1958 extendtab[(int) DImode][(int) SImode][1] = CODE_FOR_zero_extendsidi2;
1960 #ifdef HAVE_zero_extendhidi2
1961 if (HAVE_zero_extendhidi2)
1962 extendtab[(int) DImode][(int) HImode][1] = CODE_FOR_zero_extendhidi2;
1964 #ifdef HAVE_zero_extendqidi2
1965 if (HAVE_zero_extendqidi2)
1966 extendtab[(int) DImode][(int) QImode][1] = CODE_FOR_zero_extendqidi2;
1968 #ifdef HAVE_zero_extendhisi2
1969 if (HAVE_zero_extendhisi2)
1970 extendtab[(int) SImode][(int) HImode][1] = CODE_FOR_zero_extendhisi2;
1972 #ifdef HAVE_zero_extendqisi2
1973 if (HAVE_zero_extendqisi2)
1974 extendtab[(int) SImode][(int) QImode][1] = CODE_FOR_zero_extendqisi2;
1976 #ifdef HAVE_zero_extendqihi2
1977 if (HAVE_zero_extendqihi2)
1978 extendtab[(int) HImode][(int) QImode][1] = CODE_FOR_zero_extendqihi2;
1982 /* can_fix_p and can_float_p say whether the target machine
1983 can directly convert a given fixed point type to
1984 a given floating point type, or vice versa.
1985 The returned value is the CODE_FOR_... value to use,
1986 or CODE_FOR_nothing if these modes cannot be directly converted. */
1988 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1989 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1990 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1992 /* *TRUNCP_PTR is set to 1 if it is necessary to output
1993 an explicit FTRUNC insn before the fix insn; otherwise 0. */
1995 static enum insn_code
1996 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
1997 enum machine_mode fltmode, fixmode;
2002 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2003 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2005 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2008 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2010 return CODE_FOR_nothing;
2013 static enum insn_code
2014 can_float_p (fltmode, fixmode, unsignedp)
2015 enum machine_mode fixmode, fltmode;
2018 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2025 for (p = fixtab[0][0];
2026 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2028 *p = CODE_FOR_nothing;
2029 for (p = fixtrunctab[0][0];
2030 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2032 *p = CODE_FOR_nothing;
2034 #ifdef HAVE_fixsfqi2
2036 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2038 #ifdef HAVE_fixsfhi2
2040 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2042 #ifdef HAVE_fixsfsi2
2044 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2046 #ifdef HAVE_fixsfdi2
2048 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2051 #ifdef HAVE_fixdfqi2
2053 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2055 #ifdef HAVE_fixdfhi2
2057 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2059 #ifdef HAVE_fixdfsi2
2061 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2063 #ifdef HAVE_fixdfdi2
2065 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2067 #ifdef HAVE_fixdfti2
2069 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2072 #ifdef HAVE_fixtfqi2
2074 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2076 #ifdef HAVE_fixtfhi2
2078 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2080 #ifdef HAVE_fixtfsi2
2082 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2084 #ifdef HAVE_fixtfdi2
2086 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2088 #ifdef HAVE_fixtfti2
2090 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2093 #ifdef HAVE_fixunssfqi2
2094 if (HAVE_fixunssfqi2)
2095 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2097 #ifdef HAVE_fixunssfhi2
2098 if (HAVE_fixunssfhi2)
2099 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2101 #ifdef HAVE_fixunssfsi2
2102 if (HAVE_fixunssfsi2)
2103 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2105 #ifdef HAVE_fixunssfdi2
2106 if (HAVE_fixunssfdi2)
2107 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2110 #ifdef HAVE_fixunsdfqi2
2111 if (HAVE_fixunsdfqi2)
2112 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2114 #ifdef HAVE_fixunsdfhi2
2115 if (HAVE_fixunsdfhi2)
2116 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2118 #ifdef HAVE_fixunsdfsi2
2119 if (HAVE_fixunsdfsi2)
2120 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2122 #ifdef HAVE_fixunsdfdi2
2123 if (HAVE_fixunsdfdi2)
2124 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2126 #ifdef HAVE_fixunsdfti2
2127 if (HAVE_fixunsdfti2)
2128 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2131 #ifdef HAVE_fixunstfqi2
2132 if (HAVE_fixunstfqi2)
2133 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2135 #ifdef HAVE_fixunstfhi2
2136 if (HAVE_fixunstfhi2)
2137 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2139 #ifdef HAVE_fixunstfsi2
2140 if (HAVE_fixunstfsi2)
2141 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2143 #ifdef HAVE_fixunstfdi2
2144 if (HAVE_fixunstfdi2)
2145 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2147 #ifdef HAVE_fixunstfti2
2148 if (HAVE_fixunstfti2)
2149 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2152 #ifdef HAVE_fix_truncsfqi2
2153 if (HAVE_fix_truncsfqi2)
2154 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2156 #ifdef HAVE_fix_truncsfhi2
2157 if (HAVE_fix_truncsfhi2)
2158 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2160 #ifdef HAVE_fix_truncsfsi2
2161 if (HAVE_fix_truncsfsi2)
2162 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2164 #ifdef HAVE_fix_truncsfdi2
2165 if (HAVE_fix_truncsfdi2)
2166 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2169 #ifdef HAVE_fix_truncdfqi2
2170 if (HAVE_fix_truncdfsi2)
2171 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2173 #ifdef HAVE_fix_truncdfhi2
2174 if (HAVE_fix_truncdfhi2)
2175 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2177 #ifdef HAVE_fix_truncdfsi2
2178 if (HAVE_fix_truncdfsi2)
2179 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2181 #ifdef HAVE_fix_truncdfdi2
2182 if (HAVE_fix_truncdfdi2)
2183 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2185 #ifdef HAVE_fix_truncdfti2
2186 if (HAVE_fix_truncdfti2)
2187 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2190 #ifdef HAVE_fix_trunctfqi2
2191 if (HAVE_fix_trunctfqi2)
2192 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2194 #ifdef HAVE_fix_trunctfhi2
2195 if (HAVE_fix_trunctfhi2)
2196 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2198 #ifdef HAVE_fix_trunctfsi2
2199 if (HAVE_fix_trunctfsi2)
2200 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2202 #ifdef HAVE_fix_trunctfdi2
2203 if (HAVE_fix_trunctfdi2)
2204 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2206 #ifdef HAVE_fix_trunctfti2
2207 if (HAVE_fix_trunctfti2)
2208 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2211 #ifdef HAVE_fixuns_truncsfqi2
2212 if (HAVE_fixuns_truncsfqi2)
2213 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2215 #ifdef HAVE_fixuns_truncsfhi2
2216 if (HAVE_fixuns_truncsfhi2)
2217 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2219 #ifdef HAVE_fixuns_truncsfsi2
2220 if (HAVE_fixuns_truncsfsi2)
2221 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2223 #ifdef HAVE_fixuns_truncsfdi2
2224 if (HAVE_fixuns_truncsfdi2)
2225 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2228 #ifdef HAVE_fixuns_truncdfqi2
2229 if (HAVE_fixuns_truncdfqi2)
2230 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2232 #ifdef HAVE_fixuns_truncdfhi2
2233 if (HAVE_fixuns_truncdfhi2)
2234 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2236 #ifdef HAVE_fixuns_truncdfsi2
2237 if (HAVE_fixuns_truncdfsi2)
2238 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2240 #ifdef HAVE_fixuns_truncdfdi2
2241 if (HAVE_fixuns_truncdfdi2)
2242 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2244 #ifdef HAVE_fixuns_truncdfti2
2245 if (HAVE_fixuns_truncdfti2)
2246 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2249 #ifdef HAVE_fixuns_trunctfqi2
2250 if (HAVE_fixuns_trunctfqi2)
2251 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2253 #ifdef HAVE_fixuns_trunctfhi2
2254 if (HAVE_fixuns_trunctfhi2)
2255 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2257 #ifdef HAVE_fixuns_trunctfsi2
2258 if (HAVE_fixuns_trunctfsi2)
2259 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2261 #ifdef HAVE_fixuns_trunctfdi2
2262 if (HAVE_fixuns_trunctfdi2)
2263 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2265 #ifdef HAVE_fixuns_trunctfti2
2266 if (HAVE_fixuns_trunctfti2)
2267 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2270 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2271 /* This flag says the same insns that convert to a signed fixnum
2272 also convert validly to an unsigned one. */
2276 for (i = 0; i < NUM_MACHINE_MODES; i++)
2277 for (j = 0; j < NUM_MACHINE_MODES; j++)
2278 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2287 for (p = floattab[0][0];
2288 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2290 *p = CODE_FOR_nothing;
2292 #ifdef HAVE_floatqisf2
2293 if (HAVE_floatqisf2)
2294 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2296 #ifdef HAVE_floathisf2
2297 if (HAVE_floathisf2)
2298 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2300 #ifdef HAVE_floatsisf2
2301 if (HAVE_floatsisf2)
2302 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2304 #ifdef HAVE_floatdisf2
2305 if (HAVE_floatdisf2)
2306 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2308 #ifdef HAVE_floattisf2
2309 if (HAVE_floattisf2)
2310 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2313 #ifdef HAVE_floatqidf2
2314 if (HAVE_floatqidf2)
2315 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2317 #ifdef HAVE_floathidf2
2318 if (HAVE_floathidf2)
2319 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2321 #ifdef HAVE_floatsidf2
2322 if (HAVE_floatsidf2)
2323 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2325 #ifdef HAVE_floatdidf2
2326 if (HAVE_floatdidf2)
2327 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2329 #ifdef HAVE_floattidf2
2330 if (HAVE_floattidf2)
2331 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2334 #ifdef HAVE_floatqitf2
2335 if (HAVE_floatqitf2)
2336 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2338 #ifdef HAVE_floathitf2
2339 if (HAVE_floathitf2)
2340 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2342 #ifdef HAVE_floatsitf2
2343 if (HAVE_floatsitf2)
2344 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2346 #ifdef HAVE_floatditf2
2347 if (HAVE_floatditf2)
2348 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2350 #ifdef HAVE_floattitf2
2351 if (HAVE_floattitf2)
2352 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2355 #ifdef HAVE_floatunsqisf2
2356 if (HAVE_floatunsqisf2)
2357 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2359 #ifdef HAVE_floatunshisf2
2360 if (HAVE_floatunshisf2)
2361 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2363 #ifdef HAVE_floatunssisf2
2364 if (HAVE_floatunssisf2)
2365 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2367 #ifdef HAVE_floatunsdisf2
2368 if (HAVE_floatunsdisf2)
2369 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2371 #ifdef HAVE_floatunstisf2
2372 if (HAVE_floatunstisf2)
2373 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2376 #ifdef HAVE_floatunsqidf2
2377 if (HAVE_floatunsqidf2)
2378 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2380 #ifdef HAVE_floatunshidf2
2381 if (HAVE_floatunshidf2)
2382 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2384 #ifdef HAVE_floatunssidf2
2385 if (HAVE_floatunssidf2)
2386 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2388 #ifdef HAVE_floatunsdidf2
2389 if (HAVE_floatunsdidf2)
2390 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2392 #ifdef HAVE_floatunstidf2
2393 if (HAVE_floatunstidf2)
2394 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2397 #ifdef HAVE_floatunsqitf2
2398 if (HAVE_floatunsqitf2)
2399 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2401 #ifdef HAVE_floatunshitf2
2402 if (HAVE_floatunshitf2)
2403 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2405 #ifdef HAVE_floatunssitf2
2406 if (HAVE_floatunssitf2)
2407 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2409 #ifdef HAVE_floatunsditf2
2410 if (HAVE_floatunsditf2)
2411 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2413 #ifdef HAVE_floatunstitf2
2414 if (HAVE_floatunstitf2)
2415 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2419 /* Generate code to convert FROM to floating point
2420 and store in TO. FROM must be fixed point and not VOIDmode.
2421 UNSIGNEDP nonzero means regard FROM as unsigned.
2422 Normally this is done by correcting the final value
2423 if it is negative. */
2426 expand_float (to, from, unsignedp)
2430 enum insn_code icode;
2431 register rtx target = to;
2432 enum machine_mode fmode, imode;
2434 /* Crash now, because we won't be able to decide which mode to use. */
2435 if (GET_MODE (from) == VOIDmode)
2438 /* Look for an insn to do the conversion. Do it in the specified
2439 modes if possible; otherwise convert either input, output or both to
2440 wider mode. If the integer mode is wider than the mode of FROM,
2441 we can do the conversion signed even if the input is unsigned. */
2443 for (imode = GET_MODE (from); imode != VOIDmode;
2444 imode = GET_MODE_WIDER_MODE (imode))
2445 for (fmode = GET_MODE (to); fmode != VOIDmode;
2446 fmode = GET_MODE_WIDER_MODE (fmode))
2448 int doing_unsigned = unsignedp;
2450 icode = can_float_p (fmode, imode, unsignedp);
2451 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
2452 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
2454 if (icode != CODE_FOR_nothing)
2456 to = protect_from_queue (to, 1);
2458 if (imode != GET_MODE (from))
2459 from = convert_to_mode (imode, from, unsignedp);
2461 from = protect_from_queue (from, 0);
2463 if (fmode != GET_MODE (to))
2464 target = gen_reg_rtx (fmode);
2466 emit_unop_insn (icode, target, from,
2467 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
2470 convert_move (to, target, 0);
2475 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2477 /* Unsigned integer, and no way to convert directly.
2478 Convert as signed, then conditionally adjust the result. */
2481 rtx label = gen_label_rtx ();
2483 REAL_VALUE_TYPE offset;
2487 to = protect_from_queue (to, 1);
2488 from = protect_from_queue (from, 0);
2491 from = force_not_mem (from);
2493 /* If we are about to do some arithmetic to correct for an
2494 unsigned operand, do it in a pseudo-register. */
2496 if (GET_CODE (to) != REG || REGNO (to) <= LAST_VIRTUAL_REGISTER)
2497 target = gen_reg_rtx (GET_MODE (to));
2499 /* Convert as signed integer to floating. */
2500 expand_float (target, from, 0);
2502 /* If FROM is negative (and therefore TO is negative),
2503 correct its value by 2**bitwidth. */
2505 do_pending_stack_adjust ();
2506 emit_cmp_insn (from, const0_rtx, GE, 0, GET_MODE (from), 0, 0);
2507 emit_jump_insn (gen_bge (label));
2508 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
2509 Rather than setting up a dconst_dot_5, let's hope SCO
2511 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
2512 temp = expand_binop (GET_MODE (to), add_optab, target,
2513 immed_real_const_1 (offset, GET_MODE (to)),
2514 target, 0, OPTAB_LIB_WIDEN);
2516 emit_move_insn (target, temp);
2517 do_pending_stack_adjust ();
2523 /* No hardware instruction available; call a library
2524 to convert from SImode or DImode into SFmode or DFmode. */
2529 to = protect_from_queue (to, 1);
2531 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
2532 from = convert_to_mode (SImode, from, unsignedp);
2534 from = protect_from_queue (from, 0);
2537 from = force_not_mem (from);
2539 if (GET_MODE (to) == SFmode)
2541 if (GET_MODE (from) == SImode)
2542 libfcn = floatsisf_libfunc;
2543 else if (GET_MODE (from) == DImode)
2544 libfcn = floatdisf_libfunc;
2548 else if (GET_MODE (to) == DFmode)
2550 if (GET_MODE (from) == SImode)
2551 libfcn = floatsidf_libfunc;
2552 else if (GET_MODE (from) == DImode)
2553 libfcn = floatdidf_libfunc;
2562 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2563 insns = get_insns ();
2566 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2567 gen_rtx (FLOAT, GET_MODE (to), from));
2570 /* Copy result to requested destination
2571 if we have been computing in a temp location. */
2575 if (GET_MODE (target) == GET_MODE (to))
2576 emit_move_insn (to, target);
2578 convert_move (to, target, 0);
2582 /* expand_fix: generate code to convert FROM to fixed point
2583 and store in TO. FROM must be floating point. */
2589 rtx temp = gen_reg_rtx (GET_MODE (x));
2590 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2594 expand_fix (to, from, unsignedp)
2595 register rtx to, from;
2598 enum insn_code icode;
2599 register rtx target = to;
2600 enum machine_mode fmode, imode;
2604 /* We first try to find a pair of modes, one real and one integer, at
2605 least as wide as FROM and TO, respectively, in which we can open-code
2606 this conversion. If the integer mode is wider than the mode of TO,
2607 we can do the conversion either signed or unsigned. */
2609 for (imode = GET_MODE (to); imode != VOIDmode;
2610 imode = GET_MODE_WIDER_MODE (imode))
2611 for (fmode = GET_MODE (from); fmode != VOIDmode;
2612 fmode = GET_MODE_WIDER_MODE (fmode))
2614 int doing_unsigned = unsignedp;
2616 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2617 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2618 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
2620 if (icode != CODE_FOR_nothing)
2622 to = protect_from_queue (to, 1);
2624 if (fmode != GET_MODE (from))
2625 from = convert_to_mode (fmode, from, 0);
2627 from = protect_from_queue (from, 0);
2630 from = ftruncify (from);
2632 if (imode != GET_MODE (to))
2633 target = gen_reg_rtx (imode);
2635 emit_unop_insn (icode, target, from,
2636 doing_unsigned ? UNSIGNED_FIX : FIX);
2638 convert_move (to, target, unsignedp);
2643 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2644 /* For an unsigned conversion, there is one more way to do it.
2645 If we have a signed conversion, we generate code that compares
2646 the real value to the largest representable positive number. If if
2647 is smaller, the conversion is done normally. Otherwise, subtract
2648 one plus the highest signed number, convert, and add it back.
2650 We only need to check all real modes, since we know we didn't find
2651 anything with a wider inetger mode. */
2653 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT)
2654 for (fmode = GET_MODE (from); fmode != VOIDmode;
2655 fmode = GET_MODE_WIDER_MODE (fmode))
2656 /* Make sure we won't lose significant bits doing this. */
2657 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
2658 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
2661 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
2662 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
2663 rtx limit = immed_real_const_1 (offset, fmode);
2664 rtx lab1 = gen_label_rtx ();
2665 rtx lab2 = gen_label_rtx ();
2669 to = protect_from_queue (to, 1);
2670 from = protect_from_queue (from, 0);
2673 from = force_not_mem (from);
2675 if (fmode != GET_MODE (from))
2676 from = convert_to_mode (fmode, from, 0);
2678 /* See if we need to do the subtraction. */
2679 do_pending_stack_adjust ();
2680 emit_cmp_insn (from, limit, GE, 0, GET_MODE (from), 0, 0);
2681 emit_jump_insn (gen_bge (lab1));
2683 /* If not, do the signed "fix" and branch around fixup code. */
2684 expand_fix (to, from, 0);
2685 emit_jump_insn (gen_jump (lab2));
2688 /* Otherwise, subtract 2**(N-1), convert to signed number,
2689 then add 2**(N-1). Do the addition using XOR since this
2690 will often generate better code. */
2692 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
2693 0, 0, OPTAB_LIB_WIDEN);
2694 expand_fix (to, target, 0);
2695 target = expand_binop (GET_MODE (to), xor_optab, to,
2696 gen_rtx (CONST_INT, VOIDmode,
2697 1 << (bitsize - 1)),
2698 to, 1, OPTAB_LIB_WIDEN);
2701 emit_move_insn (to, target);
2705 /* Make a place for a REG_NOTE and add it. */
2706 insn = emit_move_insn (to, to);
2707 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
2708 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
2709 from), REG_NOTES (insn));
2715 /* We can't do it with an insn, so use a library call. But first ensure
2716 that the mode of TO is at least as wide as SImode, since those are the
2717 only library calls we know about. */
2719 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
2721 target = gen_reg_rtx (SImode);
2723 expand_fix (target, from, unsignedp);
2725 else if (GET_MODE (from) == SFmode)
2727 if (GET_MODE (to) == SImode)
2728 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
2729 else if (GET_MODE (to) == DImode)
2730 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
2734 else if (GET_MODE (from) == DFmode)
2736 if (GET_MODE (to) == SImode)
2737 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
2738 else if (GET_MODE (to) == DImode)
2739 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
2750 to = protect_from_queue (to, 1);
2751 from = protect_from_queue (from, 0);
2754 from = force_not_mem (from);
2758 emit_library_call (libfcn, 1, GET_MODE (to), 1, from, GET_MODE (from));
2759 insns = get_insns ();
2762 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2763 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
2764 GET_MODE (to), from));
2767 if (GET_MODE (to) == GET_MODE (target))
2768 emit_move_insn (to, target);
2770 convert_move (to, target, 0);
2778 optab op = (optab) xmalloc (sizeof (struct optab));
2780 for (i = 0; i < NUM_MACHINE_MODES; i++)
2782 op->handlers[i].insn_code = CODE_FOR_nothing;
2783 op->handlers[i].libfunc = 0;
2788 /* Call this once to initialize the contents of the optabs
2789 appropriately for the current target machine. */
2800 add_optab = init_optab (PLUS);
2801 sub_optab = init_optab (MINUS);
2802 smul_optab = init_optab (MULT);
2803 smul_widen_optab = init_optab (UNKNOWN);
2804 umul_widen_optab = init_optab (UNKNOWN);
2805 sdiv_optab = init_optab (DIV);
2806 sdivmod_optab = init_optab (UNKNOWN);
2807 udiv_optab = init_optab (UDIV);
2808 udivmod_optab = init_optab (UNKNOWN);
2809 smod_optab = init_optab (MOD);
2810 umod_optab = init_optab (UMOD);
2811 flodiv_optab = init_optab (DIV);
2812 ftrunc_optab = init_optab (UNKNOWN);
2813 and_optab = init_optab (AND);
2814 ior_optab = init_optab (IOR);
2815 xor_optab = init_optab (XOR);
2816 ashl_optab = init_optab (ASHIFT);
2817 ashr_optab = init_optab (ASHIFTRT);
2818 lshl_optab = init_optab (LSHIFT);
2819 lshr_optab = init_optab (LSHIFTRT);
2820 rotl_optab = init_optab (ROTATE);
2821 rotr_optab = init_optab (ROTATERT);
2822 smin_optab = init_optab (SMIN);
2823 smax_optab = init_optab (SMAX);
2824 umin_optab = init_optab (UMIN);
2825 umax_optab = init_optab (UMAX);
2826 mov_optab = init_optab (UNKNOWN);
2827 movstrict_optab = init_optab (UNKNOWN);
2828 cmp_optab = init_optab (UNKNOWN);
2829 ucmp_optab = init_optab (UNKNOWN);
2830 tst_optab = init_optab (UNKNOWN);
2831 neg_optab = init_optab (NEG);
2832 abs_optab = init_optab (ABS);
2833 one_cmpl_optab = init_optab (NOT);
2834 ffs_optab = init_optab (FFS);
2835 sqrt_optab = init_optab (SQRT);
2836 strlen_optab = init_optab (UNKNOWN);
2840 add_optab->handlers[(int) QImode].insn_code = CODE_FOR_addqi3;
2844 add_optab->handlers[(int) HImode].insn_code = CODE_FOR_addhi3;
2848 add_optab->handlers[(int) PSImode].insn_code = CODE_FOR_addpsi3;
2852 add_optab->handlers[(int) SImode].insn_code = CODE_FOR_addsi3;
2856 add_optab->handlers[(int) DImode].insn_code = CODE_FOR_adddi3;
2860 add_optab->handlers[(int) TImode].insn_code = CODE_FOR_addti3;
2864 add_optab->handlers[(int) SFmode].insn_code = CODE_FOR_addsf3;
2868 add_optab->handlers[(int) DFmode].insn_code = CODE_FOR_adddf3;
2872 add_optab->handlers[(int) TFmode].insn_code = CODE_FOR_addtf3;
2874 add_optab->handlers[(int) SFmode].libfunc
2875 = gen_rtx (SYMBOL_REF, Pmode, "__addsf3");
2876 add_optab->handlers[(int) DFmode].libfunc
2877 = gen_rtx (SYMBOL_REF, Pmode, "__adddf3");
2881 sub_optab->handlers[(int) QImode].insn_code = CODE_FOR_subqi3;
2885 sub_optab->handlers[(int) HImode].insn_code = CODE_FOR_subhi3;
2889 sub_optab->handlers[(int) PSImode].insn_code = CODE_FOR_subpsi3;
2893 sub_optab->handlers[(int) SImode].insn_code = CODE_FOR_subsi3;
2897 sub_optab->handlers[(int) DImode].insn_code = CODE_FOR_subdi3;
2901 sub_optab->handlers[(int) TImode].insn_code = CODE_FOR_subti3;
2905 sub_optab->handlers[(int) SFmode].insn_code = CODE_FOR_subsf3;
2909 sub_optab->handlers[(int) DFmode].insn_code = CODE_FOR_subdf3;
2913 sub_optab->handlers[(int) TFmode].insn_code = CODE_FOR_subtf3;
2915 sub_optab->handlers[(int) SFmode].libfunc
2916 = gen_rtx (SYMBOL_REF, Pmode, "__subsf3");
2917 sub_optab->handlers[(int) DFmode].libfunc
2918 = gen_rtx (SYMBOL_REF, Pmode, "__subdf3");
2922 smul_optab->handlers[(int) QImode].insn_code = CODE_FOR_mulqi3;
2926 smul_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulhi3;
2930 smul_optab->handlers[(int) PSImode].insn_code = CODE_FOR_mulpsi3;
2934 smul_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulsi3;
2938 smul_optab->handlers[(int) DImode].insn_code = CODE_FOR_muldi3;
2942 smul_optab->handlers[(int) TImode].insn_code = CODE_FOR_multi3;
2946 smul_optab->handlers[(int) SFmode].insn_code = CODE_FOR_mulsf3;
2950 smul_optab->handlers[(int) DFmode].insn_code = CODE_FOR_muldf3;
2954 smul_optab->handlers[(int) TFmode].insn_code = CODE_FOR_multf3;
2957 #ifdef MULSI3_LIBCALL
2958 smul_optab->handlers[(int) SImode].libfunc
2959 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
2961 smul_optab->handlers[(int) SImode].libfunc
2962 = gen_rtx (SYMBOL_REF, Pmode, "__mulsi3");
2964 #ifdef MULDI3_LIBCALL
2965 smul_optab->handlers[(int) DImode].libfunc
2966 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
2968 smul_optab->handlers[(int) DImode].libfunc
2969 = gen_rtx (SYMBOL_REF, Pmode, "__muldi3");
2971 smul_optab->handlers[(int) SFmode].libfunc
2972 = gen_rtx (SYMBOL_REF, Pmode, "__mulsf3");
2973 smul_optab->handlers[(int) DFmode].libfunc
2974 = gen_rtx (SYMBOL_REF, Pmode, "__muldf3");
2976 #ifdef HAVE_mulqihi3
2978 smul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_mulqihi3;
2980 #ifdef HAVE_mulhisi3
2982 smul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_mulhisi3;
2984 #ifdef HAVE_mulsidi3
2986 smul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_mulsidi3;
2988 #ifdef HAVE_mulditi3
2990 smul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_mulditi3;
2993 #ifdef HAVE_umulqihi3
2995 umul_widen_optab->handlers[(int) HImode].insn_code = CODE_FOR_umulqihi3;
2997 #ifdef HAVE_umulhisi3
2999 umul_widen_optab->handlers[(int) SImode].insn_code = CODE_FOR_umulhisi3;
3001 #ifdef HAVE_umulsidi3
3003 umul_widen_optab->handlers[(int) DImode].insn_code = CODE_FOR_umulsidi3;
3005 #ifdef HAVE_umulditi3
3007 umul_widen_optab->handlers[(int) TImode].insn_code = CODE_FOR_umulditi3;
3012 sdiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_divqi3;
3016 sdiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_divhi3;
3020 sdiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_divpsi3;
3024 sdiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_divsi3;
3028 sdiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_divdi3;
3032 sdiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_divti3;
3035 #ifdef DIVSI3_LIBCALL
3036 sdiv_optab->handlers[(int) SImode].libfunc
3037 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
3039 sdiv_optab->handlers[(int) SImode].libfunc
3040 = gen_rtx (SYMBOL_REF, Pmode, "__divsi3");
3042 #ifdef DIVDI3_LIBCALL
3043 sdiv_optab->handlers[(int) DImode].libfunc
3044 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
3046 sdiv_optab->handlers[(int) DImode].libfunc
3047 = gen_rtx (SYMBOL_REF, Pmode, "__divdi3");
3052 udiv_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivqi3;
3056 udiv_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivhi3;
3058 #ifdef HAVE_udivpsi3
3060 udiv_optab->handlers[(int) PSImode].insn_code = CODE_FOR_udivpsi3;
3064 udiv_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivsi3;
3068 udiv_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivdi3;
3072 udiv_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivti3;
3075 #ifdef UDIVSI3_LIBCALL
3076 udiv_optab->handlers[(int) SImode].libfunc
3077 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
3079 udiv_optab->handlers[(int) SImode].libfunc
3080 = gen_rtx (SYMBOL_REF, Pmode, "__udivsi3");
3082 #ifdef UDIVDI3_LIBCALL
3083 udiv_optab->handlers[(int) DImode].libfunc
3084 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
3086 udiv_optab->handlers[(int) DImode].libfunc
3087 = gen_rtx (SYMBOL_REF, Pmode, "__udivdi3");
3090 #ifdef HAVE_divmodqi4
3092 sdivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_divmodqi4;
3094 #ifdef HAVE_divmodhi4
3096 sdivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_divmodhi4;
3098 #ifdef HAVE_divmodsi4
3100 sdivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_divmodsi4;
3102 #ifdef HAVE_divmoddi4
3104 sdivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_divmoddi4;
3106 #ifdef HAVE_divmodti4
3108 sdivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_divmodti4;
3111 #ifdef HAVE_udivmodqi4
3112 if (HAVE_udivmodqi4)
3113 udivmod_optab->handlers[(int) QImode].insn_code = CODE_FOR_udivmodqi4;
3115 #ifdef HAVE_udivmodhi4
3116 if (HAVE_udivmodhi4)
3117 udivmod_optab->handlers[(int) HImode].insn_code = CODE_FOR_udivmodhi4;
3119 #ifdef HAVE_udivmodsi4
3120 if (HAVE_udivmodsi4)
3121 udivmod_optab->handlers[(int) SImode].insn_code = CODE_FOR_udivmodsi4;
3123 #ifdef HAVE_udivmoddi4
3124 if (HAVE_udivmoddi4)
3125 udivmod_optab->handlers[(int) DImode].insn_code = CODE_FOR_udivmoddi4;
3127 #ifdef HAVE_udivmodti4
3128 if (HAVE_udivmodti4)
3129 udivmod_optab->handlers[(int) TImode].insn_code = CODE_FOR_udivmodti4;
3134 smod_optab->handlers[(int) QImode].insn_code = CODE_FOR_modqi3;
3138 smod_optab->handlers[(int) HImode].insn_code = CODE_FOR_modhi3;
3142 smod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_modpsi3;
3146 smod_optab->handlers[(int) SImode].insn_code = CODE_FOR_modsi3;
3150 smod_optab->handlers[(int) DImode].insn_code = CODE_FOR_moddi3;
3154 smod_optab->handlers[(int) TImode].insn_code = CODE_FOR_modti3;
3157 #ifdef MODSI3_LIBCALL
3158 smod_optab->handlers[(int) SImode].libfunc
3159 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
3161 smod_optab->handlers[(int) SImode].libfunc
3162 = gen_rtx (SYMBOL_REF, Pmode, "__modsi3");
3164 #ifdef MODDI3_LIBCALL
3165 smod_optab->handlers[(int) DImode].libfunc
3166 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
3168 smod_optab->handlers[(int) DImode].libfunc
3169 = gen_rtx (SYMBOL_REF, Pmode, "__moddi3");
3174 umod_optab->handlers[(int) QImode].insn_code = CODE_FOR_umodqi3;
3178 umod_optab->handlers[(int) HImode].insn_code = CODE_FOR_umodhi3;
3180 #ifdef HAVE_umodpsi3
3182 umod_optab->handlers[(int) PSImode].insn_code = CODE_FOR_umodpsi3;
3186 umod_optab->handlers[(int) SImode].insn_code = CODE_FOR_umodsi3;
3190 umod_optab->handlers[(int) DImode].insn_code = CODE_FOR_umoddi3;
3194 umod_optab->handlers[(int) TImode].insn_code = CODE_FOR_umodti3;
3197 #ifdef UMODSI3_LIBCALL
3198 umod_optab->handlers[(int) SImode].libfunc
3199 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
3201 umod_optab->handlers[(int) SImode].libfunc
3202 = gen_rtx (SYMBOL_REF, Pmode, "__umodsi3");
3204 #ifdef UMODDI3_LIBCALL
3205 umod_optab->handlers[(int) DImode].libfunc
3206 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
3208 umod_optab->handlers[(int) DImode].libfunc
3209 = gen_rtx (SYMBOL_REF, Pmode, "__umoddi3");
3214 flodiv_optab->handlers[(int) SFmode].insn_code = CODE_FOR_divsf3;
3218 flodiv_optab->handlers[(int) DFmode].insn_code = CODE_FOR_divdf3;
3222 flodiv_optab->handlers[(int) TFmode].insn_code = CODE_FOR_divtf3;
3224 flodiv_optab->handlers[(int) SFmode].libfunc
3225 = gen_rtx (SYMBOL_REF, Pmode, "__divsf3");
3226 flodiv_optab->handlers[(int) DFmode].libfunc
3227 = gen_rtx (SYMBOL_REF, Pmode, "__divdf3");
3229 #ifdef HAVE_ftruncsf2
3231 ftrunc_optab->handlers[(int) SFmode].insn_code = CODE_FOR_ftruncsf2;
3233 #ifdef HAVE_ftruncdf2
3235 ftrunc_optab->handlers[(int) DFmode].insn_code = CODE_FOR_ftruncdf2;
3237 #ifdef HAVE_ftrunctf2
3239 ftrunc_optab->handlers[(int) TFmode].insn_code = CODE_FOR_ftrunctf2;
3244 and_optab->handlers[(int) QImode].insn_code = CODE_FOR_andqi3;
3248 and_optab->handlers[(int) HImode].insn_code = CODE_FOR_andhi3;
3252 and_optab->handlers[(int) PSImode].insn_code = CODE_FOR_andpsi3;
3256 and_optab->handlers[(int) SImode].insn_code = CODE_FOR_andsi3;
3260 and_optab->handlers[(int) DImode].insn_code = CODE_FOR_anddi3;
3264 and_optab->handlers[(int) TImode].insn_code = CODE_FOR_andti3;
3269 ior_optab->handlers[(int) QImode].insn_code = CODE_FOR_iorqi3;
3273 ior_optab->handlers[(int) HImode].insn_code = CODE_FOR_iorhi3;
3277 ior_optab->handlers[(int) PSImode].insn_code = CODE_FOR_iorpsi3;
3281 ior_optab->handlers[(int) SImode].insn_code = CODE_FOR_iorsi3;
3285 ior_optab->handlers[(int) DImode].insn_code = CODE_FOR_iordi3;
3289 ior_optab->handlers[(int) TImode].insn_code = CODE_FOR_iorti3;
3294 xor_optab->handlers[(int) QImode].insn_code = CODE_FOR_xorqi3;
3298 xor_optab->handlers[(int) HImode].insn_code = CODE_FOR_xorhi3;
3302 xor_optab->handlers[(int) PSImode].insn_code = CODE_FOR_xorpsi3;
3306 xor_optab->handlers[(int) SImode].insn_code = CODE_FOR_xorsi3;
3310 xor_optab->handlers[(int) DImode].insn_code = CODE_FOR_xordi3;
3314 xor_optab->handlers[(int) TImode].insn_code = CODE_FOR_xorti3;
3319 ashl_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashlqi3;
3323 ashl_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashlhi3;
3325 #ifdef HAVE_ashlpsi3
3327 ashl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashlpsi3;
3331 ashl_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashlsi3;
3335 ashl_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashldi3;
3339 ashl_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashlti3;
3341 ashl_optab->handlers[(int) SImode].libfunc
3342 = gen_rtx (SYMBOL_REF, Pmode, "__ashlsi3");
3343 ashl_optab->handlers[(int) DImode].libfunc
3344 = gen_rtx (SYMBOL_REF, Pmode, "__ashldi3");
3348 ashr_optab->handlers[(int) QImode].insn_code = CODE_FOR_ashrqi3;
3352 ashr_optab->handlers[(int) HImode].insn_code = CODE_FOR_ashrhi3;
3354 #ifdef HAVE_ashrpsi3
3356 ashr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ashrpsi3;
3360 ashr_optab->handlers[(int) SImode].insn_code = CODE_FOR_ashrsi3;
3364 ashr_optab->handlers[(int) DImode].insn_code = CODE_FOR_ashrdi3;
3368 ashr_optab->handlers[(int) TImode].insn_code = CODE_FOR_ashrti3;
3370 ashr_optab->handlers[(int) SImode].libfunc
3371 = gen_rtx (SYMBOL_REF, Pmode, "__ashrsi3");
3372 ashr_optab->handlers[(int) DImode].libfunc
3373 = gen_rtx (SYMBOL_REF, Pmode, "__ashrdi3");
3377 lshl_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshlqi3;
3381 lshl_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshlhi3;
3383 #ifdef HAVE_lshlpsi3
3385 lshl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshlpsi3;
3389 lshl_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshlsi3;
3393 lshl_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshldi3;
3397 lshl_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshlti3;
3399 lshl_optab->handlers[(int) SImode].libfunc
3400 = gen_rtx (SYMBOL_REF, Pmode, "__lshlsi3");
3401 lshl_optab->handlers[(int) DImode].libfunc
3402 = gen_rtx (SYMBOL_REF, Pmode, "__lshldi3");
3406 lshr_optab->handlers[(int) QImode].insn_code = CODE_FOR_lshrqi3;
3410 lshr_optab->handlers[(int) HImode].insn_code = CODE_FOR_lshrhi3;
3412 #ifdef HAVE_lshrpsi3
3414 lshr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_lshrpsi3;
3418 lshr_optab->handlers[(int) SImode].insn_code = CODE_FOR_lshrsi3;
3422 lshr_optab->handlers[(int) DImode].insn_code = CODE_FOR_lshrdi3;
3426 lshr_optab->handlers[(int) TImode].insn_code = CODE_FOR_lshrti3;
3428 lshr_optab->handlers[(int) SImode].libfunc
3429 = gen_rtx (SYMBOL_REF, Pmode, "__lshrsi3");
3430 lshr_optab->handlers[(int) DImode].libfunc
3431 = gen_rtx (SYMBOL_REF, Pmode, "__lshrdi3");
3435 rotl_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotlqi3;
3439 rotl_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotlhi3;
3441 #ifdef HAVE_rotlpsi3
3443 rotl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotlpsi3;
3447 rotl_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotlsi3;
3451 rotl_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotldi3;
3455 rotl_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotlti3;
3457 rotl_optab->handlers[(int) SImode].libfunc
3458 = gen_rtx (SYMBOL_REF, Pmode, "__rotlsi3");
3459 rotl_optab->handlers[(int) DImode].libfunc
3460 = gen_rtx (SYMBOL_REF, Pmode, "__rotldi3");
3464 rotr_optab->handlers[(int) QImode].insn_code = CODE_FOR_rotrqi3;
3468 rotr_optab->handlers[(int) HImode].insn_code = CODE_FOR_rotrhi3;
3470 #ifdef HAVE_rotrpsi3
3472 rotr_optab->handlers[(int) PSImode].insn_code = CODE_FOR_rotrpsi3;
3476 rotr_optab->handlers[(int) SImode].insn_code = CODE_FOR_rotrsi3;
3480 rotr_optab->handlers[(int) DImode].insn_code = CODE_FOR_rotrdi3;
3484 rotr_optab->handlers[(int) TImode].insn_code = CODE_FOR_rotrti3;
3486 rotr_optab->handlers[(int) SImode].libfunc
3487 = gen_rtx (SYMBOL_REF, Pmode, "__rotrsi3");
3488 rotr_optab->handlers[(int) DImode].libfunc
3489 = gen_rtx (SYMBOL_REF, Pmode, "__rotrdi3");
3493 smin_optab->handlers[(int) QImode].insn_code = CODE_FOR_sminqi3;
3497 smin_optab->handlers[(int) HImode].insn_code = CODE_FOR_sminhi3;
3501 smin_optab->handlers[(int) SImode].insn_code = CODE_FOR_sminsi3;
3505 smin_optab->handlers[(int) DImode].insn_code = CODE_FOR_smindi3;
3509 smin_optab->handlers[(int) TImode].insn_code = CODE_FOR_sminti3;
3513 smin_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sminsf3;
3517 smin_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smindf3;
3521 smin_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smintf3;
3526 smax_optab->handlers[(int) QImode].insn_code = CODE_FOR_smaxqi3;
3530 smax_optab->handlers[(int) HImode].insn_code = CODE_FOR_smaxhi3;
3534 smax_optab->handlers[(int) SImode].insn_code = CODE_FOR_smaxsi3;
3538 smax_optab->handlers[(int) DImode].insn_code = CODE_FOR_smaxdi3;
3542 smax_optab->handlers[(int) TImode].insn_code = CODE_FOR_smaxti3;
3546 smax_optab->handlers[(int) SFmode].insn_code = CODE_FOR_smaxsf3;
3550 smax_optab->handlers[(int) DFmode].insn_code = CODE_FOR_smaxdf3;
3554 smax_optab->handlers[(int) TFmode].insn_code = CODE_FOR_smaxtf3;
3559 umin_optab->handlers[(int) QImode].insn_code = CODE_FOR_uminqi3;
3563 umin_optab->handlers[(int) HImode].insn_code = CODE_FOR_uminhi3;
3567 umin_optab->handlers[(int) SImode].insn_code = CODE_FOR_uminsi3;
3571 umin_optab->handlers[(int) DImode].insn_code = CODE_FOR_umindi3;
3575 umin_optab->handlers[(int) TImode].insn_code = CODE_FOR_uminti3;
3580 umax_optab->handlers[(int) QImode].insn_code = CODE_FOR_umaxqi3;
3584 umax_optab->handlers[(int) HImode].insn_code = CODE_FOR_umaxhi3;
3588 umax_optab->handlers[(int) SImode].insn_code = CODE_FOR_umaxsi3;
3592 umax_optab->handlers[(int) DImode].insn_code = CODE_FOR_umaxdi3;
3596 umax_optab->handlers[(int) TImode].insn_code = CODE_FOR_umaxti3;
3601 neg_optab->handlers[(int) QImode].insn_code = CODE_FOR_negqi2;
3605 neg_optab->handlers[(int) HImode].insn_code = CODE_FOR_neghi2;
3609 neg_optab->handlers[(int) PSImode].insn_code = CODE_FOR_negpsi2;
3613 neg_optab->handlers[(int) SImode].insn_code = CODE_FOR_negsi2;
3617 neg_optab->handlers[(int) DImode].insn_code = CODE_FOR_negdi2;
3621 neg_optab->handlers[(int) TImode].insn_code = CODE_FOR_negti2;
3625 neg_optab->handlers[(int) SFmode].insn_code = CODE_FOR_negsf2;
3629 neg_optab->handlers[(int) DFmode].insn_code = CODE_FOR_negdf2;
3633 neg_optab->handlers[(int) TFmode].insn_code = CODE_FOR_negtf2;
3635 neg_optab->handlers[(int) SImode].libfunc
3636 = gen_rtx (SYMBOL_REF, Pmode, "__negsi2");
3637 neg_optab->handlers[(int) DImode].libfunc
3638 = gen_rtx (SYMBOL_REF, Pmode, "__negdi2");
3639 neg_optab->handlers[(int) SFmode].libfunc
3640 = gen_rtx (SYMBOL_REF, Pmode, "__negsf2");
3641 neg_optab->handlers[(int) DFmode].libfunc
3642 = gen_rtx (SYMBOL_REF, Pmode, "__negdf2");
3646 abs_optab->handlers[(int) QImode].insn_code = CODE_FOR_absqi2;
3650 abs_optab->handlers[(int) HImode].insn_code = CODE_FOR_abshi2;
3654 abs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_abspsi2;
3658 abs_optab->handlers[(int) SImode].insn_code = CODE_FOR_abssi2;
3662 abs_optab->handlers[(int) DImode].insn_code = CODE_FOR_absdi2;
3666 abs_optab->handlers[(int) TImode].insn_code = CODE_FOR_absti2;
3670 abs_optab->handlers[(int) SFmode].insn_code = CODE_FOR_abssf2;
3674 abs_optab->handlers[(int) DFmode].insn_code = CODE_FOR_absdf2;
3678 abs_optab->handlers[(int) TFmode].insn_code = CODE_FOR_abstf2;
3680 /* No library calls here! If there is no abs instruction,
3681 expand_expr will generate a conditional negation. */
3685 sqrt_optab->handlers[(int) QImode].insn_code = CODE_FOR_sqrtqi2;
3689 sqrt_optab->handlers[(int) HImode].insn_code = CODE_FOR_sqrthi2;
3691 #ifdef HAVE_sqrtpsi2
3693 sqrt_optab->handlers[(int) PSImode].insn_code = CODE_FOR_sqrtpsi2;
3697 sqrt_optab->handlers[(int) SImode].insn_code = CODE_FOR_sqrtsi2;
3701 sqrt_optab->handlers[(int) DImode].insn_code = CODE_FOR_sqrtdi2;
3705 sqrt_optab->handlers[(int) TImode].insn_code = CODE_FOR_sqrtti2;
3709 sqrt_optab->handlers[(int) SFmode].insn_code = CODE_FOR_sqrtsf2;
3713 sqrt_optab->handlers[(int) DFmode].insn_code = CODE_FOR_sqrtdf2;
3717 sqrt_optab->handlers[(int) TFmode].insn_code = CODE_FOR_sqrttf2;
3719 /* No library calls here! If there is no sqrt instruction expand_builtin
3720 should force the library call. */
3722 #ifdef HAVE_strlenqi
3724 strlen_optab->handlers[(int) QImode].insn_code = CODE_FOR_strlenqi;
3726 #ifdef HAVE_strlenhi
3728 strlen_optab->handlers[(int) HImode].insn_code = CODE_FOR_strlenhi;
3730 #ifdef HAVE_strlenpsi
3732 strlen_optab->handlers[(int) PSImode].insn_code = CODE_FOR_strlenpsi;
3734 #ifdef HAVE_strlensi
3736 strlen_optab->handlers[(int) SImode].insn_code = CODE_FOR_strlensi;
3738 #ifdef HAVE_strlendi
3740 strlen_optab->handlers[(int) DImode].insn_code = CODE_FOR_strlendi;
3742 #ifdef HAVE_strlenti
3744 strlen_optab->handlers[(int) TImode].insn_code = CODE_FOR_strlenti;
3746 /* No library calls here! If there is no strlen instruction expand_builtin
3747 should force the library call. */
3749 #ifdef HAVE_one_cmplqi2
3750 if (HAVE_one_cmplqi2)
3751 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
3753 #ifdef HAVE_one_cmplhi2
3754 if (HAVE_one_cmplhi2)
3755 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
3757 #ifdef HAVE_one_cmplpsi2
3758 if (HAVE_one_cmplpsi2)
3759 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
3761 #ifdef HAVE_one_cmplsi2
3762 if (HAVE_one_cmplsi2)
3763 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
3765 #ifdef HAVE_one_cmpldi2
3766 if (HAVE_one_cmpldi2)
3767 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
3769 #ifdef HAVE_one_cmplti2
3770 if (HAVE_one_cmplti2)
3771 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
3773 one_cmpl_optab->handlers[(int) SImode].libfunc
3774 = gen_rtx (SYMBOL_REF, Pmode, "__one_cmplsi2");
3778 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
3782 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
3786 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
3790 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
3794 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
3798 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
3800 ffs_optab->handlers[(int) SImode].libfunc
3801 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3805 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
3809 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
3813 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
3817 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
3821 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
3825 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
3829 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
3833 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
3837 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
3841 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
3844 #ifdef EXTRA_CC_MODES
3848 #ifdef HAVE_movstrictqi
3849 if (HAVE_movstrictqi)
3850 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
3852 #ifdef HAVE_movstricthi
3853 if (HAVE_movstricthi)
3854 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
3856 #ifdef HAVE_movstrictpsi
3857 if (HAVE_movstrictpsi)
3858 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
3860 #ifdef HAVE_movstrictsi
3861 if (HAVE_movstrictsi)
3862 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
3864 #ifdef HAVE_movstrictdi
3865 if (HAVE_movstrictdi)
3866 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
3868 #ifdef HAVE_movstrictti
3869 if (HAVE_movstrictti)
3870 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
3875 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
3879 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
3883 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
3887 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
3891 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
3895 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
3899 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
3903 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
3907 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
3911 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
3915 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
3919 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
3923 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
3927 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
3931 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
3935 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
3939 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
3943 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
3945 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3946 cmp_optab->handlers[(int) DImode].libfunc
3947 = gen_rtx (SYMBOL_REF, Pmode, "__cmpdi2");
3948 ucmp_optab->handlers[(int) DImode].libfunc
3949 = gen_rtx (SYMBOL_REF, Pmode, "__ucmpdi2");
3953 bcc_gen_fctn[(int) EQ] = gen_beq;
3957 bcc_gen_fctn[(int) NE] = gen_bne;
3961 bcc_gen_fctn[(int) GT] = gen_bgt;
3965 bcc_gen_fctn[(int) GE] = gen_bge;
3969 bcc_gen_fctn[(int) GTU] = gen_bgtu;
3973 bcc_gen_fctn[(int) GEU] = gen_bgeu;
3977 bcc_gen_fctn[(int) LT] = gen_blt;
3981 bcc_gen_fctn[(int) LE] = gen_ble;
3985 bcc_gen_fctn[(int) LTU] = gen_bltu;
3989 bcc_gen_fctn[(int) LEU] = gen_bleu;
3992 for (i = 0; i < NUM_RTX_CODE; i++)
3993 setcc_gen_code[i] = CODE_FOR_nothing;
3997 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
4001 setcc_gen_code[(int) NE] = CODE_FOR_sne;
4005 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
4009 setcc_gen_code[(int) GE] = CODE_FOR_sge;
4013 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
4017 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
4021 setcc_gen_code[(int) LT] = CODE_FOR_slt;
4025 setcc_gen_code[(int) LE] = CODE_FOR_sle;
4029 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
4033 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
4036 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4037 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4038 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4039 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4040 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4041 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
4042 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4043 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4044 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4045 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4046 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4047 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4048 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4049 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4050 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4051 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4052 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4053 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4054 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4055 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4056 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4057 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4058 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4059 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4060 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4061 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4062 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4063 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4064 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4065 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4066 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4067 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4072 /* SCO 3.2 apparently has a broken ldexp. */
4085 #endif /* BROKEN_LDEXP */