1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
25 #include "insn-flags.h"
26 #include "insn-codes.h"
28 #include "insn-config.h"
32 /* Each optab contains info on how this target machine
33 can perform a particular operation
34 for all sizes and kinds of operands.
36 The operation to be performed is often specified
37 by passing one of these optabs as an argument.
39 See expr.h for documentation of these optabs. */
44 optab smul_widen_optab
;
45 optab umul_widen_optab
;
69 optab movstrict_optab
;
80 optab ucmp_optab
; /* Used only for libcalls for unsigned comparisons. */
85 /* SYMBOL_REF rtx's for the library functions that are called
86 implicitly and not via optabs. */
88 rtx extendsfdf2_libfunc
;
89 rtx extendsfxf2_libfunc
;
90 rtx extendsftf2_libfunc
;
91 rtx extenddfxf2_libfunc
;
92 rtx extenddftf2_libfunc
;
94 rtx truncdfsf2_libfunc
;
95 rtx truncxfsf2_libfunc
;
96 rtx trunctfsf2_libfunc
;
97 rtx truncxfdf2_libfunc
;
98 rtx trunctfdf2_libfunc
;
135 rtx floatsisf_libfunc
;
136 rtx floatdisf_libfunc
;
137 rtx floattisf_libfunc
;
139 rtx floatsidf_libfunc
;
140 rtx floatdidf_libfunc
;
141 rtx floattidf_libfunc
;
143 rtx floatsixf_libfunc
;
144 rtx floatdixf_libfunc
;
145 rtx floattixf_libfunc
;
147 rtx floatsitf_libfunc
;
148 rtx floatditf_libfunc
;
149 rtx floattitf_libfunc
;
167 rtx fixunssfsi_libfunc
;
168 rtx fixunssfdi_libfunc
;
169 rtx fixunssfti_libfunc
;
171 rtx fixunsdfsi_libfunc
;
172 rtx fixunsdfdi_libfunc
;
173 rtx fixunsdfti_libfunc
;
175 rtx fixunsxfsi_libfunc
;
176 rtx fixunsxfdi_libfunc
;
177 rtx fixunsxfti_libfunc
;
179 rtx fixunstfsi_libfunc
;
180 rtx fixunstfdi_libfunc
;
181 rtx fixunstfti_libfunc
;
183 /* from emit-rtl.c */
184 extern rtx
gen_highpart ();
186 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
187 gives the gen_function to make a branch to test that condition. */
189 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
191 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
192 gives the insn code to make a store-condition insn
193 to test that condition. */
195 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
197 static void emit_float_lib_cmp ();
199 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
200 the result of operation CODE applied to OP0 (and OP1 if it is a binary
203 If the last insn does not set TARGET, don't do anything, but return 1.
205 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
206 don't add the REG_EQUAL note but return 0. Our caller can then try
207 again, ensuring that TARGET is not one of the operands. */
210 add_equal_note (seq
, target
, code
, op0
, op1
)
220 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
221 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
222 || GET_CODE (seq
) != SEQUENCE
223 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
224 || GET_CODE (target
) == ZERO_EXTRACT
225 || (! rtx_equal_p (SET_DEST (set
), target
)
226 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
228 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
229 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
233 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
234 besides the last insn. */
235 if (reg_overlap_mentioned_p (target
, op0
)
236 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
237 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
238 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
241 if (GET_RTX_CLASS (code
) == '1')
242 note
= gen_rtx (code
, GET_MODE (target
), op0
);
244 note
= gen_rtx (code
, GET_MODE (target
), op0
, op1
);
246 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))
247 = gen_rtx (EXPR_LIST
, REG_EQUAL
, note
,
248 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1)));
253 /* Generate code to perform an operation specified by BINOPTAB
254 on operands OP0 and OP1, with result having machine-mode MODE.
256 UNSIGNEDP is for the case where we have to widen the operands
257 to perform the operation. It says to use zero-extension.
259 If TARGET is nonzero, the value
260 is generated there, if it is convenient to do so.
261 In all cases an rtx is returned for the locus of the value;
262 this may or may not be TARGET. */
265 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
266 enum machine_mode mode
;
271 enum optab_methods methods
;
273 enum mode_class
class;
274 enum machine_mode wider_mode
;
276 int commutative_op
= 0;
277 int shift_op
= (binoptab
->code
== ASHIFT
278 || binoptab
->code
== ASHIFTRT
279 || binoptab
->code
== LSHIFT
280 || binoptab
->code
== LSHIFTRT
281 || binoptab
->code
== ROTATE
282 || binoptab
->code
== ROTATERT
);
283 rtx entry_last
= get_last_insn ();
286 class = GET_MODE_CLASS (mode
);
288 op0
= protect_from_queue (op0
, 0);
289 op1
= protect_from_queue (op1
, 0);
291 target
= protect_from_queue (target
, 1);
295 op0
= force_not_mem (op0
);
296 op1
= force_not_mem (op1
);
299 /* If subtracting an integer constant, convert this into an addition of
300 the negated constant. */
302 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
304 op1
= negate_rtx (mode
, op1
);
305 binoptab
= add_optab
;
308 /* If we are inside an appropriately-short loop and one operand is an
309 expensive constant, force it into a register. */
310 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
311 && rtx_cost (op0
, binoptab
->code
) > 2)
312 op0
= force_reg (mode
, op0
);
314 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
315 && rtx_cost (op1
, binoptab
->code
) > 2)
316 op1
= force_reg (shift_op
? word_mode
: mode
, op1
);
318 /* Record where to delete back to if we backtrack. */
319 last
= get_last_insn ();
321 /* If operation is commutative,
322 try to make the first operand a register.
323 Even better, try to make it the same as the target.
324 Also try to make the last operand a constant. */
325 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
326 || binoptab
== smul_widen_optab
327 || binoptab
== umul_widen_optab
)
331 if (((target
== 0 || GET_CODE (target
) == REG
)
332 ? ((GET_CODE (op1
) == REG
333 && GET_CODE (op0
) != REG
)
335 : rtx_equal_p (op1
, target
))
336 || GET_CODE (op0
) == CONST_INT
)
344 /* If we can do it with a three-operand insn, do so. */
346 if (methods
!= OPTAB_MUST_WIDEN
347 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
349 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
350 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
351 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
353 rtx xop0
= op0
, xop1
= op1
;
358 temp
= gen_reg_rtx (mode
);
360 /* If it is a commutative operator and the modes would match
361 if we would swap the operands, we can save the conversions. */
364 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
365 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
369 tmp
= op0
; op0
= op1
; op1
= tmp
;
370 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
374 /* In case the insn wants input operands in modes different from
375 the result, convert the operands. */
377 if (GET_MODE (op0
) != VOIDmode
378 && GET_MODE (op0
) != mode0
)
379 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
381 if (GET_MODE (xop1
) != VOIDmode
382 && GET_MODE (xop1
) != mode1
)
383 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
385 /* Now, if insn's predicates don't allow our operands, put them into
388 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
389 xop0
= copy_to_mode_reg (mode0
, xop0
);
391 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
392 xop1
= copy_to_mode_reg (mode1
, xop1
);
394 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
395 temp
= gen_reg_rtx (mode
);
397 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
400 /* If PAT is a multi-insn sequence, try to add an appropriate
401 REG_EQUAL note to it. If we can't because TEMP conflicts with an
402 operand, call ourselves again, this time without a target. */
403 if (GET_CODE (pat
) == SEQUENCE
404 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
406 delete_insns_since (last
);
407 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
415 delete_insns_since (last
);
418 /* If this is a multiply, see if we can do a widening operation that
419 takes operands of this mode and makes a wider mode. */
421 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
422 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
423 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
424 != CODE_FOR_nothing
))
426 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
427 unsignedp
? umul_widen_optab
: smul_widen_optab
,
428 op0
, op1
, 0, unsignedp
, OPTAB_DIRECT
);
430 if (GET_MODE_CLASS (mode
) == MODE_INT
)
431 return gen_lowpart (mode
, temp
);
433 return convert_to_mode (mode
, temp
, unsignedp
);
436 /* Look for a wider mode of the same class for which we think we
437 can open-code the operation. Check for a widening multiply at the
438 wider mode as well. */
440 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
441 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
442 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
443 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
445 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
446 || (binoptab
== smul_optab
447 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
448 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
449 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
450 != CODE_FOR_nothing
)))
452 rtx xop0
= op0
, xop1
= op1
;
455 /* For certain integer operations, we need not actually extend
456 the narrow operands, as long as we will truncate
457 the results to the same narrowness. Don't do this when
458 WIDER_MODE is wider than a word since a paradoxical SUBREG
459 isn't valid for such modes. */
461 if ((binoptab
== ior_optab
|| binoptab
== and_optab
462 || binoptab
== xor_optab
463 || binoptab
== add_optab
|| binoptab
== sub_optab
464 || binoptab
== smul_optab
465 || binoptab
== ashl_optab
|| binoptab
== lshl_optab
)
467 && GET_MODE_SIZE (wider_mode
) <= UNITS_PER_WORD
)
470 /* If an operand is a constant integer, we might as well
471 convert it since that is more efficient than using a SUBREG,
472 unlike the case for other operands. Similarly for
473 SUBREGs that were made due to promoted objects. */
475 if (no_extend
&& GET_MODE (xop0
) != VOIDmode
476 && ! (GET_CODE (xop0
) == SUBREG
477 && SUBREG_PROMOTED_VAR_P (xop0
)))
478 xop0
= gen_rtx (SUBREG
, wider_mode
,
479 force_reg (GET_MODE (xop0
), xop0
), 0);
481 xop0
= convert_to_mode (wider_mode
, xop0
, unsignedp
);
483 if (no_extend
&& GET_MODE (xop1
) != VOIDmode
484 && ! (GET_CODE (xop1
) == SUBREG
485 && SUBREG_PROMOTED_VAR_P (xop1
)))
486 xop1
= gen_rtx (SUBREG
, wider_mode
,
487 force_reg (GET_MODE (xop1
), xop1
), 0);
489 xop1
= convert_to_mode (wider_mode
, xop1
, unsignedp
);
491 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
492 unsignedp
, OPTAB_DIRECT
);
495 if (class != MODE_INT
)
498 target
= gen_reg_rtx (mode
);
499 convert_move (target
, temp
, 0);
503 return gen_lowpart (mode
, temp
);
506 delete_insns_since (last
);
510 /* These can be done a word at a time. */
511 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
513 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
514 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
520 /* If TARGET is the same as one of the operands, the REG_EQUAL note
521 won't be accurate, so use a new target. */
522 if (target
== 0 || target
== op0
|| target
== op1
)
523 target
= gen_reg_rtx (mode
);
527 /* Do the actual arithmetic. */
528 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
530 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
531 rtx x
= expand_binop (word_mode
, binoptab
,
532 operand_subword_force (op0
, i
, mode
),
533 operand_subword_force (op1
, i
, mode
),
534 target_piece
, unsignedp
, methods
);
535 if (target_piece
!= x
)
536 emit_move_insn (target_piece
, x
);
539 insns
= get_insns ();
542 if (binoptab
->code
!= UNKNOWN
)
543 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
547 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
551 /* These can be done a word at a time by propagating carries. */
552 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
554 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
555 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
558 rtx carry_tmp
= gen_reg_rtx (word_mode
);
559 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
560 int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
561 rtx carry_in
, carry_out
;
564 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
565 value is one of those, use it. Otherwise, use 1 since it is the
566 one easiest to get. */
567 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
568 int normalizep
= STORE_FLAG_VALUE
;
573 /* Prepare the operands. */
574 xop0
= force_reg (mode
, op0
);
575 xop1
= force_reg (mode
, op1
);
577 if (target
== 0 || GET_CODE (target
) != REG
578 || target
== xop0
|| target
== xop1
)
579 target
= gen_reg_rtx (mode
);
581 /* Do the actual arithmetic. */
582 for (i
= 0; i
< nwords
; i
++)
584 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
585 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
586 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
587 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
590 /* Main add/subtract of the input operands. */
591 x
= expand_binop (word_mode
, binoptab
,
592 op0_piece
, op1_piece
,
593 target_piece
, unsignedp
, methods
);
599 /* Store carry from main add/subtract. */
600 carry_out
= gen_reg_rtx (word_mode
);
601 carry_out
= emit_store_flag (carry_out
,
602 binoptab
== add_optab
? LTU
: GTU
,
604 word_mode
, 1, normalizep
);
611 /* Add/subtract previous carry to main result. */
612 x
= expand_binop (word_mode
,
613 normalizep
== 1 ? binoptab
: otheroptab
,
615 target_piece
, 1, methods
);
616 if (target_piece
!= x
)
617 emit_move_insn (target_piece
, x
);
621 /* THIS CODE HAS NOT BEEN TESTED. */
622 /* Get out carry from adding/subtracting carry in. */
623 carry_tmp
= emit_store_flag (carry_tmp
,
624 binoptab
== add_optab
627 word_mode
, 1, normalizep
);
628 /* Logical-ior the two poss. carry together. */
629 carry_out
= expand_binop (word_mode
, ior_optab
,
630 carry_out
, carry_tmp
,
631 carry_out
, 0, methods
);
637 carry_in
= carry_out
;
640 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
644 temp
= emit_move_insn (target
, target
);
645 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
646 gen_rtx (binoptab
->code
, mode
, xop0
, xop1
),
651 delete_insns_since (last
);
654 /* If we want to multiply two two-word values and have normal and widening
655 multiplies of single-word values, we can do this with three smaller
656 multiplications. Note that we do not make a REG_NO_CONFLICT block here
657 because we are not operating on one word at a time.
659 The multiplication proceeds as follows:
660 _______________________
661 [__op0_high_|__op0_low__]
662 _______________________
663 * [__op1_high_|__op1_low__]
664 _______________________________________________
665 _______________________
666 (1) [__op0_low__*__op1_low__]
667 _______________________
668 (2a) [__op0_low__*__op1_high_]
669 _______________________
670 (2b) [__op0_high_*__op1_low__]
671 _______________________
672 (3) [__op0_high_*__op1_high_]
675 This gives a 4-word result. Since we are only interested in the
676 lower 2 words, partial result (3) and the upper words of (2a) and
677 (2b) don't need to be calculated. Hence (2a) and (2b) can be
678 calculated using non-widening multiplication.
680 (1), however, needs to be calculated with an unsigned widening
681 multiplication. If this operation is not directly supported we
682 try using a signed widening multiplication and adjust the result.
683 This adjustment works as follows:
685 If both operands are positive then no adjustment is needed.
687 If the operands have different signs, for example op0_low < 0 and
688 op1_low >= 0, the instruction treats the most significant bit of
689 op0_low as a sign bit instead of a bit with significance
690 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
691 with 2**BITS_PER_WORD - op0_low, and two's complements the
692 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
695 Similarly, if both operands are negative, we need to add
696 (op0_low + op1_low) * 2**BITS_PER_WORD.
698 We use a trick to adjust quickly. We logically shift op0_low right
699 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
700 op0_high (op1_high) before it is used to calculate 2b (2a). If no
701 logical shift exists, we do an arithmetic right shift and subtract
704 if (binoptab
== smul_optab
706 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
707 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
708 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
709 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
711 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
712 != CODE_FOR_nothing
)))
714 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
715 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
716 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
717 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
718 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
719 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
724 /* If the target is the same as one of the inputs, don't use it. This
725 prevents problems with the REG_EQUAL note. */
726 if (target
== op0
|| target
== op1
)
729 /* Multiply the two lower words to get a double-word product.
730 If unsigned widening multiplication is available, use that;
731 otherwise use the signed form and compensate. */
733 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
735 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
736 target
, 1, OPTAB_DIRECT
);
738 /* If we didn't succeed, delete everything we did so far. */
740 delete_insns_since (last
);
742 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
746 && smul_widen_optab
->handlers
[(int) mode
].insn_code
749 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
750 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
751 target
, 1, OPTAB_DIRECT
);
752 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
753 NULL_RTX
, 1, OPTAB_DIRECT
);
755 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
756 op0_xhigh
, op0_xhigh
, 0, OPTAB_DIRECT
);
759 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
760 NULL_RTX
, 0, OPTAB_DIRECT
);
762 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
763 op0_xhigh
, op0_xhigh
, 0,
767 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
768 NULL_RTX
, 1, OPTAB_DIRECT
);
770 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
771 op1_xhigh
, op1_xhigh
, 0, OPTAB_DIRECT
);
774 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
775 NULL_RTX
, 0, OPTAB_DIRECT
);
777 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
778 op1_xhigh
, op1_xhigh
, 0,
783 /* If we have been able to directly compute the product of the
784 low-order words of the operands and perform any required adjustments
785 of the operands, we proceed by trying two more multiplications
786 and then computing the appropriate sum.
788 We have checked above that the required addition is provided.
789 Full-word addition will normally always succeed, especially if
790 it is provided at all, so we don't worry about its failure. The
791 multiplication may well fail, however, so we do handle that. */
793 if (product
&& op0_xhigh
&& op1_xhigh
)
796 rtx product_high
= operand_subword (product
, high
, 1, mode
);
797 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
798 NULL_RTX
, 0, OPTAB_DIRECT
);
802 product_piece
= expand_binop (word_mode
, add_optab
, temp
,
803 product_high
, product_high
,
805 if (product_piece
!= product_high
)
806 emit_move_insn (product_high
, product_piece
);
808 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
809 NULL_RTX
, 0, OPTAB_DIRECT
);
811 product_piece
= expand_binop (word_mode
, add_optab
, temp
,
812 product_high
, product_high
,
814 if (product_piece
!= product_high
)
815 emit_move_insn (product_high
, product_piece
);
817 temp
= emit_move_insn (product
, product
);
818 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
819 gen_rtx (MULT
, mode
, op0
, op1
),
826 /* If we get here, we couldn't do it for some reason even though we
827 originally thought we could. Delete anything we've emitted in
830 delete_insns_since (last
);
833 /* We need to open-code the complex type operations: '+, -, * and /' */
835 /* At this point we allow operations between two similar complex
836 numbers, and also if one of the operands is not a complex number
837 but rather of MODE_FLOAT or MODE_INT. However, the caller
838 must make sure that the MODE of the non-complex operand matches
839 the SUBMODE of the complex operand. */
841 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
853 /* Find the correct mode for the real and imaginary parts */
854 enum machine_mode submode
855 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
856 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
859 if (submode
== BLKmode
)
863 target
= gen_reg_rtx (mode
);
867 realr
= gen_realpart (submode
, target
);
868 imagr
= gen_imagpart (submode
, target
);
870 if (GET_MODE (op0
) == mode
)
872 real0
= gen_realpart (submode
, op0
);
873 imag0
= gen_imagpart (submode
, op0
);
878 if (GET_MODE (op1
) == mode
)
880 real1
= gen_realpart (submode
, op1
);
881 imag1
= gen_imagpart (submode
, op1
);
886 if (! real0
|| ! real1
|| ! (imag0
|| imag1
))
889 switch (binoptab
->code
)
892 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
894 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
895 res
= expand_binop (submode
, binoptab
, real0
, real1
,
896 realr
, unsignedp
, methods
);
898 emit_move_insn (realr
, res
);
901 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
902 imagr
, unsignedp
, methods
);
905 else if (binoptab
->code
== MINUS
)
906 res
= expand_unop (submode
, neg_optab
, imag1
, imagr
, unsignedp
);
911 emit_move_insn (imagr
, res
);
915 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
920 expand_binop (submode
, sub_optab
,
921 expand_binop (submode
, binoptab
, real0
,
922 real1
, 0, unsignedp
, methods
),
923 expand_binop (submode
, binoptab
, imag0
,
924 imag1
, 0, unsignedp
, methods
),
925 realr
, unsignedp
, methods
);
928 emit_move_insn (realr
, temp
);
930 res
= expand_binop (submode
, add_optab
,
931 expand_binop (submode
, binoptab
,
933 0, unsignedp
, methods
),
934 expand_binop (submode
, binoptab
,
936 0, unsignedp
, methods
),
937 imagr
, unsignedp
, methods
);
939 emit_move_insn (imagr
, res
);
943 res
= expand_binop (submode
, binoptab
, real0
, real1
,
944 realr
, unsignedp
, methods
);
946 emit_move_insn (realr
, res
);
949 res
= expand_binop (submode
, binoptab
,
950 real1
, imag0
, imagr
, unsignedp
, methods
);
952 res
= expand_binop (submode
, binoptab
,
953 real0
, imag1
, imagr
, unsignedp
, methods
);
955 emit_move_insn (imagr
, res
);
960 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
963 { /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
964 /* Simply divide the real and imaginary parts by `c' */
965 res
= expand_binop (submode
, binoptab
, real0
, real1
,
966 realr
, unsignedp
, methods
);
968 emit_move_insn (realr
, res
);
970 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
971 imagr
, unsignedp
, methods
);
973 emit_move_insn (imagr
, res
);
975 else /* Divisor is of complex type */
982 optab mulopt
= unsignedp
? umul_widen_optab
: smul_optab
;
984 /* Divisor: c*c + d*d */
985 divisor
= expand_binop (submode
, add_optab
,
986 expand_binop (submode
, mulopt
,
988 0, unsignedp
, methods
),
989 expand_binop (submode
, mulopt
,
991 0, unsignedp
, methods
),
992 0, unsignedp
, methods
);
994 if (! imag0
) /* ((a)(c-id))/divisor */
995 { /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
996 /* Calculate the dividend */
997 real_t
= expand_binop (submode
, mulopt
, real0
, real1
,
998 0, unsignedp
, methods
);
1001 = expand_unop (submode
, neg_optab
,
1002 expand_binop (submode
, mulopt
, real0
, imag1
,
1003 0, unsignedp
, methods
),
1006 else /* ((a+ib)(c-id))/divider */
1008 /* Calculate the dividend */
1009 real_t
= expand_binop (submode
, add_optab
,
1010 expand_binop (submode
, mulopt
,
1012 0, unsignedp
, methods
),
1013 expand_binop (submode
, mulopt
,
1015 0, unsignedp
, methods
),
1016 0, unsignedp
, methods
);
1018 imag_t
= expand_binop (submode
, sub_optab
,
1019 expand_binop (submode
, mulopt
,
1021 0, unsignedp
, methods
),
1022 expand_binop (submode
, mulopt
,
1024 0, unsignedp
, methods
),
1025 0, unsignedp
, methods
);
1029 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
1030 realr
, unsignedp
, methods
);
1032 emit_move_insn (realr
, res
);
1034 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
1035 imagr
, unsignedp
, methods
);
1037 emit_move_insn (imagr
, res
);
1048 if (binoptab
->code
!= UNKNOWN
)
1049 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
1053 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1058 /* It can't be open-coded in this mode.
1059 Use a library call if one is available and caller says that's ok. */
1061 if (binoptab
->handlers
[(int) mode
].libfunc
1062 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1065 rtx funexp
= binoptab
->handlers
[(int) mode
].libfunc
;
1067 enum machine_mode op1_mode
= mode
;
1073 op1_mode
= word_mode
;
1074 /* Specify unsigned here,
1075 since negative shift counts are meaningless. */
1076 op1x
= convert_to_mode (word_mode
, op1
, 1);
1079 /* Pass 1 for NO_QUEUE so we don't lose any increments
1080 if the libcall is cse'd or moved. */
1081 emit_library_call (binoptab
->handlers
[(int) mode
].libfunc
,
1082 1, mode
, 2, op0
, mode
, op1x
, op1_mode
);
1084 insns
= get_insns ();
1087 target
= gen_reg_rtx (mode
);
1088 emit_libcall_block (insns
, target
, hard_libcall_value (mode
),
1089 gen_rtx (binoptab
->code
, mode
, op0
, op1
));
1094 delete_insns_since (last
);
1096 /* It can't be done in this mode. Can we do it in a wider mode? */
1098 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1099 || methods
== OPTAB_MUST_WIDEN
))
1101 /* Caller says, don't even try. */
1102 delete_insns_since (entry_last
);
1106 /* Compute the value of METHODS to pass to recursive calls.
1107 Don't allow widening to be tried recursively. */
1109 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1111 /* Look for a wider mode of the same class for which it appears we can do
1114 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1116 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1117 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1119 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1120 != CODE_FOR_nothing
)
1121 || (methods
== OPTAB_LIB
1122 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1124 rtx xop0
= op0
, xop1
= op1
;
1127 /* For certain integer operations, we need not actually extend
1128 the narrow operands, as long as we will truncate
1129 the results to the same narrowness. Don't do this when
1130 WIDER_MODE is wider than a word since a paradoxical SUBREG
1131 isn't valid for such modes. */
1133 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1134 || binoptab
== xor_optab
1135 || binoptab
== add_optab
|| binoptab
== sub_optab
1136 || binoptab
== smul_optab
1137 || binoptab
== ashl_optab
|| binoptab
== lshl_optab
)
1138 && class == MODE_INT
1139 && GET_MODE_SIZE (wider_mode
) <= UNITS_PER_WORD
)
1142 /* If an operand is a constant integer, we might as well
1143 convert it since that is more efficient than using a SUBREG,
1144 unlike the case for other operands. Similarly for
1145 SUBREGs that were made due to promoted objects.*/
1147 if (no_extend
&& GET_MODE (xop0
) != VOIDmode
1148 && ! (GET_CODE (xop0
) == SUBREG
1149 && SUBREG_PROMOTED_VAR_P (xop0
)))
1150 xop0
= gen_rtx (SUBREG
, wider_mode
,
1151 force_reg (GET_MODE (xop0
), xop0
), 0);
1153 xop0
= convert_to_mode (wider_mode
, xop0
, unsignedp
);
1155 if (no_extend
&& GET_MODE (xop1
) != VOIDmode
1156 && ! (GET_CODE (xop1
) == SUBREG
1157 && SUBREG_PROMOTED_VAR_P (xop1
)))
1158 xop1
= gen_rtx (SUBREG
, wider_mode
,
1159 force_reg (GET_MODE (xop1
), xop1
), 0);
1161 xop1
= convert_to_mode (wider_mode
, xop1
, unsignedp
);
1163 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1164 unsignedp
, methods
);
1167 if (class != MODE_INT
)
1170 target
= gen_reg_rtx (mode
);
1171 convert_move (target
, temp
, 0);
1175 return gen_lowpart (mode
, temp
);
1178 delete_insns_since (last
);
1183 delete_insns_since (entry_last
);
1187 /* Expand a binary operator which has both signed and unsigned forms.
1188 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1191 If we widen unsigned operands, we may use a signed wider operation instead
1192 of an unsigned wider operation, since the result would be the same. */
1195 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1196 enum machine_mode mode
;
1197 optab uoptab
, soptab
;
1198 rtx op0
, op1
, target
;
1200 enum optab_methods methods
;
1203 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1204 struct optab wide_soptab
;
1206 /* Do it without widening, if possible. */
1207 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1208 unsignedp
, OPTAB_DIRECT
);
1209 if (temp
|| methods
== OPTAB_DIRECT
)
1212 /* Try widening to a signed int. Make a fake signed optab that
1213 hides any signed insn for direct use. */
1214 wide_soptab
= *soptab
;
1215 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1216 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1218 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1219 unsignedp
, OPTAB_WIDEN
);
1221 /* For unsigned operands, try widening to an unsigned int. */
1222 if (temp
== 0 && unsignedp
)
1223 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1224 unsignedp
, OPTAB_WIDEN
);
1225 if (temp
|| methods
== OPTAB_WIDEN
)
1228 /* Use the right width lib call if that exists. */
1229 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1230 if (temp
|| methods
== OPTAB_LIB
)
1233 /* Must widen and use a lib call, use either signed or unsigned. */
1234 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1235 unsignedp
, methods
);
1239 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1240 unsignedp
, methods
);
1244 /* Generate code to perform an operation specified by BINOPTAB
1245 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1246 We assume that the order of the operands for the instruction
1247 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1248 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1250 Either TARG0 or TARG1 may be zero, but what that means is that
1251 that result is not actually wanted. We will generate it into
1252 a dummy pseudo-reg and discard it. They may not both be zero.
1254 Returns 1 if this operation can be performed; 0 if not. */
1257 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1263 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1264 enum mode_class
class;
1265 enum machine_mode wider_mode
;
1266 rtx entry_last
= get_last_insn ();
1269 class = GET_MODE_CLASS (mode
);
1271 op0
= protect_from_queue (op0
, 0);
1272 op1
= protect_from_queue (op1
, 0);
1276 op0
= force_not_mem (op0
);
1277 op1
= force_not_mem (op1
);
1280 /* If we are inside an appropriately-short loop and one operand is an
1281 expensive constant, force it into a register. */
1282 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1283 && rtx_cost (op0
, binoptab
->code
) > 2)
1284 op0
= force_reg (mode
, op0
);
1286 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1287 && rtx_cost (op1
, binoptab
->code
) > 2)
1288 op1
= force_reg (mode
, op1
);
1291 targ0
= protect_from_queue (targ0
, 1);
1293 targ0
= gen_reg_rtx (mode
);
1295 targ1
= protect_from_queue (targ1
, 1);
1297 targ1
= gen_reg_rtx (mode
);
1299 /* Record where to go back to if we fail. */
1300 last
= get_last_insn ();
1302 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1304 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1305 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1306 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
1308 rtx xop0
= op0
, xop1
= op1
;
1310 /* In case this insn wants input operands in modes different from the
1311 result, convert the operands. */
1312 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1313 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1315 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1316 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1318 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1319 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1320 xop0
= copy_to_mode_reg (mode0
, xop0
);
1322 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
1323 xop1
= copy_to_mode_reg (mode1
, xop1
);
1325 /* We could handle this, but we should always be called with a pseudo
1326 for our targets and all insns should take them as outputs. */
1327 if (! (*insn_operand_predicate
[icode
][0]) (targ0
, mode
)
1328 || ! (*insn_operand_predicate
[icode
][3]) (targ1
, mode
))
1331 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1338 delete_insns_since (last
);
1341 /* It can't be done in this mode. Can we do it in a wider mode? */
1343 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1345 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1346 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1348 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1349 != CODE_FOR_nothing
)
1351 register rtx t0
= gen_reg_rtx (wider_mode
);
1352 register rtx t1
= gen_reg_rtx (wider_mode
);
1354 if (expand_twoval_binop (binoptab
,
1355 convert_to_mode (wider_mode
, op0
,
1357 convert_to_mode (wider_mode
, op1
,
1361 convert_move (targ0
, t0
, unsignedp
);
1362 convert_move (targ1
, t1
, unsignedp
);
1366 delete_insns_since (last
);
1371 delete_insns_since (entry_last
);
1375 /* Generate code to perform an operation specified by UNOPTAB
1376 on operand OP0, with result having machine-mode MODE.
1378 UNSIGNEDP is for the case where we have to widen the operands
1379 to perform the operation. It says to use zero-extension.
1381 If TARGET is nonzero, the value
1382 is generated there, if it is convenient to do so.
1383 In all cases an rtx is returned for the locus of the value;
1384 this may or may not be TARGET. */
1387 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
1388 enum machine_mode mode
;
1394 enum mode_class
class;
1395 enum machine_mode wider_mode
;
1397 rtx last
= get_last_insn ();
1400 class = GET_MODE_CLASS (mode
);
1402 op0
= protect_from_queue (op0
, 0);
1406 op0
= force_not_mem (op0
);
1410 target
= protect_from_queue (target
, 1);
1412 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1414 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
1415 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1421 temp
= gen_reg_rtx (mode
);
1423 if (GET_MODE (xop0
) != VOIDmode
1424 && GET_MODE (xop0
) != mode0
)
1425 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1427 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1429 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1430 xop0
= copy_to_mode_reg (mode0
, xop0
);
1432 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
1433 temp
= gen_reg_rtx (mode
);
1435 pat
= GEN_FCN (icode
) (temp
, xop0
);
1438 if (GET_CODE (pat
) == SEQUENCE
1439 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
1441 delete_insns_since (last
);
1442 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
1450 delete_insns_since (last
);
1453 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1455 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1456 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1457 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1459 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
1463 /* For certain operations, we need not actually extend
1464 the narrow operand, as long as we will truncate the
1465 results to the same narrowness. But it is faster to
1466 convert a SUBREG due to mode promotion. */
1468 if ((unoptab
== neg_optab
|| unoptab
== one_cmpl_optab
)
1469 && GET_MODE_SIZE (wider_mode
) <= UNITS_PER_WORD
1470 && class == MODE_INT
1471 && ! (GET_CODE (xop0
) == SUBREG
1472 && SUBREG_PROMOTED_VAR_P (xop0
)))
1473 xop0
= gen_rtx (SUBREG
, wider_mode
, force_reg (mode
, xop0
), 0);
1475 xop0
= convert_to_mode (wider_mode
, xop0
, unsignedp
);
1477 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
1482 if (class != MODE_INT
)
1485 target
= gen_reg_rtx (mode
);
1486 convert_move (target
, temp
, 0);
1490 return gen_lowpart (mode
, temp
);
1493 delete_insns_since (last
);
1497 /* These can be done a word at a time. */
1498 if (unoptab
== one_cmpl_optab
1499 && class == MODE_INT
1500 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1501 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1506 if (target
== 0 || target
== op0
)
1507 target
= gen_reg_rtx (mode
);
1511 /* Do the actual arithmetic. */
1512 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1514 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1515 rtx x
= expand_unop (word_mode
, unoptab
,
1516 operand_subword_force (op0
, i
, mode
),
1517 target_piece
, unsignedp
);
1518 if (target_piece
!= x
)
1519 emit_move_insn (target_piece
, x
);
1522 insns
= get_insns ();
1525 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
1526 gen_rtx (unoptab
->code
, mode
, op0
));
1530 /* Open-code the complex negation operation. */
1531 else if (unoptab
== neg_optab
1532 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
1538 /* Find the correct mode for the real and imaginary parts */
1539 enum machine_mode submode
1540 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1541 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1544 if (submode
== BLKmode
)
1548 target
= gen_reg_rtx (mode
);
1552 target_piece
= gen_imagpart (submode
, target
);
1553 x
= expand_unop (submode
, unoptab
,
1554 gen_imagpart (submode
, op0
),
1555 target_piece
, unsignedp
);
1556 if (target_piece
!= x
)
1557 emit_move_insn (target_piece
, x
);
1559 target_piece
= gen_realpart (submode
, target
);
1560 x
= expand_unop (submode
, unoptab
,
1561 gen_realpart (submode
, op0
),
1562 target_piece
, unsignedp
);
1563 if (target_piece
!= x
)
1564 emit_move_insn (target_piece
, x
);
1569 emit_no_conflict_block (seq
, target
, op0
, 0,
1570 gen_rtx (unoptab
->code
, mode
, op0
));
1574 /* Now try a library call in this mode. */
1575 if (unoptab
->handlers
[(int) mode
].libfunc
)
1578 rtx funexp
= unoptab
->handlers
[(int) mode
].libfunc
;
1582 /* Pass 1 for NO_QUEUE so we don't lose any increments
1583 if the libcall is cse'd or moved. */
1584 emit_library_call (unoptab
->handlers
[(int) mode
].libfunc
,
1585 1, mode
, 1, op0
, mode
);
1586 insns
= get_insns ();
1589 target
= gen_reg_rtx (mode
);
1590 emit_libcall_block (insns
, target
, hard_libcall_value (mode
),
1591 gen_rtx (unoptab
->code
, mode
, op0
));
1596 /* It can't be done in this mode. Can we do it in a wider mode? */
1598 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1600 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1601 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1603 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
1604 != CODE_FOR_nothing
)
1605 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
1609 /* For certain operations, we need not actually extend
1610 the narrow operand, as long as we will truncate the
1611 results to the same narrowness. */
1613 if ((unoptab
== neg_optab
|| unoptab
== one_cmpl_optab
)
1614 && GET_MODE_SIZE (wider_mode
) <= UNITS_PER_WORD
1615 && class == MODE_INT
1616 && ! (GET_CODE (xop0
) == SUBREG
1617 && SUBREG_PROMOTED_VAR_P (xop0
)))
1618 xop0
= gen_rtx (SUBREG
, wider_mode
, force_reg (mode
, xop0
), 0);
1620 xop0
= convert_to_mode (wider_mode
, xop0
, unsignedp
);
1622 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
1627 if (class != MODE_INT
)
1630 target
= gen_reg_rtx (mode
);
1631 convert_move (target
, temp
, 0);
1635 return gen_lowpart (mode
, temp
);
1638 delete_insns_since (last
);
1646 /* Emit code to compute the absolute value of OP0, with result to
1647 TARGET if convenient. (TARGET may be 0.) The return value says
1648 where the result actually is to be found.
1650 MODE is the mode of the operand; the mode of the result is
1651 different but can be deduced from MODE.
1653 UNSIGNEDP is relevant for complex integer modes. */
1656 expand_complex_abs (mode
, op0
, target
, unsignedp
)
1657 enum machine_mode mode
;
1662 enum mode_class
class = GET_MODE_CLASS (mode
);
1663 enum machine_mode wider_mode
;
1665 rtx entry_last
= get_last_insn ();
1669 /* Find the correct mode for the real and imaginary parts. */
1670 enum machine_mode submode
1671 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1672 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1675 if (submode
== BLKmode
)
1678 op0
= protect_from_queue (op0
, 0);
1682 op0
= force_not_mem (op0
);
1685 last
= get_last_insn ();
1688 target
= protect_from_queue (target
, 1);
1690 if (abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1692 int icode
= (int) abs_optab
->handlers
[(int) mode
].insn_code
;
1693 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1699 temp
= gen_reg_rtx (submode
);
1701 if (GET_MODE (xop0
) != VOIDmode
1702 && GET_MODE (xop0
) != mode0
)
1703 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1705 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1707 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1708 xop0
= copy_to_mode_reg (mode0
, xop0
);
1710 if (! (*insn_operand_predicate
[icode
][0]) (temp
, submode
))
1711 temp
= gen_reg_rtx (submode
);
1713 pat
= GEN_FCN (icode
) (temp
, xop0
);
1716 if (GET_CODE (pat
) == SEQUENCE
1717 && ! add_equal_note (pat
, temp
, abs_optab
->code
, xop0
, NULL_RTX
))
1719 delete_insns_since (last
);
1720 return expand_unop (mode
, abs_optab
, op0
, NULL_RTX
, unsignedp
);
1728 delete_insns_since (last
);
1731 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1733 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1734 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1736 if (abs_optab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
1740 xop0
= convert_to_mode (wider_mode
, xop0
, unsignedp
);
1741 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
1745 if (class != MODE_COMPLEX_INT
)
1748 target
= gen_reg_rtx (submode
);
1749 convert_move (target
, temp
, 0);
1753 return gen_lowpart (submode
, temp
);
1756 delete_insns_since (last
);
1760 /* Open-code the complex absolute-value operation
1761 if we can open-code sqrt. Otherwise it's not worth while. */
1762 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
)
1764 rtx real
, imag
, total
;
1766 real
= gen_realpart (submode
, op0
);
1767 imag
= gen_imagpart (submode
, op0
);
1768 /* Square both parts. */
1769 real
= expand_mult (mode
, real
, real
, NULL_RTX
, 0);
1770 imag
= expand_mult (mode
, imag
, imag
, NULL_RTX
, 0);
1771 /* Sum the parts. */
1772 total
= expand_binop (submode
, add_optab
, real
, imag
, 0,
1773 0, OPTAB_LIB_WIDEN
);
1774 /* Get sqrt in TARGET. Set TARGET to where the result is. */
1775 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
1777 delete_insns_since (last
);
1782 /* Now try a library call in this mode. */
1783 if (abs_optab
->handlers
[(int) mode
].libfunc
)
1786 rtx funexp
= abs_optab
->handlers
[(int) mode
].libfunc
;
1790 /* Pass 1 for NO_QUEUE so we don't lose any increments
1791 if the libcall is cse'd or moved. */
1792 emit_library_call (abs_optab
->handlers
[(int) mode
].libfunc
,
1793 1, mode
, 1, op0
, mode
);
1794 insns
= get_insns ();
1797 target
= gen_reg_rtx (submode
);
1798 emit_libcall_block (insns
, target
, hard_libcall_value (submode
),
1799 gen_rtx (abs_optab
->code
, mode
, op0
));
1804 /* It can't be done in this mode. Can we do it in a wider mode? */
1806 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1807 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1809 if ((abs_optab
->handlers
[(int) wider_mode
].insn_code
1810 != CODE_FOR_nothing
)
1811 || abs_optab
->handlers
[(int) wider_mode
].libfunc
)
1815 xop0
= convert_to_mode (wider_mode
, xop0
, unsignedp
);
1817 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
1821 if (class != MODE_COMPLEX_INT
)
1824 target
= gen_reg_rtx (submode
);
1825 convert_move (target
, temp
, 0);
1829 return gen_lowpart (submode
, temp
);
1832 delete_insns_since (last
);
1836 delete_insns_since (entry_last
);
1840 /* Generate an instruction whose insn-code is INSN_CODE,
1841 with two operands: an output TARGET and an input OP0.
1842 TARGET *must* be nonzero, and the output is always stored there.
1843 CODE is an rtx code such that (CODE OP0) is an rtx that describes
1844 the value that is stored into TARGET. */
1847 emit_unop_insn (icode
, target
, op0
, code
)
1854 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1857 temp
= target
= protect_from_queue (target
, 1);
1859 op0
= protect_from_queue (op0
, 0);
1862 op0
= force_not_mem (op0
);
1864 /* Now, if insn does not accept our operands, put them into pseudos. */
1866 if (! (*insn_operand_predicate
[icode
][1]) (op0
, mode0
))
1867 op0
= copy_to_mode_reg (mode0
, op0
);
1869 if (! (*insn_operand_predicate
[icode
][0]) (temp
, GET_MODE (temp
))
1870 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
1871 temp
= gen_reg_rtx (GET_MODE (temp
));
1873 pat
= GEN_FCN (icode
) (temp
, op0
);
1875 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
1876 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
1881 emit_move_insn (target
, temp
);
1884 /* Emit code to perform a series of operations on a multi-word quantity, one
1887 Such a block is preceded by a CLOBBER of the output, consists of multiple
1888 insns, each setting one word of the output, and followed by a SET copying
1889 the output to itself.
1891 Each of the insns setting words of the output receives a REG_NO_CONFLICT
1892 note indicating that it doesn't conflict with the (also multi-word)
1893 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
1896 INSNS is a block of code generated to perform the operation, not including
1897 the CLOBBER and final copy. All insns that compute intermediate values
1898 are first emitted, followed by the block as described above. Only
1899 INSNs are allowed in the block; no library calls or jumps may be
1902 TARGET, OP0, and OP1 are the output and inputs of the operations,
1903 respectively. OP1 may be zero for a unary operation.
1905 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
1908 If TARGET is not a register, INSNS is simply emitted with no special
1911 The final insn emitted is returned. */
1914 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
1920 rtx prev
, next
, first
, last
, insn
;
1922 if (GET_CODE (target
) != REG
|| reload_in_progress
)
1923 return emit_insns (insns
);
1925 /* First emit all insns that do not store into words of the output and remove
1926 these from the list. */
1927 for (insn
= insns
; insn
; insn
= next
)
1932 next
= NEXT_INSN (insn
);
1934 if (GET_CODE (insn
) != INSN
)
1937 if (GET_CODE (PATTERN (insn
)) == SET
)
1938 set
= PATTERN (insn
);
1939 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
1941 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
1942 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
1944 set
= XVECEXP (PATTERN (insn
), 0, i
);
1952 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
1954 if (PREV_INSN (insn
))
1955 NEXT_INSN (PREV_INSN (insn
)) = next
;
1960 PREV_INSN (next
) = PREV_INSN (insn
);
1966 prev
= get_last_insn ();
1968 /* Now write the CLOBBER of the output, followed by the setting of each
1969 of the words, followed by the final copy. */
1970 if (target
!= op0
&& target
!= op1
)
1971 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, target
));
1973 for (insn
= insns
; insn
; insn
= next
)
1975 next
= NEXT_INSN (insn
);
1978 if (op1
&& GET_CODE (op1
) == REG
)
1979 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op1
,
1982 if (op0
&& GET_CODE (op0
) == REG
)
1983 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op0
,
1987 last
= emit_move_insn (target
, target
);
1989 REG_NOTES (last
) = gen_rtx (EXPR_LIST
, REG_EQUAL
, equiv
, REG_NOTES (last
));
1992 first
= get_insns ();
1994 first
= NEXT_INSN (prev
);
1996 /* Encapsulate the block so it gets manipulated as a unit. */
1997 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
1999 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2004 /* Emit code to make a call to a constant function or a library call.
2006 INSNS is a list containing all insns emitted in the call.
2007 These insns leave the result in RESULT. Our block is to copy RESULT
2008 to TARGET, which is logically equivalent to EQUIV.
2010 We first emit any insns that set a pseudo on the assumption that these are
2011 loading constants into registers; doing so allows them to be safely cse'ed
2012 between blocks. Then we emit all the other insns in the block, followed by
2013 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2014 note with an operand of EQUIV.
2016 Moving assignments to pseudos outside of the block is done to improve
2017 the generated code, but is not required to generate correct code,
2018 hence being unable to move an assignment is not grounds for not making
2019 a libcall block. There are two reasons why it is safe to leave these
2020 insns inside the block: First, we know that these pseudos cannot be
2021 used in generated RTL outside the block since they are created for
2022 temporary purposes within the block. Second, CSE will not record the
2023 values of anything set inside a libcall block, so we know they must
2024 be dead at the end of the block.
2026 Except for the first group of insns (the ones setting pseudos), the
2027 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2030 emit_libcall_block (insns
, target
, result
, equiv
)
2036 rtx prev
, next
, first
, last
, insn
;
2038 /* First emit all insns that set pseudos. Remove them from the list as
2039 we go. Avoid insns that set pseudo which were referenced in previous
2040 insns. These can be generated by move_by_pieces, for example,
2041 to update an address. */
2043 for (insn
= insns
; insn
; insn
= next
)
2045 rtx set
= single_set (insn
);
2047 next
= NEXT_INSN (insn
);
2049 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2050 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2052 || (! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
))
2053 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
))))
2055 if (PREV_INSN (insn
))
2056 NEXT_INSN (PREV_INSN (insn
)) = next
;
2061 PREV_INSN (next
) = PREV_INSN (insn
);
2067 prev
= get_last_insn ();
2069 /* Write the remaining insns followed by the final copy. */
2071 for (insn
= insns
; insn
; insn
= next
)
2073 next
= NEXT_INSN (insn
);
2078 last
= emit_move_insn (target
, result
);
2079 REG_NOTES (last
) = gen_rtx (EXPR_LIST
, REG_EQUAL
, equiv
, REG_NOTES (last
));
2082 first
= get_insns ();
2084 first
= NEXT_INSN (prev
);
2086 /* Encapsulate the block so it gets manipulated as a unit. */
2087 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
2089 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2092 /* Generate code to store zero in X. */
2098 emit_move_insn (x
, const0_rtx
);
2101 /* Generate code to store 1 in X
2102 assuming it contains zero beforehand. */
2105 emit_0_to_1_insn (x
)
2108 emit_move_insn (x
, const1_rtx
);
2111 /* Generate code to compare X with Y
2112 so that the condition codes are set.
2114 MODE is the mode of the inputs (in case they are const_int).
2115 UNSIGNEDP nonzero says that X and Y are unsigned;
2116 this matters if they need to be widened.
2118 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2119 and ALIGN specifies the known shared alignment of X and Y.
2121 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2122 It is ignored for fixed-point and block comparisons;
2123 it is used only for floating-point comparisons. */
2126 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
2128 enum rtx_code comparison
;
2130 enum machine_mode mode
;
2134 enum mode_class
class;
2135 enum machine_mode wider_mode
;
2137 class = GET_MODE_CLASS (mode
);
2139 /* They could both be VOIDmode if both args are immediate constants,
2140 but we should fold that at an earlier stage.
2141 With no special code here, this will call abort,
2142 reminding the programmer to implement such folding. */
2144 if (mode
!= BLKmode
&& flag_force_mem
)
2146 x
= force_not_mem (x
);
2147 y
= force_not_mem (y
);
2150 /* If we are inside an appropriately-short loop and one operand is an
2151 expensive constant, force it into a register. */
2152 if (CONSTANT_P (x
) && preserve_subexpressions_p () && rtx_cost (x
, COMPARE
) > 2)
2153 x
= force_reg (mode
, x
);
2155 if (CONSTANT_P (y
) && preserve_subexpressions_p () && rtx_cost (y
, COMPARE
) > 2)
2156 y
= force_reg (mode
, y
);
2158 /* Don't let both operands fail to indicate the mode. */
2159 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
2160 x
= force_reg (mode
, x
);
2162 /* Handle all BLKmode compares. */
2164 if (mode
== BLKmode
)
2167 x
= protect_from_queue (x
, 0);
2168 y
= protect_from_queue (y
, 0);
2172 #ifdef HAVE_cmpstrqi
2174 && GET_CODE (size
) == CONST_INT
2175 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
2177 enum machine_mode result_mode
2178 = insn_operand_mode
[(int) CODE_FOR_cmpstrqi
][0];
2179 rtx result
= gen_reg_rtx (result_mode
);
2180 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, GEN_INT (align
)));
2181 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2186 #ifdef HAVE_cmpstrhi
2188 && GET_CODE (size
) == CONST_INT
2189 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
2191 enum machine_mode result_mode
2192 = insn_operand_mode
[(int) CODE_FOR_cmpstrhi
][0];
2193 rtx result
= gen_reg_rtx (result_mode
);
2194 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, GEN_INT (align
)));
2195 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2200 #ifdef HAVE_cmpstrsi
2203 enum machine_mode result_mode
2204 = insn_operand_mode
[(int) CODE_FOR_cmpstrsi
][0];
2205 rtx result
= gen_reg_rtx (result_mode
);
2206 size
= protect_from_queue (size
, 0);
2207 emit_insn (gen_cmpstrsi (result
, x
, y
,
2208 convert_to_mode (SImode
, size
, 1),
2210 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2216 #ifdef TARGET_MEM_FUNCTIONS
2217 emit_library_call (memcmp_libfunc
, 0,
2218 TYPE_MODE (integer_type_node
), 3,
2219 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2222 emit_library_call (bcmp_libfunc
, 0,
2223 TYPE_MODE (integer_type_node
), 3,
2224 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2227 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node
)),
2228 const0_rtx
, comparison
, NULL_RTX
,
2229 TYPE_MODE (integer_type_node
), 0, 0);
2234 /* Handle some compares against zero. */
2236 if (y
== CONST0_RTX (mode
)
2237 && tst_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2239 int icode
= (int) tst_optab
->handlers
[(int) mode
].insn_code
;
2242 x
= protect_from_queue (x
, 0);
2243 y
= protect_from_queue (y
, 0);
2245 /* Now, if insn does accept these operands, put them into pseudos. */
2246 if (! (*insn_operand_predicate
[icode
][0])
2247 (x
, insn_operand_mode
[icode
][0]))
2248 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2250 emit_insn (GEN_FCN (icode
) (x
));
2254 /* Handle compares for which there is a directly suitable insn. */
2256 if (cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2258 int icode
= (int) cmp_optab
->handlers
[(int) mode
].insn_code
;
2261 x
= protect_from_queue (x
, 0);
2262 y
= protect_from_queue (y
, 0);
2264 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2265 if (! (*insn_operand_predicate
[icode
][0])
2266 (x
, insn_operand_mode
[icode
][0]))
2267 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2269 if (! (*insn_operand_predicate
[icode
][1])
2270 (y
, insn_operand_mode
[icode
][1]))
2271 y
= copy_to_mode_reg (insn_operand_mode
[icode
][1], y
);
2273 emit_insn (GEN_FCN (icode
) (x
, y
));
2277 /* Try widening if we can find a direct insn that way. */
2279 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2281 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2282 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2284 if (cmp_optab
->handlers
[(int) wider_mode
].insn_code
2285 != CODE_FOR_nothing
)
2287 x
= protect_from_queue (x
, 0);
2288 y
= protect_from_queue (y
, 0);
2289 x
= convert_to_mode (wider_mode
, x
, unsignedp
);
2290 y
= convert_to_mode (wider_mode
, y
, unsignedp
);
2291 emit_cmp_insn (x
, y
, comparison
, NULL_RTX
,
2292 wider_mode
, unsignedp
, align
);
2298 /* Handle a lib call just for the mode we are using. */
2300 if (cmp_optab
->handlers
[(int) mode
].libfunc
2301 && class != MODE_FLOAT
)
2303 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
2304 /* If we want unsigned, and this mode has a distinct unsigned
2305 comparison routine, use that. */
2306 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
2307 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
2309 emit_library_call (libfunc
, 1,
2310 word_mode
, 2, x
, mode
, y
, mode
);
2312 /* Integer comparison returns a result that must be compared against 1,
2313 so that even if we do an unsigned compare afterward,
2314 there is still a value that can represent the result "less than". */
2316 emit_cmp_insn (hard_libcall_value (word_mode
), const1_rtx
,
2317 comparison
, NULL_RTX
, word_mode
, unsignedp
, 0);
2321 if (class == MODE_FLOAT
)
2322 emit_float_lib_cmp (x
, y
, comparison
);
2328 /* Nonzero if a compare of mode MODE can be done straightforwardly
2329 (without splitting it into pieces). */
2332 can_compare_p (mode
)
2333 enum machine_mode mode
;
2337 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2339 mode
= GET_MODE_WIDER_MODE (mode
);
2340 } while (mode
!= VOIDmode
);
2345 /* Emit a library call comparison between floating point X and Y.
2346 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2349 emit_float_lib_cmp (x
, y
, comparison
)
2351 enum rtx_code comparison
;
2353 enum machine_mode mode
= GET_MODE (x
);
2360 libfunc
= eqsf2_libfunc
;
2364 libfunc
= nesf2_libfunc
;
2368 libfunc
= gtsf2_libfunc
;
2372 libfunc
= gesf2_libfunc
;
2376 libfunc
= ltsf2_libfunc
;
2380 libfunc
= lesf2_libfunc
;
2383 else if (mode
== DFmode
)
2387 libfunc
= eqdf2_libfunc
;
2391 libfunc
= nedf2_libfunc
;
2395 libfunc
= gtdf2_libfunc
;
2399 libfunc
= gedf2_libfunc
;
2403 libfunc
= ltdf2_libfunc
;
2407 libfunc
= ledf2_libfunc
;
2410 else if (mode
== XFmode
)
2414 libfunc
= eqxf2_libfunc
;
2418 libfunc
= nexf2_libfunc
;
2422 libfunc
= gtxf2_libfunc
;
2426 libfunc
= gexf2_libfunc
;
2430 libfunc
= ltxf2_libfunc
;
2434 libfunc
= lexf2_libfunc
;
2437 else if (mode
== TFmode
)
2441 libfunc
= eqtf2_libfunc
;
2445 libfunc
= netf2_libfunc
;
2449 libfunc
= gttf2_libfunc
;
2453 libfunc
= getf2_libfunc
;
2457 libfunc
= lttf2_libfunc
;
2461 libfunc
= letf2_libfunc
;
2466 enum machine_mode wider_mode
;
2468 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2469 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2471 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
2472 != CODE_FOR_nothing
)
2473 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
2475 x
= protect_from_queue (x
, 0);
2476 y
= protect_from_queue (y
, 0);
2477 x
= convert_to_mode (wider_mode
, x
, 0);
2478 y
= convert_to_mode (wider_mode
, y
, 0);
2479 emit_float_lib_cmp (x
, y
, comparison
);
2486 emit_library_call (libfunc
, 1,
2487 word_mode
, 2, x
, mode
, y
, mode
);
2489 emit_cmp_insn (hard_libcall_value (word_mode
), const0_rtx
, comparison
,
2490 NULL_RTX
, word_mode
, 0, 0);
2493 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2496 emit_indirect_jump (loc
)
2499 if (! ((*insn_operand_predicate
[(int)CODE_FOR_indirect_jump
][0])
2501 loc
= copy_to_mode_reg (Pmode
, loc
);
2503 emit_jump_insn (gen_indirect_jump (loc
));
2507 /* These three functions generate an insn body and return it
2508 rather than emitting the insn.
2510 They do not protect from queued increments,
2511 because they may be used 1) in protect_from_queue itself
2512 and 2) in other passes where there is no queue. */
2514 /* Generate and return an insn body to add Y to X. */
2517 gen_add2_insn (x
, y
)
2520 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
2522 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
2523 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
2524 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
2527 return (GEN_FCN (icode
) (x
, x
, y
));
2531 have_add2_insn (mode
)
2532 enum machine_mode mode
;
2534 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
2537 /* Generate and return an insn body to subtract Y from X. */
2540 gen_sub2_insn (x
, y
)
2543 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
2545 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
2546 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
2547 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
2550 return (GEN_FCN (icode
) (x
, x
, y
));
2554 have_sub2_insn (mode
)
2555 enum machine_mode mode
;
2557 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
2560 /* Generate the body of an instruction to copy Y into X.
2561 It may be a SEQUENCE, if one insn isn't enough. */
2564 gen_move_insn (x
, y
)
2567 register enum machine_mode mode
= GET_MODE (x
);
2568 enum insn_code insn_code
;
2571 if (mode
== VOIDmode
)
2572 mode
= GET_MODE (y
);
2574 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
2576 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2577 find a mode to do it in. If we have a movcc, use it. Otherwise,
2578 find the MODE_INT mode of the same width. */
2580 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
2582 enum machine_mode tmode
= VOIDmode
;
2586 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
2589 for (tmode
= QImode
; tmode
!= VOIDmode
;
2590 tmode
= GET_MODE_WIDER_MODE (tmode
))
2591 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
2594 if (tmode
== VOIDmode
)
2597 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2598 may call change_address which is not appropriate if we were
2599 called when a reload was in progress. We don't have to worry
2600 about changing the address since the size in bytes is supposed to
2601 be the same. Copy the MEM to change the mode and move any
2602 substitutions from the old MEM to the new one. */
2604 if (reload_in_progress
)
2606 x
= gen_lowpart_common (tmode
, x1
);
2607 if (x
== 0 && GET_CODE (x1
) == MEM
)
2609 x
= gen_rtx (MEM
, tmode
, XEXP (x1
, 0));
2610 RTX_UNCHANGING_P (x
) = RTX_UNCHANGING_P (x1
);
2611 MEM_IN_STRUCT_P (x
) = MEM_IN_STRUCT_P (x1
);
2612 MEM_VOLATILE_P (x
) = MEM_VOLATILE_P (x1
);
2613 copy_replacements (x1
, x
);
2616 y
= gen_lowpart_common (tmode
, y1
);
2617 if (y
== 0 && GET_CODE (y1
) == MEM
)
2619 y
= gen_rtx (MEM
, tmode
, XEXP (y1
, 0));
2620 RTX_UNCHANGING_P (y
) = RTX_UNCHANGING_P (y1
);
2621 MEM_IN_STRUCT_P (y
) = MEM_IN_STRUCT_P (y1
);
2622 MEM_VOLATILE_P (y
) = MEM_VOLATILE_P (y1
);
2623 copy_replacements (y1
, y
);
2628 x
= gen_lowpart (tmode
, x
);
2629 y
= gen_lowpart (tmode
, y
);
2632 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
2633 return (GEN_FCN (insn_code
) (x
, y
));
2637 emit_move_insn_1 (x
, y
);
2638 seq
= gen_sequence ();
2643 /* Tables of patterns for extending one integer mode to another. */
2644 static enum insn_code extendtab
[MAX_MACHINE_MODE
][MAX_MACHINE_MODE
][2];
2646 /* Return the insn code used to extend FROM_MODE to TO_MODE.
2647 UNSIGNEDP specifies zero-extension instead of sign-extension. If
2648 no such operation exists, CODE_FOR_nothing will be returned. */
2651 can_extend_p (to_mode
, from_mode
, unsignedp
)
2652 enum machine_mode to_mode
, from_mode
;
2655 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
];
2658 /* Generate the body of an insn to extend Y (with mode MFROM)
2659 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
2662 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
2664 enum machine_mode mto
, mfrom
;
2667 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
]) (x
, y
));
2675 for (p
= extendtab
[0][0];
2676 p
< extendtab
[0][0] + sizeof extendtab
/ sizeof extendtab
[0][0][0];
2678 *p
= CODE_FOR_nothing
;
2680 #ifdef HAVE_extendditi2
2681 if (HAVE_extendditi2
)
2682 extendtab
[(int) TImode
][(int) DImode
][0] = CODE_FOR_extendditi2
;
2684 #ifdef HAVE_extendsiti2
2685 if (HAVE_extendsiti2
)
2686 extendtab
[(int) TImode
][(int) SImode
][0] = CODE_FOR_extendsiti2
;
2688 #ifdef HAVE_extendhiti2
2689 if (HAVE_extendhiti2
)
2690 extendtab
[(int) TImode
][(int) HImode
][0] = CODE_FOR_extendhiti2
;
2692 #ifdef HAVE_extendqiti2
2693 if (HAVE_extendqiti2
)
2694 extendtab
[(int) TImode
][(int) QImode
][0] = CODE_FOR_extendqiti2
;
2696 #ifdef HAVE_extendsidi2
2697 if (HAVE_extendsidi2
)
2698 extendtab
[(int) DImode
][(int) SImode
][0] = CODE_FOR_extendsidi2
;
2700 #ifdef HAVE_extendhidi2
2701 if (HAVE_extendhidi2
)
2702 extendtab
[(int) DImode
][(int) HImode
][0] = CODE_FOR_extendhidi2
;
2704 #ifdef HAVE_extendqidi2
2705 if (HAVE_extendqidi2
)
2706 extendtab
[(int) DImode
][(int) QImode
][0] = CODE_FOR_extendqidi2
;
2708 #ifdef HAVE_extendhisi2
2709 if (HAVE_extendhisi2
)
2710 extendtab
[(int) SImode
][(int) HImode
][0] = CODE_FOR_extendhisi2
;
2712 #ifdef HAVE_extendqisi2
2713 if (HAVE_extendqisi2
)
2714 extendtab
[(int) SImode
][(int) QImode
][0] = CODE_FOR_extendqisi2
;
2716 #ifdef HAVE_extendqihi2
2717 if (HAVE_extendqihi2
)
2718 extendtab
[(int) HImode
][(int) QImode
][0] = CODE_FOR_extendqihi2
;
2721 #ifdef HAVE_zero_extendditi2
2722 if (HAVE_zero_extendsiti2
)
2723 extendtab
[(int) TImode
][(int) DImode
][1] = CODE_FOR_zero_extendditi2
;
2725 #ifdef HAVE_zero_extendsiti2
2726 if (HAVE_zero_extendsiti2
)
2727 extendtab
[(int) TImode
][(int) SImode
][1] = CODE_FOR_zero_extendsiti2
;
2729 #ifdef HAVE_zero_extendhiti2
2730 if (HAVE_zero_extendhiti2
)
2731 extendtab
[(int) TImode
][(int) HImode
][1] = CODE_FOR_zero_extendhiti2
;
2733 #ifdef HAVE_zero_extendqiti2
2734 if (HAVE_zero_extendqiti2
)
2735 extendtab
[(int) TImode
][(int) QImode
][1] = CODE_FOR_zero_extendqiti2
;
2737 #ifdef HAVE_zero_extendsidi2
2738 if (HAVE_zero_extendsidi2
)
2739 extendtab
[(int) DImode
][(int) SImode
][1] = CODE_FOR_zero_extendsidi2
;
2741 #ifdef HAVE_zero_extendhidi2
2742 if (HAVE_zero_extendhidi2
)
2743 extendtab
[(int) DImode
][(int) HImode
][1] = CODE_FOR_zero_extendhidi2
;
2745 #ifdef HAVE_zero_extendqidi2
2746 if (HAVE_zero_extendqidi2
)
2747 extendtab
[(int) DImode
][(int) QImode
][1] = CODE_FOR_zero_extendqidi2
;
2749 #ifdef HAVE_zero_extendhisi2
2750 if (HAVE_zero_extendhisi2
)
2751 extendtab
[(int) SImode
][(int) HImode
][1] = CODE_FOR_zero_extendhisi2
;
2753 #ifdef HAVE_zero_extendqisi2
2754 if (HAVE_zero_extendqisi2
)
2755 extendtab
[(int) SImode
][(int) QImode
][1] = CODE_FOR_zero_extendqisi2
;
2757 #ifdef HAVE_zero_extendqihi2
2758 if (HAVE_zero_extendqihi2
)
2759 extendtab
[(int) HImode
][(int) QImode
][1] = CODE_FOR_zero_extendqihi2
;
2763 /* can_fix_p and can_float_p say whether the target machine
2764 can directly convert a given fixed point type to
2765 a given floating point type, or vice versa.
2766 The returned value is the CODE_FOR_... value to use,
2767 or CODE_FOR_nothing if these modes cannot be directly converted. */
2769 static enum insn_code fixtab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
2770 static enum insn_code fixtrunctab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
2771 static enum insn_code floattab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
2773 /* *TRUNCP_PTR is set to 1 if it is necessary to output
2774 an explicit FTRUNC insn before the fix insn; otherwise 0. */
2776 static enum insn_code
2777 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
2778 enum machine_mode fltmode
, fixmode
;
2783 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
] != CODE_FOR_nothing
)
2784 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
];
2786 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
2789 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
];
2791 return CODE_FOR_nothing
;
2794 static enum insn_code
2795 can_float_p (fltmode
, fixmode
, unsignedp
)
2796 enum machine_mode fixmode
, fltmode
;
2799 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
];
2806 for (p
= fixtab
[0][0];
2807 p
< fixtab
[0][0] + sizeof fixtab
/ sizeof (fixtab
[0][0][0]);
2809 *p
= CODE_FOR_nothing
;
2810 for (p
= fixtrunctab
[0][0];
2811 p
< fixtrunctab
[0][0] + sizeof fixtrunctab
/ sizeof (fixtrunctab
[0][0][0]);
2813 *p
= CODE_FOR_nothing
;
2815 #ifdef HAVE_fixqfqi2
2817 fixtab
[(int) QFmode
][(int) QImode
][0] = CODE_FOR_fixqfqi2
;
2819 #ifdef HAVE_fixhfqi2
2821 fixtab
[(int) HFmode
][(int) QImode
][0] = CODE_FOR_fixhfqi2
;
2823 #ifdef HAVE_fixhfhi2
2825 fixtab
[(int) HFmode
][(int) HImode
][0] = CODE_FOR_fixhfhi2
;
2827 #ifdef HAVE_fixsfqi2
2829 fixtab
[(int) SFmode
][(int) QImode
][0] = CODE_FOR_fixsfqi2
;
2831 #ifdef HAVE_fixsfhi2
2833 fixtab
[(int) SFmode
][(int) HImode
][0] = CODE_FOR_fixsfhi2
;
2835 #ifdef HAVE_fixsfsi2
2837 fixtab
[(int) SFmode
][(int) SImode
][0] = CODE_FOR_fixsfsi2
;
2839 #ifdef HAVE_fixsfdi2
2841 fixtab
[(int) SFmode
][(int) DImode
][0] = CODE_FOR_fixsfdi2
;
2844 #ifdef HAVE_fixdfqi2
2846 fixtab
[(int) DFmode
][(int) QImode
][0] = CODE_FOR_fixdfqi2
;
2848 #ifdef HAVE_fixdfhi2
2850 fixtab
[(int) DFmode
][(int) HImode
][0] = CODE_FOR_fixdfhi2
;
2852 #ifdef HAVE_fixdfsi2
2854 fixtab
[(int) DFmode
][(int) SImode
][0] = CODE_FOR_fixdfsi2
;
2856 #ifdef HAVE_fixdfdi2
2858 fixtab
[(int) DFmode
][(int) DImode
][0] = CODE_FOR_fixdfdi2
;
2860 #ifdef HAVE_fixdfti2
2862 fixtab
[(int) DFmode
][(int) TImode
][0] = CODE_FOR_fixdfti2
;
2865 #ifdef HAVE_fixxfqi2
2867 fixtab
[(int) XFmode
][(int) QImode
][0] = CODE_FOR_fixxfqi2
;
2869 #ifdef HAVE_fixxfhi2
2871 fixtab
[(int) XFmode
][(int) HImode
][0] = CODE_FOR_fixxfhi2
;
2873 #ifdef HAVE_fixxfsi2
2875 fixtab
[(int) XFmode
][(int) SImode
][0] = CODE_FOR_fixxfsi2
;
2877 #ifdef HAVE_fixxfdi2
2879 fixtab
[(int) XFmode
][(int) DImode
][0] = CODE_FOR_fixxfdi2
;
2881 #ifdef HAVE_fixxfti2
2883 fixtab
[(int) XFmode
][(int) TImode
][0] = CODE_FOR_fixxfti2
;
2886 #ifdef HAVE_fixtfqi2
2888 fixtab
[(int) TFmode
][(int) QImode
][0] = CODE_FOR_fixtfqi2
;
2890 #ifdef HAVE_fixtfhi2
2892 fixtab
[(int) TFmode
][(int) HImode
][0] = CODE_FOR_fixtfhi2
;
2894 #ifdef HAVE_fixtfsi2
2896 fixtab
[(int) TFmode
][(int) SImode
][0] = CODE_FOR_fixtfsi2
;
2898 #ifdef HAVE_fixtfdi2
2900 fixtab
[(int) TFmode
][(int) DImode
][0] = CODE_FOR_fixtfdi2
;
2902 #ifdef HAVE_fixtfti2
2904 fixtab
[(int) TFmode
][(int) TImode
][0] = CODE_FOR_fixtfti2
;
2907 #ifdef HAVE_fixunsqfqi2
2908 if (HAVE_fixunsqfqi2
)
2909 fixtab
[(int) QFmode
][(int) QImode
][1] = CODE_FOR_fixunsqfqi2
;
2911 #ifdef HAVE_fixunshfqi2
2912 if (HAVE_fixunshfqi2
)
2913 fixtab
[(int) HFmode
][(int) QImode
][1] = CODE_FOR_fixunshfqi2
;
2915 #ifdef HAVE_fixunshfhi2
2916 if (HAVE_fixunshfhi2
)
2917 fixtab
[(int) HFmode
][(int) HImode
][1] = CODE_FOR_fixunshfhi2
;
2920 #ifdef HAVE_fixunssfqi2
2921 if (HAVE_fixunssfqi2
)
2922 fixtab
[(int) SFmode
][(int) QImode
][1] = CODE_FOR_fixunssfqi2
;
2924 #ifdef HAVE_fixunssfhi2
2925 if (HAVE_fixunssfhi2
)
2926 fixtab
[(int) SFmode
][(int) HImode
][1] = CODE_FOR_fixunssfhi2
;
2928 #ifdef HAVE_fixunssfsi2
2929 if (HAVE_fixunssfsi2
)
2930 fixtab
[(int) SFmode
][(int) SImode
][1] = CODE_FOR_fixunssfsi2
;
2932 #ifdef HAVE_fixunssfdi2
2933 if (HAVE_fixunssfdi2
)
2934 fixtab
[(int) SFmode
][(int) DImode
][1] = CODE_FOR_fixunssfdi2
;
2937 #ifdef HAVE_fixunsdfqi2
2938 if (HAVE_fixunsdfqi2
)
2939 fixtab
[(int) DFmode
][(int) QImode
][1] = CODE_FOR_fixunsdfqi2
;
2941 #ifdef HAVE_fixunsdfhi2
2942 if (HAVE_fixunsdfhi2
)
2943 fixtab
[(int) DFmode
][(int) HImode
][1] = CODE_FOR_fixunsdfhi2
;
2945 #ifdef HAVE_fixunsdfsi2
2946 if (HAVE_fixunsdfsi2
)
2947 fixtab
[(int) DFmode
][(int) SImode
][1] = CODE_FOR_fixunsdfsi2
;
2949 #ifdef HAVE_fixunsdfdi2
2950 if (HAVE_fixunsdfdi2
)
2951 fixtab
[(int) DFmode
][(int) DImode
][1] = CODE_FOR_fixunsdfdi2
;
2953 #ifdef HAVE_fixunsdfti2
2954 if (HAVE_fixunsdfti2
)
2955 fixtab
[(int) DFmode
][(int) TImode
][1] = CODE_FOR_fixunsdfti2
;
2958 #ifdef HAVE_fixunsxfqi2
2959 if (HAVE_fixunsxfqi2
)
2960 fixtab
[(int) XFmode
][(int) QImode
][1] = CODE_FOR_fixunsxfqi2
;
2962 #ifdef HAVE_fixunsxfhi2
2963 if (HAVE_fixunsxfhi2
)
2964 fixtab
[(int) XFmode
][(int) HImode
][1] = CODE_FOR_fixunsxfhi2
;
2966 #ifdef HAVE_fixunsxfsi2
2967 if (HAVE_fixunsxfsi2
)
2968 fixtab
[(int) XFmode
][(int) SImode
][1] = CODE_FOR_fixunsxfsi2
;
2970 #ifdef HAVE_fixunsxfdi2
2971 if (HAVE_fixunsxfdi2
)
2972 fixtab
[(int) XFmode
][(int) DImode
][1] = CODE_FOR_fixunsxfdi2
;
2974 #ifdef HAVE_fixunsxfti2
2975 if (HAVE_fixunsxfti2
)
2976 fixtab
[(int) XFmode
][(int) TImode
][1] = CODE_FOR_fixunsxfti2
;
2979 #ifdef HAVE_fixunstfqi2
2980 if (HAVE_fixunstfqi2
)
2981 fixtab
[(int) TFmode
][(int) QImode
][1] = CODE_FOR_fixunstfqi2
;
2983 #ifdef HAVE_fixunstfhi2
2984 if (HAVE_fixunstfhi2
)
2985 fixtab
[(int) TFmode
][(int) HImode
][1] = CODE_FOR_fixunstfhi2
;
2987 #ifdef HAVE_fixunstfsi2
2988 if (HAVE_fixunstfsi2
)
2989 fixtab
[(int) TFmode
][(int) SImode
][1] = CODE_FOR_fixunstfsi2
;
2991 #ifdef HAVE_fixunstfdi2
2992 if (HAVE_fixunstfdi2
)
2993 fixtab
[(int) TFmode
][(int) DImode
][1] = CODE_FOR_fixunstfdi2
;
2995 #ifdef HAVE_fixunstfti2
2996 if (HAVE_fixunstfti2
)
2997 fixtab
[(int) TFmode
][(int) TImode
][1] = CODE_FOR_fixunstfti2
;
3000 #ifdef HAVE_fix_truncqfqi2
3001 if (HAVE_fix_truncqfqi2
)
3002 fixtrunctab
[(int) QFmode
][(int) QImode
][0] = CODE_FOR_fix_truncqfqi2
;
3004 #ifdef HAVE_fix_trunchfqi2
3005 if (HAVE_fix_trunchfqi2
)
3006 fixtrunctab
[(int) HFmode
][(int) QImode
][0] = CODE_FOR_fix_trunchfqi2
;
3008 #ifdef HAVE_fix_trunchfhi2
3009 if (HAVE_fix_trunchfhi2
)
3010 fixtrunctab
[(int) HFmode
][(int) HImode
][0] = CODE_FOR_fix_trunchfhi2
;
3012 #ifdef HAVE_fix_truncsfqi2
3013 if (HAVE_fix_truncsfqi2
)
3014 fixtrunctab
[(int) SFmode
][(int) QImode
][0] = CODE_FOR_fix_truncsfqi2
;
3016 #ifdef HAVE_fix_truncsfhi2
3017 if (HAVE_fix_truncsfhi2
)
3018 fixtrunctab
[(int) SFmode
][(int) HImode
][0] = CODE_FOR_fix_truncsfhi2
;
3020 #ifdef HAVE_fix_truncsfsi2
3021 if (HAVE_fix_truncsfsi2
)
3022 fixtrunctab
[(int) SFmode
][(int) SImode
][0] = CODE_FOR_fix_truncsfsi2
;
3024 #ifdef HAVE_fix_truncsfdi2
3025 if (HAVE_fix_truncsfdi2
)
3026 fixtrunctab
[(int) SFmode
][(int) DImode
][0] = CODE_FOR_fix_truncsfdi2
;
3029 #ifdef HAVE_fix_truncdfqi2
3030 if (HAVE_fix_truncdfqi2
)
3031 fixtrunctab
[(int) DFmode
][(int) QImode
][0] = CODE_FOR_fix_truncdfqi2
;
3033 #ifdef HAVE_fix_truncdfhi2
3034 if (HAVE_fix_truncdfhi2
)
3035 fixtrunctab
[(int) DFmode
][(int) HImode
][0] = CODE_FOR_fix_truncdfhi2
;
3037 #ifdef HAVE_fix_truncdfsi2
3038 if (HAVE_fix_truncdfsi2
)
3039 fixtrunctab
[(int) DFmode
][(int) SImode
][0] = CODE_FOR_fix_truncdfsi2
;
3041 #ifdef HAVE_fix_truncdfdi2
3042 if (HAVE_fix_truncdfdi2
)
3043 fixtrunctab
[(int) DFmode
][(int) DImode
][0] = CODE_FOR_fix_truncdfdi2
;
3045 #ifdef HAVE_fix_truncdfti2
3046 if (HAVE_fix_truncdfti2
)
3047 fixtrunctab
[(int) DFmode
][(int) TImode
][0] = CODE_FOR_fix_truncdfti2
;
3050 #ifdef HAVE_fix_truncxfqi2
3051 if (HAVE_fix_truncxfqi2
)
3052 fixtrunctab
[(int) XFmode
][(int) QImode
][0] = CODE_FOR_fix_truncxfqi2
;
3054 #ifdef HAVE_fix_truncxfhi2
3055 if (HAVE_fix_truncxfhi2
)
3056 fixtrunctab
[(int) XFmode
][(int) HImode
][0] = CODE_FOR_fix_truncxfhi2
;
3058 #ifdef HAVE_fix_truncxfsi2
3059 if (HAVE_fix_truncxfsi2
)
3060 fixtrunctab
[(int) XFmode
][(int) SImode
][0] = CODE_FOR_fix_truncxfsi2
;
3062 #ifdef HAVE_fix_truncxfdi2
3063 if (HAVE_fix_truncxfdi2
)
3064 fixtrunctab
[(int) XFmode
][(int) DImode
][0] = CODE_FOR_fix_truncxfdi2
;
3066 #ifdef HAVE_fix_truncxfti2
3067 if (HAVE_fix_truncxfti2
)
3068 fixtrunctab
[(int) XFmode
][(int) TImode
][0] = CODE_FOR_fix_truncxfti2
;
3071 #ifdef HAVE_fix_trunctfqi2
3072 if (HAVE_fix_trunctfqi2
)
3073 fixtrunctab
[(int) TFmode
][(int) QImode
][0] = CODE_FOR_fix_trunctfqi2
;
3075 #ifdef HAVE_fix_trunctfhi2
3076 if (HAVE_fix_trunctfhi2
)
3077 fixtrunctab
[(int) TFmode
][(int) HImode
][0] = CODE_FOR_fix_trunctfhi2
;
3079 #ifdef HAVE_fix_trunctfsi2
3080 if (HAVE_fix_trunctfsi2
)
3081 fixtrunctab
[(int) TFmode
][(int) SImode
][0] = CODE_FOR_fix_trunctfsi2
;
3083 #ifdef HAVE_fix_trunctfdi2
3084 if (HAVE_fix_trunctfdi2
)
3085 fixtrunctab
[(int) TFmode
][(int) DImode
][0] = CODE_FOR_fix_trunctfdi2
;
3087 #ifdef HAVE_fix_trunctfti2
3088 if (HAVE_fix_trunctfti2
)
3089 fixtrunctab
[(int) TFmode
][(int) TImode
][0] = CODE_FOR_fix_trunctfti2
;
3092 #ifdef HAVE_fixuns_truncqfqi2
3093 if (HAVE_fixuns_truncqfqi2
)
3094 fixtrunctab
[(int) QFmode
][(int) QImode
][1] = CODE_FOR_fixuns_truncqfqi2
;
3096 #ifdef HAVE_fixuns_trunchfqi2
3097 if (HAVE_fixuns_trunchfqi2
)
3098 fixtrunctab
[(int) HFmode
][(int) QImode
][1] = CODE_FOR_fixuns_trunchfqi2
;
3100 #ifdef HAVE_fixuns_trunchfhi2
3101 if (HAVE_fixuns_trunchfhi2
)
3102 fixtrunctab
[(int) HFmode
][(int) HImode
][1] = CODE_FOR_fixuns_trunchfhi2
;
3104 #ifdef HAVE_fixuns_truncsfqi2
3105 if (HAVE_fixuns_truncsfqi2
)
3106 fixtrunctab
[(int) SFmode
][(int) QImode
][1] = CODE_FOR_fixuns_truncsfqi2
;
3108 #ifdef HAVE_fixuns_truncsfhi2
3109 if (HAVE_fixuns_truncsfhi2
)
3110 fixtrunctab
[(int) SFmode
][(int) HImode
][1] = CODE_FOR_fixuns_truncsfhi2
;
3112 #ifdef HAVE_fixuns_truncsfsi2
3113 if (HAVE_fixuns_truncsfsi2
)
3114 fixtrunctab
[(int) SFmode
][(int) SImode
][1] = CODE_FOR_fixuns_truncsfsi2
;
3116 #ifdef HAVE_fixuns_truncsfdi2
3117 if (HAVE_fixuns_truncsfdi2
)
3118 fixtrunctab
[(int) SFmode
][(int) DImode
][1] = CODE_FOR_fixuns_truncsfdi2
;
3121 #ifdef HAVE_fixuns_truncdfqi2
3122 if (HAVE_fixuns_truncdfqi2
)
3123 fixtrunctab
[(int) DFmode
][(int) QImode
][1] = CODE_FOR_fixuns_truncdfqi2
;
3125 #ifdef HAVE_fixuns_truncdfhi2
3126 if (HAVE_fixuns_truncdfhi2
)
3127 fixtrunctab
[(int) DFmode
][(int) HImode
][1] = CODE_FOR_fixuns_truncdfhi2
;
3129 #ifdef HAVE_fixuns_truncdfsi2
3130 if (HAVE_fixuns_truncdfsi2
)
3131 fixtrunctab
[(int) DFmode
][(int) SImode
][1] = CODE_FOR_fixuns_truncdfsi2
;
3133 #ifdef HAVE_fixuns_truncdfdi2
3134 if (HAVE_fixuns_truncdfdi2
)
3135 fixtrunctab
[(int) DFmode
][(int) DImode
][1] = CODE_FOR_fixuns_truncdfdi2
;
3137 #ifdef HAVE_fixuns_truncdfti2
3138 if (HAVE_fixuns_truncdfti2
)
3139 fixtrunctab
[(int) DFmode
][(int) TImode
][1] = CODE_FOR_fixuns_truncdfti2
;
3142 #ifdef HAVE_fixuns_truncxfqi2
3143 if (HAVE_fixuns_truncxfqi2
)
3144 fixtrunctab
[(int) XFmode
][(int) QImode
][1] = CODE_FOR_fixuns_truncxfqi2
;
3146 #ifdef HAVE_fixuns_truncxfhi2
3147 if (HAVE_fixuns_truncxfhi2
)
3148 fixtrunctab
[(int) XFmode
][(int) HImode
][1] = CODE_FOR_fixuns_truncxfhi2
;
3150 #ifdef HAVE_fixuns_truncxfsi2
3151 if (HAVE_fixuns_truncxfsi2
)
3152 fixtrunctab
[(int) XFmode
][(int) SImode
][1] = CODE_FOR_fixuns_truncxfsi2
;
3154 #ifdef HAVE_fixuns_truncxfdi2
3155 if (HAVE_fixuns_truncxfdi2
)
3156 fixtrunctab
[(int) XFmode
][(int) DImode
][1] = CODE_FOR_fixuns_truncxfdi2
;
3158 #ifdef HAVE_fixuns_truncxfti2
3159 if (HAVE_fixuns_truncxfti2
)
3160 fixtrunctab
[(int) XFmode
][(int) TImode
][1] = CODE_FOR_fixuns_truncxfti2
;
3163 #ifdef HAVE_fixuns_trunctfqi2
3164 if (HAVE_fixuns_trunctfqi2
)
3165 fixtrunctab
[(int) TFmode
][(int) QImode
][1] = CODE_FOR_fixuns_trunctfqi2
;
3167 #ifdef HAVE_fixuns_trunctfhi2
3168 if (HAVE_fixuns_trunctfhi2
)
3169 fixtrunctab
[(int) TFmode
][(int) HImode
][1] = CODE_FOR_fixuns_trunctfhi2
;
3171 #ifdef HAVE_fixuns_trunctfsi2
3172 if (HAVE_fixuns_trunctfsi2
)
3173 fixtrunctab
[(int) TFmode
][(int) SImode
][1] = CODE_FOR_fixuns_trunctfsi2
;
3175 #ifdef HAVE_fixuns_trunctfdi2
3176 if (HAVE_fixuns_trunctfdi2
)
3177 fixtrunctab
[(int) TFmode
][(int) DImode
][1] = CODE_FOR_fixuns_trunctfdi2
;
3179 #ifdef HAVE_fixuns_trunctfti2
3180 if (HAVE_fixuns_trunctfti2
)
3181 fixtrunctab
[(int) TFmode
][(int) TImode
][1] = CODE_FOR_fixuns_trunctfti2
;
3184 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3185 /* This flag says the same insns that convert to a signed fixnum
3186 also convert validly to an unsigned one. */
3190 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3191 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
3192 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
3201 for (p
= floattab
[0][0];
3202 p
< floattab
[0][0] + sizeof floattab
/ sizeof (floattab
[0][0][0]);
3204 *p
= CODE_FOR_nothing
;
3206 #ifdef HAVE_floatqiqf2
3207 if (HAVE_floatqiqf2
)
3208 floattab
[(int) QFmode
][(int) QImode
][0] = CODE_FOR_floatqiqf2
;
3210 #ifdef HAVE_floathiqf2
3211 if (HAVE_floathiqf2
)
3212 floattab
[(int) QFmode
][(int) HImode
][0] = CODE_FOR_floathiqf2
;
3214 #ifdef HAVE_floatsiqf2
3215 if (HAVE_floatsiqf2
)
3216 floattab
[(int) QFmode
][(int) SImode
][0] = CODE_FOR_floatsiqf2
;
3218 #ifdef HAVE_floatdiqf2
3219 if (HAVE_floatdiqf2
)
3220 floattab
[(int) QFmode
][(int) DImode
][0] = CODE_FOR_floatdiqf2
;
3222 #ifdef HAVE_floattiqf2
3223 if (HAVE_floattiqf2
)
3224 floattab
[(int) QFmode
][(int) TImode
][0] = CODE_FOR_floattiqf2
;
3227 #ifdef HAVE_floatqihf2
3228 if (HAVE_floatqihf2
)
3229 floattab
[(int) HFmode
][(int) QImode
][0] = CODE_FOR_floatqihf2
;
3231 #ifdef HAVE_floathihf2
3232 if (HAVE_floathihf2
)
3233 floattab
[(int) HFmode
][(int) HImode
][0] = CODE_FOR_floathihf2
;
3235 #ifdef HAVE_floatsihf2
3236 if (HAVE_floatsihf2
)
3237 floattab
[(int) HFmode
][(int) SImode
][0] = CODE_FOR_floatsihf2
;
3239 #ifdef HAVE_floatdihf2
3240 if (HAVE_floatdihf2
)
3241 floattab
[(int) HFmode
][(int) DImode
][0] = CODE_FOR_floatdihf2
;
3243 #ifdef HAVE_floattihf2
3244 if (HAVE_floattihf2
)
3245 floattab
[(int) HFmode
][(int) TImode
][0] = CODE_FOR_floattihf2
;
3248 #ifdef HAVE_floatqisf2
3249 if (HAVE_floatqisf2
)
3250 floattab
[(int) SFmode
][(int) QImode
][0] = CODE_FOR_floatqisf2
;
3252 #ifdef HAVE_floathisf2
3253 if (HAVE_floathisf2
)
3254 floattab
[(int) SFmode
][(int) HImode
][0] = CODE_FOR_floathisf2
;
3256 #ifdef HAVE_floatsisf2
3257 if (HAVE_floatsisf2
)
3258 floattab
[(int) SFmode
][(int) SImode
][0] = CODE_FOR_floatsisf2
;
3260 #ifdef HAVE_floatdisf2
3261 if (HAVE_floatdisf2
)
3262 floattab
[(int) SFmode
][(int) DImode
][0] = CODE_FOR_floatdisf2
;
3264 #ifdef HAVE_floattisf2
3265 if (HAVE_floattisf2
)
3266 floattab
[(int) SFmode
][(int) TImode
][0] = CODE_FOR_floattisf2
;
3269 #ifdef HAVE_floatqidf2
3270 if (HAVE_floatqidf2
)
3271 floattab
[(int) DFmode
][(int) QImode
][0] = CODE_FOR_floatqidf2
;
3273 #ifdef HAVE_floathidf2
3274 if (HAVE_floathidf2
)
3275 floattab
[(int) DFmode
][(int) HImode
][0] = CODE_FOR_floathidf2
;
3277 #ifdef HAVE_floatsidf2
3278 if (HAVE_floatsidf2
)
3279 floattab
[(int) DFmode
][(int) SImode
][0] = CODE_FOR_floatsidf2
;
3281 #ifdef HAVE_floatdidf2
3282 if (HAVE_floatdidf2
)
3283 floattab
[(int) DFmode
][(int) DImode
][0] = CODE_FOR_floatdidf2
;
3285 #ifdef HAVE_floattidf2
3286 if (HAVE_floattidf2
)
3287 floattab
[(int) DFmode
][(int) TImode
][0] = CODE_FOR_floattidf2
;
3290 #ifdef HAVE_floatqixf2
3291 if (HAVE_floatqixf2
)
3292 floattab
[(int) XFmode
][(int) QImode
][0] = CODE_FOR_floatqixf2
;
3294 #ifdef HAVE_floathixf2
3295 if (HAVE_floathixf2
)
3296 floattab
[(int) XFmode
][(int) HImode
][0] = CODE_FOR_floathixf2
;
3298 #ifdef HAVE_floatsixf2
3299 if (HAVE_floatsixf2
)
3300 floattab
[(int) XFmode
][(int) SImode
][0] = CODE_FOR_floatsixf2
;
3302 #ifdef HAVE_floatdixf2
3303 if (HAVE_floatdixf2
)
3304 floattab
[(int) XFmode
][(int) DImode
][0] = CODE_FOR_floatdixf2
;
3306 #ifdef HAVE_floattixf2
3307 if (HAVE_floattixf2
)
3308 floattab
[(int) XFmode
][(int) TImode
][0] = CODE_FOR_floattixf2
;
3311 #ifdef HAVE_floatqitf2
3312 if (HAVE_floatqitf2
)
3313 floattab
[(int) TFmode
][(int) QImode
][0] = CODE_FOR_floatqitf2
;
3315 #ifdef HAVE_floathitf2
3316 if (HAVE_floathitf2
)
3317 floattab
[(int) TFmode
][(int) HImode
][0] = CODE_FOR_floathitf2
;
3319 #ifdef HAVE_floatsitf2
3320 if (HAVE_floatsitf2
)
3321 floattab
[(int) TFmode
][(int) SImode
][0] = CODE_FOR_floatsitf2
;
3323 #ifdef HAVE_floatditf2
3324 if (HAVE_floatditf2
)
3325 floattab
[(int) TFmode
][(int) DImode
][0] = CODE_FOR_floatditf2
;
3327 #ifdef HAVE_floattitf2
3328 if (HAVE_floattitf2
)
3329 floattab
[(int) TFmode
][(int) TImode
][0] = CODE_FOR_floattitf2
;
3332 #ifdef HAVE_floatunsqiqf2
3333 if (HAVE_floatunsqiqf2
)
3334 floattab
[(int) QFmode
][(int) QImode
][1] = CODE_FOR_floatunsqiqf2
;
3336 #ifdef HAVE_floatunshiqf2
3337 if (HAVE_floatunshiqf2
)
3338 floattab
[(int) QFmode
][(int) HImode
][1] = CODE_FOR_floatunshiqf2
;
3340 #ifdef HAVE_floatunssiqf2
3341 if (HAVE_floatunsqsiqf2
)
3342 floattab
[(int) QFmode
][(int) SImode
][1] = CODE_FOR_floatunssiqf2
;
3344 #ifdef HAVE_floatunsdiqf2
3345 if (HAVE_floatunsdiqf2
)
3346 floattab
[(int) QFmode
][(int) DImode
][1] = CODE_FOR_floatunsdiqf2
;
3348 #ifdef HAVE_floatunstiqf2
3349 if (HAVE_floatunstiqf2
)
3350 floattab
[(int) QFmode
][(int) TImode
][1] = CODE_FOR_floatunstiqf2
;
3353 #ifdef HAVE_floatunsqihf2
3354 if (HAVE_floatunsqihf2
)
3355 floattab
[(int) HFmode
][(int) QImode
][1] = CODE_FOR_floatunsqihf2
;
3357 #ifdef HAVE_floatunshihf2
3358 if (HAVE_floatunshihf2
)
3359 floattab
[(int) HFmode
][(int) HImode
][1] = CODE_FOR_floatunshihf2
;
3361 #ifdef HAVE_floatunssihf2
3362 if (HAVE_floatunssihf2
)
3363 floattab
[(int) HFmode
][(int) SImode
][1] = CODE_FOR_floatunssihf2
;
3365 #ifdef HAVE_floatunsdihf2
3366 if (HAVE_floatunsdihf2
)
3367 floattab
[(int) HFmode
][(int) DImode
][1] = CODE_FOR_floatunsdihf2
;
3369 #ifdef HAVE_floatunstihf2
3370 if (HAVE_floatunstihf2
)
3371 floattab
[(int) HFmode
][(int) TImode
][1] = CODE_FOR_floatunstihf2
;
3374 #ifdef HAVE_floatqunsqisf2
3375 if (HAVE_floatunsqisf2
)
3376 floattab
[(int) SFmode
][(int) QImode
][1] = CODE_FOR_floatunsqisf2
;
3378 #ifdef HAVE_floatunshisf2
3379 if (HAVE_floatunshisf2
)
3380 floattab
[(int) SFmode
][(int) HImode
][1] = CODE_FOR_floatunshisf2
;
3382 #ifdef HAVE_floatunssisf2
3383 if (HAVE_floatunssisf2
)
3384 floattab
[(int) SFmode
][(int) SImode
][1] = CODE_FOR_floatunssisf2
;
3386 #ifdef HAVE_floatunsdisf2
3387 if (HAVE_floatunsdisf2
)
3388 floattab
[(int) SFmode
][(int) DImode
][1] = CODE_FOR_floatunsdisf2
;
3390 #ifdef HAVE_floatunstisf2
3391 if (HAVE_floatunstisf2
)
3392 floattab
[(int) SFmode
][(int) TImode
][1] = CODE_FOR_floatunstisf2
;
3395 #ifdef HAVE_floatunsqidf2
3396 if (HAVE_floatunsqidf2
)
3397 floattab
[(int) DFmode
][(int) QImode
][1] = CODE_FOR_floatunsqidf2
;
3399 #ifdef HAVE_floatunshidf2
3400 if (HAVE_floatunshidf2
)
3401 floattab
[(int) DFmode
][(int) HImode
][1] = CODE_FOR_floatunshidf2
;
3403 #ifdef HAVE_floatunssidf2
3404 if (HAVE_floatunssidf2
)
3405 floattab
[(int) DFmode
][(int) SImode
][1] = CODE_FOR_floatunssidf2
;
3407 #ifdef HAVE_floatunsdidf2
3408 if (HAVE_floatunsdidf2
)
3409 floattab
[(int) DFmode
][(int) DImode
][1] = CODE_FOR_floatunsdidf2
;
3411 #ifdef HAVE_floatunstidf2
3412 if (HAVE_floatunstidf2
)
3413 floattab
[(int) DFmode
][(int) TImode
][1] = CODE_FOR_floatunstidf2
;
3416 #ifdef HAVE_floatunsqixf2
3417 if (HAVE_floatunsqixf2
)
3418 floattab
[(int) XFmode
][(int) QImode
][1] = CODE_FOR_floatunsqixf2
;
3420 #ifdef HAVE_floatunshixf2
3421 if (HAVE_floatunshixf2
)
3422 floattab
[(int) XFmode
][(int) HImode
][1] = CODE_FOR_floatunshixf2
;
3424 #ifdef HAVE_floatunssixf2
3425 if (HAVE_floatunssixf2
)
3426 floattab
[(int) XFmode
][(int) SImode
][1] = CODE_FOR_floatunssixf2
;
3428 #ifdef HAVE_floatunsdixf2
3429 if (HAVE_floatunsdixf2
)
3430 floattab
[(int) XFmode
][(int) DImode
][1] = CODE_FOR_floatunsdixf2
;
3432 #ifdef HAVE_floatunstixf2
3433 if (HAVE_floatunstixf2
)
3434 floattab
[(int) XFmode
][(int) TImode
][1] = CODE_FOR_floatunstixf2
;
3437 #ifdef HAVE_floatunsqitf2
3438 if (HAVE_floatunsqitf2
)
3439 floattab
[(int) TFmode
][(int) QImode
][1] = CODE_FOR_floatunsqitf2
;
3441 #ifdef HAVE_floatunshitf2
3442 if (HAVE_floatunshitf2
)
3443 floattab
[(int) TFmode
][(int) HImode
][1] = CODE_FOR_floatunshitf2
;
3445 #ifdef HAVE_floatunssitf2
3446 if (HAVE_floatunssitf2
)
3447 floattab
[(int) TFmode
][(int) SImode
][1] = CODE_FOR_floatunssitf2
;
3449 #ifdef HAVE_floatunsditf2
3450 if (HAVE_floatunsditf2
)
3451 floattab
[(int) TFmode
][(int) DImode
][1] = CODE_FOR_floatunsditf2
;
3453 #ifdef HAVE_floatunstitf2
3454 if (HAVE_floatunstitf2
)
3455 floattab
[(int) TFmode
][(int) TImode
][1] = CODE_FOR_floatunstitf2
;
3459 /* Generate code to convert FROM to floating point
3460 and store in TO. FROM must be fixed point and not VOIDmode.
3461 UNSIGNEDP nonzero means regard FROM as unsigned.
3462 Normally this is done by correcting the final value
3463 if it is negative. */
3466 expand_float (to
, from
, unsignedp
)
3470 enum insn_code icode
;
3471 register rtx target
= to
;
3472 enum machine_mode fmode
, imode
;
3474 /* Crash now, because we won't be able to decide which mode to use. */
3475 if (GET_MODE (from
) == VOIDmode
)
3478 /* Look for an insn to do the conversion. Do it in the specified
3479 modes if possible; otherwise convert either input, output or both to
3480 wider mode. If the integer mode is wider than the mode of FROM,
3481 we can do the conversion signed even if the input is unsigned. */
3483 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3484 imode
= GET_MODE_WIDER_MODE (imode
))
3485 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3486 fmode
= GET_MODE_WIDER_MODE (fmode
))
3488 int doing_unsigned
= unsignedp
;
3490 icode
= can_float_p (fmode
, imode
, unsignedp
);
3491 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3492 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3494 if (icode
!= CODE_FOR_nothing
)
3496 to
= protect_from_queue (to
, 1);
3497 from
= protect_from_queue (from
, 0);
3499 if (imode
!= GET_MODE (from
))
3500 from
= convert_to_mode (imode
, from
, unsignedp
);
3502 if (fmode
!= GET_MODE (to
))
3503 target
= gen_reg_rtx (fmode
);
3505 emit_unop_insn (icode
, target
, from
,
3506 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3509 convert_move (to
, target
, 0);
3514 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3516 /* Unsigned integer, and no way to convert directly.
3517 Convert as signed, then conditionally adjust the result. */
3520 rtx label
= gen_label_rtx ();
3522 REAL_VALUE_TYPE offset
;
3526 to
= protect_from_queue (to
, 1);
3527 from
= protect_from_queue (from
, 0);
3530 from
= force_not_mem (from
);
3532 /* If we are about to do some arithmetic to correct for an
3533 unsigned operand, do it in a pseudo-register. */
3535 if (GET_CODE (to
) != REG
|| REGNO (to
) <= LAST_VIRTUAL_REGISTER
)
3536 target
= gen_reg_rtx (GET_MODE (to
));
3538 /* Convert as signed integer to floating. */
3539 expand_float (target
, from
, 0);
3541 /* If FROM is negative (and therefore TO is negative),
3542 correct its value by 2**bitwidth. */
3544 do_pending_stack_adjust ();
3545 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3546 emit_jump_insn (gen_bge (label
));
3547 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3548 Rather than setting up a dconst_dot_5, let's hope SCO
3550 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
3551 temp
= expand_binop (GET_MODE (to
), add_optab
, target
,
3552 immed_real_const_1 (offset
, GET_MODE (to
)),
3553 target
, 0, OPTAB_LIB_WIDEN
);
3555 emit_move_insn (target
, temp
);
3556 do_pending_stack_adjust ();
3562 /* No hardware instruction available; call a library rotine to convert from
3563 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3568 to
= protect_from_queue (to
, 1);
3569 from
= protect_from_queue (from
, 0);
3571 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
3572 from
= convert_to_mode (SImode
, from
, unsignedp
);
3575 from
= force_not_mem (from
);
3577 if (GET_MODE (to
) == SFmode
)
3579 if (GET_MODE (from
) == SImode
)
3580 libfcn
= floatsisf_libfunc
;
3581 else if (GET_MODE (from
) == DImode
)
3582 libfcn
= floatdisf_libfunc
;
3583 else if (GET_MODE (from
) == TImode
)
3584 libfcn
= floattisf_libfunc
;
3588 else if (GET_MODE (to
) == DFmode
)
3590 if (GET_MODE (from
) == SImode
)
3591 libfcn
= floatsidf_libfunc
;
3592 else if (GET_MODE (from
) == DImode
)
3593 libfcn
= floatdidf_libfunc
;
3594 else if (GET_MODE (from
) == TImode
)
3595 libfcn
= floattidf_libfunc
;
3599 else if (GET_MODE (to
) == XFmode
)
3601 if (GET_MODE (from
) == SImode
)
3602 libfcn
= floatsixf_libfunc
;
3603 else if (GET_MODE (from
) == DImode
)
3604 libfcn
= floatdixf_libfunc
;
3605 else if (GET_MODE (from
) == TImode
)
3606 libfcn
= floattixf_libfunc
;
3610 else if (GET_MODE (to
) == TFmode
)
3612 if (GET_MODE (from
) == SImode
)
3613 libfcn
= floatsitf_libfunc
;
3614 else if (GET_MODE (from
) == DImode
)
3615 libfcn
= floatditf_libfunc
;
3616 else if (GET_MODE (from
) == TImode
)
3617 libfcn
= floattitf_libfunc
;
3626 emit_library_call (libfcn
, 1, GET_MODE (to
), 1, from
, GET_MODE (from
));
3627 insns
= get_insns ();
3630 emit_libcall_block (insns
, target
, hard_libcall_value (GET_MODE (to
)),
3631 gen_rtx (FLOAT
, GET_MODE (to
), from
));
3634 /* Copy result to requested destination
3635 if we have been computing in a temp location. */
3639 if (GET_MODE (target
) == GET_MODE (to
))
3640 emit_move_insn (to
, target
);
3642 convert_move (to
, target
, 0);
3646 /* expand_fix: generate code to convert FROM to fixed point
3647 and store in TO. FROM must be floating point. */
3653 rtx temp
= gen_reg_rtx (GET_MODE (x
));
3654 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
3658 expand_fix (to
, from
, unsignedp
)
3659 register rtx to
, from
;
3662 enum insn_code icode
;
3663 register rtx target
= to
;
3664 enum machine_mode fmode
, imode
;
3668 /* We first try to find a pair of modes, one real and one integer, at
3669 least as wide as FROM and TO, respectively, in which we can open-code
3670 this conversion. If the integer mode is wider than the mode of TO,
3671 we can do the conversion either signed or unsigned. */
3673 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
3674 imode
= GET_MODE_WIDER_MODE (imode
))
3675 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3676 fmode
= GET_MODE_WIDER_MODE (fmode
))
3678 int doing_unsigned
= unsignedp
;
3680 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
3681 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
3682 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
3684 if (icode
!= CODE_FOR_nothing
)
3686 to
= protect_from_queue (to
, 1);
3687 from
= protect_from_queue (from
, 0);
3689 if (fmode
!= GET_MODE (from
))
3690 from
= convert_to_mode (fmode
, from
, 0);
3693 from
= ftruncify (from
);
3695 if (imode
!= GET_MODE (to
))
3696 target
= gen_reg_rtx (imode
);
3698 emit_unop_insn (icode
, target
, from
,
3699 doing_unsigned
? UNSIGNED_FIX
: FIX
);
3701 convert_move (to
, target
, unsignedp
);
3706 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3707 /* For an unsigned conversion, there is one more way to do it.
3708 If we have a signed conversion, we generate code that compares
3709 the real value to the largest representable positive number. If if
3710 is smaller, the conversion is done normally. Otherwise, subtract
3711 one plus the highest signed number, convert, and add it back.
3713 We only need to check all real modes, since we know we didn't find
3714 anything with a wider integer mode. */
3716 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
3717 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3718 fmode
= GET_MODE_WIDER_MODE (fmode
))
3719 /* Make sure we won't lose significant bits doing this. */
3720 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
3721 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
3724 int bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
3725 REAL_VALUE_TYPE offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
3726 rtx limit
= immed_real_const_1 (offset
, fmode
);
3727 rtx lab1
= gen_label_rtx ();
3728 rtx lab2
= gen_label_rtx ();
3732 to
= protect_from_queue (to
, 1);
3733 from
= protect_from_queue (from
, 0);
3736 from
= force_not_mem (from
);
3738 if (fmode
!= GET_MODE (from
))
3739 from
= convert_to_mode (fmode
, from
, 0);
3741 /* See if we need to do the subtraction. */
3742 do_pending_stack_adjust ();
3743 emit_cmp_insn (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3744 emit_jump_insn (gen_bge (lab1
));
3746 /* If not, do the signed "fix" and branch around fixup code. */
3747 expand_fix (to
, from
, 0);
3748 emit_jump_insn (gen_jump (lab2
));
3751 /* Otherwise, subtract 2**(N-1), convert to signed number,
3752 then add 2**(N-1). Do the addition using XOR since this
3753 will often generate better code. */
3755 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
3756 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3757 expand_fix (to
, target
, 0);
3758 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
3759 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
3760 to
, 1, OPTAB_LIB_WIDEN
);
3763 emit_move_insn (to
, target
);
3767 /* Make a place for a REG_NOTE and add it. */
3768 insn
= emit_move_insn (to
, to
);
3769 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
3770 gen_rtx (UNSIGNED_FIX
, GET_MODE (to
),
3771 from
), REG_NOTES (insn
));
3777 /* We can't do it with an insn, so use a library call. But first ensure
3778 that the mode of TO is at least as wide as SImode, since those are the
3779 only library calls we know about. */
3781 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
3783 target
= gen_reg_rtx (SImode
);
3785 expand_fix (target
, from
, unsignedp
);
3787 else if (GET_MODE (from
) == SFmode
)
3789 if (GET_MODE (to
) == SImode
)
3790 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
3791 else if (GET_MODE (to
) == DImode
)
3792 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
3793 else if (GET_MODE (to
) == TImode
)
3794 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
3798 else if (GET_MODE (from
) == DFmode
)
3800 if (GET_MODE (to
) == SImode
)
3801 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
3802 else if (GET_MODE (to
) == DImode
)
3803 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
3804 else if (GET_MODE (to
) == TImode
)
3805 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
3809 else if (GET_MODE (from
) == XFmode
)
3811 if (GET_MODE (to
) == SImode
)
3812 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
3813 else if (GET_MODE (to
) == DImode
)
3814 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
3815 else if (GET_MODE (to
) == TImode
)
3816 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
3820 else if (GET_MODE (from
) == TFmode
)
3822 if (GET_MODE (to
) == SImode
)
3823 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
3824 else if (GET_MODE (to
) == DImode
)
3825 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
3826 else if (GET_MODE (to
) == TImode
)
3827 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
3838 to
= protect_from_queue (to
, 1);
3839 from
= protect_from_queue (from
, 0);
3842 from
= force_not_mem (from
);
3846 emit_library_call (libfcn
, 1, GET_MODE (to
), 1, from
, GET_MODE (from
));
3847 insns
= get_insns ();
3850 emit_libcall_block (insns
, target
, hard_libcall_value (GET_MODE (to
)),
3851 gen_rtx (unsignedp
? FIX
: UNSIGNED_FIX
,
3852 GET_MODE (to
), from
));
3855 if (GET_MODE (to
) == GET_MODE (target
))
3856 emit_move_insn (to
, target
);
3858 convert_move (to
, target
, 0);
3866 optab op
= (optab
) xmalloc (sizeof (struct optab
));
3868 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3870 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
3871 op
->handlers
[i
].libfunc
= 0;
3876 /* Initialize the libfunc fields of an entire group of entries in some
3877 optab. Each entry is set equal to a string consisting of a leading
3878 pair of underscores followed by a generic operation name followed by
3879 a mode name (downshifted to lower case) followed by a single character
3880 representing the number of operands for the given operation (which is
3881 usually one of the characters '2', '3', or '4').
3883 OPTABLE is the table in which libfunc fields are to be initialized.
3884 FIRST_MODE is the first machine mode index in the given optab to
3886 LAST_MODE is the last machine mode index in the given optab to
3888 OPNAME is the generic (string) name of the operation.
3889 SUFFIX is the character which specifies the number of operands for
3890 the given generic operation.
3894 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
3895 register optab optable
;
3896 register char *opname
;
3897 register int first_mode
;
3898 register int last_mode
;
3899 register char suffix
;
3902 register unsigned opname_len
= strlen (opname
);
3904 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
3905 mode
= (enum machine_mode
) ((int) mode
+ 1))
3907 register char *mname
= mode_name
[(int) mode
];
3908 register unsigned mname_len
= strlen (mname
);
3909 register char *libfunc_name
3910 = (char *) xmalloc (2 + opname_len
+ mname_len
+ 1 + 1);
3917 for (q
= opname
; *q
; )
3919 for (q
= mname
; *q
; q
++)
3920 *p
++ = tolower (*q
);
3923 optable
->handlers
[(int) mode
].libfunc
3924 = gen_rtx (SYMBOL_REF
, Pmode
, libfunc_name
);
3928 /* Initialize the libfunc fields of an entire group of entries in some
3929 optab which correspond to all integer mode operations. The parameters
3930 have the same meaning as similarly named ones for the `init_libfuncs'
3931 routine. (See above). */
3934 init_integral_libfuncs (optable
, opname
, suffix
)
3935 register optab optable
;
3936 register char *opname
;
3937 register char suffix
;
3939 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
3942 /* Initialize the libfunc fields of an entire group of entries in some
3943 optab which correspond to all real mode operations. The parameters
3944 have the same meaning as similarly named ones for the `init_libfuncs'
3945 routine. (See above). */
3948 init_floating_libfuncs (optable
, opname
, suffix
)
3949 register optab optable
;
3950 register char *opname
;
3951 register char suffix
;
3953 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
3956 /* Initialize the libfunc fields of an entire group of entries in some
3957 optab which correspond to all complex floating modes. The parameters
3958 have the same meaning as similarly named ones for the `init_libfuncs'
3959 routine. (See above). */
3962 init_complex_libfuncs (optable
, opname
, suffix
)
3963 register optab optable
;
3964 register char *opname
;
3965 register char suffix
;
3967 init_libfuncs (optable
, SCmode
, TCmode
, opname
, suffix
);
3970 /* Call this once to initialize the contents of the optabs
3971 appropriately for the current target machine. */
3982 add_optab
= init_optab (PLUS
);
3983 sub_optab
= init_optab (MINUS
);
3984 smul_optab
= init_optab (MULT
);
3985 smul_widen_optab
= init_optab (UNKNOWN
);
3986 umul_widen_optab
= init_optab (UNKNOWN
);
3987 sdiv_optab
= init_optab (DIV
);
3988 sdivmod_optab
= init_optab (UNKNOWN
);
3989 udiv_optab
= init_optab (UDIV
);
3990 udivmod_optab
= init_optab (UNKNOWN
);
3991 smod_optab
= init_optab (MOD
);
3992 umod_optab
= init_optab (UMOD
);
3993 flodiv_optab
= init_optab (DIV
);
3994 ftrunc_optab
= init_optab (UNKNOWN
);
3995 and_optab
= init_optab (AND
);
3996 ior_optab
= init_optab (IOR
);
3997 xor_optab
= init_optab (XOR
);
3998 ashl_optab
= init_optab (ASHIFT
);
3999 ashr_optab
= init_optab (ASHIFTRT
);
4000 lshl_optab
= init_optab (LSHIFT
);
4001 lshr_optab
= init_optab (LSHIFTRT
);
4002 rotl_optab
= init_optab (ROTATE
);
4003 rotr_optab
= init_optab (ROTATERT
);
4004 smin_optab
= init_optab (SMIN
);
4005 smax_optab
= init_optab (SMAX
);
4006 umin_optab
= init_optab (UMIN
);
4007 umax_optab
= init_optab (UMAX
);
4008 mov_optab
= init_optab (UNKNOWN
);
4009 movstrict_optab
= init_optab (UNKNOWN
);
4010 cmp_optab
= init_optab (UNKNOWN
);
4011 ucmp_optab
= init_optab (UNKNOWN
);
4012 tst_optab
= init_optab (UNKNOWN
);
4013 neg_optab
= init_optab (NEG
);
4014 abs_optab
= init_optab (ABS
);
4015 one_cmpl_optab
= init_optab (NOT
);
4016 ffs_optab
= init_optab (FFS
);
4017 sqrt_optab
= init_optab (SQRT
);
4018 sin_optab
= init_optab (UNKNOWN
);
4019 cos_optab
= init_optab (UNKNOWN
);
4020 strlen_optab
= init_optab (UNKNOWN
);
4024 add_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_addqi3
;
4028 add_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_addhi3
;
4032 add_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_addpsi3
;
4036 add_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_addsi3
;
4040 add_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_adddi3
;
4044 add_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_addti3
;
4048 add_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_addqf3
;
4052 add_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_addhf3
;
4056 add_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_addsf3
;
4060 add_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_adddf3
;
4064 add_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_addxf3
;
4068 add_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_addtf3
;
4070 init_integral_libfuncs (add_optab
, "add", '3');
4071 init_floating_libfuncs (add_optab
, "add", '3');
4075 sub_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_subqi3
;
4079 sub_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_subhi3
;
4083 sub_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_subpsi3
;
4087 sub_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_subsi3
;
4091 sub_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_subdi3
;
4095 sub_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_subti3
;
4099 sub_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_subqf3
;
4103 sub_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_subhf3
;
4107 sub_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_subsf3
;
4111 sub_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_subdf3
;
4115 sub_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_subxf3
;
4119 sub_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_subtf3
;
4121 init_integral_libfuncs (sub_optab
, "sub", '3');
4122 init_floating_libfuncs (sub_optab
, "sub", '3');
4126 smul_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_mulqi3
;
4130 smul_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_mulhi3
;
4134 smul_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_mulpsi3
;
4138 smul_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_mulsi3
;
4142 smul_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_muldi3
;
4146 smul_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_multi3
;
4150 smul_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_mulqf3
;
4154 smul_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_mulhf3
;
4158 smul_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_mulsf3
;
4162 smul_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_muldf3
;
4166 smul_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_mulxf3
;
4170 smul_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_multf3
;
4172 init_integral_libfuncs (smul_optab
, "mul", '3');
4173 init_floating_libfuncs (smul_optab
, "mul", '3');
4175 #ifdef MULSI3_LIBCALL
4176 smul_optab
->handlers
[(int) SImode
].libfunc
4177 = gen_rtx (SYMBOL_REF
, Pmode
, MULSI3_LIBCALL
);
4179 #ifdef MULDI3_LIBCALL
4180 smul_optab
->handlers
[(int) DImode
].libfunc
4181 = gen_rtx (SYMBOL_REF
, Pmode
, MULDI3_LIBCALL
);
4183 #ifdef MULTI3_LIBCALL
4184 smul_optab
->handlers
[(int) TImode
].libfunc
4185 = gen_rtx (SYMBOL_REF
, Pmode
, MULTI3_LIBCALL
);
4188 #ifdef HAVE_mulqihi3
4190 smul_widen_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_mulqihi3
;
4192 #ifdef HAVE_mulhisi3
4194 smul_widen_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_mulhisi3
;
4196 #ifdef HAVE_mulsidi3
4198 smul_widen_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_mulsidi3
;
4200 #ifdef HAVE_mulditi3
4202 smul_widen_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_mulditi3
;
4205 #ifdef HAVE_umulqihi3
4207 umul_widen_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_umulqihi3
;
4209 #ifdef HAVE_umulhisi3
4211 umul_widen_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_umulhisi3
;
4213 #ifdef HAVE_umulsidi3
4215 umul_widen_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_umulsidi3
;
4217 #ifdef HAVE_umulditi3
4219 umul_widen_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_umulditi3
;
4224 sdiv_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_divqi3
;
4228 sdiv_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_divhi3
;
4232 sdiv_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_divpsi3
;
4236 sdiv_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_divsi3
;
4240 sdiv_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_divdi3
;
4244 sdiv_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_divti3
;
4246 init_integral_libfuncs (sdiv_optab
, "div", '3');
4248 #ifdef DIVSI3_LIBCALL
4249 sdiv_optab
->handlers
[(int) SImode
].libfunc
4250 = gen_rtx (SYMBOL_REF
, Pmode
, DIVSI3_LIBCALL
);
4252 #ifdef DIVDI3_LIBCALL
4253 sdiv_optab
->handlers
[(int) DImode
].libfunc
4254 = gen_rtx (SYMBOL_REF
, Pmode
, DIVDI3_LIBCALL
);
4256 #ifdef DIVTI3_LIBCALL
4257 sdiv_optab
->handlers
[(int) TImode
].libfunc
4258 = gen_rtx (SYMBOL_REF
, Pmode
, DIVTI3_LIBCALL
);
4263 udiv_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_udivqi3
;
4267 udiv_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_udivhi3
;
4269 #ifdef HAVE_udivpsi3
4271 udiv_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_udivpsi3
;
4275 udiv_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_udivsi3
;
4279 udiv_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_udivdi3
;
4283 udiv_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_udivti3
;
4285 init_integral_libfuncs (udiv_optab
, "udiv", '3');
4287 #ifdef UDIVSI3_LIBCALL
4288 udiv_optab
->handlers
[(int) SImode
].libfunc
4289 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVSI3_LIBCALL
);
4291 #ifdef UDIVDI3_LIBCALL
4292 udiv_optab
->handlers
[(int) DImode
].libfunc
4293 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVDI3_LIBCALL
);
4295 #ifdef UDIVTI3_LIBCALL
4296 udiv_optab
->handlers
[(int) TImode
].libfunc
4297 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVTI3_LIBCALL
);
4300 #ifdef HAVE_divmodqi4
4302 sdivmod_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_divmodqi4
;
4304 #ifdef HAVE_divmodhi4
4306 sdivmod_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_divmodhi4
;
4308 #ifdef HAVE_divmodsi4
4310 sdivmod_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_divmodsi4
;
4312 #ifdef HAVE_divmoddi4
4314 sdivmod_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_divmoddi4
;
4316 #ifdef HAVE_divmodti4
4318 sdivmod_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_divmodti4
;
4320 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
4322 #ifdef HAVE_udivmodqi4
4323 if (HAVE_udivmodqi4
)
4324 udivmod_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_udivmodqi4
;
4326 #ifdef HAVE_udivmodhi4
4327 if (HAVE_udivmodhi4
)
4328 udivmod_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_udivmodhi4
;
4330 #ifdef HAVE_udivmodsi4
4331 if (HAVE_udivmodsi4
)
4332 udivmod_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_udivmodsi4
;
4334 #ifdef HAVE_udivmoddi4
4335 if (HAVE_udivmoddi4
)
4336 udivmod_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_udivmoddi4
;
4338 #ifdef HAVE_udivmodti4
4339 if (HAVE_udivmodti4
)
4340 udivmod_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_udivmodti4
;
4342 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
4346 smod_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_modqi3
;
4350 smod_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_modhi3
;
4354 smod_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_modpsi3
;
4358 smod_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_modsi3
;
4362 smod_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_moddi3
;
4366 smod_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_modti3
;
4368 init_integral_libfuncs (smod_optab
, "mod", '3');
4370 #ifdef MODSI3_LIBCALL
4371 smod_optab
->handlers
[(int) SImode
].libfunc
4372 = gen_rtx (SYMBOL_REF
, Pmode
, MODSI3_LIBCALL
);
4374 #ifdef MODDI3_LIBCALL
4375 smod_optab
->handlers
[(int) DImode
].libfunc
4376 = gen_rtx (SYMBOL_REF
, Pmode
, MODDI3_LIBCALL
);
4378 #ifdef MODTI3_LIBCALL
4379 smod_optab
->handlers
[(int) TImode
].libfunc
4380 = gen_rtx (SYMBOL_REF
, Pmode
, MODTI3_LIBCALL
);
4385 umod_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_umodqi3
;
4389 umod_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_umodhi3
;
4391 #ifdef HAVE_umodpsi3
4393 umod_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_umodpsi3
;
4397 umod_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_umodsi3
;
4401 umod_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_umoddi3
;
4405 umod_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_umodti3
;
4407 init_integral_libfuncs (umod_optab
, "umod", '3');
4409 #ifdef UMODSI3_LIBCALL
4410 umod_optab
->handlers
[(int) SImode
].libfunc
4411 = gen_rtx (SYMBOL_REF
, Pmode
, UMODSI3_LIBCALL
);
4413 #ifdef UMODDI3_LIBCALL
4414 umod_optab
->handlers
[(int) DImode
].libfunc
4415 = gen_rtx (SYMBOL_REF
, Pmode
, UMODDI3_LIBCALL
);
4417 #ifdef UMODTI3_LIBCALL
4418 umod_optab
->handlers
[(int) TImode
].libfunc
4419 = gen_rtx (SYMBOL_REF
, Pmode
, UMODTI3_LIBCALL
);
4424 flodiv_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_divqf3
;
4428 flodiv_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_divhf3
;
4432 flodiv_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_divsf3
;
4436 flodiv_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_divdf3
;
4440 flodiv_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_divxf3
;
4444 flodiv_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_divtf3
;
4446 init_floating_libfuncs (flodiv_optab
, "div", '3');
4448 #ifdef HAVE_ftruncqf2
4450 ftrunc_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_ftruncqf2
;
4452 #ifdef HAVE_ftrunchf2
4454 ftrunc_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_ftrunchf3
;
4456 #ifdef HAVE_ftruncsf2
4458 ftrunc_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_ftruncsf2
;
4460 #ifdef HAVE_ftruncdf2
4462 ftrunc_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_ftruncdf2
;
4464 #ifdef HAVE_ftruncxf2
4466 ftrunc_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_ftruncxf2
;
4468 #ifdef HAVE_ftrunctf2
4470 ftrunc_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_ftrunctf2
;
4472 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
4476 and_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_andqi3
;
4480 and_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_andhi3
;
4484 and_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_andpsi3
;
4488 and_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_andsi3
;
4492 and_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_anddi3
;
4496 and_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_andti3
;
4498 init_integral_libfuncs (and_optab
, "and", '3');
4502 ior_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_iorqi3
;
4506 ior_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_iorhi3
;
4510 ior_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_iorpsi3
;
4514 ior_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_iorsi3
;
4518 ior_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_iordi3
;
4522 ior_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_iorti3
;
4524 init_integral_libfuncs (ior_optab
, "ior", '3');
4528 xor_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_xorqi3
;
4532 xor_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_xorhi3
;
4536 xor_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_xorpsi3
;
4540 xor_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_xorsi3
;
4544 xor_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_xordi3
;
4548 xor_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_xorti3
;
4550 init_integral_libfuncs (xor_optab
, "xor", '3');
4554 ashl_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_ashlqi3
;
4558 ashl_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_ashlhi3
;
4560 #ifdef HAVE_ashlpsi3
4562 ashl_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_ashlpsi3
;
4566 ashl_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_ashlsi3
;
4570 ashl_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_ashldi3
;
4574 ashl_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_ashlti3
;
4576 init_integral_libfuncs (ashl_optab
, "ashl", '3');
4580 ashr_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_ashrqi3
;
4584 ashr_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_ashrhi3
;
4586 #ifdef HAVE_ashrpsi3
4588 ashr_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_ashrpsi3
;
4592 ashr_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_ashrsi3
;
4596 ashr_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_ashrdi3
;
4600 ashr_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_ashrti3
;
4602 init_integral_libfuncs (ashr_optab
, "ashr", '3');
4606 lshl_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_lshlqi3
;
4610 lshl_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_lshlhi3
;
4612 #ifdef HAVE_lshlpsi3
4614 lshl_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_lshlpsi3
;
4618 lshl_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_lshlsi3
;
4622 lshl_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_lshldi3
;
4626 lshl_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_lshlti3
;
4628 init_integral_libfuncs (lshl_optab
, "lshl", '3');
4632 lshr_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_lshrqi3
;
4636 lshr_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_lshrhi3
;
4638 #ifdef HAVE_lshrpsi3
4640 lshr_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_lshrpsi3
;
4644 lshr_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_lshrsi3
;
4648 lshr_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_lshrdi3
;
4652 lshr_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_lshrti3
;
4654 init_integral_libfuncs (lshr_optab
, "lshr", '3');
4658 rotl_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_rotlqi3
;
4662 rotl_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_rotlhi3
;
4664 #ifdef HAVE_rotlpsi3
4666 rotl_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_rotlpsi3
;
4670 rotl_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_rotlsi3
;
4674 rotl_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_rotldi3
;
4678 rotl_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_rotlti3
;
4680 init_integral_libfuncs (rotl_optab
, "rotl", '3');
4684 rotr_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_rotrqi3
;
4688 rotr_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_rotrhi3
;
4690 #ifdef HAVE_rotrpsi3
4692 rotr_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_rotrpsi3
;
4696 rotr_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_rotrsi3
;
4700 rotr_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_rotrdi3
;
4704 rotr_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_rotrti3
;
4706 init_integral_libfuncs (rotr_optab
, "rotr", '3');
4710 smin_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_sminqi3
;
4714 smin_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_sminhi3
;
4718 smin_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_sminsi3
;
4722 smin_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_smindi3
;
4726 smin_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_sminti3
;
4730 smin_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_minqf3
;
4734 smin_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_minhf3
;
4738 smin_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_minsf3
;
4742 smin_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_mindf3
;
4746 smin_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_minxf3
;
4750 smin_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_mintf3
;
4752 init_integral_libfuncs (smin_optab
, "min", '3');
4753 init_floating_libfuncs (smin_optab
, "min", '3');
4757 smax_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_smaxqi3
;
4761 smax_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_smaxhi3
;
4765 smax_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_smaxsi3
;
4769 smax_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_smaxdi3
;
4773 smax_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_smaxti3
;
4777 smax_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_maxqf3
;
4781 smax_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_maxhf3
;
4785 smax_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_maxsf3
;
4789 smax_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_maxdf3
;
4793 smax_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_maxxf3
;
4797 smax_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_maxtf3
;
4799 init_integral_libfuncs (smax_optab
, "max", '3');
4800 init_floating_libfuncs (smax_optab
, "max", '3');
4804 umin_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_uminqi3
;
4808 umin_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_uminhi3
;
4812 umin_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_uminsi3
;
4816 umin_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_umindi3
;
4820 umin_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_uminti3
;
4822 init_integral_libfuncs (umin_optab
, "umin", '3');
4826 umax_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_umaxqi3
;
4830 umax_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_umaxhi3
;
4834 umax_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_umaxsi3
;
4838 umax_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_umaxdi3
;
4842 umax_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_umaxti3
;
4844 init_integral_libfuncs (umax_optab
, "umax", '3');
4848 neg_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_negqi2
;
4852 neg_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_neghi2
;
4856 neg_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_negpsi2
;
4860 neg_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_negsi2
;
4864 neg_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_negdi2
;
4868 neg_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_negti2
;
4872 neg_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_negqf2
;
4876 neg_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_neghf2
;
4880 neg_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_negsf2
;
4884 neg_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_negdf2
;
4888 neg_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_negxf2
;
4892 neg_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_negtf2
;
4894 init_integral_libfuncs (neg_optab
, "neg", '2');
4895 init_floating_libfuncs (neg_optab
, "neg", '2');
4899 abs_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_absqi2
;
4903 abs_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_abshi2
;
4907 abs_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_abspsi2
;
4911 abs_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_abssi2
;
4915 abs_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_absdi2
;
4919 abs_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_absti2
;
4923 abs_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_absqf2
;
4927 abs_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_abshf2
;
4931 abs_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_abssf2
;
4935 abs_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_absdf2
;
4939 abs_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_absxf2
;
4943 abs_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_abstf2
;
4946 /* Use cabs for DC complex abs, since systems generally have cabs.
4947 Don't define any libcall for SCmode, so that cabs will be used. */
4948 abs_optab
->handlers
[(int) DCmode
].libfunc
4949 = gen_rtx (SYMBOL_REF
, Pmode
, "cabs");
4953 sqrt_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_sqrtqi2
;
4957 sqrt_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_sqrthi2
;
4959 #ifdef HAVE_sqrtpsi2
4961 sqrt_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_sqrtpsi2
;
4965 sqrt_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_sqrtsi2
;
4969 sqrt_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_sqrtdi2
;
4973 sqrt_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_sqrtti2
;
4977 sqrt_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_sqrtqf2
;
4981 sqrt_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_sqrthf2
;
4985 sqrt_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_sqrtsf2
;
4989 sqrt_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_sqrtdf2
;
4993 sqrt_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_sqrttf2
;
4995 /* No library calls here! If there is no sqrt instruction expand_builtin
4996 should force the library call. */
5000 sin_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_sinqf2
;
5004 sin_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_sinhf2
;
5008 sin_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_sinsf2
;
5012 sin_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_sindf2
;
5016 sin_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_sintf2
;
5018 /* No library calls here! If there is no sin instruction expand_builtin
5019 should force the library call. */
5023 cos_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_cosqf2
;
5027 cos_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_coshf2
;
5031 cos_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_cossf2
;
5035 cos_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_cosdf2
;
5039 cos_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_costf2
;
5041 /* No library calls here! If there is no cos instruction expand_builtin
5042 should force the library call. */
5044 #ifdef HAVE_strlenqi
5046 strlen_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_strlenqi
;
5048 #ifdef HAVE_strlenhi
5050 strlen_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_strlenhi
;
5052 #ifdef HAVE_strlenpsi
5054 strlen_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_strlenpsi
;
5056 #ifdef HAVE_strlensi
5058 strlen_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_strlensi
;
5060 #ifdef HAVE_strlendi
5062 strlen_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_strlendi
;
5064 #ifdef HAVE_strlenti
5066 strlen_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_strlenti
;
5068 /* No library calls here! If there is no strlen instruction expand_builtin
5069 should force the library call. */
5071 #ifdef HAVE_one_cmplqi2
5072 if (HAVE_one_cmplqi2
)
5073 one_cmpl_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_one_cmplqi2
;
5075 #ifdef HAVE_one_cmplhi2
5076 if (HAVE_one_cmplhi2
)
5077 one_cmpl_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_one_cmplhi2
;
5079 #ifdef HAVE_one_cmplpsi2
5080 if (HAVE_one_cmplpsi2
)
5081 one_cmpl_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_one_cmplpsi2
;
5083 #ifdef HAVE_one_cmplsi2
5084 if (HAVE_one_cmplsi2
)
5085 one_cmpl_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_one_cmplsi2
;
5087 #ifdef HAVE_one_cmpldi2
5088 if (HAVE_one_cmpldi2
)
5089 one_cmpl_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_one_cmpldi2
;
5091 #ifdef HAVE_one_cmplti2
5092 if (HAVE_one_cmplti2
)
5093 one_cmpl_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_one_cmplti2
;
5095 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
5099 ffs_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_ffsqi2
;
5103 ffs_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_ffshi2
;
5107 ffs_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_ffspsi2
;
5111 ffs_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_ffssi2
;
5115 ffs_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_ffsdi2
;
5119 ffs_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_ffsti2
;
5121 init_integral_libfuncs (ffs_optab
, "ffs", '2');
5122 ffs_optab
->handlers
[(int) SImode
].libfunc
5123 = gen_rtx (SYMBOL_REF
, Pmode
, "ffs");
5127 mov_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_movqi
;
5131 mov_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_movhi
;
5135 mov_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_movpsi
;
5139 mov_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_movsi
;
5143 mov_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_movdi
;
5147 mov_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_movti
;
5151 mov_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_movqf
;
5155 mov_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_movhf
;
5159 mov_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_movsf
;
5163 mov_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_movdf
;
5167 mov_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_movxf
;
5171 mov_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_movtf
;
5175 mov_optab
->handlers
[(int) CCmode
].insn_code
= CODE_FOR_movcc
;
5178 #ifdef EXTRA_CC_MODES
5182 #ifdef HAVE_movstrictqi
5183 if (HAVE_movstrictqi
)
5184 movstrict_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_movstrictqi
;
5186 #ifdef HAVE_movstricthi
5187 if (HAVE_movstricthi
)
5188 movstrict_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_movstricthi
;
5190 #ifdef HAVE_movstrictpsi
5191 if (HAVE_movstrictpsi
)
5192 movstrict_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_movstrictpsi
;
5194 #ifdef HAVE_movstrictsi
5195 if (HAVE_movstrictsi
)
5196 movstrict_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_movstrictsi
;
5198 #ifdef HAVE_movstrictdi
5199 if (HAVE_movstrictdi
)
5200 movstrict_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_movstrictdi
;
5202 #ifdef HAVE_movstrictti
5203 if (HAVE_movstrictti
)
5204 movstrict_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_movstrictti
;
5209 cmp_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_cmpqi
;
5213 cmp_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_cmphi
;
5217 cmp_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_cmppsi
;
5221 cmp_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_cmpsi
;
5225 cmp_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_cmpdi
;
5229 cmp_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_cmpti
;
5233 cmp_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_cmpqf
;
5237 cmp_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_cmphf
;
5241 cmp_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_cmpsf
;
5245 cmp_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_cmpdf
;
5249 cmp_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_cmpxf
;
5253 cmp_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_cmptf
;
5255 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
5256 init_integral_libfuncs (cmp_optab
, "cmp", '2');
5257 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
5258 init_floating_libfuncs (cmp_optab
, "cmp", '2');
5262 tst_optab
->handlers
[(int) QImode
].insn_code
= CODE_FOR_tstqi
;
5266 tst_optab
->handlers
[(int) HImode
].insn_code
= CODE_FOR_tsthi
;
5270 tst_optab
->handlers
[(int) PSImode
].insn_code
= CODE_FOR_tstpsi
;
5274 tst_optab
->handlers
[(int) SImode
].insn_code
= CODE_FOR_tstsi
;
5278 tst_optab
->handlers
[(int) DImode
].insn_code
= CODE_FOR_tstdi
;
5282 tst_optab
->handlers
[(int) TImode
].insn_code
= CODE_FOR_tstti
;
5286 tst_optab
->handlers
[(int) QFmode
].insn_code
= CODE_FOR_tstqf
;
5290 tst_optab
->handlers
[(int) HFmode
].insn_code
= CODE_FOR_tsthf
;
5294 tst_optab
->handlers
[(int) SFmode
].insn_code
= CODE_FOR_tstsf
;
5298 tst_optab
->handlers
[(int) DFmode
].insn_code
= CODE_FOR_tstdf
;
5302 tst_optab
->handlers
[(int) XFmode
].insn_code
= CODE_FOR_tstxf
;
5306 tst_optab
->handlers
[(int) TFmode
].insn_code
= CODE_FOR_tsttf
;
5311 bcc_gen_fctn
[(int) EQ
] = gen_beq
;
5315 bcc_gen_fctn
[(int) NE
] = gen_bne
;
5319 bcc_gen_fctn
[(int) GT
] = gen_bgt
;
5323 bcc_gen_fctn
[(int) GE
] = gen_bge
;
5327 bcc_gen_fctn
[(int) GTU
] = gen_bgtu
;
5331 bcc_gen_fctn
[(int) GEU
] = gen_bgeu
;
5335 bcc_gen_fctn
[(int) LT
] = gen_blt
;
5339 bcc_gen_fctn
[(int) LE
] = gen_ble
;
5343 bcc_gen_fctn
[(int) LTU
] = gen_bltu
;
5347 bcc_gen_fctn
[(int) LEU
] = gen_bleu
;
5350 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
5351 setcc_gen_code
[i
] = CODE_FOR_nothing
;
5355 setcc_gen_code
[(int) EQ
] = CODE_FOR_seq
;
5359 setcc_gen_code
[(int) NE
] = CODE_FOR_sne
;
5363 setcc_gen_code
[(int) GT
] = CODE_FOR_sgt
;
5367 setcc_gen_code
[(int) GE
] = CODE_FOR_sge
;
5371 setcc_gen_code
[(int) GTU
] = CODE_FOR_sgtu
;
5375 setcc_gen_code
[(int) GEU
] = CODE_FOR_sgeu
;
5379 setcc_gen_code
[(int) LT
] = CODE_FOR_slt
;
5383 setcc_gen_code
[(int) LE
] = CODE_FOR_sle
;
5387 setcc_gen_code
[(int) LTU
] = CODE_FOR_sltu
;
5391 setcc_gen_code
[(int) LEU
] = CODE_FOR_sleu
;
5394 extendsfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfdf2");
5395 extendsfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfxf2");
5396 extendsftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsftf2");
5397 extenddfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddfxf2");
5398 extenddftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddftf2");
5400 truncdfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncdfsf2");
5401 truncxfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfsf2");
5402 trunctfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfsf2");
5403 truncxfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfdf2");
5404 trunctfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfdf2");
5406 memcpy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcpy");
5407 bcopy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bcopy");
5408 memcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcmp");
5409 bcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gcc_bcmp");
5410 memset_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memset");
5411 bzero_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bzero");
5413 eqsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqsf2");
5414 nesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nesf2");
5415 gtsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtsf2");
5416 gesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gesf2");
5417 ltsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltsf2");
5418 lesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lesf2");
5420 eqdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqdf2");
5421 nedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nedf2");
5422 gtdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtdf2");
5423 gedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gedf2");
5424 ltdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltdf2");
5425 ledf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ledf2");
5427 eqxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqxf2");
5428 nexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nexf2");
5429 gtxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtxf2");
5430 gexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gexf2");
5431 ltxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltxf2");
5432 lexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lexf2");
5434 eqtf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqtf2");
5435 netf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__netf2");
5436 gttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gttf2");
5437 getf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__getf2");
5438 lttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lttf2");
5439 letf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__letf2");
5441 floatsisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsisf");
5442 floatdisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdisf");
5443 floattisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattisf");
5445 floatsidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsidf");
5446 floatdidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdidf");
5447 floattidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattidf");
5449 floatsixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsixf");
5450 floatdixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdixf");
5451 floattixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattixf");
5453 floatsitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsitf");
5454 floatditf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatditf");
5455 floattitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattitf");
5457 fixsfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfsi");
5458 fixsfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfdi");
5459 fixsfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfti");
5461 fixdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfsi");
5462 fixdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfdi");
5463 fixdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfti");
5465 fixxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfsi");
5466 fixxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfdi");
5467 fixxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfti");
5469 fixtfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfsi");
5470 fixtfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfdi");
5471 fixtfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfti");
5473 fixunssfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfsi");
5474 fixunssfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfdi");
5475 fixunssfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfti");
5477 fixunsdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfsi");
5478 fixunsdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfdi");
5479 fixunsdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfti");
5481 fixunsxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfsi");
5482 fixunsxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfdi");
5483 fixunsxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfti");
5485 fixunstfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfsi");
5486 fixunstfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfdi");
5487 fixunstfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfti");
5492 /* SCO 3.2 apparently has a broken ldexp. */
5505 #endif /* BROKEN_LDEXP */