1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987-1991 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;
76 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
79 /* SYMBOL_REF rtx's for the library functions that are called
80 implicitly and not via optabs. */
82 rtx extendsfdf2_libfunc;
83 rtx truncdfsf2_libfunc;
103 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
104 gives the gen_function to make a branch to test that condition. */
106 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
108 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
109 gives the insn code to make a store-condition insn
110 to test that condition. */
112 enum insn_code setcc_gen_code[NUM_RTX_CODE];
114 static void emit_float_lib_cmp ();
116 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
117 the result of operation CODE applied to OP0 (and OP1 if it is a binary
120 If the last insn does not set TARGET, don't do anything, but return 1.
122 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
123 don't add the REG_EQUAL note but return 0. Our caller can then try
124 again, ensuring that TARGET is not one of the operands. */
127 add_equal_note (seq, target, code, op0, op1)
137 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
138 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
139 || GET_CODE (seq) != SEQUENCE
140 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
141 || GET_CODE (target) == ZERO_EXTRACT
142 || (! rtx_equal_p (SET_DEST (set), target)
143 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
145 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
146 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
150 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
151 besides the last insn. */
152 if (reg_overlap_mentioned_p (target, op0)
153 || (op1 && reg_overlap_mentioned_p (target, op1)))
154 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
155 if (reg_set_p (target, XVECEXP (seq, 0, i)))
158 if (GET_RTX_CLASS (code) == '1')
159 note = gen_rtx (code, GET_MODE (target), op0);
161 note = gen_rtx (code, GET_MODE (target), op0, op1);
163 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
164 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
165 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
170 /* Generate code to perform an operation specified by BINOPTAB
171 on operands OP0 and OP1, with result having machine-mode MODE.
173 UNSIGNEDP is for the case where we have to widen the operands
174 to perform the operation. It says to use zero-extension.
176 If TARGET is nonzero, the value
177 is generated there, if it is convenient to do so.
178 In all cases an rtx is returned for the locus of the value;
179 this may or may not be TARGET. */
182 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
183 enum machine_mode mode;
188 enum optab_methods methods;
190 enum mode_class class;
191 enum machine_mode wider_mode;
192 enum machine_mode submode = mode_for_size (BITS_PER_WORD, MODE_INT, 0);
194 int commutative_op = 0;
195 int shift_op = (binoptab->code == ASHIFT
196 || binoptab->code == ASHIFTRT
197 || binoptab->code == LSHIFT
198 || binoptab->code == LSHIFTRT
199 || binoptab->code == ROTATE
200 || binoptab->code == ROTATERT);
203 class = GET_MODE_CLASS (mode);
205 op0 = protect_from_queue (op0, 0);
206 op1 = protect_from_queue (op1, 0);
208 target = protect_from_queue (target, 1);
212 op0 = force_not_mem (op0);
213 op1 = force_not_mem (op1);
216 /* If we are inside an appropriately-short loop and one operand is an
217 expensive constant, force it into a register. */
218 if (CONSTANT_P (op0) && preserve_subexpressions_p () && rtx_cost (op0) > 2)
219 op0 = force_reg (mode, op0);
221 if (CONSTANT_P (op1) && preserve_subexpressions_p () && rtx_cost (op1) > 2)
222 op1 = force_reg ((shift_op
223 ? mode_for_size (BITS_PER_WORD, MODE_INT, 0)
227 #if 0 /* Turned off because it seems to be a kludgy method. */
228 /* If subtracting integer from pointer, and the pointer has a special mode,
229 then change it to an add. We use the add insn of Pmode for combining
230 integers with pointers, and the sub insn to subtract two pointers. */
232 if (binoptab == sub_optab
233 && GET_MODE (op0) == Pmode && GET_MODE (op1) != Pmode)
235 op1 = negate_rtx (GET_MODE(op1), op1);
236 binoptab = add_optab;
240 /* Record where to delete back to if we backtrack. */
241 last = get_last_insn ();
243 /* If operation is commutative,
244 try to make the first operand a register.
245 Even better, try to make it the same as the target.
246 Also try to make the last operand a constant. */
247 if (GET_RTX_CLASS (binoptab->code) == 'c'
248 || binoptab == smul_widen_optab
249 || binoptab == umul_widen_optab)
253 if (((target == 0 || GET_CODE (target) == REG)
254 ? ((GET_CODE (op1) == REG
255 && GET_CODE (op0) != REG)
257 : rtx_equal_p (op1, target))
258 || GET_CODE (op0) == CONST_INT)
266 /* If we can do it with a three-operand insn, do so. */
268 if (methods != OPTAB_MUST_WIDEN
269 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
271 int icode = (int) binoptab->handlers[(int) mode].insn_code;
272 enum machine_mode mode0 = insn_operand_mode[icode][1];
273 enum machine_mode mode1 = insn_operand_mode[icode][2];
275 rtx xop0 = op0, xop1 = op1;
280 temp = gen_reg_rtx (mode);
282 /* If it is a commutative operator and the modes would match
283 if we would swap the operands, we can save the conversions. */
286 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
287 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
291 tmp = op0; op0 = op1; op1 = tmp;
292 tmp = xop0; xop0 = xop1; xop1 = tmp;
296 /* In case the insn wants input operands in modes different from
297 the result, convert the operands. */
299 if (GET_MODE (op0) != VOIDmode
300 && GET_MODE (op0) != mode0)
301 xop0 = convert_to_mode (mode0, xop0, unsignedp);
303 if (GET_MODE (xop1) != VOIDmode
304 && GET_MODE (xop1) != mode1)
305 xop1 = convert_to_mode (mode1, xop1, unsignedp);
307 /* Now, if insn's predicates don't allow our operands, put them into
310 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
311 xop0 = copy_to_mode_reg (mode0, xop0);
313 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
314 xop1 = copy_to_mode_reg (mode1, xop1);
316 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
317 temp = gen_reg_rtx (mode);
319 pat = GEN_FCN (icode) (temp, xop0, xop1);
322 /* If PAT is a multi-insn sequence, try to add an appropriate
323 REG_EQUAL note to it. If we can't because TEMP conflicts with an
324 operand, call ourselves again, this time without a target. */
325 if (GET_CODE (pat) == SEQUENCE
326 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
328 delete_insns_since (last);
329 return expand_binop (mode, binoptab, op0, op1, 0, unsignedp,
337 delete_insns_since (last);
340 /* These can be done a word at a time. */
341 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
343 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
344 && binoptab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
350 /* If TARGET is the same as one of the operands, the REG_EQUAL note
351 won't be accurate, so use a new target. */
352 if (target == 0 || target == op0 || target == op1)
353 target = gen_reg_rtx (mode);
357 /* Do the actual arithmetic. */
358 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
360 rtx target_piece = operand_subword (target, i, 1, mode);
361 rtx x = expand_binop (submode, binoptab,
362 operand_subword_force (op0, i, mode),
363 operand_subword_force (op1, i, mode),
364 target_piece, unsignedp, methods);
365 if (target_piece != x)
366 emit_move_insn (target_piece, x);
369 insns = get_insns ();
372 if (binoptab->code != UNKNOWN)
373 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
377 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
381 /* These can be done a word at a time by propagating carries. */
382 if ((binoptab == add_optab || binoptab == sub_optab)
384 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
385 && binoptab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
388 rtx carry_tmp = gen_reg_rtx (submode);
389 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
390 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
391 rtx carry_in, carry_out;
393 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
394 value is one of those, use it. Otherwise, use 1 since it is the
395 one easiest to get. */
396 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
397 int normalizep = STORE_FLAG_VALUE;
402 /* Prepare the operands. */
403 op0 = force_reg (mode, op0);
404 op1 = force_reg (mode, op1);
406 if (target == 0 || GET_CODE (target) != REG
407 || target == op0 || target == op1)
408 target = gen_reg_rtx (mode);
410 /* Do the actual arithmetic. */
411 for (i = 0; i < nwords; i++)
413 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
414 rtx target_piece = operand_subword (target, index, 1, mode);
415 rtx op0_piece = operand_subword_force (op0, index, mode);
416 rtx op1_piece = operand_subword_force (op1, index, mode);
419 /* Main add/subtract of the input operands. */
420 x = expand_binop (submode, binoptab,
421 op0_piece, op1_piece,
422 target_piece, unsignedp, methods);
428 /* Store carry from main add/subtract. */
429 carry_out = gen_reg_rtx (submode);
430 carry_out = emit_store_flag (carry_out,
431 binoptab == add_optab ? LTU : GTU,
433 submode, 1, normalizep);
440 /* Add/subtract previous carry to main result. */
441 x = expand_binop (submode,
442 normalizep == 1 ? binoptab : otheroptab,
444 target_piece, 1, methods);
445 if (target_piece != x)
446 emit_move_insn (target_piece, x);
450 /* THIS CODE HAS NOT BEEN TESTED. */
451 /* Get out carry from adding/subtracting carry in. */
452 carry_tmp = emit_store_flag (carry_tmp,
453 binoptab == add_optab
456 submode, 1, normalizep);
457 /* Logical-ior the two poss. carry together. */
458 carry_out = expand_binop (submode, ior_optab,
459 carry_out, carry_tmp,
460 carry_out, 0, methods);
466 carry_in = carry_out;
469 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
473 temp = emit_move_insn (target, target);
474 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
475 gen_rtx (binoptab->code, mode, op0, op1),
480 delete_insns_since (last);
483 /* If we want to multiply two two-word values and have normal and widening
484 multiplies of single-word values, we can do this with three smaller
485 multiplications. Note that we do not make a REG_NO_CONFLICT block here
486 because we are not operating on one word at a time.
488 The multiplication proceeds as follows:
489 _______________________
490 [__op0_high_|__op0_low__]
491 _______________________
492 * [__op1_high_|__op1_low__]
493 _______________________________________________
494 _______________________
495 (1) [__op0_low__*__op1_low__]
496 _______________________
497 (2a) [__op0_low__*__op1_high_]
498 _______________________
499 (2b) [__op0_high_*__op1_low__]
500 _______________________
501 (3) [__op0_high_*__op1_high_]
504 This gives a 4-word result. Since we are only interested in the
505 lower 2 words, partial result (3) and the upper words of (2a) and
506 (2b) don't need to be calculated. Hence (2a) and (2b) can be
507 calculated using non-widening multiplication.
509 (1), however, needs to be calculated with an unsigned widening
510 multiplication. If this operation is not directly supported we
511 try using a signed widening multiplication and adjust the result.
512 This adjustment works as follows:
514 If both operands are positive then no adjustment is needed.
516 If the operands have different signs, for example op0_low < 0 and
517 op1_low >= 0, the instruction treats the most significant bit of
518 op0_low as a sign bit instead of a bit with significance
519 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
520 with 2**BITS_PER_WORD - op0_low, and two's complements the
521 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
524 Similarly, if both operands are negative, we need to add
525 (op0_low + op1_low) * 2**BITS_PER_WORD.
527 We use a trick to adjust quickly. We logically shift op0_low right
528 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
529 op0_high (op1_high) before it is used to calculate 2b (2a). If no
530 logical shift exists, we do an arithmetic right shift and subtract
533 if (binoptab == smul_optab
535 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
536 && smul_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
537 && add_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
538 && ((umul_widen_optab->handlers[(int) mode].insn_code
540 || (smul_widen_optab->handlers[(int) mode].insn_code
541 != CODE_FOR_nothing)))
543 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
544 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
545 rtx op0_high = operand_subword_force (op0, high, mode);
546 rtx op0_low = operand_subword_force (op0, low, mode);
547 rtx op1_high = operand_subword_force (op1, high, mode);
548 rtx op1_low = operand_subword_force (op1, low, mode);
553 /* If the target is the same as one of the inputs, don't use it. This
554 prevents problems with the REG_EQUAL note. */
555 if (target == op0 || target == op1)
558 /* Multiply the two lower words to get a double-word product.
559 If unsigned widening multiplication is available, use that;
560 otherwise use the signed form and compensate. */
562 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
564 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
565 target, 1, OPTAB_DIRECT);
567 /* If we didn't succeed, delete everything we did so far. */
569 delete_insns_since (last);
571 op0_xhigh = op0_high, op1_xhigh = op1_high;
575 && smul_widen_optab->handlers[(int) mode].insn_code
578 rtx wordm1 = gen_rtx (CONST_INT, VOIDmode, BITS_PER_WORD - 1);
579 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
580 target, 1, OPTAB_DIRECT);
581 op0_xhigh = expand_binop (submode, lshr_optab, op0_low, wordm1,
584 op0_xhigh = expand_binop (submode, add_optab, op0_high, op0_xhigh,
585 op0_xhigh, 0, OPTAB_DIRECT);
588 op0_xhigh = expand_binop (submode, ashr_optab, op0_low, wordm1,
591 op0_xhigh = expand_binop (submode, sub_optab, op0_high,
592 op0_xhigh, op0_xhigh, 0,
596 op1_xhigh = expand_binop (submode, lshr_optab, op1_low, wordm1,
599 op1_xhigh = expand_binop (SImode, add_optab, op1_high, op1_xhigh,
600 op1_xhigh, 0, OPTAB_DIRECT);
603 op1_xhigh = expand_binop (submode, ashr_optab, op1_low, wordm1,
606 op1_xhigh = expand_binop (SImode, sub_optab, op1_high,
607 op1_xhigh, op1_xhigh, 0,
612 /* If we have been able to directly compute the product of the
613 low-order words of the operands and perform any required adjustments
614 of the operands, we proceed by trying two more multiplications
615 and then computing the appropriate sum.
617 We have checked above that the required addition is provided.
618 Full-word addition will normally always succeed, especially if
619 it is provided at all, so we don't worry about its failure. The
620 multiplication may well fail, however, so we do handle that. */
622 if (product && op0_xhigh && op1_xhigh)
625 rtx product_high = operand_subword (product, high, 1, mode);
626 rtx temp = expand_binop (submode, binoptab, op0_low, op1_xhigh, 0,
631 product_piece = expand_binop (submode, add_optab, temp,
632 product_high, product_high,
634 if (product_piece != product_high)
635 emit_move_insn (product_high, product_piece);
637 temp = expand_binop (submode, binoptab, op1_low, op0_xhigh, 0,
640 product_piece = expand_binop (submode, add_optab, temp,
641 product_high, product_high,
643 if (product_piece != product_high)
644 emit_move_insn (product_high, product_piece);
646 temp = emit_move_insn (product, product);
647 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
648 gen_rtx (MULT, mode, op0, op1),
655 /* If we get here, we couldn't do it for some reason even though we
656 originally thought we could. Delete anything we've emitted in
659 delete_insns_since (last);
662 /* It can't be open-coded in this mode.
663 Use a library call if one is available and caller says that's ok. */
665 if (binoptab->handlers[(int) mode].libfunc
666 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
669 rtx funexp = binoptab->handlers[(int) mode].libfunc;
673 /* Pass 1 for NO_QUEUE so we don't lose any increments
674 if the libcall is cse'd or moved. */
675 emit_library_call (binoptab->handlers[(int) mode].libfunc,
676 1, mode, 2, op0, mode, op1,
678 ? mode_for_size (BITS_PER_WORD, MODE_INT, 0)
681 insns = get_insns ();
684 target = gen_reg_rtx (mode);
685 emit_libcall_block (insns, target, hard_libcall_value (mode),
686 gen_rtx (binoptab->code, mode, op0, op1));
691 delete_insns_since (last);
693 /* It can't be done in this mode. Can we do it in a wider mode? */
695 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
696 || methods == OPTAB_MUST_WIDEN))
697 return 0; /* Caller says, don't even try. */
699 /* Compute the value of METHODS to pass to recursive calls.
700 Don't allow widening to be tried recursively. */
702 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
704 /* Widening is now independent of specific machine modes.
705 It is assumed that widening may be performed to any
706 higher numbered mode in the same mode class. */
708 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
710 for (wider_mode = GET_MODE_WIDER_MODE (mode);
711 ((int) wider_mode < (int) MAX_MACHINE_MODE
712 && GET_MODE_CLASS (wider_mode) == class);
713 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
715 if ((binoptab->handlers[(int) wider_mode].insn_code
717 || (methods == OPTAB_LIB
718 && binoptab->handlers[(int) wider_mode].libfunc))
720 rtx xop0 = op0, xop1 = op1;
723 /* For certain operations, we need not actually extend
724 the narrow operands, as long as we will truncate
725 the results to the same narrowness. */
727 if (binoptab == ior_optab || binoptab == and_optab
728 || binoptab == xor_optab
729 || binoptab == add_optab || binoptab == sub_optab
730 || binoptab == smul_optab
731 || binoptab == ashl_optab || binoptab == lshl_optab)
734 if (GET_MODE (xop0) != VOIDmode
735 && GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT)
739 temp = force_reg (GET_MODE (xop0), xop0);
740 xop0 = gen_rtx (SUBREG, wider_mode, temp, 0);
744 temp = gen_reg_rtx (wider_mode);
745 convert_move (temp, xop0, unsignedp);
749 if (GET_MODE (xop1) != VOIDmode
750 && GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT)
754 temp = force_reg (GET_MODE (xop1), xop1);
755 xop1 = gen_rtx (SUBREG, wider_mode, temp, 0);
759 temp = gen_reg_rtx (wider_mode);
760 convert_move (temp, xop1, unsignedp);
765 temp = expand_binop (wider_mode, binoptab, xop0, xop1, 0,
769 if (class == MODE_FLOAT)
772 target = gen_reg_rtx (mode);
773 convert_move (target, temp, 0);
777 return gen_lowpart (mode, temp);
780 delete_insns_since (last);
788 /* Expand a binary operator which has both signed and unsigned forms.
789 UOPTAB is the optab for unsigned operations, and SOPTAB is for
792 If we widen unsigned operands, we may use a signed wider operation instead
793 of an unsigned wider operation, since the result would be the same. */
796 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
797 enum machine_mode mode;
798 optab uoptab, soptab;
799 rtx op0, op1, target;
801 enum optab_methods methods;
804 optab direct_optab = unsignedp ? uoptab : soptab;
805 struct optab wide_soptab;
807 /* Do it without widening, if possible. */
808 temp = expand_binop (mode, direct_optab, op0, op1, target,
809 unsignedp, OPTAB_DIRECT);
810 if (temp || methods == OPTAB_DIRECT)
813 /* Try widening to a signed int. Make a fake signed optab that
814 hides any signed insn for direct use. */
815 wide_soptab = *soptab;
816 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
817 wide_soptab.handlers[(int) mode].libfunc = 0;
819 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
820 unsignedp, OPTAB_WIDEN);
822 /* For unsigned operands, try widening to an unsigned int. */
823 if (temp == 0 && unsignedp)
824 temp = expand_binop (mode, uoptab, op0, op1, target,
825 unsignedp, OPTAB_WIDEN);
826 if (temp || methods == OPTAB_WIDEN)
829 /* Use the right width lib call if that exists. */
830 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
831 if (temp || methods == OPTAB_LIB)
834 /* Must widen and use a lib call, use either signed or unsigned. */
835 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
840 return expand_binop (mode, uoptab, op0, op1, target,
845 /* Generate code to perform an operation specified by BINOPTAB
846 on operands OP0 and OP1, with two results to TARG1 and TARG2.
847 We assume that the order of the operands for the instruction
848 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
849 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
851 Either TARG0 or TARG1 may be zero, but what that means is that
852 that result is not actually wanted. We will generate it into
853 a dummy pseudo-reg and discard it. They may not both be zero.
855 Returns 1 if this operation can be performed; 0 if not. */
858 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
864 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
865 enum mode_class class;
866 enum machine_mode wider_mode;
869 class = GET_MODE_CLASS (mode);
871 op0 = protect_from_queue (op0, 0);
872 op1 = protect_from_queue (op1, 0);
876 op0 = force_not_mem (op0);
877 op1 = force_not_mem (op1);
880 /* If we are inside an appropriately-short loop and one operand is an
881 expensive constant, force it into a register. */
882 if (CONSTANT_P (op0) && preserve_subexpressions_p () && rtx_cost (op0) > 2)
883 op0 = force_reg (mode, op0);
885 if (CONSTANT_P (op1) && preserve_subexpressions_p () && rtx_cost (op1) > 2)
886 op1 = force_reg (mode, op1);
889 targ0 = protect_from_queue (targ0, 1);
891 targ0 = gen_reg_rtx (mode);
893 targ1 = protect_from_queue (targ1, 1);
895 targ1 = gen_reg_rtx (mode);
897 /* Record where to go back to if we fail. */
898 last = get_last_insn ();
900 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
902 int icode = (int) binoptab->handlers[(int) mode].insn_code;
903 enum machine_mode mode0 = insn_operand_mode[icode][1];
904 enum machine_mode mode1 = insn_operand_mode[icode][2];
906 rtx xop0 = op0, xop1 = op1;
908 /* In case this insn wants input operands in modes different from the
909 result, convert the operands. */
910 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
911 xop0 = convert_to_mode (mode0, xop0, unsignedp);
913 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
914 xop1 = convert_to_mode (mode1, xop1, unsignedp);
916 /* Now, if insn doesn't accept these operands, put them into pseudos. */
917 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
918 xop0 = copy_to_mode_reg (mode0, xop0);
920 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
921 xop1 = copy_to_mode_reg (mode1, xop1);
923 /* We could handle this, but we should always be called with a pseudo
924 for our targets and all insns should take them as outputs. */
925 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
926 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
929 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
936 delete_insns_since (last);
939 /* It can't be done in this mode. Can we do it in a wider mode? */
941 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
943 for (wider_mode = GET_MODE_WIDER_MODE (mode);
944 GET_MODE_CLASS (wider_mode) == class;
945 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
947 if (binoptab->handlers[(int) wider_mode].insn_code
950 register rtx t0 = gen_reg_rtx (wider_mode);
951 register rtx t1 = gen_reg_rtx (wider_mode);
953 if (expand_twoval_binop (binoptab,
954 convert_to_mode (wider_mode, op0,
956 convert_to_mode (wider_mode, op1,
960 convert_move (targ0, t0, unsignedp);
961 convert_move (targ1, t1, unsignedp);
965 delete_insns_since (last);
973 /* Generate code to perform an operation specified by UNOPTAB
974 on operand OP0, with result having machine-mode MODE.
976 UNSIGNEDP is for the case where we have to widen the operands
977 to perform the operation. It says to use zero-extension.
979 If TARGET is nonzero, the value
980 is generated there, if it is convenient to do so.
981 In all cases an rtx is returned for the locus of the value;
982 this may or may not be TARGET. */
985 expand_unop (mode, unoptab, op0, target, unsignedp)
986 enum machine_mode mode;
992 enum mode_class class;
993 enum machine_mode wider_mode;
994 enum machine_mode submode = mode_for_size (BITS_PER_WORD, MODE_INT, 0);
996 rtx last = get_last_insn ();
999 class = GET_MODE_CLASS (mode);
1001 op0 = protect_from_queue (op0, 0);
1005 op0 = force_not_mem (op0);
1009 target = protect_from_queue (target, 1);
1011 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1013 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1014 enum machine_mode mode0 = insn_operand_mode[icode][1];
1020 temp = gen_reg_rtx (mode);
1022 if (GET_MODE (xop0) != VOIDmode
1023 && GET_MODE (xop0) != mode0)
1024 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1026 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1028 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1029 xop0 = copy_to_mode_reg (mode0, xop0);
1031 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1032 temp = gen_reg_rtx (mode);
1034 pat = GEN_FCN (icode) (temp, xop0);
1037 if (GET_CODE (pat) == SEQUENCE
1038 && ! add_equal_note (pat, temp, unoptab->code, xop0, 0))
1040 delete_insns_since (last);
1041 return expand_unop (mode, unoptab, op0, 0, unsignedp);
1049 delete_insns_since (last);
1052 /* These can be done a word at a time. */
1053 if (unoptab == one_cmpl_optab
1054 && class == MODE_INT
1055 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1056 && unoptab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
1061 if (target == 0 || target == op0)
1062 target = gen_reg_rtx (mode);
1066 /* Do the actual arithmetic. */
1067 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1069 rtx target_piece = operand_subword (target, i, 1, mode);
1070 rtx x = expand_unop (submode, unoptab,
1071 operand_subword_force (op0, i, mode),
1072 target_piece, unsignedp);
1073 if (target_piece != x)
1074 emit_move_insn (target_piece, x);
1077 insns = get_insns ();
1080 emit_no_conflict_block (insns, target, op0, 0,
1081 gen_rtx (unoptab->code, mode, op0));
1085 if (unoptab->handlers[(int) mode].libfunc)
1088 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1092 /* Pass 1 for NO_QUEUE so we don't lose any increments
1093 if the libcall is cse'd or moved. */
1094 emit_library_call (unoptab->handlers[(int) mode].libfunc,
1095 1, mode, 1, op0, mode);
1096 insns = get_insns ();
1099 target = gen_reg_rtx (mode);
1100 emit_libcall_block (insns, target, hard_libcall_value (mode),
1101 gen_rtx (unoptab->code, mode, op0));
1106 /* It can't be done in this mode. Can we do it in a wider mode? */
1108 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1110 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1111 GET_MODE_CLASS (wider_mode) == class;
1112 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1114 if ((unoptab->handlers[(int) wider_mode].insn_code
1115 != CODE_FOR_nothing)
1116 || unoptab->handlers[(int) wider_mode].libfunc)
1118 if (GET_MODE (op0) != VOIDmode
1119 && GET_MODE_BITSIZE (wider_mode) <= HOST_BITS_PER_INT)
1121 temp = gen_reg_rtx (wider_mode);
1122 convert_move (temp, op0, unsignedp);
1126 target = expand_unop (wider_mode, unoptab, op0, 0, unsignedp);
1127 if (class == MODE_FLOAT)
1130 target = gen_reg_rtx (mode);
1131 convert_move (target, temp, 0);
1135 return gen_lowpart (mode, target);
1143 /* Generate an instruction whose insn-code is INSN_CODE,
1144 with two operands: an output TARGET and an input OP0.
1145 TARGET *must* be nonzero, and the output is always stored there.
1146 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1147 the value that is stored into TARGET. */
1150 emit_unop_insn (icode, target, op0, code)
1157 enum machine_mode mode0 = insn_operand_mode[icode][1];
1160 temp = target = protect_from_queue (target, 1);
1162 op0 = protect_from_queue (op0, 0);
1165 op0 = force_not_mem (op0);
1167 /* Now, if insn does not accept our operands, put them into pseudos. */
1169 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
1170 op0 = copy_to_mode_reg (mode0, op0);
1172 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
1173 || (flag_force_mem && GET_CODE (temp) == MEM))
1174 temp = gen_reg_rtx (GET_MODE (temp));
1176 pat = GEN_FCN (icode) (temp, op0);
1178 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
1179 add_equal_note (pat, temp, code, op0, 0);
1184 emit_move_insn (target, temp);
1187 /* Emit code to perform a series of operations on a multi-word quantity, one
1190 Such a block is preceeded by a CLOBBER of the output, consists of multiple
1191 insns, each setting one word of the output, and followed by a SET copying
1192 the output to itself.
1194 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1195 note indicating that it doesn't conflict with the (also multi-word)
1196 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1199 INSNS is a block of code generated to perform the operation, not including
1200 the CLOBBER and final copy. All insns that compute intermediate values
1201 are first emitted, followed by the block as described above. Only
1202 INSNs are allowed in the block; no library calls or jumps may be
1205 TARGET, OP0, and OP1 are the output and inputs of the operations,
1206 respectively. OP1 may be zero for a unary operation.
1208 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1211 If TARGET is not a register, INSNS is simply emitted with no special
1214 The final insn emitted is returned. */
1217 emit_no_conflict_block (insns, target, op0, op1, equiv)
1223 rtx prev, next, first, last, insn;
1225 if (GET_CODE (target) != REG || reload_in_progress)
1226 return emit_insns (insns);
1228 /* First emit all insns that do not store into words of the output and remove
1229 these from the list. */
1230 for (insn = insns; insn; insn = next)
1235 next = NEXT_INSN (insn);
1237 if (GET_CODE (insn) != INSN)
1240 if (GET_CODE (PATTERN (insn)) == SET)
1241 set = PATTERN (insn);
1242 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1244 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
1245 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1247 set = XVECEXP (PATTERN (insn), 0, i);
1255 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
1257 if (PREV_INSN (insn))
1258 NEXT_INSN (PREV_INSN (insn)) = next;
1263 PREV_INSN (next) = PREV_INSN (insn);
1269 prev = get_last_insn ();
1271 /* Now write the CLOBBER of the output, followed by the setting of each
1272 of the words, followed by the final copy. */
1273 if (target != op0 && target != op1)
1274 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
1276 for (insn = insns; insn; insn = next)
1278 next = NEXT_INSN (insn);
1281 if (op1 && GET_CODE (op1) == REG)
1282 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
1285 if (op0 && GET_CODE (op0) == REG)
1286 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
1290 last = emit_move_insn (target, target);
1292 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1295 first = get_insns ();
1297 first = NEXT_INSN (prev);
1299 /* Encapsulate the block so it gets manipulated as a unit. */
1300 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1302 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1307 /* Emit code to make a call to a constant function or a library call.
1309 INSNS is a list containing all insns emitted in the call.
1310 These insns leave the result in RESULT. Our block is to copy RESULT
1311 to TARGET, which is logically equivalent to EQUIV.
1313 We first emit any insns that set a pseudo on the assumption that these are
1314 loading constants into registers; doing so allows them to be safely cse'ed
1315 between blocks. Then we emit all the other insns in the block, followed by
1316 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
1317 note with an operand of EQUIV.
1319 Except for the first group of insns (the ones setting pseudos), the
1320 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
1323 emit_libcall_block (insns, target, result, equiv)
1329 rtx prev, next, first, last, insn;
1331 /* First emit all insns that set pseudos. Remove them from the list as
1334 for (insn = insns; insn; insn = next)
1336 rtx set = single_set (insn);
1338 next = NEXT_INSN (insn);
1340 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
1341 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
1343 if (PREV_INSN (insn))
1344 NEXT_INSN (PREV_INSN (insn)) = next;
1349 PREV_INSN (next) = PREV_INSN (insn);
1355 prev = get_last_insn ();
1357 /* Write the remaining insns followed by the final copy. */
1359 for (insn = insns; insn; insn = next)
1361 next = NEXT_INSN (insn);
1366 last = emit_move_insn (target, result);
1367 REG_NOTES (last) = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
1370 first = get_insns ();
1372 first = NEXT_INSN (prev);
1374 /* Encapsulate the block so it gets manipulated as a unit. */
1375 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
1377 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
1380 /* Generate code to store zero in X. */
1386 emit_move_insn (x, const0_rtx);
1389 /* Generate code to store 1 in X
1390 assuming it contains zero beforehand. */
1393 emit_0_to_1_insn (x)
1396 emit_move_insn (x, const1_rtx);
1399 /* Generate code to compare X with Y
1400 so that the condition codes are set.
1402 MODE is the mode of the inputs (in case they are const_int).
1403 UNSIGNEDP nonzero says that X and Y are unsigned;
1404 this matters if they need to be widened.
1406 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
1407 and ALIGN specifies the known shared alignment of X and Y.
1409 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
1410 It is ignored for fixed-point and block comparisons;
1411 it is used only for floating-point comparisons. */
1414 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
1416 enum rtx_code comparison;
1421 enum mode_class class;
1422 enum machine_mode wider_mode;
1424 class = GET_MODE_CLASS (mode);
1426 /* They could both be VOIDmode if both args are immediate constants,
1427 but we should fold that at an earlier stage.
1428 With no special code here, this will call abort,
1429 reminding the programmer to implement such folding. */
1431 if (mode != BLKmode && flag_force_mem)
1433 x = force_not_mem (x);
1434 y = force_not_mem (y);
1437 /* If we are inside an appropriately-short loop and one operand is an
1438 expensive constant, force it into a register. */
1439 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x) > 2)
1440 x = force_reg (mode, x);
1442 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y) > 2)
1443 y = force_reg (mode, y);
1445 /* Don't let both operands fail to indicate the mode. */
1446 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
1447 x = force_reg (mode, x);
1449 /* Handle all BLKmode compares. */
1451 if (mode == BLKmode)
1454 x = protect_from_queue (x, 0);
1455 y = protect_from_queue (y, 0);
1459 #ifdef HAVE_cmpstrqi
1461 && GET_CODE (size) == CONST_INT
1462 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
1464 enum machine_mode result_mode
1465 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
1466 rtx result = gen_reg_rtx (result_mode);
1467 emit_insn (gen_cmpstrqi (result, x, y, size,
1468 gen_rtx (CONST_INT, VOIDmode, align)));
1469 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1473 #ifdef HAVE_cmpstrhi
1475 && GET_CODE (size) == CONST_INT
1476 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
1478 enum machine_mode result_mode
1479 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
1480 rtx result = gen_reg_rtx (result_mode);
1481 emit_insn (gen_cmpstrhi (result, x, y, size,
1482 gen_rtx (CONST_INT, VOIDmode, align)));
1483 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1487 #ifdef HAVE_cmpstrsi
1490 enum machine_mode result_mode
1491 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
1492 rtx result = gen_reg_rtx (result_mode);
1493 emit_insn (gen_cmpstrsi (result, x, y,
1494 convert_to_mode (SImode, size, 1),
1495 gen_rtx (CONST_INT, VOIDmode, align)));
1496 emit_cmp_insn (result, const0_rtx, comparison, 0, result_mode, 0, 0);
1501 #ifdef TARGET_MEM_FUNCTIONS
1502 emit_library_call (memcmp_libfunc, 0,
1503 TYPE_MODE (integer_type_node), 3,
1504 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1507 emit_library_call (bcmp_libfunc, 0,
1508 TYPE_MODE (integer_type_node), 3,
1509 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
1512 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
1513 const0_rtx, comparison, 0,
1514 TYPE_MODE (integer_type_node), 0, 0);
1519 /* Handle some compares against zero. */
1521 if (y == CONST0_RTX (mode)
1522 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1524 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
1527 x = protect_from_queue (x, 0);
1528 y = protect_from_queue (y, 0);
1530 /* Now, if insn does accept these operands, put them into pseudos. */
1531 if (! (*insn_operand_predicate[icode][0])
1532 (x, insn_operand_mode[icode][0]))
1533 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1535 emit_insn (GEN_FCN (icode) (x));
1539 /* Handle compares for which there is a directly suitable insn. */
1541 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1543 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
1546 x = protect_from_queue (x, 0);
1547 y = protect_from_queue (y, 0);
1549 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1550 if (! (*insn_operand_predicate[icode][0])
1551 (x, insn_operand_mode[icode][0]))
1552 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
1554 if (! (*insn_operand_predicate[icode][1])
1555 (y, insn_operand_mode[icode][1]))
1556 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
1558 emit_insn (GEN_FCN (icode) (x, y));
1562 /* Try widening if we can find a direct insn that way. */
1564 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1566 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1567 GET_MODE_CLASS (wider_mode) == class;
1568 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1570 if (cmp_optab->handlers[(int) wider_mode].insn_code
1571 != CODE_FOR_nothing)
1573 x = convert_to_mode (wider_mode, x, unsignedp);
1574 y = convert_to_mode (wider_mode, y, unsignedp);
1575 emit_cmp_insn (x, y, comparison, 0,
1576 wider_mode, unsignedp, align);
1582 /* Handle a lib call just for the mode we are using. */
1584 if (cmp_optab->handlers[(int) mode].libfunc
1585 && class != MODE_FLOAT)
1587 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
1588 /* If we want unsigned, and this mode has a distinct unsigned
1589 comparison routine, use that. */
1590 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
1591 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
1593 emit_library_call (libfunc, 0,
1594 SImode, 2, x, mode, y, mode);
1596 /* Integer comparison returns a result that must be compared against 1,
1597 so that even if we do an unsigned compare afterward,
1598 there is still a value that can represent the result "less than". */
1600 emit_cmp_insn (hard_libcall_value (SImode), const1_rtx,
1601 comparison, 0, SImode, unsignedp, 0);
1605 if (class == MODE_FLOAT)
1606 emit_float_lib_cmp (x, y, comparison);
1612 /* Nonzero if a compare of mode MODE can be done straightforwardly
1613 (without splitting it into pieces). */
1616 can_compare_p (mode)
1617 enum machine_mode mode;
1621 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
1623 mode = GET_MODE_WIDER_MODE (mode);
1624 } while (mode != VOIDmode);
1629 /* Emit a library call comparison between floating point X and Y.
1630 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
1633 emit_float_lib_cmp (x, y, comparison)
1635 enum rtx_code comparison;
1637 enum machine_mode mode = GET_MODE (x);
1644 libfunc = eqsf2_libfunc;
1648 libfunc = nesf2_libfunc;
1652 libfunc = gtsf2_libfunc;
1656 libfunc = gesf2_libfunc;
1660 libfunc = ltsf2_libfunc;
1664 libfunc = lesf2_libfunc;
1667 else if (mode == DFmode)
1671 libfunc = eqdf2_libfunc;
1675 libfunc = nedf2_libfunc;
1679 libfunc = gtdf2_libfunc;
1683 libfunc = gedf2_libfunc;
1687 libfunc = ltdf2_libfunc;
1691 libfunc = ledf2_libfunc;
1696 enum machine_mode wider_mode;
1698 for (wider_mode = GET_MODE_WIDER_MODE (mode);
1699 GET_MODE_CLASS (wider_mode) == MODE_FLOAT;
1700 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1702 if ((cmp_optab->handlers[(int) wider_mode].insn_code
1703 != CODE_FOR_nothing)
1704 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
1706 x = convert_to_mode (wider_mode, x, 0);
1707 y = convert_to_mode (wider_mode, y, 0);
1708 emit_float_lib_cmp (x, y, comparison);
1715 emit_library_call (libfunc, 0,
1716 SImode, 2, x, mode, y, mode);
1718 emit_cmp_insn (hard_libcall_value (SImode), const0_rtx, comparison,
1722 /* Generate code to indirectly jump to a location given in the rtx LOC. */
1725 emit_indirect_jump (loc)
1728 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
1730 loc = copy_to_mode_reg (insn_operand_mode[(int)CODE_FOR_indirect_jump][0],
1733 emit_jump_insn (gen_indirect_jump (loc));
1736 /* These three functions generate an insn body and return it
1737 rather than emitting the insn.
1739 They do not protect from queued increments,
1740 because they may be used 1) in protect_from_queue itself
1741 and 2) in other passes where there is no queue. */
1743 /* Generate and return an insn body to add Y to X. */
1746 gen_add2_insn (x, y)
1749 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
1751 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1752 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1753 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1756 return (GEN_FCN (icode) (x, x, y));
1760 have_add2_insn (mode)
1761 enum machine_mode mode;
1763 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1766 /* Generate and return an insn body to subtract Y from X. */
1769 gen_sub2_insn (x, y)
1772 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
1774 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
1775 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
1776 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
1779 return (GEN_FCN (icode) (x, x, y));
1783 have_sub2_insn (mode)
1784 enum machine_mode mode;
1786 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
1789 /* Generate the body of an instruction to copy Y into X. */
1792 gen_move_insn (x, y)
1795 register enum machine_mode mode = GET_MODE (x);
1796 enum insn_code insn_code;
1798 if (mode == VOIDmode)
1799 mode = GET_MODE (y);
1801 insn_code = mov_optab->handlers[(int) mode].insn_code;
1803 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
1804 find a mode to do it in. If we have a movcc, use it. Otherwise,
1805 find the MODE_INT mode of the same width. */
1807 if (insn_code == CODE_FOR_nothing)
1809 enum machine_mode tmode = VOIDmode;
1812 if (GET_MODE_CLASS (mode) == MODE_CC && mode != CCmode
1813 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
1815 else if (GET_MODE_CLASS (mode) == MODE_CC)
1816 for (tmode = QImode; tmode != VOIDmode;
1817 tmode = GET_MODE_WIDER_MODE (tmode))
1818 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
1821 if (tmode == VOIDmode)
1824 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
1825 may call change_address which is not appropriate if we were
1826 called when a reload was in progress. We don't have to worry
1827 about changing the address since the size in bytes is supposed to
1828 be the same. Copy the MEM to change the mode and move any
1829 substitutions from the old MEM to the new one. */
1831 if (reload_in_progress)
1833 x = gen_lowpart_common (tmode, x1);
1834 if (x == 0 && GET_CODE (x1) == MEM)
1836 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
1837 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
1838 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
1839 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
1840 copy_replacements (x1, x);
1843 y = gen_lowpart_common (tmode, y1);
1844 if (y == 0 && GET_CODE (y1) == MEM)
1846 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
1847 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
1848 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
1849 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
1850 copy_replacements (y1, y);
1855 x = gen_lowpart (tmode, x);
1856 y = gen_lowpart (tmode, y);
1859 insn_code = mov_optab->handlers[(int) tmode].insn_code;
1862 return (GEN_FCN (insn_code) (x, y));
1865 /* Tables of patterns for extending one integer mode to another. */
1866 static enum insn_code zero_extend_codes[MAX_MACHINE_MODE][MAX_MACHINE_MODE];
1867 static enum insn_code sign_extend_codes[MAX_MACHINE_MODE][MAX_MACHINE_MODE];
1869 /* Return nonzero if it's possible to extend FROM_MODE to TO_MODE.
1870 UNSIGNEDP specifies zero-extension instead of sign-extension.
1872 Actually, the value is the instruction code for the extension pattern. */
1875 can_extend_p (to_mode, from_mode, unsignedp)
1876 enum machine_mode to_mode, from_mode;
1879 return ((unsignedp ? zero_extend_codes : sign_extend_codes)
1880 [(int) to_mode][(int) from_mode]);
1883 /* Generate the body of an insn to extend Y (with mode MFROM)
1884 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
1887 gen_extend_insn (x, y, mto, mfrom, unsignedp)
1889 enum machine_mode mto, mfrom;
1892 return (GEN_FCN ((unsignedp ? zero_extend_codes : sign_extend_codes)
1893 [(int)mto][(int)mfrom])
1900 bzero (sign_extend_codes, sizeof sign_extend_codes);
1901 bzero (zero_extend_codes, sizeof zero_extend_codes);
1903 #ifdef HAVE_extendditi2
1904 if (HAVE_extendditi2)
1905 sign_extend_codes[(int) TImode][(int) DImode] = CODE_FOR_extendditi2;
1907 #ifdef HAVE_extendsiti2
1908 if (HAVE_extendsiti2)
1909 sign_extend_codes[(int) TImode][(int) SImode] = CODE_FOR_extendsiti2;
1911 #ifdef HAVE_extendhiti2
1912 if (HAVE_extendhiti2)
1913 sign_extend_codes[(int) TImode][(int) HImode] = CODE_FOR_extendhiti2;
1915 #ifdef HAVE_extendqiti2
1916 if (HAVE_extendqiti2)
1917 sign_extend_codes[(int) TImode][(int) QImode] = CODE_FOR_extendqiti2;
1919 #ifdef HAVE_extendsidi2
1920 if (HAVE_extendsidi2)
1921 sign_extend_codes[(int) DImode][(int) SImode] = CODE_FOR_extendsidi2;
1923 #ifdef HAVE_extendhidi2
1924 if (HAVE_extendhidi2)
1925 sign_extend_codes[(int) DImode][(int) HImode] = CODE_FOR_extendhidi2;
1927 #ifdef HAVE_extendqidi2
1928 if (HAVE_extendqidi2)
1929 sign_extend_codes[(int) DImode][(int) QImode] = CODE_FOR_extendqidi2;
1931 #ifdef HAVE_extendhisi2
1932 if (HAVE_extendhisi2)
1933 sign_extend_codes[(int) SImode][(int) HImode] = CODE_FOR_extendhisi2;
1935 #ifdef HAVE_extendqisi2
1936 if (HAVE_extendqisi2)
1937 sign_extend_codes[(int) SImode][(int) QImode] = CODE_FOR_extendqisi2;
1939 #ifdef HAVE_extendqihi2
1940 if (HAVE_extendqihi2)
1941 sign_extend_codes[(int) HImode][(int) QImode] = CODE_FOR_extendqihi2;
1944 #ifdef HAVE_zero_extendditi2
1945 if (HAVE_zero_extendsiti2)
1946 zero_extend_codes[(int) TImode][(int) DImode] = CODE_FOR_zero_extendditi2;
1948 #ifdef HAVE_zero_extendsiti2
1949 if (HAVE_zero_extendsiti2)
1950 zero_extend_codes[(int) TImode][(int) SImode] = CODE_FOR_zero_extendsiti2;
1952 #ifdef HAVE_zero_extendhiti2
1953 if (HAVE_zero_extendhiti2)
1954 zero_extend_codes[(int) TImode][(int) HImode] = CODE_FOR_zero_extendhiti2;
1956 #ifdef HAVE_zero_extendqiti2
1957 if (HAVE_zero_extendqiti2)
1958 zero_extend_codes[(int) TImode][(int) QImode] = CODE_FOR_zero_extendqiti2;
1960 #ifdef HAVE_zero_extendsidi2
1961 if (HAVE_zero_extendsidi2)
1962 zero_extend_codes[(int) DImode][(int) SImode] = CODE_FOR_zero_extendsidi2;
1964 #ifdef HAVE_zero_extendhidi2
1965 if (HAVE_zero_extendhidi2)
1966 zero_extend_codes[(int) DImode][(int) HImode] = CODE_FOR_zero_extendhidi2;
1968 #ifdef HAVE_zero_extendqidi2
1969 if (HAVE_zero_extendqidi2)
1970 zero_extend_codes[(int) DImode][(int) QImode] = CODE_FOR_zero_extendqidi2;
1972 #ifdef HAVE_zero_extendhisi2
1973 if (HAVE_zero_extendhisi2)
1974 zero_extend_codes[(int) SImode][(int) HImode] = CODE_FOR_zero_extendhisi2;
1976 #ifdef HAVE_zero_extendqisi2
1977 if (HAVE_zero_extendqisi2)
1978 zero_extend_codes[(int) SImode][(int) QImode] = CODE_FOR_zero_extendqisi2;
1980 #ifdef HAVE_zero_extendqihi2
1981 if (HAVE_zero_extendqihi2)
1982 zero_extend_codes[(int) HImode][(int) QImode] = CODE_FOR_zero_extendqihi2;
1986 /* can_fix_p and can_float_p say whether the target machine
1987 can directly convert a given fixed point type to
1988 a given floating point type, or vice versa.
1989 The returned value is the CODE_FOR_... value to use,
1990 or CODE_FOR_nothing if these modes cannot be directly converted. */
1992 static enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1993 static enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1994 static enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
1996 /* *TRUNCP_PTR is set to 1 if it is necessary to output
1997 an explicit FTRUNC insn before the fix insn; otherwise 0. */
1999 static enum insn_code
2000 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
2001 enum machine_mode fltmode, fixmode;
2006 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
2007 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
2009 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
2012 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
2014 return CODE_FOR_nothing;
2017 static enum insn_code
2018 can_float_p (fltmode, fixmode, unsignedp)
2019 enum machine_mode fixmode, fltmode;
2022 return floattab[(int) fltmode][(int) fixmode][unsignedp];
2029 for (p = fixtab[0][0];
2030 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
2032 *p = CODE_FOR_nothing;
2033 for (p = fixtrunctab[0][0];
2034 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
2036 *p = CODE_FOR_nothing;
2038 #ifdef HAVE_fixsfqi2
2040 fixtab[(int) SFmode][(int) QImode][0] = CODE_FOR_fixsfqi2;
2042 #ifdef HAVE_fixsfhi2
2044 fixtab[(int) SFmode][(int) HImode][0] = CODE_FOR_fixsfhi2;
2046 #ifdef HAVE_fixsfsi2
2048 fixtab[(int) SFmode][(int) SImode][0] = CODE_FOR_fixsfsi2;
2050 #ifdef HAVE_fixsfdi2
2052 fixtab[(int) SFmode][(int) DImode][0] = CODE_FOR_fixsfdi2;
2055 #ifdef HAVE_fixdfqi2
2057 fixtab[(int) DFmode][(int) QImode][0] = CODE_FOR_fixdfqi2;
2059 #ifdef HAVE_fixdfhi2
2061 fixtab[(int) DFmode][(int) HImode][0] = CODE_FOR_fixdfhi2;
2063 #ifdef HAVE_fixdfsi2
2065 fixtab[(int) DFmode][(int) SImode][0] = CODE_FOR_fixdfsi2;
2067 #ifdef HAVE_fixdfdi2
2069 fixtab[(int) DFmode][(int) DImode][0] = CODE_FOR_fixdfdi2;
2071 #ifdef HAVE_fixdfti2
2073 fixtab[(int) DFmode][(int) TImode][0] = CODE_FOR_fixdfti2;
2076 #ifdef HAVE_fixtfqi2
2078 fixtab[(int) TFmode][(int) QImode][0] = CODE_FOR_fixtfqi2;
2080 #ifdef HAVE_fixtfhi2
2082 fixtab[(int) TFmode][(int) HImode][0] = CODE_FOR_fixtfhi2;
2084 #ifdef HAVE_fixtfsi2
2086 fixtab[(int) TFmode][(int) SImode][0] = CODE_FOR_fixtfsi2;
2088 #ifdef HAVE_fixtfdi2
2090 fixtab[(int) TFmode][(int) DImode][0] = CODE_FOR_fixtfdi2;
2092 #ifdef HAVE_fixtfti2
2094 fixtab[(int) TFmode][(int) TImode][0] = CODE_FOR_fixtfti2;
2097 #ifdef HAVE_fixunssfqi2
2098 if (HAVE_fixunssfqi2)
2099 fixtab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixunssfqi2;
2101 #ifdef HAVE_fixunssfhi2
2102 if (HAVE_fixunssfhi2)
2103 fixtab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixunssfhi2;
2105 #ifdef HAVE_fixunssfsi2
2106 if (HAVE_fixunssfsi2)
2107 fixtab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixunssfsi2;
2109 #ifdef HAVE_fixunssfdi2
2110 if (HAVE_fixunssfdi2)
2111 fixtab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixunssfdi2;
2114 #ifdef HAVE_fixunsdfqi2
2115 if (HAVE_fixunsdfqi2)
2116 fixtab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixunsdfqi2;
2118 #ifdef HAVE_fixunsdfhi2
2119 if (HAVE_fixunsdfhi2)
2120 fixtab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixunsdfhi2;
2122 #ifdef HAVE_fixunsdfsi2
2123 if (HAVE_fixunsdfsi2)
2124 fixtab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixunsdfsi2;
2126 #ifdef HAVE_fixunsdfdi2
2127 if (HAVE_fixunsdfdi2)
2128 fixtab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixunsdfdi2;
2130 #ifdef HAVE_fixunsdfti2
2131 if (HAVE_fixunsdfti2)
2132 fixtab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixunsdfti2;
2135 #ifdef HAVE_fixunstfqi2
2136 if (HAVE_fixunstfqi2)
2137 fixtab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixunstfqi2;
2139 #ifdef HAVE_fixunstfhi2
2140 if (HAVE_fixunstfhi2)
2141 fixtab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixunstfhi2;
2143 #ifdef HAVE_fixunstfsi2
2144 if (HAVE_fixunstfsi2)
2145 fixtab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixunstfsi2;
2147 #ifdef HAVE_fixunstfdi2
2148 if (HAVE_fixunstfdi2)
2149 fixtab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixunstfdi2;
2151 #ifdef HAVE_fixunstfti2
2152 if (HAVE_fixunstfti2)
2153 fixtab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixunstfti2;
2156 #ifdef HAVE_fix_truncsfqi2
2157 if (HAVE_fix_truncsfqi2)
2158 fixtrunctab[(int) SFmode][(int) QImode][0] = CODE_FOR_fix_truncsfqi2;
2160 #ifdef HAVE_fix_truncsfhi2
2161 if (HAVE_fix_truncsfhi2)
2162 fixtrunctab[(int) SFmode][(int) HImode][0] = CODE_FOR_fix_truncsfhi2;
2164 #ifdef HAVE_fix_truncsfsi2
2165 if (HAVE_fix_truncsfsi2)
2166 fixtrunctab[(int) SFmode][(int) SImode][0] = CODE_FOR_fix_truncsfsi2;
2168 #ifdef HAVE_fix_truncsfdi2
2169 if (HAVE_fix_truncsfdi2)
2170 fixtrunctab[(int) SFmode][(int) DImode][0] = CODE_FOR_fix_truncsfdi2;
2173 #ifdef HAVE_fix_truncdfqi2
2174 if (HAVE_fix_truncdfsi2)
2175 fixtrunctab[(int) DFmode][(int) QImode][0] = CODE_FOR_fix_truncdfqi2;
2177 #ifdef HAVE_fix_truncdfhi2
2178 if (HAVE_fix_truncdfhi2)
2179 fixtrunctab[(int) DFmode][(int) HImode][0] = CODE_FOR_fix_truncdfhi2;
2181 #ifdef HAVE_fix_truncdfsi2
2182 if (HAVE_fix_truncdfsi2)
2183 fixtrunctab[(int) DFmode][(int) SImode][0] = CODE_FOR_fix_truncdfsi2;
2185 #ifdef HAVE_fix_truncdfdi2
2186 if (HAVE_fix_truncdfdi2)
2187 fixtrunctab[(int) DFmode][(int) DImode][0] = CODE_FOR_fix_truncdfdi2;
2189 #ifdef HAVE_fix_truncdfti2
2190 if (HAVE_fix_truncdfti2)
2191 fixtrunctab[(int) DFmode][(int) TImode][0] = CODE_FOR_fix_truncdfti2;
2194 #ifdef HAVE_fix_trunctfqi2
2195 if (HAVE_fix_trunctfqi2)
2196 fixtrunctab[(int) TFmode][(int) QImode][0] = CODE_FOR_fix_trunctfqi2;
2198 #ifdef HAVE_fix_trunctfhi2
2199 if (HAVE_fix_trunctfhi2)
2200 fixtrunctab[(int) TFmode][(int) HImode][0] = CODE_FOR_fix_trunctfhi2;
2202 #ifdef HAVE_fix_trunctfsi2
2203 if (HAVE_fix_trunctfsi2)
2204 fixtrunctab[(int) TFmode][(int) SImode][0] = CODE_FOR_fix_trunctfsi2;
2206 #ifdef HAVE_fix_trunctfdi2
2207 if (HAVE_fix_trunctfdi2)
2208 fixtrunctab[(int) TFmode][(int) DImode][0] = CODE_FOR_fix_trunctfdi2;
2210 #ifdef HAVE_fix_trunctfti2
2211 if (HAVE_fix_trunctfti2)
2212 fixtrunctab[(int) TFmode][(int) TImode][0] = CODE_FOR_fix_trunctfti2;
2215 #ifdef HAVE_fixuns_truncsfqi2
2216 if (HAVE_fixuns_truncsfqi2)
2217 fixtrunctab[(int) SFmode][(int) QImode][1] = CODE_FOR_fixuns_truncsfqi2;
2219 #ifdef HAVE_fixuns_truncsfhi2
2220 if (HAVE_fixuns_truncsfhi2)
2221 fixtrunctab[(int) SFmode][(int) HImode][1] = CODE_FOR_fixuns_truncsfhi2;
2223 #ifdef HAVE_fixuns_truncsfsi2
2224 if (HAVE_fixuns_truncsfsi2)
2225 fixtrunctab[(int) SFmode][(int) SImode][1] = CODE_FOR_fixuns_truncsfsi2;
2227 #ifdef HAVE_fixuns_truncsfdi2
2228 if (HAVE_fixuns_truncsfdi2)
2229 fixtrunctab[(int) SFmode][(int) DImode][1] = CODE_FOR_fixuns_truncsfdi2;
2232 #ifdef HAVE_fixuns_truncdfqi2
2233 if (HAVE_fixuns_truncdfqi2)
2234 fixtrunctab[(int) DFmode][(int) QImode][1] = CODE_FOR_fixuns_truncdfqi2;
2236 #ifdef HAVE_fixuns_truncdfhi2
2237 if (HAVE_fixuns_truncdfhi2)
2238 fixtrunctab[(int) DFmode][(int) HImode][1] = CODE_FOR_fixuns_truncdfhi2;
2240 #ifdef HAVE_fixuns_truncdfsi2
2241 if (HAVE_fixuns_truncdfsi2)
2242 fixtrunctab[(int) DFmode][(int) SImode][1] = CODE_FOR_fixuns_truncdfsi2;
2244 #ifdef HAVE_fixuns_truncdfdi2
2245 if (HAVE_fixuns_truncdfdi2)
2246 fixtrunctab[(int) DFmode][(int) DImode][1] = CODE_FOR_fixuns_truncdfdi2;
2248 #ifdef HAVE_fixuns_truncdfti2
2249 if (HAVE_fixuns_truncdfti2)
2250 fixtrunctab[(int) DFmode][(int) TImode][1] = CODE_FOR_fixuns_truncdfti2;
2253 #ifdef HAVE_fixuns_trunctfqi2
2254 if (HAVE_fixuns_trunctfqi2)
2255 fixtrunctab[(int) TFmode][(int) QImode][1] = CODE_FOR_fixuns_trunctfqi2;
2257 #ifdef HAVE_fixuns_trunctfhi2
2258 if (HAVE_fixuns_trunctfhi2)
2259 fixtrunctab[(int) TFmode][(int) HImode][1] = CODE_FOR_fixuns_trunctfhi2;
2261 #ifdef HAVE_fixuns_trunctfsi2
2262 if (HAVE_fixuns_trunctfsi2)
2263 fixtrunctab[(int) TFmode][(int) SImode][1] = CODE_FOR_fixuns_trunctfsi2;
2265 #ifdef HAVE_fixuns_trunctfdi2
2266 if (HAVE_fixuns_trunctfdi2)
2267 fixtrunctab[(int) TFmode][(int) DImode][1] = CODE_FOR_fixuns_trunctfdi2;
2269 #ifdef HAVE_fixuns_trunctfti2
2270 if (HAVE_fixuns_trunctfti2)
2271 fixtrunctab[(int) TFmode][(int) TImode][1] = CODE_FOR_fixuns_trunctfti2;
2274 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
2275 /* This flag says the same insns that convert to a signed fixnum
2276 also convert validly to an unsigned one. */
2280 for (i = 0; i < NUM_MACHINE_MODES; i++)
2281 for (j = 0; j < NUM_MACHINE_MODES; j++)
2282 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
2291 for (p = floattab[0][0];
2292 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
2294 *p = CODE_FOR_nothing;
2296 #ifdef HAVE_floatqisf2
2297 if (HAVE_floatqisf2)
2298 floattab[(int) SFmode][(int) QImode][0] = CODE_FOR_floatqisf2;
2300 #ifdef HAVE_floathisf2
2301 if (HAVE_floathisf2)
2302 floattab[(int) SFmode][(int) HImode][0] = CODE_FOR_floathisf2;
2304 #ifdef HAVE_floatsisf2
2305 if (HAVE_floatsisf2)
2306 floattab[(int) SFmode][(int) SImode][0] = CODE_FOR_floatsisf2;
2308 #ifdef HAVE_floatdisf2
2309 if (HAVE_floatdisf2)
2310 floattab[(int) SFmode][(int) DImode][0] = CODE_FOR_floatdisf2;
2312 #ifdef HAVE_floattisf2
2313 if (HAVE_floattisf2)
2314 floattab[(int) SFmode][(int) TImode][0] = CODE_FOR_floattisf2;
2317 #ifdef HAVE_floatqidf2
2318 if (HAVE_floatqidf2)
2319 floattab[(int) DFmode][(int) QImode][0] = CODE_FOR_floatqidf2;
2321 #ifdef HAVE_floathidf2
2322 if (HAVE_floathidf2)
2323 floattab[(int) DFmode][(int) HImode][0] = CODE_FOR_floathidf2;
2325 #ifdef HAVE_floatsidf2
2326 if (HAVE_floatsidf2)
2327 floattab[(int) DFmode][(int) SImode][0] = CODE_FOR_floatsidf2;
2329 #ifdef HAVE_floatdidf2
2330 if (HAVE_floatdidf2)
2331 floattab[(int) DFmode][(int) DImode][0] = CODE_FOR_floatdidf2;
2333 #ifdef HAVE_floattidf2
2334 if (HAVE_floattidf2)
2335 floattab[(int) DFmode][(int) TImode][0] = CODE_FOR_floattidf2;
2338 #ifdef HAVE_floatqitf2
2339 if (HAVE_floatqitf2)
2340 floattab[(int) TFmode][(int) QImode][0] = CODE_FOR_floatqitf2;
2342 #ifdef HAVE_floathitf2
2343 if (HAVE_floathitf2)
2344 floattab[(int) TFmode][(int) HImode][0] = CODE_FOR_floathitf2;
2346 #ifdef HAVE_floatsitf2
2347 if (HAVE_floatsitf2)
2348 floattab[(int) TFmode][(int) SImode][0] = CODE_FOR_floatsitf2;
2350 #ifdef HAVE_floatditf2
2351 if (HAVE_floatditf2)
2352 floattab[(int) TFmode][(int) DImode][0] = CODE_FOR_floatditf2;
2354 #ifdef HAVE_floattitf2
2355 if (HAVE_floattitf2)
2356 floattab[(int) TFmode][(int) TImode][0] = CODE_FOR_floattitf2;
2359 #ifdef HAVE_floatunsqisf2
2360 if (HAVE_floatunsqisf2)
2361 floattab[(int) SFmode][(int) QImode][1] = CODE_FOR_floatunsqisf2;
2363 #ifdef HAVE_floatunshisf2
2364 if (HAVE_floatunshisf2)
2365 floattab[(int) SFmode][(int) HImode][1] = CODE_FOR_floatunshisf2;
2367 #ifdef HAVE_floatunssisf2
2368 if (HAVE_floatunssisf2)
2369 floattab[(int) SFmode][(int) SImode][1] = CODE_FOR_floatunssisf2;
2371 #ifdef HAVE_floatunsdisf2
2372 if (HAVE_floatunsdisf2)
2373 floattab[(int) SFmode][(int) DImode][1] = CODE_FOR_floatunsdisf2;
2375 #ifdef HAVE_floatunstisf2
2376 if (HAVE_floatunstisf2)
2377 floattab[(int) SFmode][(int) TImode][1] = CODE_FOR_floatunstisf2;
2380 #ifdef HAVE_floatunsqidf2
2381 if (HAVE_floatunsqidf2)
2382 floattab[(int) DFmode][(int) QImode][1] = CODE_FOR_floatunsqidf2;
2384 #ifdef HAVE_floatunshidf2
2385 if (HAVE_floatunshidf2)
2386 floattab[(int) DFmode][(int) HImode][1] = CODE_FOR_floatunshidf2;
2388 #ifdef HAVE_floatunssidf2
2389 if (HAVE_floatunssidf2)
2390 floattab[(int) DFmode][(int) SImode][1] = CODE_FOR_floatunssidf2;
2392 #ifdef HAVE_floatunsdidf2
2393 if (HAVE_floatunsdidf2)
2394 floattab[(int) DFmode][(int) DImode][1] = CODE_FOR_floatunsdidf2;
2396 #ifdef HAVE_floatunstidf2
2397 if (HAVE_floatunstidf2)
2398 floattab[(int) DFmode][(int) TImode][1] = CODE_FOR_floatunstidf2;
2401 #ifdef HAVE_floatunsqitf2
2402 if (HAVE_floatunsqitf2)
2403 floattab[(int) TFmode][(int) QImode][1] = CODE_FOR_floatunsqitf2;
2405 #ifdef HAVE_floatunshitf2
2406 if (HAVE_floatunshitf2)
2407 floattab[(int) TFmode][(int) HImode][1] = CODE_FOR_floatunshitf2;
2409 #ifdef HAVE_floatunssitf2
2410 if (HAVE_floatunssitf2)
2411 floattab[(int) TFmode][(int) SImode][1] = CODE_FOR_floatunssitf2;
2413 #ifdef HAVE_floatunsditf2
2414 if (HAVE_floatunsditf2)
2415 floattab[(int) TFmode][(int) DImode][1] = CODE_FOR_floatunsditf2;
2417 #ifdef HAVE_floatunstitf2
2418 if (HAVE_floatunstitf2)
2419 floattab[(int) TFmode][(int) TImode][1] = CODE_FOR_floatunstitf2;
2423 /* Generate code to convert FROM to floating point
2424 and store in TO. FROM must be fixed point.
2425 UNSIGNEDP nonzero means regard FROM as unsigned.
2426 Normally this is done by correcting the final value
2427 if it is negative. */
2430 expand_float (to, from, unsignedp)
2434 enum insn_code icode;
2435 register rtx target = to;
2436 enum machine_mode fmode, imode;
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 fnname = "__floatsisf";
2543 else if (GET_MODE (from) == DImode)
2544 fnname = "__floatdisf";
2548 else if (GET_MODE (to) == DFmode)
2550 if (GET_MODE (from) == SImode)
2551 fnname = "__floatsidf";
2552 else if (GET_MODE (from) == DImode)
2553 fnname = "__floatdidf";
2562 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, fnname),
2563 0, GET_MODE (to), 1, from, GET_MODE (from));
2564 insns = get_insns ();
2567 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2568 gen_rtx (FLOAT, GET_MODE (to), from));
2571 /* Copy result to requested destination
2572 if we have been computing in a temp location. */
2576 if (GET_MODE (target) == GET_MODE (to))
2577 emit_move_insn (to, target);
2579 convert_move (to, target, 0);
2583 /* expand_fix: generate code to convert FROM to fixed point
2584 and store in TO. FROM must be floating point. */
2590 rtx temp = gen_reg_rtx (GET_MODE (x));
2591 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
2595 expand_fix (to, from, unsignedp)
2596 register rtx to, from;
2599 enum insn_code icode;
2600 register rtx target = to;
2601 enum machine_mode fmode, imode;
2605 /* We first try to find a pair of modes, one real and one integer, at
2606 least as wide as FROM and TO, respectively, in which we can open-code
2607 this conversion. If the integer mode is wider than the mode of TO,
2608 we can do the conversion either signed or unsigned. */
2610 for (imode = GET_MODE (to); imode != VOIDmode;
2611 imode = GET_MODE_WIDER_MODE (imode))
2612 for (fmode = GET_MODE (from); fmode != VOIDmode;
2613 fmode = GET_MODE_WIDER_MODE (fmode))
2615 int doing_unsigned = unsignedp;
2617 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
2618 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
2619 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
2621 if (icode != CODE_FOR_nothing)
2623 to = protect_from_queue (to, 1);
2625 if (fmode != GET_MODE (from))
2626 from = convert_to_mode (fmode, from, 0);
2628 from = protect_from_queue (from, 0);
2631 from = ftruncify (from);
2633 if (imode != GET_MODE (to))
2634 target = gen_reg_rtx (imode);
2636 emit_unop_insn (icode, target, from,
2637 doing_unsigned ? UNSIGNED_FIX : FIX);
2639 convert_move (to, target, unsignedp);
2644 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
2645 /* For an unsigned conversion, there is one more way to do it.
2646 If we have a signed conversion, we generate code that compares
2647 the real value to the largest representable positive number. If if
2648 is smaller, the conversion is done normally. Otherwise, subtract
2649 one plus the highest signed number, convert, and add it back.
2651 We only need to check all real modes, since we know we didn't find
2652 anything with a wider inetger mode. */
2654 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_INT)
2655 for (fmode = GET_MODE (from); fmode != VOIDmode;
2656 fmode = GET_MODE_WIDER_MODE (fmode))
2657 /* Make sure we won't lose significant bits doing this. */
2658 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
2659 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
2662 int bitsize = GET_MODE_BITSIZE (GET_MODE (to));
2663 REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
2664 rtx limit = immed_real_const_1 (offset, fmode);
2665 rtx lab1 = gen_label_rtx ();
2666 rtx lab2 = gen_label_rtx ();
2670 to = protect_from_queue (to, 1);
2671 from = protect_from_queue (from, 0);
2674 from = force_not_mem (from);
2676 if (fmode != GET_MODE (from))
2677 from = convert_to_mode (fmode, from, 0);
2679 /* See if we need to do the subtraction. */
2680 do_pending_stack_adjust ();
2681 emit_cmp_insn (from, limit, GE, 0, GET_MODE (from), 0, 0);
2682 emit_jump_insn (gen_bge (lab1));
2684 /* If not, do the signed "fix" and branch around fixup code. */
2685 expand_fix (to, from, 0);
2686 emit_jump_insn (gen_jump (lab2));
2689 /* Otherwise, subtract 2**(N-1), convert to signed number,
2690 then add 2**(N-1). Do the addition using XOR since this
2691 will often generate better code. */
2693 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
2694 0, 0, OPTAB_LIB_WIDEN);
2695 expand_fix (to, target, 0);
2696 target = expand_binop (GET_MODE (to), xor_optab, to,
2697 gen_rtx (CONST_INT, VOIDmode,
2698 1 << (bitsize - 1)),
2699 to, 1, OPTAB_LIB_WIDEN);
2702 emit_move_insn (to, target);
2706 /* Make a place for a REG_NOTE and add it. */
2707 insn = emit_move_insn (to, to);
2708 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
2709 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
2710 from), REG_NOTES (insn));
2716 /* We can't do it with an insn, so use a library call. But first ensure
2717 that the mode of TO is at least as wide as SImode, since those are the
2718 only library calls we know about. */
2720 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
2722 target = gen_reg_rtx (SImode);
2724 expand_fix (target, from, unsignedp);
2726 else if (GET_MODE (from) == SFmode)
2728 if (GET_MODE (to) == SImode)
2729 fnname = unsignedp ? "__fixunssfsi" : "__fixsfsi";
2730 else if (GET_MODE (to) == DImode)
2731 fnname = unsignedp ? "__fixunssfdi" : "__fixsfdi";
2735 else if (GET_MODE (from) == DFmode)
2737 if (GET_MODE (to) == SImode)
2738 fnname = unsignedp ? "__fixunsdfsi" : "__fixdfsi";
2739 else if (GET_MODE (to) == DImode)
2740 fnname = unsignedp ? "__fixunsdfdi" : "__fixdfdi";
2751 to = protect_from_queue (to, 1);
2752 from = protect_from_queue (from, 0);
2755 from = force_not_mem (from);
2759 emit_library_call (gen_rtx (SYMBOL_REF, Pmode, fnname),
2760 0, GET_MODE (to), 1, from, GET_MODE (from));
2761 insns = get_insns ();
2764 emit_libcall_block (insns, target, hard_libcall_value (GET_MODE (to)),
2765 gen_rtx (unsignedp ? FIX : UNSIGNED_FIX,
2766 GET_MODE (to), from));
2769 if (GET_MODE (to) == GET_MODE (target))
2770 emit_move_insn (to, target);
2772 convert_move (to, target, 0);
2780 optab op = (optab) xmalloc (sizeof (struct optab));
2782 for (i = 0; i < NUM_MACHINE_MODES; i++)
2784 op->handlers[i].insn_code = CODE_FOR_nothing;
2785 op->handlers[i].libfunc = 0;
2790 /* Call this once to initialize the contents of the optabs
2791 appropriately for the current target machine. */
2802 add_optab = init_optab (PLUS);
2803 sub_optab = init_optab (MINUS);
2804 smul_optab = init_optab (MULT);
2805 smul_widen_optab = init_optab (UNKNOWN);
2806 umul_widen_optab = init_optab (UNKNOWN);
2807 sdiv_optab = init_optab (DIV);
2808 sdivmod_optab = init_optab (UNKNOWN);
2809 udiv_optab = init_optab (UDIV);
2810 udivmod_optab = init_optab (UNKNOWN);
2811 smod_optab = init_optab (MOD);
2812 umod_optab = init_optab (UMOD);
2813 flodiv_optab = init_optab (DIV);
2814 ftrunc_optab = init_optab (UNKNOWN);
2815 and_optab = init_optab (AND);
2816 ior_optab = init_optab (IOR);
2817 xor_optab = init_optab (XOR);
2818 ashl_optab = init_optab (ASHIFT);
2819 ashr_optab = init_optab (ASHIFTRT);
2820 lshl_optab = init_optab (LSHIFT);
2821 lshr_optab = init_optab (LSHIFTRT);
2822 rotl_optab = init_optab (ROTATE);
2823 rotr_optab = init_optab (ROTATERT);
2824 smin_optab = init_optab (SMIN);
2825 smax_optab = init_optab (SMAX);
2826 umin_optab = init_optab (UMIN);
2827 umax_optab = init_optab (UMAX);
2828 mov_optab = init_optab (UNKNOWN);
2829 movstrict_optab = init_optab (UNKNOWN);
2830 cmp_optab = init_optab (UNKNOWN);
2831 ucmp_optab = init_optab (UNKNOWN);
2832 tst_optab = init_optab (UNKNOWN);
2833 neg_optab = init_optab (NEG);
2834 abs_optab = init_optab (ABS);
2835 one_cmpl_optab = init_optab (NOT);
2836 ffs_optab = init_optab (FFS);
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) Imode].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. */
3683 #ifdef HAVE_one_cmplqi2
3684 if (HAVE_one_cmplqi2)
3685 one_cmpl_optab->handlers[(int) QImode].insn_code = CODE_FOR_one_cmplqi2;
3687 #ifdef HAVE_one_cmplhi2
3688 if (HAVE_one_cmplhi2)
3689 one_cmpl_optab->handlers[(int) HImode].insn_code = CODE_FOR_one_cmplhi2;
3691 #ifdef HAVE_one_cmplpsi2
3692 if (HAVE_one_cmplpsi2)
3693 one_cmpl_optab->handlers[(int) PSImode].insn_code = CODE_FOR_one_cmplpsi2;
3695 #ifdef HAVE_one_cmplsi2
3696 if (HAVE_one_cmplsi2)
3697 one_cmpl_optab->handlers[(int) SImode].insn_code = CODE_FOR_one_cmplsi2;
3699 #ifdef HAVE_one_cmpldi2
3700 if (HAVE_one_cmpldi2)
3701 one_cmpl_optab->handlers[(int) DImode].insn_code = CODE_FOR_one_cmpldi2;
3703 #ifdef HAVE_one_cmplti2
3704 if (HAVE_one_cmplti2)
3705 one_cmpl_optab->handlers[(int) TImode].insn_code = CODE_FOR_one_cmplti2;
3707 one_cmpl_optab->handlers[(int) SImode].libfunc
3708 = gen_rtx (SYMBOL_REF, Pmode, "__one_cmplsi2");
3712 ffs_optab->handlers[(int) QImode].insn_code = CODE_FOR_ffsqi2;
3716 ffs_optab->handlers[(int) HImode].insn_code = CODE_FOR_ffshi2;
3720 ffs_optab->handlers[(int) PSImode].insn_code = CODE_FOR_ffspsi2;
3724 ffs_optab->handlers[(int) SImode].insn_code = CODE_FOR_ffssi2;
3728 ffs_optab->handlers[(int) DImode].insn_code = CODE_FOR_ffsdi2;
3732 ffs_optab->handlers[(int) TImode].insn_code = CODE_FOR_ffsti2;
3734 ffs_optab->handlers[(int) SImode].libfunc
3735 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
3739 mov_optab->handlers[(int) QImode].insn_code = CODE_FOR_movqi;
3743 mov_optab->handlers[(int) HImode].insn_code = CODE_FOR_movhi;
3747 mov_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movpsi;
3751 mov_optab->handlers[(int) SImode].insn_code = CODE_FOR_movsi;
3755 mov_optab->handlers[(int) DImode].insn_code = CODE_FOR_movdi;
3759 mov_optab->handlers[(int) TImode].insn_code = CODE_FOR_movti;
3763 mov_optab->handlers[(int) SFmode].insn_code = CODE_FOR_movsf;
3767 mov_optab->handlers[(int) DFmode].insn_code = CODE_FOR_movdf;
3771 mov_optab->handlers[(int) TFmode].insn_code = CODE_FOR_movtf;
3775 mov_optab->handlers[(int) CCmode].insn_code = CODE_FOR_movcc;
3778 #ifdef EXTRA_CC_MODES
3782 #ifdef HAVE_movstrictqi
3783 if (HAVE_movstrictqi)
3784 movstrict_optab->handlers[(int) QImode].insn_code = CODE_FOR_movstrictqi;
3786 #ifdef HAVE_movstricthi
3787 if (HAVE_movstricthi)
3788 movstrict_optab->handlers[(int) HImode].insn_code = CODE_FOR_movstricthi;
3790 #ifdef HAVE_movstrictpsi
3791 if (HAVE_movstrictpsi)
3792 movstrict_optab->handlers[(int) PSImode].insn_code = CODE_FOR_movstrictpsi;
3794 #ifdef HAVE_movstrictsi
3795 if (HAVE_movstrictsi)
3796 movstrict_optab->handlers[(int) SImode].insn_code = CODE_FOR_movstrictsi;
3798 #ifdef HAVE_movstrictdi
3799 if (HAVE_movstrictdi)
3800 movstrict_optab->handlers[(int) DImode].insn_code = CODE_FOR_movstrictdi;
3802 #ifdef HAVE_movstrictti
3803 if (HAVE_movstrictti)
3804 movstrict_optab->handlers[(int) TImode].insn_code = CODE_FOR_movstrictti;
3809 cmp_optab->handlers[(int) QImode].insn_code = CODE_FOR_cmpqi;
3813 cmp_optab->handlers[(int) HImode].insn_code = CODE_FOR_cmphi;
3817 cmp_optab->handlers[(int) PSImode].insn_code = CODE_FOR_cmppsi;
3821 cmp_optab->handlers[(int) SImode].insn_code = CODE_FOR_cmpsi;
3825 cmp_optab->handlers[(int) DImode].insn_code = CODE_FOR_cmpdi;
3829 cmp_optab->handlers[(int) TImode].insn_code = CODE_FOR_cmpti;
3833 cmp_optab->handlers[(int) SFmode].insn_code = CODE_FOR_cmpsf;
3837 cmp_optab->handlers[(int) DFmode].insn_code = CODE_FOR_cmpdf;
3841 cmp_optab->handlers[(int) TFmode].insn_code = CODE_FOR_cmptf;
3845 tst_optab->handlers[(int) QImode].insn_code = CODE_FOR_tstqi;
3849 tst_optab->handlers[(int) HImode].insn_code = CODE_FOR_tsthi;
3853 tst_optab->handlers[(int) PSImode].insn_code = CODE_FOR_tstpsi;
3857 tst_optab->handlers[(int) SImode].insn_code = CODE_FOR_tstsi;
3861 tst_optab->handlers[(int) DImode].insn_code = CODE_FOR_tstdi;
3865 tst_optab->handlers[(int) TImode].insn_code = CODE_FOR_tstti;
3869 tst_optab->handlers[(int) SFmode].insn_code = CODE_FOR_tstsf;
3873 tst_optab->handlers[(int) DFmode].insn_code = CODE_FOR_tstdf;
3877 tst_optab->handlers[(int) TFmode].insn_code = CODE_FOR_tsttf;
3879 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3880 cmp_optab->handlers[(int) DImode].libfunc
3881 = gen_rtx (SYMBOL_REF, Pmode, "__cmpdi2");
3882 ucmp_optab->handlers[(int) DImode].libfunc
3883 = gen_rtx (SYMBOL_REF, Pmode, "__ucmpdi2");
3887 bcc_gen_fctn[(int) EQ] = gen_beq;
3891 bcc_gen_fctn[(int) NE] = gen_bne;
3895 bcc_gen_fctn[(int) GT] = gen_bgt;
3899 bcc_gen_fctn[(int) GE] = gen_bge;
3903 bcc_gen_fctn[(int) GTU] = gen_bgtu;
3907 bcc_gen_fctn[(int) GEU] = gen_bgeu;
3911 bcc_gen_fctn[(int) LT] = gen_blt;
3915 bcc_gen_fctn[(int) LE] = gen_ble;
3919 bcc_gen_fctn[(int) LTU] = gen_bltu;
3923 bcc_gen_fctn[(int) LEU] = gen_bleu;
3926 for (i = 0; i < NUM_RTX_CODE; i++)
3927 setcc_gen_code[i] = CODE_FOR_nothing;
3931 setcc_gen_code[(int) EQ] = CODE_FOR_seq;
3935 setcc_gen_code[(int) NE] = CODE_FOR_sne;
3939 setcc_gen_code[(int) GT] = CODE_FOR_sgt;
3943 setcc_gen_code[(int) GE] = CODE_FOR_sge;
3947 setcc_gen_code[(int) GTU] = CODE_FOR_sgtu;
3951 setcc_gen_code[(int) GEU] = CODE_FOR_sgeu;
3955 setcc_gen_code[(int) LT] = CODE_FOR_slt;
3959 setcc_gen_code[(int) LE] = CODE_FOR_sle;
3963 setcc_gen_code[(int) LTU] = CODE_FOR_sltu;
3967 setcc_gen_code[(int) LEU] = CODE_FOR_sleu;
3970 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
3971 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
3972 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
3973 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
3974 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
3975 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcmp");
3976 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
3977 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
3978 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
3979 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
3980 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
3981 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
3982 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
3983 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
3984 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
3985 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
3986 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
3987 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
3988 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
3989 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");