1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994 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"
33 /* Each optab contains info on how this target machine
34 can perform a particular operation
35 for all sizes and kinds of operands.
37 The operation to be performed is often specified
38 by passing one of these optabs as an argument.
40 See expr.h for documentation of these optabs. */
45 optab smul_highpart_optab
;
46 optab umul_highpart_optab
;
47 optab smul_widen_optab
;
48 optab umul_widen_optab
;
71 optab movstrict_optab
;
82 optab ucmp_optab
; /* Used only for libcalls for unsigned comparisons. */
87 /* Tables of patterns for extending one integer mode to another. */
88 enum insn_code extendtab
[MAX_MACHINE_MODE
][MAX_MACHINE_MODE
][2];
90 /* Tables of patterns for converting between fixed and floating point. */
91 enum insn_code fixtab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
92 enum insn_code fixtrunctab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
93 enum insn_code floattab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
95 /* Contains the optab used for each rtx code. */
96 optab code_to_optab
[NUM_RTX_CODE
+ 1];
98 /* SYMBOL_REF rtx's for the library functions that are called
99 implicitly and not via optabs. */
101 rtx extendsfdf2_libfunc
;
102 rtx extendsfxf2_libfunc
;
103 rtx extendsftf2_libfunc
;
104 rtx extenddfxf2_libfunc
;
105 rtx extenddftf2_libfunc
;
107 rtx truncdfsf2_libfunc
;
108 rtx truncxfsf2_libfunc
;
109 rtx trunctfsf2_libfunc
;
110 rtx truncxfdf2_libfunc
;
111 rtx trunctfdf2_libfunc
;
155 rtx floatsisf_libfunc
;
156 rtx floatdisf_libfunc
;
157 rtx floattisf_libfunc
;
159 rtx floatsidf_libfunc
;
160 rtx floatdidf_libfunc
;
161 rtx floattidf_libfunc
;
163 rtx floatsixf_libfunc
;
164 rtx floatdixf_libfunc
;
165 rtx floattixf_libfunc
;
167 rtx floatsitf_libfunc
;
168 rtx floatditf_libfunc
;
169 rtx floattitf_libfunc
;
187 rtx fixunssfsi_libfunc
;
188 rtx fixunssfdi_libfunc
;
189 rtx fixunssfti_libfunc
;
191 rtx fixunsdfsi_libfunc
;
192 rtx fixunsdfdi_libfunc
;
193 rtx fixunsdfti_libfunc
;
195 rtx fixunsxfsi_libfunc
;
196 rtx fixunsxfdi_libfunc
;
197 rtx fixunsxfti_libfunc
;
199 rtx fixunstfsi_libfunc
;
200 rtx fixunstfdi_libfunc
;
201 rtx fixunstfti_libfunc
;
203 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
204 gives the gen_function to make a branch to test that condition. */
206 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
208 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
209 gives the insn code to make a store-condition insn
210 to test that condition. */
212 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
214 static int add_equal_note
PROTO((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
215 static rtx widen_operand
PROTO((rtx
, enum machine_mode
,
216 enum machine_mode
, int, int));
217 static enum insn_code can_fix_p
PROTO((enum machine_mode
, enum machine_mode
,
219 static enum insn_code can_float_p
PROTO((enum machine_mode
, enum machine_mode
,
221 static rtx ftruncify
PROTO((rtx
));
222 static optab init_optab
PROTO((enum rtx_code
));
223 static void init_libfuncs
PROTO((optab
, int, int, char *, int));
224 static void init_integral_libfuncs
PROTO((optab
, char *, int));
225 static void init_floating_libfuncs
PROTO((optab
, char *, int));
226 static void init_complex_libfuncs
PROTO((optab
, char *, int));
228 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
229 the result of operation CODE applied to OP0 (and OP1 if it is a binary
232 If the last insn does not set TARGET, don't do anything, but return 1.
234 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
235 don't add the REG_EQUAL note but return 0. Our caller can then try
236 again, ensuring that TARGET is not one of the operands. */
239 add_equal_note (seq
, target
, code
, op0
, op1
)
249 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
250 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
251 || GET_CODE (seq
) != SEQUENCE
252 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
253 || GET_CODE (target
) == ZERO_EXTRACT
254 || (! rtx_equal_p (SET_DEST (set
), target
)
255 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
257 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
258 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
262 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
263 besides the last insn. */
264 if (reg_overlap_mentioned_p (target
, op0
)
265 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
266 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
267 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
270 if (GET_RTX_CLASS (code
) == '1')
271 note
= gen_rtx (code
, GET_MODE (target
), copy_rtx (op0
));
273 note
= gen_rtx (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
275 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))
276 = gen_rtx (EXPR_LIST
, REG_EQUAL
, note
,
277 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1)));
282 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
283 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
284 not actually do a sign-extend or zero-extend, but can leave the
285 higher-order bits of the result rtx undefined, for example, in the case
286 of logical operations, but not right shifts. */
289 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
291 enum machine_mode mode
, oldmode
;
297 /* If we must extend do so. If OP is either a constant or a SUBREG
298 for a promoted object, also extend since it will be more efficient to
301 || GET_MODE (op
) == VOIDmode
302 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
303 return convert_modes (mode
, oldmode
, op
, unsignedp
);
305 /* If MODE is no wider than a single word, we return a paradoxical
307 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
308 return gen_rtx (SUBREG
, mode
, force_reg (GET_MODE (op
), op
), 0);
310 /* Otherwise, get an object of MODE, clobber it, and set the low-order
313 result
= gen_reg_rtx (mode
);
314 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, result
));
315 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
319 /* Generate code to perform an operation specified by BINOPTAB
320 on operands OP0 and OP1, with result having machine-mode MODE.
322 UNSIGNEDP is for the case where we have to widen the operands
323 to perform the operation. It says to use zero-extension.
325 If TARGET is nonzero, the value
326 is generated there, if it is convenient to do so.
327 In all cases an rtx is returned for the locus of the value;
328 this may or may not be TARGET. */
331 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
332 enum machine_mode mode
;
337 enum optab_methods methods
;
339 enum optab_methods next_methods
340 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
341 ? OPTAB_WIDEN
: methods
);
342 enum mode_class
class;
343 enum machine_mode wider_mode
;
345 int commutative_op
= 0;
346 int shift_op
= (binoptab
->code
== ASHIFT
347 || binoptab
->code
== ASHIFTRT
348 || binoptab
->code
== LSHIFTRT
349 || binoptab
->code
== ROTATE
350 || binoptab
->code
== ROTATERT
);
351 rtx entry_last
= get_last_insn ();
354 class = GET_MODE_CLASS (mode
);
356 op0
= protect_from_queue (op0
, 0);
357 op1
= protect_from_queue (op1
, 0);
359 target
= protect_from_queue (target
, 1);
363 op0
= force_not_mem (op0
);
364 op1
= force_not_mem (op1
);
367 /* If subtracting an integer constant, convert this into an addition of
368 the negated constant. */
370 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
372 op1
= negate_rtx (mode
, op1
);
373 binoptab
= add_optab
;
376 /* If we are inside an appropriately-short loop and one operand is an
377 expensive constant, force it into a register. */
378 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
379 && rtx_cost (op0
, binoptab
->code
) > 2)
380 op0
= force_reg (mode
, op0
);
382 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
383 && rtx_cost (op1
, binoptab
->code
) > 2)
384 op1
= force_reg (shift_op
? word_mode
: mode
, op1
);
386 /* Record where to delete back to if we backtrack. */
387 last
= get_last_insn ();
389 /* If operation is commutative,
390 try to make the first operand a register.
391 Even better, try to make it the same as the target.
392 Also try to make the last operand a constant. */
393 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
394 || binoptab
== smul_widen_optab
395 || binoptab
== umul_widen_optab
396 || binoptab
== smul_highpart_optab
397 || binoptab
== umul_highpart_optab
)
401 if (((target
== 0 || GET_CODE (target
) == REG
)
402 ? ((GET_CODE (op1
) == REG
403 && GET_CODE (op0
) != REG
)
405 : rtx_equal_p (op1
, target
))
406 || GET_CODE (op0
) == CONST_INT
)
414 /* If we can do it with a three-operand insn, do so. */
416 if (methods
!= OPTAB_MUST_WIDEN
417 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
419 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
420 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
421 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
423 rtx xop0
= op0
, xop1
= op1
;
428 temp
= gen_reg_rtx (mode
);
430 /* If it is a commutative operator and the modes would match
431 if we would swap the operands, we can save the conversions. */
434 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
435 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
439 tmp
= op0
; op0
= op1
; op1
= tmp
;
440 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
444 /* In case the insn wants input operands in modes different from
445 the result, convert the operands. */
447 if (GET_MODE (op0
) != VOIDmode
448 && GET_MODE (op0
) != mode0
)
449 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
451 if (GET_MODE (xop1
) != VOIDmode
452 && GET_MODE (xop1
) != mode1
)
453 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
455 /* Now, if insn's predicates don't allow our operands, put them into
458 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
459 xop0
= copy_to_mode_reg (mode0
, xop0
);
461 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
462 xop1
= copy_to_mode_reg (mode1
, xop1
);
464 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
465 temp
= gen_reg_rtx (mode
);
467 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
470 /* If PAT is a multi-insn sequence, try to add an appropriate
471 REG_EQUAL note to it. If we can't because TEMP conflicts with an
472 operand, call ourselves again, this time without a target. */
473 if (GET_CODE (pat
) == SEQUENCE
474 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
476 delete_insns_since (last
);
477 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
485 delete_insns_since (last
);
488 /* If this is a multiply, see if we can do a widening operation that
489 takes operands of this mode and makes a wider mode. */
491 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
492 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
493 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
494 != CODE_FOR_nothing
))
496 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
497 unsignedp
? umul_widen_optab
: smul_widen_optab
,
498 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
502 if (GET_MODE_CLASS (mode
) == MODE_INT
)
503 return gen_lowpart (mode
, temp
);
505 return convert_to_mode (mode
, temp
, unsignedp
);
509 /* Look for a wider mode of the same class for which we think we
510 can open-code the operation. Check for a widening multiply at the
511 wider mode as well. */
513 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
514 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
515 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
516 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
518 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
519 || (binoptab
== smul_optab
520 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
521 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
522 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
523 != CODE_FOR_nothing
)))
525 rtx xop0
= op0
, xop1
= op1
;
528 /* For certain integer operations, we need not actually extend
529 the narrow operands, as long as we will truncate
530 the results to the same narrowness. */
532 if ((binoptab
== ior_optab
|| binoptab
== and_optab
533 || binoptab
== xor_optab
534 || binoptab
== add_optab
|| binoptab
== sub_optab
535 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
536 && class == MODE_INT
)
539 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
541 /* The second operand of a shift must always be extended. */
542 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
543 no_extend
&& binoptab
!= ashl_optab
);
545 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
546 unsignedp
, OPTAB_DIRECT
);
549 if (class != MODE_INT
)
552 target
= gen_reg_rtx (mode
);
553 convert_move (target
, temp
, 0);
557 return gen_lowpart (mode
, temp
);
560 delete_insns_since (last
);
564 /* These can be done a word at a time. */
565 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
567 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
568 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
574 /* If TARGET is the same as one of the operands, the REG_EQUAL note
575 won't be accurate, so use a new target. */
576 if (target
== 0 || target
== op0
|| target
== op1
)
577 target
= gen_reg_rtx (mode
);
581 /* Do the actual arithmetic. */
582 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
584 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
585 rtx x
= expand_binop (word_mode
, binoptab
,
586 operand_subword_force (op0
, i
, mode
),
587 operand_subword_force (op1
, i
, mode
),
588 target_piece
, unsignedp
, next_methods
);
593 if (target_piece
!= x
)
594 emit_move_insn (target_piece
, x
);
597 insns
= get_insns ();
600 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
602 if (binoptab
->code
!= UNKNOWN
)
604 = gen_rtx (binoptab
->code
, mode
, copy_rtx (op0
), copy_rtx (op1
));
608 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
613 /* Synthesize double word shifts from single word shifts. */
614 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
615 || binoptab
== ashr_optab
)
617 && GET_CODE (op1
) == CONST_INT
618 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
619 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
620 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
621 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
623 rtx insns
, inter
, equiv_value
;
624 rtx into_target
, outof_target
;
625 rtx into_input
, outof_input
;
626 int shift_count
, left_shift
, outof_word
;
628 /* If TARGET is the same as one of the operands, the REG_EQUAL note
629 won't be accurate, so use a new target. */
630 if (target
== 0 || target
== op0
|| target
== op1
)
631 target
= gen_reg_rtx (mode
);
635 shift_count
= INTVAL (op1
);
637 /* OUTOF_* is the word we are shifting bits away from, and
638 INTO_* is the word that we are shifting bits towards, thus
639 they differ depending on the direction of the shift and
642 left_shift
= binoptab
== ashl_optab
;
643 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
645 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
646 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
648 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
649 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
651 if (shift_count
>= BITS_PER_WORD
)
653 inter
= expand_binop (word_mode
, binoptab
,
655 GEN_INT (shift_count
- BITS_PER_WORD
),
656 into_target
, unsignedp
, next_methods
);
658 if (inter
!= 0 && inter
!= into_target
)
659 emit_move_insn (into_target
, inter
);
661 /* For a signed right shift, we must fill the word we are shifting
662 out of with copies of the sign bit. Otherwise it is zeroed. */
663 if (inter
!= 0 && binoptab
!= ashr_optab
)
664 inter
= CONST0_RTX (word_mode
);
666 inter
= expand_binop (word_mode
, binoptab
,
668 GEN_INT (BITS_PER_WORD
- 1),
669 outof_target
, unsignedp
, next_methods
);
671 if (inter
!= 0 && inter
!= outof_target
)
672 emit_move_insn (outof_target
, inter
);
677 optab reverse_unsigned_shift
, unsigned_shift
;
679 /* For a shift of less then BITS_PER_WORD, to compute the carry,
680 we must do a logical shift in the opposite direction of the
683 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
685 /* For a shift of less than BITS_PER_WORD, to compute the word
686 shifted towards, we need to unsigned shift the orig value of
689 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
691 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
693 GEN_INT (BITS_PER_WORD
- shift_count
),
694 0, unsignedp
, next_methods
);
699 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
700 op1
, 0, unsignedp
, next_methods
);
703 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
704 into_target
, unsignedp
, next_methods
);
706 if (inter
!= 0 && inter
!= into_target
)
707 emit_move_insn (into_target
, inter
);
710 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
711 op1
, outof_target
, unsignedp
, next_methods
);
713 if (inter
!= 0 && inter
!= outof_target
)
714 emit_move_insn (outof_target
, inter
);
717 insns
= get_insns ();
722 if (binoptab
->code
!= UNKNOWN
)
723 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
727 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
732 /* Synthesize double word rotates from single word shifts. */
733 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
735 && GET_CODE (op1
) == CONST_INT
736 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
737 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
738 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
740 rtx insns
, equiv_value
;
741 rtx into_target
, outof_target
;
742 rtx into_input
, outof_input
;
744 int shift_count
, left_shift
, outof_word
;
746 /* If TARGET is the same as one of the operands, the REG_EQUAL note
747 won't be accurate, so use a new target. */
748 if (target
== 0 || target
== op0
|| target
== op1
)
749 target
= gen_reg_rtx (mode
);
753 shift_count
= INTVAL (op1
);
755 /* OUTOF_* is the word we are shifting bits away from, and
756 INTO_* is the word that we are shifting bits towards, thus
757 they differ depending on the direction of the shift and
760 left_shift
= (binoptab
== rotl_optab
);
761 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
763 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
764 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
766 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
767 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
769 if (shift_count
== BITS_PER_WORD
)
771 /* This is just a word swap. */
772 emit_move_insn (outof_target
, into_input
);
773 emit_move_insn (into_target
, outof_input
);
778 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
779 rtx first_shift_count
, second_shift_count
;
780 optab reverse_unsigned_shift
, unsigned_shift
;
782 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
783 ? lshr_optab
: ashl_optab
);
785 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
786 ? ashl_optab
: lshr_optab
);
788 if (shift_count
> BITS_PER_WORD
)
790 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
791 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
795 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
796 second_shift_count
= GEN_INT (shift_count
);
799 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
800 outof_input
, first_shift_count
,
801 NULL_RTX
, unsignedp
, next_methods
);
802 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
803 into_input
, second_shift_count
,
804 into_target
, unsignedp
, next_methods
);
806 if (into_temp1
!= 0 && into_temp2
!= 0)
807 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
808 into_target
, unsignedp
, next_methods
);
812 if (inter
!= 0 && inter
!= into_target
)
813 emit_move_insn (into_target
, inter
);
815 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
816 into_input
, first_shift_count
,
817 NULL_RTX
, unsignedp
, next_methods
);
818 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
819 outof_input
, second_shift_count
,
820 outof_target
, unsignedp
, next_methods
);
822 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
823 inter
= expand_binop (word_mode
, ior_optab
,
824 outof_temp1
, outof_temp2
,
825 outof_target
, unsignedp
, next_methods
);
827 if (inter
!= 0 && inter
!= outof_target
)
828 emit_move_insn (outof_target
, inter
);
831 insns
= get_insns ();
836 if (binoptab
->code
!= UNKNOWN
)
837 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
841 /* We can't make this a no conflict block if this is a word swap,
842 because the word swap case fails if the input and output values
843 are in the same register. */
844 if (shift_count
!= BITS_PER_WORD
)
845 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
854 /* These can be done a word at a time by propagating carries. */
855 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
857 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
858 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
861 rtx carry_tmp
= gen_reg_rtx (word_mode
);
862 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
863 int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
864 rtx carry_in
, carry_out
;
867 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
868 value is one of those, use it. Otherwise, use 1 since it is the
869 one easiest to get. */
870 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
871 int normalizep
= STORE_FLAG_VALUE
;
876 /* Prepare the operands. */
877 xop0
= force_reg (mode
, op0
);
878 xop1
= force_reg (mode
, op1
);
880 if (target
== 0 || GET_CODE (target
) != REG
881 || target
== xop0
|| target
== xop1
)
882 target
= gen_reg_rtx (mode
);
884 /* Indicate for flow that the entire target reg is being set. */
885 if (GET_CODE (target
) == REG
)
886 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, target
));
888 /* Do the actual arithmetic. */
889 for (i
= 0; i
< nwords
; i
++)
891 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
892 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
893 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
894 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
897 /* Main add/subtract of the input operands. */
898 x
= expand_binop (word_mode
, binoptab
,
899 op0_piece
, op1_piece
,
900 target_piece
, unsignedp
, next_methods
);
906 /* Store carry from main add/subtract. */
907 carry_out
= gen_reg_rtx (word_mode
);
908 carry_out
= emit_store_flag (carry_out
,
909 binoptab
== add_optab
? LTU
: GTU
,
911 word_mode
, 1, normalizep
);
918 /* Add/subtract previous carry to main result. */
919 x
= expand_binop (word_mode
,
920 normalizep
== 1 ? binoptab
: otheroptab
,
922 target_piece
, 1, next_methods
);
925 else if (target_piece
!= x
)
926 emit_move_insn (target_piece
, x
);
930 /* THIS CODE HAS NOT BEEN TESTED. */
931 /* Get out carry from adding/subtracting carry in. */
932 carry_tmp
= emit_store_flag (carry_tmp
,
933 binoptab
== add_optab
936 word_mode
, 1, normalizep
);
938 /* Logical-ior the two poss. carry together. */
939 carry_out
= expand_binop (word_mode
, ior_optab
,
940 carry_out
, carry_tmp
,
941 carry_out
, 0, next_methods
);
947 carry_in
= carry_out
;
950 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
952 rtx temp
= emit_move_insn (target
, target
);
954 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
955 gen_rtx (binoptab
->code
, mode
,
962 delete_insns_since (last
);
965 /* If we want to multiply two two-word values and have normal and widening
966 multiplies of single-word values, we can do this with three smaller
967 multiplications. Note that we do not make a REG_NO_CONFLICT block here
968 because we are not operating on one word at a time.
970 The multiplication proceeds as follows:
971 _______________________
972 [__op0_high_|__op0_low__]
973 _______________________
974 * [__op1_high_|__op1_low__]
975 _______________________________________________
976 _______________________
977 (1) [__op0_low__*__op1_low__]
978 _______________________
979 (2a) [__op0_low__*__op1_high_]
980 _______________________
981 (2b) [__op0_high_*__op1_low__]
982 _______________________
983 (3) [__op0_high_*__op1_high_]
986 This gives a 4-word result. Since we are only interested in the
987 lower 2 words, partial result (3) and the upper words of (2a) and
988 (2b) don't need to be calculated. Hence (2a) and (2b) can be
989 calculated using non-widening multiplication.
991 (1), however, needs to be calculated with an unsigned widening
992 multiplication. If this operation is not directly supported we
993 try using a signed widening multiplication and adjust the result.
994 This adjustment works as follows:
996 If both operands are positive then no adjustment is needed.
998 If the operands have different signs, for example op0_low < 0 and
999 op1_low >= 0, the instruction treats the most significant bit of
1000 op0_low as a sign bit instead of a bit with significance
1001 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1002 with 2**BITS_PER_WORD - op0_low, and two's complements the
1003 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1006 Similarly, if both operands are negative, we need to add
1007 (op0_low + op1_low) * 2**BITS_PER_WORD.
1009 We use a trick to adjust quickly. We logically shift op0_low right
1010 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1011 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1012 logical shift exists, we do an arithmetic right shift and subtract
1015 if (binoptab
== smul_optab
1016 && class == MODE_INT
1017 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1018 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1019 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1020 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1021 != CODE_FOR_nothing
)
1022 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1023 != CODE_FOR_nothing
)))
1025 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1026 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1027 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1028 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1029 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1030 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1035 /* If the target is the same as one of the inputs, don't use it. This
1036 prevents problems with the REG_EQUAL note. */
1037 if (target
== op0
|| target
== op1
)
1040 /* Multiply the two lower words to get a double-word product.
1041 If unsigned widening multiplication is available, use that;
1042 otherwise use the signed form and compensate. */
1044 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1046 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1047 target
, 1, OPTAB_DIRECT
);
1049 /* If we didn't succeed, delete everything we did so far. */
1051 delete_insns_since (last
);
1053 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1057 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1058 != CODE_FOR_nothing
)
1060 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1061 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1062 target
, 1, OPTAB_DIRECT
);
1063 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1064 NULL_RTX
, 1, next_methods
);
1066 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1067 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1070 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1071 NULL_RTX
, 0, next_methods
);
1073 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1074 op0_xhigh
, op0_xhigh
, 0,
1078 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1079 NULL_RTX
, 1, next_methods
);
1081 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1082 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1085 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1086 NULL_RTX
, 0, next_methods
);
1088 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1089 op1_xhigh
, op1_xhigh
, 0,
1094 /* If we have been able to directly compute the product of the
1095 low-order words of the operands and perform any required adjustments
1096 of the operands, we proceed by trying two more multiplications
1097 and then computing the appropriate sum.
1099 We have checked above that the required addition is provided.
1100 Full-word addition will normally always succeed, especially if
1101 it is provided at all, so we don't worry about its failure. The
1102 multiplication may well fail, however, so we do handle that. */
1104 if (product
&& op0_xhigh
&& op1_xhigh
)
1106 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1107 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1108 NULL_RTX
, 0, OPTAB_DIRECT
);
1111 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1112 product_high
, 0, next_methods
);
1114 if (temp
!= 0 && temp
!= product_high
)
1115 emit_move_insn (product_high
, temp
);
1118 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1119 NULL_RTX
, 0, OPTAB_DIRECT
);
1122 temp
= expand_binop (word_mode
, add_optab
, temp
,
1123 product_high
, product_high
,
1126 if (temp
!= 0 && temp
!= product_high
)
1127 emit_move_insn (product_high
, temp
);
1131 temp
= emit_move_insn (product
, product
);
1132 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
1133 gen_rtx (MULT
, mode
, copy_rtx (op0
),
1141 /* If we get here, we couldn't do it for some reason even though we
1142 originally thought we could. Delete anything we've emitted in
1145 delete_insns_since (last
);
1148 /* We need to open-code the complex type operations: '+, -, * and /' */
1150 /* At this point we allow operations between two similar complex
1151 numbers, and also if one of the operands is not a complex number
1152 but rather of MODE_FLOAT or MODE_INT. However, the caller
1153 must make sure that the MODE of the non-complex operand matches
1154 the SUBMODE of the complex operand. */
1156 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1158 rtx real0
= 0, imag0
= 0;
1159 rtx real1
= 0, imag1
= 0;
1160 rtx realr
, imagr
, res
;
1165 /* Find the correct mode for the real and imaginary parts */
1166 enum machine_mode submode
1167 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1168 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1171 if (submode
== BLKmode
)
1175 target
= gen_reg_rtx (mode
);
1179 realr
= gen_realpart (submode
, target
);
1180 imagr
= gen_imagpart (submode
, target
);
1182 if (GET_MODE (op0
) == mode
)
1184 real0
= gen_realpart (submode
, op0
);
1185 imag0
= gen_imagpart (submode
, op0
);
1190 if (GET_MODE (op1
) == mode
)
1192 real1
= gen_realpart (submode
, op1
);
1193 imag1
= gen_imagpart (submode
, op1
);
1198 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1201 switch (binoptab
->code
)
1204 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1206 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1207 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1208 realr
, unsignedp
, methods
);
1212 else if (res
!= realr
)
1213 emit_move_insn (realr
, res
);
1216 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1217 imagr
, unsignedp
, methods
);
1220 else if (binoptab
->code
== MINUS
)
1221 res
= expand_unop (submode
, neg_optab
, imag1
, imagr
, unsignedp
);
1227 else if (res
!= imagr
)
1228 emit_move_insn (imagr
, res
);
1234 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1240 /* Don't fetch these from memory more than once. */
1241 real0
= force_reg (submode
, real0
);
1242 real1
= force_reg (submode
, real1
);
1243 imag0
= force_reg (submode
, imag0
);
1244 imag1
= force_reg (submode
, imag1
);
1246 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1247 unsignedp
, methods
);
1249 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1250 unsignedp
, methods
);
1252 if (temp1
== 0 || temp2
== 0)
1255 res
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1256 realr
, unsignedp
, methods
);
1260 else if (res
!= realr
)
1261 emit_move_insn (realr
, res
);
1263 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1264 NULL_RTX
, unsignedp
, methods
);
1266 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1267 NULL_RTX
, unsignedp
, methods
);
1269 if (temp1
== 0 || temp2
== 0)
1272 res
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1273 imagr
, unsignedp
, methods
);
1277 else if (res
!= imagr
)
1278 emit_move_insn (imagr
, res
);
1284 /* Don't fetch these from memory more than once. */
1285 real0
= force_reg (submode
, real0
);
1286 real1
= force_reg (submode
, real1
);
1288 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1289 realr
, unsignedp
, methods
);
1292 else if (res
!= realr
)
1293 emit_move_insn (realr
, res
);
1296 res
= expand_binop (submode
, binoptab
,
1297 real1
, imag0
, imagr
, unsignedp
, methods
);
1299 res
= expand_binop (submode
, binoptab
,
1300 real0
, imag1
, imagr
, unsignedp
, methods
);
1304 else if (res
!= imagr
)
1305 emit_move_insn (imagr
, res
);
1312 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1316 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1318 /* Don't fetch these from memory more than once. */
1319 real1
= force_reg (submode
, real1
);
1321 /* Simply divide the real and imaginary parts by `c' */
1322 if (class == MODE_COMPLEX_FLOAT
)
1323 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1324 realr
, unsignedp
, methods
);
1326 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1327 real0
, real1
, realr
, unsignedp
);
1331 else if (res
!= realr
)
1332 emit_move_insn (realr
, res
);
1334 if (class == MODE_COMPLEX_FLOAT
)
1335 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1336 imagr
, unsignedp
, methods
);
1338 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1339 imag0
, real1
, imagr
, unsignedp
);
1343 else if (res
!= imagr
)
1344 emit_move_insn (imagr
, res
);
1350 /* Divisor is of complex type:
1357 /* Don't fetch these from memory more than once. */
1358 real0
= force_reg (submode
, real0
);
1359 real1
= force_reg (submode
, real1
);
1362 imag0
= force_reg (submode
, imag0
);
1364 imag1
= force_reg (submode
, imag1
);
1366 /* Divisor: c*c + d*d */
1367 temp1
= expand_binop (submode
, smul_optab
, real1
, real1
,
1368 NULL_RTX
, unsignedp
, methods
);
1370 temp2
= expand_binop (submode
, smul_optab
, imag1
, imag1
,
1371 NULL_RTX
, unsignedp
, methods
);
1373 if (temp1
== 0 || temp2
== 0)
1376 divisor
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1377 NULL_RTX
, unsignedp
, methods
);
1383 /* ((a)(c-id))/divisor */
1384 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1386 /* Calculate the dividend */
1387 real_t
= expand_binop (submode
, smul_optab
, real0
, real1
,
1388 NULL_RTX
, unsignedp
, methods
);
1390 imag_t
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1391 NULL_RTX
, unsignedp
, methods
);
1393 if (real_t
== 0 || imag_t
== 0)
1396 imag_t
= expand_unop (submode
, neg_optab
, imag_t
,
1397 NULL_RTX
, unsignedp
);
1401 /* ((a+ib)(c-id))/divider */
1402 /* Calculate the dividend */
1403 temp1
= expand_binop (submode
, smul_optab
, real0
, real1
,
1404 NULL_RTX
, unsignedp
, methods
);
1406 temp2
= expand_binop (submode
, smul_optab
, imag0
, imag1
,
1407 NULL_RTX
, unsignedp
, methods
);
1409 if (temp1
== 0 || temp2
== 0)
1412 real_t
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1413 NULL_RTX
, unsignedp
, methods
);
1415 temp1
= expand_binop (submode
, smul_optab
, imag0
, real1
,
1416 NULL_RTX
, unsignedp
, methods
);
1418 temp2
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1419 NULL_RTX
, unsignedp
, methods
);
1421 if (temp1
== 0 || temp2
== 0)
1424 imag_t
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1425 NULL_RTX
, unsignedp
, methods
);
1427 if (real_t
== 0 || imag_t
== 0)
1431 if (class == MODE_COMPLEX_FLOAT
)
1432 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
1433 realr
, unsignedp
, methods
);
1435 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1436 real_t
, divisor
, realr
, unsignedp
);
1440 else if (res
!= realr
)
1441 emit_move_insn (realr
, res
);
1443 if (class == MODE_COMPLEX_FLOAT
)
1444 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
1445 imagr
, unsignedp
, methods
);
1447 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1448 imag_t
, divisor
, imagr
, unsignedp
);
1452 else if (res
!= imagr
)
1453 emit_move_insn (imagr
, res
);
1468 if (binoptab
->code
!= UNKNOWN
)
1470 = gen_rtx (binoptab
->code
, mode
, copy_rtx (op0
), copy_rtx (op1
));
1474 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1480 /* It can't be open-coded in this mode.
1481 Use a library call if one is available and caller says that's ok. */
1483 if (binoptab
->handlers
[(int) mode
].libfunc
1484 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1487 rtx funexp
= binoptab
->handlers
[(int) mode
].libfunc
;
1489 enum machine_mode op1_mode
= mode
;
1496 op1_mode
= word_mode
;
1497 /* Specify unsigned here,
1498 since negative shift counts are meaningless. */
1499 op1x
= convert_to_mode (word_mode
, op1
, 1);
1502 if (GET_MODE (op0
) != mode
)
1503 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1505 /* Pass 1 for NO_QUEUE so we don't lose any increments
1506 if the libcall is cse'd or moved. */
1507 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1508 NULL_RTX
, 1, mode
, 2,
1509 op0
, mode
, op1x
, op1_mode
);
1511 insns
= get_insns ();
1514 target
= gen_reg_rtx (mode
);
1515 emit_libcall_block (insns
, target
, value
,
1516 gen_rtx (binoptab
->code
, mode
, op0
, op1
));
1521 delete_insns_since (last
);
1523 /* It can't be done in this mode. Can we do it in a wider mode? */
1525 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1526 || methods
== OPTAB_MUST_WIDEN
))
1528 /* Caller says, don't even try. */
1529 delete_insns_since (entry_last
);
1533 /* Compute the value of METHODS to pass to recursive calls.
1534 Don't allow widening to be tried recursively. */
1536 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1538 /* Look for a wider mode of the same class for which it appears we can do
1541 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1543 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1544 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1546 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1547 != CODE_FOR_nothing
)
1548 || (methods
== OPTAB_LIB
1549 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1551 rtx xop0
= op0
, xop1
= op1
;
1554 /* For certain integer operations, we need not actually extend
1555 the narrow operands, as long as we will truncate
1556 the results to the same narrowness. */
1558 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1559 || binoptab
== xor_optab
1560 || binoptab
== add_optab
|| binoptab
== sub_optab
1561 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1562 && class == MODE_INT
)
1565 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1566 unsignedp
, no_extend
);
1568 /* The second operand of a shift must always be extended. */
1569 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1570 no_extend
&& binoptab
!= ashl_optab
);
1572 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1573 unsignedp
, methods
);
1576 if (class != MODE_INT
)
1579 target
= gen_reg_rtx (mode
);
1580 convert_move (target
, temp
, 0);
1584 return gen_lowpart (mode
, temp
);
1587 delete_insns_since (last
);
1592 delete_insns_since (entry_last
);
1596 /* Expand a binary operator which has both signed and unsigned forms.
1597 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1600 If we widen unsigned operands, we may use a signed wider operation instead
1601 of an unsigned wider operation, since the result would be the same. */
1604 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1605 enum machine_mode mode
;
1606 optab uoptab
, soptab
;
1607 rtx op0
, op1
, target
;
1609 enum optab_methods methods
;
1612 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1613 struct optab wide_soptab
;
1615 /* Do it without widening, if possible. */
1616 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1617 unsignedp
, OPTAB_DIRECT
);
1618 if (temp
|| methods
== OPTAB_DIRECT
)
1621 /* Try widening to a signed int. Make a fake signed optab that
1622 hides any signed insn for direct use. */
1623 wide_soptab
= *soptab
;
1624 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1625 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1627 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1628 unsignedp
, OPTAB_WIDEN
);
1630 /* For unsigned operands, try widening to an unsigned int. */
1631 if (temp
== 0 && unsignedp
)
1632 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1633 unsignedp
, OPTAB_WIDEN
);
1634 if (temp
|| methods
== OPTAB_WIDEN
)
1637 /* Use the right width lib call if that exists. */
1638 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1639 if (temp
|| methods
== OPTAB_LIB
)
1642 /* Must widen and use a lib call, use either signed or unsigned. */
1643 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1644 unsignedp
, methods
);
1648 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1649 unsignedp
, methods
);
1653 /* Generate code to perform an operation specified by BINOPTAB
1654 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1655 We assume that the order of the operands for the instruction
1656 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1657 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1659 Either TARG0 or TARG1 may be zero, but what that means is that
1660 that result is not actually wanted. We will generate it into
1661 a dummy pseudo-reg and discard it. They may not both be zero.
1663 Returns 1 if this operation can be performed; 0 if not. */
1666 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1672 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1673 enum mode_class
class;
1674 enum machine_mode wider_mode
;
1675 rtx entry_last
= get_last_insn ();
1678 class = GET_MODE_CLASS (mode
);
1680 op0
= protect_from_queue (op0
, 0);
1681 op1
= protect_from_queue (op1
, 0);
1685 op0
= force_not_mem (op0
);
1686 op1
= force_not_mem (op1
);
1689 /* If we are inside an appropriately-short loop and one operand is an
1690 expensive constant, force it into a register. */
1691 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1692 && rtx_cost (op0
, binoptab
->code
) > 2)
1693 op0
= force_reg (mode
, op0
);
1695 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1696 && rtx_cost (op1
, binoptab
->code
) > 2)
1697 op1
= force_reg (mode
, op1
);
1700 targ0
= protect_from_queue (targ0
, 1);
1702 targ0
= gen_reg_rtx (mode
);
1704 targ1
= protect_from_queue (targ1
, 1);
1706 targ1
= gen_reg_rtx (mode
);
1708 /* Record where to go back to if we fail. */
1709 last
= get_last_insn ();
1711 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1713 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1714 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1715 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
1717 rtx xop0
= op0
, xop1
= op1
;
1719 /* In case this insn wants input operands in modes different from the
1720 result, convert the operands. */
1721 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1722 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1724 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1725 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1727 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1728 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1729 xop0
= copy_to_mode_reg (mode0
, xop0
);
1731 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
1732 xop1
= copy_to_mode_reg (mode1
, xop1
);
1734 /* We could handle this, but we should always be called with a pseudo
1735 for our targets and all insns should take them as outputs. */
1736 if (! (*insn_operand_predicate
[icode
][0]) (targ0
, mode
)
1737 || ! (*insn_operand_predicate
[icode
][3]) (targ1
, mode
))
1740 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1747 delete_insns_since (last
);
1750 /* It can't be done in this mode. Can we do it in a wider mode? */
1752 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1754 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1755 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1757 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1758 != CODE_FOR_nothing
)
1760 register rtx t0
= gen_reg_rtx (wider_mode
);
1761 register rtx t1
= gen_reg_rtx (wider_mode
);
1763 if (expand_twoval_binop (binoptab
,
1764 convert_modes (wider_mode
, mode
, op0
,
1766 convert_modes (wider_mode
, mode
, op1
,
1770 convert_move (targ0
, t0
, unsignedp
);
1771 convert_move (targ1
, t1
, unsignedp
);
1775 delete_insns_since (last
);
1780 delete_insns_since (entry_last
);
1784 /* Generate code to perform an operation specified by UNOPTAB
1785 on operand OP0, with result having machine-mode MODE.
1787 UNSIGNEDP is for the case where we have to widen the operands
1788 to perform the operation. It says to use zero-extension.
1790 If TARGET is nonzero, the value
1791 is generated there, if it is convenient to do so.
1792 In all cases an rtx is returned for the locus of the value;
1793 this may or may not be TARGET. */
1796 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
1797 enum machine_mode mode
;
1803 enum mode_class
class;
1804 enum machine_mode wider_mode
;
1806 rtx last
= get_last_insn ();
1809 class = GET_MODE_CLASS (mode
);
1811 op0
= protect_from_queue (op0
, 0);
1815 op0
= force_not_mem (op0
);
1819 target
= protect_from_queue (target
, 1);
1821 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1823 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
1824 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1830 temp
= gen_reg_rtx (mode
);
1832 if (GET_MODE (xop0
) != VOIDmode
1833 && GET_MODE (xop0
) != mode0
)
1834 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1836 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1838 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1839 xop0
= copy_to_mode_reg (mode0
, xop0
);
1841 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
1842 temp
= gen_reg_rtx (mode
);
1844 pat
= GEN_FCN (icode
) (temp
, xop0
);
1847 if (GET_CODE (pat
) == SEQUENCE
1848 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
1850 delete_insns_since (last
);
1851 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
1859 delete_insns_since (last
);
1862 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1864 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1865 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1866 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1868 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
1872 /* For certain operations, we need not actually extend
1873 the narrow operand, as long as we will truncate the
1874 results to the same narrowness. */
1876 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
1877 (unoptab
== neg_optab
1878 || unoptab
== one_cmpl_optab
)
1879 && class == MODE_INT
);
1881 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
1886 if (class != MODE_INT
)
1889 target
= gen_reg_rtx (mode
);
1890 convert_move (target
, temp
, 0);
1894 return gen_lowpart (mode
, temp
);
1897 delete_insns_since (last
);
1901 /* These can be done a word at a time. */
1902 if (unoptab
== one_cmpl_optab
1903 && class == MODE_INT
1904 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1905 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1910 if (target
== 0 || target
== op0
)
1911 target
= gen_reg_rtx (mode
);
1915 /* Do the actual arithmetic. */
1916 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1918 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1919 rtx x
= expand_unop (word_mode
, unoptab
,
1920 operand_subword_force (op0
, i
, mode
),
1921 target_piece
, unsignedp
);
1922 if (target_piece
!= x
)
1923 emit_move_insn (target_piece
, x
);
1926 insns
= get_insns ();
1929 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
1930 gen_rtx (unoptab
->code
, mode
, copy_rtx (op0
)));
1934 /* Open-code the complex negation operation. */
1935 else if (unoptab
== neg_optab
1936 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
1942 /* Find the correct mode for the real and imaginary parts */
1943 enum machine_mode submode
1944 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1945 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1948 if (submode
== BLKmode
)
1952 target
= gen_reg_rtx (mode
);
1956 target_piece
= gen_imagpart (submode
, target
);
1957 x
= expand_unop (submode
, unoptab
,
1958 gen_imagpart (submode
, op0
),
1959 target_piece
, unsignedp
);
1960 if (target_piece
!= x
)
1961 emit_move_insn (target_piece
, x
);
1963 target_piece
= gen_realpart (submode
, target
);
1964 x
= expand_unop (submode
, unoptab
,
1965 gen_realpart (submode
, op0
),
1966 target_piece
, unsignedp
);
1967 if (target_piece
!= x
)
1968 emit_move_insn (target_piece
, x
);
1973 emit_no_conflict_block (seq
, target
, op0
, 0,
1974 gen_rtx (unoptab
->code
, mode
, copy_rtx (op0
)));
1978 /* Now try a library call in this mode. */
1979 if (unoptab
->handlers
[(int) mode
].libfunc
)
1982 rtx funexp
= unoptab
->handlers
[(int) mode
].libfunc
;
1987 /* Pass 1 for NO_QUEUE so we don't lose any increments
1988 if the libcall is cse'd or moved. */
1989 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
1990 NULL_RTX
, 1, mode
, 1, op0
, mode
);
1991 insns
= get_insns ();
1994 target
= gen_reg_rtx (mode
);
1995 emit_libcall_block (insns
, target
, value
,
1996 gen_rtx (unoptab
->code
, mode
, op0
));
2001 /* It can't be done in this mode. Can we do it in a wider mode? */
2003 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2005 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2006 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2008 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
2009 != CODE_FOR_nothing
)
2010 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
2014 /* For certain operations, we need not actually extend
2015 the narrow operand, as long as we will truncate the
2016 results to the same narrowness. */
2018 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2019 (unoptab
== neg_optab
2020 || unoptab
== one_cmpl_optab
)
2021 && class == MODE_INT
);
2023 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2028 if (class != MODE_INT
)
2031 target
= gen_reg_rtx (mode
);
2032 convert_move (target
, temp
, 0);
2036 return gen_lowpart (mode
, temp
);
2039 delete_insns_since (last
);
2044 /* If there is no negate operation, try doing a subtract from zero.
2045 The US Software GOFAST library needs this. */
2046 if (unoptab
== neg_optab
)
2049 temp
= expand_binop (mode
, sub_optab
, CONST0_RTX (mode
), op0
,
2050 target
, unsignedp
, OPTAB_LIB_WIDEN
);
2058 /* Emit code to compute the absolute value of OP0, with result to
2059 TARGET if convenient. (TARGET may be 0.) The return value says
2060 where the result actually is to be found.
2062 MODE is the mode of the operand; the mode of the result is
2063 different but can be deduced from MODE.
2065 UNSIGNEDP is relevant if extension is needed. */
2068 expand_abs (mode
, op0
, target
, unsignedp
, safe
)
2069 enum machine_mode mode
;
2077 /* First try to do it with a special abs instruction. */
2078 temp
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
2082 /* If this machine has expensive jumps, we can do integer absolute
2083 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2084 where W is the width of MODE. */
2086 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
2088 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
2089 size_int (GET_MODE_BITSIZE (mode
) - 1),
2092 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
2095 temp
= expand_binop (mode
, sub_optab
, temp
, extended
, target
, 0,
2102 /* If that does not win, use conditional jump and negate. */
2103 op1
= gen_label_rtx ();
2104 if (target
== 0 || ! safe
2105 || GET_MODE (target
) != mode
2106 || (GET_CODE (target
) == MEM
&& MEM_VOLATILE_P (target
))
2107 || (GET_CODE (target
) == REG
2108 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
2109 target
= gen_reg_rtx (mode
);
2111 emit_move_insn (target
, op0
);
2114 /* If this mode is an integer too wide to compare properly,
2115 compare word by word. Rely on CSE to optimize constant cases. */
2116 if (GET_MODE_CLASS (mode
) == MODE_INT
&& ! can_compare_p (mode
))
2117 do_jump_by_parts_greater_rtx (mode
, 0, target
, const0_rtx
,
2121 temp
= compare_from_rtx (target
, CONST0_RTX (mode
), GE
, 0, mode
,
2123 if (temp
== const1_rtx
)
2125 else if (temp
!= const0_rtx
)
2127 if (bcc_gen_fctn
[(int) GET_CODE (temp
)] != 0)
2128 emit_jump_insn ((*bcc_gen_fctn
[(int) GET_CODE (temp
)]) (op1
));
2134 op0
= expand_unop (mode
, neg_optab
, target
, target
, 0);
2136 emit_move_insn (target
, op0
);
2142 /* Emit code to compute the absolute value of OP0, with result to
2143 TARGET if convenient. (TARGET may be 0.) The return value says
2144 where the result actually is to be found.
2146 MODE is the mode of the operand; the mode of the result is
2147 different but can be deduced from MODE.
2149 UNSIGNEDP is relevant for complex integer modes. */
2152 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2153 enum machine_mode mode
;
2158 enum mode_class
class = GET_MODE_CLASS (mode
);
2159 enum machine_mode wider_mode
;
2161 rtx entry_last
= get_last_insn ();
2165 /* Find the correct mode for the real and imaginary parts. */
2166 enum machine_mode submode
2167 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2168 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2171 if (submode
== BLKmode
)
2174 op0
= protect_from_queue (op0
, 0);
2178 op0
= force_not_mem (op0
);
2181 last
= get_last_insn ();
2184 target
= protect_from_queue (target
, 1);
2186 if (abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2188 int icode
= (int) abs_optab
->handlers
[(int) mode
].insn_code
;
2189 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2195 temp
= gen_reg_rtx (submode
);
2197 if (GET_MODE (xop0
) != VOIDmode
2198 && GET_MODE (xop0
) != mode0
)
2199 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2201 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2203 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
2204 xop0
= copy_to_mode_reg (mode0
, xop0
);
2206 if (! (*insn_operand_predicate
[icode
][0]) (temp
, submode
))
2207 temp
= gen_reg_rtx (submode
);
2209 pat
= GEN_FCN (icode
) (temp
, xop0
);
2212 if (GET_CODE (pat
) == SEQUENCE
2213 && ! add_equal_note (pat
, temp
, abs_optab
->code
, xop0
, NULL_RTX
))
2215 delete_insns_since (last
);
2216 return expand_unop (mode
, abs_optab
, op0
, NULL_RTX
, unsignedp
);
2224 delete_insns_since (last
);
2227 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2229 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2230 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2232 if (abs_optab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2236 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2237 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2241 if (class != MODE_COMPLEX_INT
)
2244 target
= gen_reg_rtx (submode
);
2245 convert_move (target
, temp
, 0);
2249 return gen_lowpart (submode
, temp
);
2252 delete_insns_since (last
);
2256 /* Open-code the complex absolute-value operation
2257 if we can open-code sqrt. Otherwise it's not worth while. */
2258 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
)
2260 rtx real
, imag
, total
;
2262 real
= gen_realpart (submode
, op0
);
2263 imag
= gen_imagpart (submode
, op0
);
2265 /* Square both parts. */
2266 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2267 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2269 /* Sum the parts. */
2270 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2271 0, OPTAB_LIB_WIDEN
);
2273 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2274 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2276 delete_insns_since (last
);
2281 /* Now try a library call in this mode. */
2282 if (abs_optab
->handlers
[(int) mode
].libfunc
)
2285 rtx funexp
= abs_optab
->handlers
[(int) mode
].libfunc
;
2290 /* Pass 1 for NO_QUEUE so we don't lose any increments
2291 if the libcall is cse'd or moved. */
2292 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2293 NULL_RTX
, 1, submode
, 1, op0
, mode
);
2294 insns
= get_insns ();
2297 target
= gen_reg_rtx (submode
);
2298 emit_libcall_block (insns
, target
, value
,
2299 gen_rtx (abs_optab
->code
, mode
, op0
));
2304 /* It can't be done in this mode. Can we do it in a wider mode? */
2306 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2307 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2309 if ((abs_optab
->handlers
[(int) wider_mode
].insn_code
2310 != CODE_FOR_nothing
)
2311 || abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2315 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2317 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2321 if (class != MODE_COMPLEX_INT
)
2324 target
= gen_reg_rtx (submode
);
2325 convert_move (target
, temp
, 0);
2329 return gen_lowpart (submode
, temp
);
2332 delete_insns_since (last
);
2336 delete_insns_since (entry_last
);
2340 /* Generate an instruction whose insn-code is INSN_CODE,
2341 with two operands: an output TARGET and an input OP0.
2342 TARGET *must* be nonzero, and the output is always stored there.
2343 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2344 the value that is stored into TARGET. */
2347 emit_unop_insn (icode
, target
, op0
, code
)
2354 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2357 temp
= target
= protect_from_queue (target
, 1);
2359 op0
= protect_from_queue (op0
, 0);
2362 op0
= force_not_mem (op0
);
2364 /* Now, if insn does not accept our operands, put them into pseudos. */
2366 if (! (*insn_operand_predicate
[icode
][1]) (op0
, mode0
))
2367 op0
= copy_to_mode_reg (mode0
, op0
);
2369 if (! (*insn_operand_predicate
[icode
][0]) (temp
, GET_MODE (temp
))
2370 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2371 temp
= gen_reg_rtx (GET_MODE (temp
));
2373 pat
= GEN_FCN (icode
) (temp
, op0
);
2375 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2376 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2381 emit_move_insn (target
, temp
);
2384 /* Emit code to perform a series of operations on a multi-word quantity, one
2387 Such a block is preceded by a CLOBBER of the output, consists of multiple
2388 insns, each setting one word of the output, and followed by a SET copying
2389 the output to itself.
2391 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2392 note indicating that it doesn't conflict with the (also multi-word)
2393 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2396 INSNS is a block of code generated to perform the operation, not including
2397 the CLOBBER and final copy. All insns that compute intermediate values
2398 are first emitted, followed by the block as described above. Only
2399 INSNs are allowed in the block; no library calls or jumps may be
2402 TARGET, OP0, and OP1 are the output and inputs of the operations,
2403 respectively. OP1 may be zero for a unary operation.
2405 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2408 If TARGET is not a register, INSNS is simply emitted with no special
2411 The final insn emitted is returned. */
2414 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2420 rtx prev
, next
, first
, last
, insn
;
2422 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2423 return emit_insns (insns
);
2425 /* First emit all insns that do not store into words of the output and remove
2426 these from the list. */
2427 for (insn
= insns
; insn
; insn
= next
)
2432 next
= NEXT_INSN (insn
);
2434 if (GET_CODE (insn
) != INSN
)
2437 if (GET_CODE (PATTERN (insn
)) == SET
)
2438 set
= PATTERN (insn
);
2439 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2441 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2442 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2444 set
= XVECEXP (PATTERN (insn
), 0, i
);
2452 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2454 if (PREV_INSN (insn
))
2455 NEXT_INSN (PREV_INSN (insn
)) = next
;
2460 PREV_INSN (next
) = PREV_INSN (insn
);
2466 prev
= get_last_insn ();
2468 /* Now write the CLOBBER of the output, followed by the setting of each
2469 of the words, followed by the final copy. */
2470 if (target
!= op0
&& target
!= op1
)
2471 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, target
));
2473 for (insn
= insns
; insn
; insn
= next
)
2475 next
= NEXT_INSN (insn
);
2478 if (op1
&& GET_CODE (op1
) == REG
)
2479 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op1
,
2482 if (op0
&& GET_CODE (op0
) == REG
)
2483 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op0
,
2487 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2488 != CODE_FOR_nothing
)
2490 last
= emit_move_insn (target
, target
);
2493 = gen_rtx (EXPR_LIST
, REG_EQUAL
, equiv
, REG_NOTES (last
));
2496 last
= get_last_insn ();
2499 first
= get_insns ();
2501 first
= NEXT_INSN (prev
);
2503 /* Encapsulate the block so it gets manipulated as a unit. */
2504 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
2506 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2511 /* Emit code to make a call to a constant function or a library call.
2513 INSNS is a list containing all insns emitted in the call.
2514 These insns leave the result in RESULT. Our block is to copy RESULT
2515 to TARGET, which is logically equivalent to EQUIV.
2517 We first emit any insns that set a pseudo on the assumption that these are
2518 loading constants into registers; doing so allows them to be safely cse'ed
2519 between blocks. Then we emit all the other insns in the block, followed by
2520 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2521 note with an operand of EQUIV.
2523 Moving assignments to pseudos outside of the block is done to improve
2524 the generated code, but is not required to generate correct code,
2525 hence being unable to move an assignment is not grounds for not making
2526 a libcall block. There are two reasons why it is safe to leave these
2527 insns inside the block: First, we know that these pseudos cannot be
2528 used in generated RTL outside the block since they are created for
2529 temporary purposes within the block. Second, CSE will not record the
2530 values of anything set inside a libcall block, so we know they must
2531 be dead at the end of the block.
2533 Except for the first group of insns (the ones setting pseudos), the
2534 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2537 emit_libcall_block (insns
, target
, result
, equiv
)
2543 rtx prev
, next
, first
, last
, insn
;
2545 /* First emit all insns that set pseudos. Remove them from the list as
2546 we go. Avoid insns that set pseudos which were referenced in previous
2547 insns. These can be generated by move_by_pieces, for example,
2548 to update an address. Similarly, avoid insns that reference things
2549 set in previous insns. */
2551 for (insn
= insns
; insn
; insn
= next
)
2553 rtx set
= single_set (insn
);
2555 next
= NEXT_INSN (insn
);
2557 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2558 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2560 || (! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
))
2561 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2562 && ! modified_in_p (SET_SRC (set
), insns
)
2563 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2565 if (PREV_INSN (insn
))
2566 NEXT_INSN (PREV_INSN (insn
)) = next
;
2571 PREV_INSN (next
) = PREV_INSN (insn
);
2577 prev
= get_last_insn ();
2579 /* Write the remaining insns followed by the final copy. */
2581 for (insn
= insns
; insn
; insn
= next
)
2583 next
= NEXT_INSN (insn
);
2588 last
= emit_move_insn (target
, result
);
2589 REG_NOTES (last
) = gen_rtx (EXPR_LIST
,
2590 REG_EQUAL
, copy_rtx (equiv
), REG_NOTES (last
));
2593 first
= get_insns ();
2595 first
= NEXT_INSN (prev
);
2597 /* Encapsulate the block so it gets manipulated as a unit. */
2598 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
2600 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2603 /* Generate code to store zero in X. */
2609 emit_move_insn (x
, const0_rtx
);
2612 /* Generate code to store 1 in X
2613 assuming it contains zero beforehand. */
2616 emit_0_to_1_insn (x
)
2619 emit_move_insn (x
, const1_rtx
);
2622 /* Generate code to compare X with Y
2623 so that the condition codes are set.
2625 MODE is the mode of the inputs (in case they are const_int).
2626 UNSIGNEDP nonzero says that X and Y are unsigned;
2627 this matters if they need to be widened.
2629 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2630 and ALIGN specifies the known shared alignment of X and Y.
2632 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2633 It is ignored for fixed-point and block comparisons;
2634 it is used only for floating-point comparisons. */
2637 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
2639 enum rtx_code comparison
;
2641 enum machine_mode mode
;
2645 enum mode_class
class;
2646 enum machine_mode wider_mode
;
2648 class = GET_MODE_CLASS (mode
);
2650 /* They could both be VOIDmode if both args are immediate constants,
2651 but we should fold that at an earlier stage.
2652 With no special code here, this will call abort,
2653 reminding the programmer to implement such folding. */
2655 if (mode
!= BLKmode
&& flag_force_mem
)
2657 x
= force_not_mem (x
);
2658 y
= force_not_mem (y
);
2661 /* If we are inside an appropriately-short loop and one operand is an
2662 expensive constant, force it into a register. */
2663 if (CONSTANT_P (x
) && preserve_subexpressions_p () && rtx_cost (x
, COMPARE
) > 2)
2664 x
= force_reg (mode
, x
);
2666 if (CONSTANT_P (y
) && preserve_subexpressions_p () && rtx_cost (y
, COMPARE
) > 2)
2667 y
= force_reg (mode
, y
);
2669 /* Don't let both operands fail to indicate the mode. */
2670 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
2671 x
= force_reg (mode
, x
);
2673 /* Handle all BLKmode compares. */
2675 if (mode
== BLKmode
)
2678 x
= protect_from_queue (x
, 0);
2679 y
= protect_from_queue (y
, 0);
2683 #ifdef HAVE_cmpstrqi
2685 && GET_CODE (size
) == CONST_INT
2686 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
2688 enum machine_mode result_mode
2689 = insn_operand_mode
[(int) CODE_FOR_cmpstrqi
][0];
2690 rtx result
= gen_reg_rtx (result_mode
);
2691 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, GEN_INT (align
)));
2692 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2697 #ifdef HAVE_cmpstrhi
2699 && GET_CODE (size
) == CONST_INT
2700 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
2702 enum machine_mode result_mode
2703 = insn_operand_mode
[(int) CODE_FOR_cmpstrhi
][0];
2704 rtx result
= gen_reg_rtx (result_mode
);
2705 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, GEN_INT (align
)));
2706 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2711 #ifdef HAVE_cmpstrsi
2714 enum machine_mode result_mode
2715 = insn_operand_mode
[(int) CODE_FOR_cmpstrsi
][0];
2716 rtx result
= gen_reg_rtx (result_mode
);
2717 size
= protect_from_queue (size
, 0);
2718 emit_insn (gen_cmpstrsi (result
, x
, y
,
2719 convert_to_mode (SImode
, size
, 1),
2721 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2727 #ifdef TARGET_MEM_FUNCTIONS
2728 emit_library_call (memcmp_libfunc
, 0,
2729 TYPE_MODE (integer_type_node
), 3,
2730 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2733 emit_library_call (bcmp_libfunc
, 0,
2734 TYPE_MODE (integer_type_node
), 3,
2735 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2738 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node
)),
2739 const0_rtx
, comparison
, NULL_RTX
,
2740 TYPE_MODE (integer_type_node
), 0, 0);
2745 /* Handle some compares against zero. */
2747 if (y
== CONST0_RTX (mode
)
2748 && tst_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2750 int icode
= (int) tst_optab
->handlers
[(int) mode
].insn_code
;
2753 x
= protect_from_queue (x
, 0);
2754 y
= protect_from_queue (y
, 0);
2756 /* Now, if insn does accept these operands, put them into pseudos. */
2757 if (! (*insn_operand_predicate
[icode
][0])
2758 (x
, insn_operand_mode
[icode
][0]))
2759 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2761 emit_insn (GEN_FCN (icode
) (x
));
2765 /* Handle compares for which there is a directly suitable insn. */
2767 if (cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2769 int icode
= (int) cmp_optab
->handlers
[(int) mode
].insn_code
;
2772 x
= protect_from_queue (x
, 0);
2773 y
= protect_from_queue (y
, 0);
2775 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2776 if (! (*insn_operand_predicate
[icode
][0])
2777 (x
, insn_operand_mode
[icode
][0]))
2778 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2780 if (! (*insn_operand_predicate
[icode
][1])
2781 (y
, insn_operand_mode
[icode
][1]))
2782 y
= copy_to_mode_reg (insn_operand_mode
[icode
][1], y
);
2784 emit_insn (GEN_FCN (icode
) (x
, y
));
2788 /* Try widening if we can find a direct insn that way. */
2790 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2792 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2793 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2795 if (cmp_optab
->handlers
[(int) wider_mode
].insn_code
2796 != CODE_FOR_nothing
)
2798 x
= protect_from_queue (x
, 0);
2799 y
= protect_from_queue (y
, 0);
2800 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
2801 y
= convert_modes (wider_mode
, mode
, y
, unsignedp
);
2802 emit_cmp_insn (x
, y
, comparison
, NULL_RTX
,
2803 wider_mode
, unsignedp
, align
);
2809 /* Handle a lib call just for the mode we are using. */
2811 if (cmp_optab
->handlers
[(int) mode
].libfunc
2812 && class != MODE_FLOAT
)
2814 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
2815 /* If we want unsigned, and this mode has a distinct unsigned
2816 comparison routine, use that. */
2817 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
2818 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
2820 emit_library_call (libfunc
, 1,
2821 word_mode
, 2, x
, mode
, y
, mode
);
2823 /* Integer comparison returns a result that must be compared against 1,
2824 so that even if we do an unsigned compare afterward,
2825 there is still a value that can represent the result "less than". */
2827 emit_cmp_insn (hard_libcall_value (word_mode
), const1_rtx
,
2828 comparison
, NULL_RTX
, word_mode
, unsignedp
, 0);
2832 if (class == MODE_FLOAT
)
2833 emit_float_lib_cmp (x
, y
, comparison
);
2839 /* Nonzero if a compare of mode MODE can be done straightforwardly
2840 (without splitting it into pieces). */
2843 can_compare_p (mode
)
2844 enum machine_mode mode
;
2848 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2850 mode
= GET_MODE_WIDER_MODE (mode
);
2851 } while (mode
!= VOIDmode
);
2856 /* Emit a library call comparison between floating point X and Y.
2857 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2860 emit_float_lib_cmp (x
, y
, comparison
)
2862 enum rtx_code comparison
;
2864 enum machine_mode mode
= GET_MODE (x
);
2871 libfunc
= eqhf2_libfunc
;
2875 libfunc
= nehf2_libfunc
;
2879 libfunc
= gthf2_libfunc
;
2883 libfunc
= gehf2_libfunc
;
2887 libfunc
= lthf2_libfunc
;
2891 libfunc
= lehf2_libfunc
;
2894 else if (mode
== SFmode
)
2898 libfunc
= eqsf2_libfunc
;
2902 libfunc
= nesf2_libfunc
;
2906 libfunc
= gtsf2_libfunc
;
2910 libfunc
= gesf2_libfunc
;
2914 libfunc
= ltsf2_libfunc
;
2918 libfunc
= lesf2_libfunc
;
2921 else if (mode
== DFmode
)
2925 libfunc
= eqdf2_libfunc
;
2929 libfunc
= nedf2_libfunc
;
2933 libfunc
= gtdf2_libfunc
;
2937 libfunc
= gedf2_libfunc
;
2941 libfunc
= ltdf2_libfunc
;
2945 libfunc
= ledf2_libfunc
;
2948 else if (mode
== XFmode
)
2952 libfunc
= eqxf2_libfunc
;
2956 libfunc
= nexf2_libfunc
;
2960 libfunc
= gtxf2_libfunc
;
2964 libfunc
= gexf2_libfunc
;
2968 libfunc
= ltxf2_libfunc
;
2972 libfunc
= lexf2_libfunc
;
2975 else if (mode
== TFmode
)
2979 libfunc
= eqtf2_libfunc
;
2983 libfunc
= netf2_libfunc
;
2987 libfunc
= gttf2_libfunc
;
2991 libfunc
= getf2_libfunc
;
2995 libfunc
= lttf2_libfunc
;
2999 libfunc
= letf2_libfunc
;
3004 enum machine_mode wider_mode
;
3006 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
3007 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3009 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
3010 != CODE_FOR_nothing
)
3011 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
3013 x
= protect_from_queue (x
, 0);
3014 y
= protect_from_queue (y
, 0);
3015 x
= convert_to_mode (wider_mode
, x
, 0);
3016 y
= convert_to_mode (wider_mode
, y
, 0);
3017 emit_float_lib_cmp (x
, y
, comparison
);
3027 emit_library_call (libfunc
, 1,
3028 word_mode
, 2, x
, mode
, y
, mode
);
3030 emit_cmp_insn (hard_libcall_value (word_mode
), const0_rtx
, comparison
,
3031 NULL_RTX
, word_mode
, 0, 0);
3034 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3037 emit_indirect_jump (loc
)
3040 if (! ((*insn_operand_predicate
[(int)CODE_FOR_indirect_jump
][0])
3042 loc
= copy_to_mode_reg (Pmode
, loc
);
3044 emit_jump_insn (gen_indirect_jump (loc
));
3048 /* These three functions generate an insn body and return it
3049 rather than emitting the insn.
3051 They do not protect from queued increments,
3052 because they may be used 1) in protect_from_queue itself
3053 and 2) in other passes where there is no queue. */
3055 /* Generate and return an insn body to add Y to X. */
3058 gen_add2_insn (x
, y
)
3061 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3063 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
3064 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
3065 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
3068 return (GEN_FCN (icode
) (x
, x
, y
));
3072 have_add2_insn (mode
)
3073 enum machine_mode mode
;
3075 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3078 /* Generate and return an insn body to subtract Y from X. */
3081 gen_sub2_insn (x
, y
)
3084 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3086 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
3087 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
3088 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
3091 return (GEN_FCN (icode
) (x
, x
, y
));
3095 have_sub2_insn (mode
)
3096 enum machine_mode mode
;
3098 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3101 /* Generate the body of an instruction to copy Y into X.
3102 It may be a SEQUENCE, if one insn isn't enough. */
3105 gen_move_insn (x
, y
)
3108 register enum machine_mode mode
= GET_MODE (x
);
3109 enum insn_code insn_code
;
3112 if (mode
== VOIDmode
)
3113 mode
= GET_MODE (y
);
3115 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
3117 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3118 find a mode to do it in. If we have a movcc, use it. Otherwise,
3119 find the MODE_INT mode of the same width. */
3121 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
3123 enum machine_mode tmode
= VOIDmode
;
3127 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
3130 for (tmode
= QImode
; tmode
!= VOIDmode
;
3131 tmode
= GET_MODE_WIDER_MODE (tmode
))
3132 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
3135 if (tmode
== VOIDmode
)
3138 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3139 may call change_address which is not appropriate if we were
3140 called when a reload was in progress. We don't have to worry
3141 about changing the address since the size in bytes is supposed to
3142 be the same. Copy the MEM to change the mode and move any
3143 substitutions from the old MEM to the new one. */
3145 if (reload_in_progress
)
3147 x
= gen_lowpart_common (tmode
, x1
);
3148 if (x
== 0 && GET_CODE (x1
) == MEM
)
3150 x
= gen_rtx (MEM
, tmode
, XEXP (x1
, 0));
3151 RTX_UNCHANGING_P (x
) = RTX_UNCHANGING_P (x1
);
3152 MEM_IN_STRUCT_P (x
) = MEM_IN_STRUCT_P (x1
);
3153 MEM_VOLATILE_P (x
) = MEM_VOLATILE_P (x1
);
3154 copy_replacements (x1
, x
);
3157 y
= gen_lowpart_common (tmode
, y1
);
3158 if (y
== 0 && GET_CODE (y1
) == MEM
)
3160 y
= gen_rtx (MEM
, tmode
, XEXP (y1
, 0));
3161 RTX_UNCHANGING_P (y
) = RTX_UNCHANGING_P (y1
);
3162 MEM_IN_STRUCT_P (y
) = MEM_IN_STRUCT_P (y1
);
3163 MEM_VOLATILE_P (y
) = MEM_VOLATILE_P (y1
);
3164 copy_replacements (y1
, y
);
3169 x
= gen_lowpart (tmode
, x
);
3170 y
= gen_lowpart (tmode
, y
);
3173 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3174 return (GEN_FCN (insn_code
) (x
, y
));
3178 emit_move_insn_1 (x
, y
);
3179 seq
= gen_sequence ();
3184 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3185 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3186 no such operation exists, CODE_FOR_nothing will be returned. */
3189 can_extend_p (to_mode
, from_mode
, unsignedp
)
3190 enum machine_mode to_mode
, from_mode
;
3193 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
];
3196 /* Generate the body of an insn to extend Y (with mode MFROM)
3197 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3200 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3202 enum machine_mode mto
, mfrom
;
3205 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
]) (x
, y
));
3208 /* can_fix_p and can_float_p say whether the target machine
3209 can directly convert a given fixed point type to
3210 a given floating point type, or vice versa.
3211 The returned value is the CODE_FOR_... value to use,
3212 or CODE_FOR_nothing if these modes cannot be directly converted.
3214 *TRUNCP_PTR is set to 1 if it is necessary to output
3215 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3217 static enum insn_code
3218 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3219 enum machine_mode fltmode
, fixmode
;
3224 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
] != CODE_FOR_nothing
)
3225 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3227 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3230 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3232 return CODE_FOR_nothing
;
3235 static enum insn_code
3236 can_float_p (fltmode
, fixmode
, unsignedp
)
3237 enum machine_mode fixmode
, fltmode
;
3240 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3243 /* Generate code to convert FROM to floating point
3244 and store in TO. FROM must be fixed point and not VOIDmode.
3245 UNSIGNEDP nonzero means regard FROM as unsigned.
3246 Normally this is done by correcting the final value
3247 if it is negative. */
3250 expand_float (to
, from
, unsignedp
)
3254 enum insn_code icode
;
3255 register rtx target
= to
;
3256 enum machine_mode fmode
, imode
;
3258 /* Crash now, because we won't be able to decide which mode to use. */
3259 if (GET_MODE (from
) == VOIDmode
)
3262 /* Look for an insn to do the conversion. Do it in the specified
3263 modes if possible; otherwise convert either input, output or both to
3264 wider mode. If the integer mode is wider than the mode of FROM,
3265 we can do the conversion signed even if the input is unsigned. */
3267 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3268 imode
= GET_MODE_WIDER_MODE (imode
))
3269 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3270 fmode
= GET_MODE_WIDER_MODE (fmode
))
3272 int doing_unsigned
= unsignedp
;
3274 icode
= can_float_p (fmode
, imode
, unsignedp
);
3275 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3276 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3278 if (icode
!= CODE_FOR_nothing
)
3280 to
= protect_from_queue (to
, 1);
3281 from
= protect_from_queue (from
, 0);
3283 if (imode
!= GET_MODE (from
))
3284 from
= convert_to_mode (imode
, from
, unsignedp
);
3286 if (fmode
!= GET_MODE (to
))
3287 target
= gen_reg_rtx (fmode
);
3289 emit_unop_insn (icode
, target
, from
,
3290 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3293 convert_move (to
, target
, 0);
3298 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3300 /* Unsigned integer, and no way to convert directly.
3301 Convert as signed, then conditionally adjust the result. */
3304 rtx label
= gen_label_rtx ();
3306 REAL_VALUE_TYPE offset
;
3310 to
= protect_from_queue (to
, 1);
3311 from
= protect_from_queue (from
, 0);
3314 from
= force_not_mem (from
);
3316 /* Look for a usable floating mode FMODE wider than the source and at
3317 least as wide as the target. Using FMODE will avoid rounding woes
3318 with unsigned values greater than the signed maximum value. */
3320 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3321 fmode
= GET_MODE_WIDER_MODE (fmode
))
3322 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
3323 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
3326 if (fmode
== VOIDmode
)
3328 /* There is no such mode. Pretend the target is wide enough. */
3329 fmode
= GET_MODE (to
);
3331 /* Avoid double-rounding when TO is narrower than FROM. */
3332 if ((significand_size (fmode
) + 1)
3333 < GET_MODE_BITSIZE (GET_MODE (from
)))
3336 rtx neglabel
= gen_label_rtx ();
3338 /* Don't use TARGET if it isn't a register, is a hard register,
3339 or is the wrong mode. */
3340 if (GET_CODE (target
) != REG
3341 || REGNO (target
) < FIRST_PSEUDO_REGISTER
3342 || GET_MODE (target
) != fmode
)
3343 target
= gen_reg_rtx (fmode
);
3345 imode
= GET_MODE (from
);
3346 do_pending_stack_adjust ();
3348 /* Test whether the sign bit is set. */
3349 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, imode
, 0, 0);
3350 emit_jump_insn (gen_blt (neglabel
));
3352 /* The sign bit is not set. Convert as signed. */
3353 expand_float (target
, from
, 0);
3354 emit_jump_insn (gen_jump (label
));
3356 /* The sign bit is set.
3357 Convert to a usable (positive signed) value by shifting right
3358 one bit, while remembering if a nonzero bit was shifted
3359 out; i.e., compute (from & 1) | (from >> 1). */
3361 emit_label (neglabel
);
3362 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
3363 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3364 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
3366 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
3368 expand_float (target
, temp
, 0);
3370 /* Multiply by 2 to undo the shift above. */
3371 temp
= expand_binop (fmode
, add_optab
, target
, target
,
3372 target
, 0, OPTAB_LIB_WIDEN
);
3374 emit_move_insn (target
, temp
);
3376 do_pending_stack_adjust ();
3382 /* If we are about to do some arithmetic to correct for an
3383 unsigned operand, do it in a pseudo-register. */
3385 if (GET_MODE (to
) != fmode
3386 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
3387 target
= gen_reg_rtx (fmode
);
3389 /* Convert as signed integer to floating. */
3390 expand_float (target
, from
, 0);
3392 /* If FROM is negative (and therefore TO is negative),
3393 correct its value by 2**bitwidth. */
3395 do_pending_stack_adjust ();
3396 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3397 emit_jump_insn (gen_bge (label
));
3399 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3400 Rather than setting up a dconst_dot_5, let's hope SCO
3402 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
3403 temp
= expand_binop (fmode
, add_optab
, target
,
3404 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
3405 target
, 0, OPTAB_LIB_WIDEN
);
3407 emit_move_insn (target
, temp
);
3409 do_pending_stack_adjust ();
3415 /* No hardware instruction available; call a library routine to convert from
3416 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3422 to
= protect_from_queue (to
, 1);
3423 from
= protect_from_queue (from
, 0);
3425 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
3426 from
= convert_to_mode (SImode
, from
, unsignedp
);
3429 from
= force_not_mem (from
);
3431 if (GET_MODE (to
) == SFmode
)
3433 if (GET_MODE (from
) == SImode
)
3434 libfcn
= floatsisf_libfunc
;
3435 else if (GET_MODE (from
) == DImode
)
3436 libfcn
= floatdisf_libfunc
;
3437 else if (GET_MODE (from
) == TImode
)
3438 libfcn
= floattisf_libfunc
;
3442 else if (GET_MODE (to
) == DFmode
)
3444 if (GET_MODE (from
) == SImode
)
3445 libfcn
= floatsidf_libfunc
;
3446 else if (GET_MODE (from
) == DImode
)
3447 libfcn
= floatdidf_libfunc
;
3448 else if (GET_MODE (from
) == TImode
)
3449 libfcn
= floattidf_libfunc
;
3453 else if (GET_MODE (to
) == XFmode
)
3455 if (GET_MODE (from
) == SImode
)
3456 libfcn
= floatsixf_libfunc
;
3457 else if (GET_MODE (from
) == DImode
)
3458 libfcn
= floatdixf_libfunc
;
3459 else if (GET_MODE (from
) == TImode
)
3460 libfcn
= floattixf_libfunc
;
3464 else if (GET_MODE (to
) == TFmode
)
3466 if (GET_MODE (from
) == SImode
)
3467 libfcn
= floatsitf_libfunc
;
3468 else if (GET_MODE (from
) == DImode
)
3469 libfcn
= floatditf_libfunc
;
3470 else if (GET_MODE (from
) == TImode
)
3471 libfcn
= floattitf_libfunc
;
3480 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1,
3482 1, from
, GET_MODE (from
));
3483 insns
= get_insns ();
3486 emit_libcall_block (insns
, target
, value
,
3487 gen_rtx (FLOAT
, GET_MODE (to
), from
));
3492 /* Copy result to requested destination
3493 if we have been computing in a temp location. */
3497 if (GET_MODE (target
) == GET_MODE (to
))
3498 emit_move_insn (to
, target
);
3500 convert_move (to
, target
, 0);
3504 /* expand_fix: generate code to convert FROM to fixed point
3505 and store in TO. FROM must be floating point. */
3511 rtx temp
= gen_reg_rtx (GET_MODE (x
));
3512 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
3516 expand_fix (to
, from
, unsignedp
)
3517 register rtx to
, from
;
3520 enum insn_code icode
;
3521 register rtx target
= to
;
3522 enum machine_mode fmode
, imode
;
3526 /* We first try to find a pair of modes, one real and one integer, at
3527 least as wide as FROM and TO, respectively, in which we can open-code
3528 this conversion. If the integer mode is wider than the mode of TO,
3529 we can do the conversion either signed or unsigned. */
3531 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
3532 imode
= GET_MODE_WIDER_MODE (imode
))
3533 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3534 fmode
= GET_MODE_WIDER_MODE (fmode
))
3536 int doing_unsigned
= unsignedp
;
3538 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
3539 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
3540 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
3542 if (icode
!= CODE_FOR_nothing
)
3544 to
= protect_from_queue (to
, 1);
3545 from
= protect_from_queue (from
, 0);
3547 if (fmode
!= GET_MODE (from
))
3548 from
= convert_to_mode (fmode
, from
, 0);
3551 from
= ftruncify (from
);
3553 if (imode
!= GET_MODE (to
))
3554 target
= gen_reg_rtx (imode
);
3556 emit_unop_insn (icode
, target
, from
,
3557 doing_unsigned
? UNSIGNED_FIX
: FIX
);
3559 convert_move (to
, target
, unsignedp
);
3564 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3565 /* For an unsigned conversion, there is one more way to do it.
3566 If we have a signed conversion, we generate code that compares
3567 the real value to the largest representable positive number. If if
3568 is smaller, the conversion is done normally. Otherwise, subtract
3569 one plus the highest signed number, convert, and add it back.
3571 We only need to check all real modes, since we know we didn't find
3572 anything with a wider integer mode. */
3574 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
3575 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3576 fmode
= GET_MODE_WIDER_MODE (fmode
))
3577 /* Make sure we won't lose significant bits doing this. */
3578 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
3579 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
3583 REAL_VALUE_TYPE offset
;
3584 rtx limit
, lab1
, lab2
, insn
;
3586 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
3587 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
3588 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
3589 lab1
= gen_label_rtx ();
3590 lab2
= gen_label_rtx ();
3593 to
= protect_from_queue (to
, 1);
3594 from
= protect_from_queue (from
, 0);
3597 from
= force_not_mem (from
);
3599 if (fmode
!= GET_MODE (from
))
3600 from
= convert_to_mode (fmode
, from
, 0);
3602 /* See if we need to do the subtraction. */
3603 do_pending_stack_adjust ();
3604 emit_cmp_insn (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3605 emit_jump_insn (gen_bge (lab1
));
3607 /* If not, do the signed "fix" and branch around fixup code. */
3608 expand_fix (to
, from
, 0);
3609 emit_jump_insn (gen_jump (lab2
));
3612 /* Otherwise, subtract 2**(N-1), convert to signed number,
3613 then add 2**(N-1). Do the addition using XOR since this
3614 will often generate better code. */
3616 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
3617 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3618 expand_fix (to
, target
, 0);
3619 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
3620 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
3621 to
, 1, OPTAB_LIB_WIDEN
);
3624 emit_move_insn (to
, target
);
3628 /* Make a place for a REG_NOTE and add it. */
3629 insn
= emit_move_insn (to
, to
);
3630 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
3631 gen_rtx (UNSIGNED_FIX
, GET_MODE (to
),
3639 /* We can't do it with an insn, so use a library call. But first ensure
3640 that the mode of TO is at least as wide as SImode, since those are the
3641 only library calls we know about. */
3643 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
3645 target
= gen_reg_rtx (SImode
);
3647 expand_fix (target
, from
, unsignedp
);
3649 else if (GET_MODE (from
) == SFmode
)
3651 if (GET_MODE (to
) == SImode
)
3652 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
3653 else if (GET_MODE (to
) == DImode
)
3654 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
3655 else if (GET_MODE (to
) == TImode
)
3656 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
3660 else if (GET_MODE (from
) == DFmode
)
3662 if (GET_MODE (to
) == SImode
)
3663 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
3664 else if (GET_MODE (to
) == DImode
)
3665 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
3666 else if (GET_MODE (to
) == TImode
)
3667 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
3671 else if (GET_MODE (from
) == XFmode
)
3673 if (GET_MODE (to
) == SImode
)
3674 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
3675 else if (GET_MODE (to
) == DImode
)
3676 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
3677 else if (GET_MODE (to
) == TImode
)
3678 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
3682 else if (GET_MODE (from
) == TFmode
)
3684 if (GET_MODE (to
) == SImode
)
3685 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
3686 else if (GET_MODE (to
) == DImode
)
3687 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
3688 else if (GET_MODE (to
) == TImode
)
3689 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
3701 to
= protect_from_queue (to
, 1);
3702 from
= protect_from_queue (from
, 0);
3705 from
= force_not_mem (from
);
3709 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1, GET_MODE (to
),
3711 1, from
, GET_MODE (from
));
3712 insns
= get_insns ();
3715 emit_libcall_block (insns
, target
, value
,
3716 gen_rtx (unsignedp
? UNSIGNED_FIX
: FIX
,
3717 GET_MODE (to
), from
));
3720 if (GET_MODE (to
) == GET_MODE (target
))
3721 emit_move_insn (to
, target
);
3723 convert_move (to
, target
, 0);
3731 optab op
= (optab
) xmalloc (sizeof (struct optab
));
3733 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3735 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
3736 op
->handlers
[i
].libfunc
= 0;
3739 if (code
!= UNKNOWN
)
3740 code_to_optab
[(int) code
] = op
;
3745 /* Initialize the libfunc fields of an entire group of entries in some
3746 optab. Each entry is set equal to a string consisting of a leading
3747 pair of underscores followed by a generic operation name followed by
3748 a mode name (downshifted to lower case) followed by a single character
3749 representing the number of operands for the given operation (which is
3750 usually one of the characters '2', '3', or '4').
3752 OPTABLE is the table in which libfunc fields are to be initialized.
3753 FIRST_MODE is the first machine mode index in the given optab to
3755 LAST_MODE is the last machine mode index in the given optab to
3757 OPNAME is the generic (string) name of the operation.
3758 SUFFIX is the character which specifies the number of operands for
3759 the given generic operation.
3763 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
3764 register optab optable
;
3765 register int first_mode
;
3766 register int last_mode
;
3767 register char *opname
;
3768 register char suffix
;
3771 register unsigned opname_len
= strlen (opname
);
3773 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
3774 mode
= (enum machine_mode
) ((int) mode
+ 1))
3776 register char *mname
= mode_name
[(int) mode
];
3777 register unsigned mname_len
= strlen (mname
);
3778 register char *libfunc_name
3779 = (char *) xmalloc (2 + opname_len
+ mname_len
+ 1 + 1);
3786 for (q
= opname
; *q
; )
3788 for (q
= mname
; *q
; q
++)
3789 *p
++ = tolower (*q
);
3792 optable
->handlers
[(int) mode
].libfunc
3793 = gen_rtx (SYMBOL_REF
, Pmode
, libfunc_name
);
3797 /* Initialize the libfunc fields of an entire group of entries in some
3798 optab which correspond to all integer mode operations. The parameters
3799 have the same meaning as similarly named ones for the `init_libfuncs'
3800 routine. (See above). */
3803 init_integral_libfuncs (optable
, opname
, suffix
)
3804 register optab optable
;
3805 register char *opname
;
3806 register char suffix
;
3808 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
3811 /* Initialize the libfunc fields of an entire group of entries in some
3812 optab which correspond to all real mode operations. The parameters
3813 have the same meaning as similarly named ones for the `init_libfuncs'
3814 routine. (See above). */
3817 init_floating_libfuncs (optable
, opname
, suffix
)
3818 register optab optable
;
3819 register char *opname
;
3820 register char suffix
;
3822 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
3825 /* Initialize the libfunc fields of an entire group of entries in some
3826 optab which correspond to all complex floating modes. The parameters
3827 have the same meaning as similarly named ones for the `init_libfuncs'
3828 routine. (See above). */
3831 init_complex_libfuncs (optable
, opname
, suffix
)
3832 register optab optable
;
3833 register char *opname
;
3834 register char suffix
;
3836 init_libfuncs (optable
, SCmode
, TCmode
, opname
, suffix
);
3839 /* Call this once to initialize the contents of the optabs
3840 appropriately for the current target machine. */
3848 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3850 for (p
= fixtab
[0][0];
3851 p
< fixtab
[0][0] + sizeof fixtab
/ sizeof (fixtab
[0][0][0]);
3853 *p
= CODE_FOR_nothing
;
3855 for (p
= fixtrunctab
[0][0];
3856 p
< fixtrunctab
[0][0] + sizeof fixtrunctab
/ sizeof (fixtrunctab
[0][0][0]);
3858 *p
= CODE_FOR_nothing
;
3860 for (p
= floattab
[0][0];
3861 p
< floattab
[0][0] + sizeof floattab
/ sizeof (floattab
[0][0][0]);
3863 *p
= CODE_FOR_nothing
;
3865 for (p
= extendtab
[0][0];
3866 p
< extendtab
[0][0] + sizeof extendtab
/ sizeof extendtab
[0][0][0];
3868 *p
= CODE_FOR_nothing
;
3870 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
3871 setcc_gen_code
[i
] = CODE_FOR_nothing
;
3873 add_optab
= init_optab (PLUS
);
3874 sub_optab
= init_optab (MINUS
);
3875 smul_optab
= init_optab (MULT
);
3876 smul_highpart_optab
= init_optab (UNKNOWN
);
3877 umul_highpart_optab
= init_optab (UNKNOWN
);
3878 smul_widen_optab
= init_optab (UNKNOWN
);
3879 umul_widen_optab
= init_optab (UNKNOWN
);
3880 sdiv_optab
= init_optab (DIV
);
3881 sdivmod_optab
= init_optab (UNKNOWN
);
3882 udiv_optab
= init_optab (UDIV
);
3883 udivmod_optab
= init_optab (UNKNOWN
);
3884 smod_optab
= init_optab (MOD
);
3885 umod_optab
= init_optab (UMOD
);
3886 flodiv_optab
= init_optab (DIV
);
3887 ftrunc_optab
= init_optab (UNKNOWN
);
3888 and_optab
= init_optab (AND
);
3889 ior_optab
= init_optab (IOR
);
3890 xor_optab
= init_optab (XOR
);
3891 ashl_optab
= init_optab (ASHIFT
);
3892 ashr_optab
= init_optab (ASHIFTRT
);
3893 lshr_optab
= init_optab (LSHIFTRT
);
3894 rotl_optab
= init_optab (ROTATE
);
3895 rotr_optab
= init_optab (ROTATERT
);
3896 smin_optab
= init_optab (SMIN
);
3897 smax_optab
= init_optab (SMAX
);
3898 umin_optab
= init_optab (UMIN
);
3899 umax_optab
= init_optab (UMAX
);
3900 mov_optab
= init_optab (UNKNOWN
);
3901 movstrict_optab
= init_optab (UNKNOWN
);
3902 cmp_optab
= init_optab (UNKNOWN
);
3903 ucmp_optab
= init_optab (UNKNOWN
);
3904 tst_optab
= init_optab (UNKNOWN
);
3905 neg_optab
= init_optab (NEG
);
3906 abs_optab
= init_optab (ABS
);
3907 one_cmpl_optab
= init_optab (NOT
);
3908 ffs_optab
= init_optab (FFS
);
3909 sqrt_optab
= init_optab (SQRT
);
3910 sin_optab
= init_optab (UNKNOWN
);
3911 cos_optab
= init_optab (UNKNOWN
);
3912 strlen_optab
= init_optab (UNKNOWN
);
3914 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3916 movstr_optab
[i
] = CODE_FOR_nothing
;
3918 #ifdef HAVE_SECONDARY_RELOADS
3919 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
3923 /* Fill in the optabs with the insns we support. */
3926 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3927 /* This flag says the same insns that convert to a signed fixnum
3928 also convert validly to an unsigned one. */
3929 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3930 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
3931 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
3934 #ifdef EXTRA_CC_MODES
3938 /* Initialize the optabs with the names of the library functions. */
3939 init_integral_libfuncs (add_optab
, "add", '3');
3940 init_floating_libfuncs (add_optab
, "add", '3');
3941 init_integral_libfuncs (sub_optab
, "sub", '3');
3942 init_floating_libfuncs (sub_optab
, "sub", '3');
3943 init_integral_libfuncs (smul_optab
, "mul", '3');
3944 init_floating_libfuncs (smul_optab
, "mul", '3');
3945 init_integral_libfuncs (sdiv_optab
, "div", '3');
3946 init_integral_libfuncs (udiv_optab
, "udiv", '3');
3947 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
3948 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
3949 init_integral_libfuncs (smod_optab
, "mod", '3');
3950 init_integral_libfuncs (umod_optab
, "umod", '3');
3951 init_floating_libfuncs (flodiv_optab
, "div", '3');
3952 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
3953 init_integral_libfuncs (and_optab
, "and", '3');
3954 init_integral_libfuncs (ior_optab
, "ior", '3');
3955 init_integral_libfuncs (xor_optab
, "xor", '3');
3956 init_integral_libfuncs (ashl_optab
, "ashl", '3');
3957 init_integral_libfuncs (ashr_optab
, "ashr", '3');
3958 init_integral_libfuncs (lshr_optab
, "lshr", '3');
3959 init_integral_libfuncs (rotl_optab
, "rotl", '3');
3960 init_integral_libfuncs (rotr_optab
, "rotr", '3');
3961 init_integral_libfuncs (smin_optab
, "min", '3');
3962 init_floating_libfuncs (smin_optab
, "min", '3');
3963 init_integral_libfuncs (smax_optab
, "max", '3');
3964 init_floating_libfuncs (smax_optab
, "max", '3');
3965 init_integral_libfuncs (umin_optab
, "umin", '3');
3966 init_integral_libfuncs (umax_optab
, "umax", '3');
3967 init_integral_libfuncs (neg_optab
, "neg", '2');
3968 init_floating_libfuncs (neg_optab
, "neg", '2');
3969 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
3970 init_integral_libfuncs (ffs_optab
, "ffs", '2');
3972 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3973 init_integral_libfuncs (cmp_optab
, "cmp", '2');
3974 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
3975 init_floating_libfuncs (cmp_optab
, "cmp", '2');
3977 #ifdef MULSI3_LIBCALL
3978 smul_optab
->handlers
[(int) SImode
].libfunc
3979 = gen_rtx (SYMBOL_REF
, Pmode
, MULSI3_LIBCALL
);
3981 #ifdef MULDI3_LIBCALL
3982 smul_optab
->handlers
[(int) DImode
].libfunc
3983 = gen_rtx (SYMBOL_REF
, Pmode
, MULDI3_LIBCALL
);
3985 #ifdef MULTI3_LIBCALL
3986 smul_optab
->handlers
[(int) TImode
].libfunc
3987 = gen_rtx (SYMBOL_REF
, Pmode
, MULTI3_LIBCALL
);
3990 #ifdef DIVSI3_LIBCALL
3991 sdiv_optab
->handlers
[(int) SImode
].libfunc
3992 = gen_rtx (SYMBOL_REF
, Pmode
, DIVSI3_LIBCALL
);
3994 #ifdef DIVDI3_LIBCALL
3995 sdiv_optab
->handlers
[(int) DImode
].libfunc
3996 = gen_rtx (SYMBOL_REF
, Pmode
, DIVDI3_LIBCALL
);
3998 #ifdef DIVTI3_LIBCALL
3999 sdiv_optab
->handlers
[(int) TImode
].libfunc
4000 = gen_rtx (SYMBOL_REF
, Pmode
, DIVTI3_LIBCALL
);
4003 #ifdef UDIVSI3_LIBCALL
4004 udiv_optab
->handlers
[(int) SImode
].libfunc
4005 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVSI3_LIBCALL
);
4007 #ifdef UDIVDI3_LIBCALL
4008 udiv_optab
->handlers
[(int) DImode
].libfunc
4009 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVDI3_LIBCALL
);
4011 #ifdef UDIVTI3_LIBCALL
4012 udiv_optab
->handlers
[(int) TImode
].libfunc
4013 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVTI3_LIBCALL
);
4017 #ifdef MODSI3_LIBCALL
4018 smod_optab
->handlers
[(int) SImode
].libfunc
4019 = gen_rtx (SYMBOL_REF
, Pmode
, MODSI3_LIBCALL
);
4021 #ifdef MODDI3_LIBCALL
4022 smod_optab
->handlers
[(int) DImode
].libfunc
4023 = gen_rtx (SYMBOL_REF
, Pmode
, MODDI3_LIBCALL
);
4025 #ifdef MODTI3_LIBCALL
4026 smod_optab
->handlers
[(int) TImode
].libfunc
4027 = gen_rtx (SYMBOL_REF
, Pmode
, MODTI3_LIBCALL
);
4031 #ifdef UMODSI3_LIBCALL
4032 umod_optab
->handlers
[(int) SImode
].libfunc
4033 = gen_rtx (SYMBOL_REF
, Pmode
, UMODSI3_LIBCALL
);
4035 #ifdef UMODDI3_LIBCALL
4036 umod_optab
->handlers
[(int) DImode
].libfunc
4037 = gen_rtx (SYMBOL_REF
, Pmode
, UMODDI3_LIBCALL
);
4039 #ifdef UMODTI3_LIBCALL
4040 umod_optab
->handlers
[(int) TImode
].libfunc
4041 = gen_rtx (SYMBOL_REF
, Pmode
, UMODTI3_LIBCALL
);
4044 /* Define library calls for quad FP instructions */
4045 #ifdef ADDTF3_LIBCALL
4046 add_optab
->handlers
[(int) TFmode
].libfunc
4047 = gen_rtx (SYMBOL_REF
, Pmode
, ADDTF3_LIBCALL
);
4049 #ifdef SUBTF3_LIBCALL
4050 sub_optab
->handlers
[(int) TFmode
].libfunc
4051 = gen_rtx (SYMBOL_REF
, Pmode
, SUBTF3_LIBCALL
);
4053 #ifdef MULTF3_LIBCALL
4054 smul_optab
->handlers
[(int) TFmode
].libfunc
4055 = gen_rtx (SYMBOL_REF
, Pmode
, MULTF3_LIBCALL
);
4057 #ifdef DIVTF3_LIBCALL
4058 flodiv_optab
->handlers
[(int) TFmode
].libfunc
4059 = gen_rtx (SYMBOL_REF
, Pmode
, DIVTF3_LIBCALL
);
4061 #ifdef SQRTTF2_LIBCALL
4062 sqrt_optab
->handlers
[(int) TFmode
].libfunc
4063 = gen_rtx (SYMBOL_REF
, Pmode
, SQRTTF2_LIBCALL
);
4066 /* Use cabs for DC complex abs, since systems generally have cabs.
4067 Don't define any libcall for SCmode, so that cabs will be used. */
4068 abs_optab
->handlers
[(int) DCmode
].libfunc
4069 = gen_rtx (SYMBOL_REF
, Pmode
, "cabs");
4071 /* The ffs function operates on `int'. */
4072 #ifndef INT_TYPE_SIZE
4073 #define INT_TYPE_SIZE BITS_PER_WORD
4075 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)] .libfunc
4076 = gen_rtx (SYMBOL_REF
, Pmode
, "ffs");
4078 extendsfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfdf2");
4079 extendsfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfxf2");
4080 extendsftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsftf2");
4081 extenddfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddfxf2");
4082 extenddftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddftf2");
4084 truncdfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncdfsf2");
4085 truncxfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfsf2");
4086 trunctfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfsf2");
4087 truncxfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfdf2");
4088 trunctfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfdf2");
4090 memcpy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcpy");
4091 bcopy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bcopy");
4092 memcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcmp");
4093 bcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gcc_bcmp");
4094 memset_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memset");
4095 bzero_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bzero");
4097 eqhf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqhf2");
4098 nehf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nehf2");
4099 gthf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gthf2");
4100 gehf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gehf2");
4101 lthf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lthf2");
4102 lehf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lehf2");
4104 eqsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqsf2");
4105 nesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nesf2");
4106 gtsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtsf2");
4107 gesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gesf2");
4108 ltsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltsf2");
4109 lesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lesf2");
4111 eqdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqdf2");
4112 nedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nedf2");
4113 gtdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtdf2");
4114 gedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gedf2");
4115 ltdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltdf2");
4116 ledf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ledf2");
4118 eqxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqxf2");
4119 nexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nexf2");
4120 gtxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtxf2");
4121 gexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gexf2");
4122 ltxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltxf2");
4123 lexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lexf2");
4125 eqtf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqtf2");
4126 netf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__netf2");
4127 gttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gttf2");
4128 getf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__getf2");
4129 lttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lttf2");
4130 letf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__letf2");
4132 /* Define library calls for quad FP instructions */
4133 #ifdef EQTF2_LIBCALL
4134 eqtf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, EQTF2_LIBCALL
);
4136 #ifdef NETF2_LIBCALL
4137 netf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, NETF2_LIBCALL
);
4139 #ifdef GTTF2_LIBCALL
4140 gttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, GTTF2_LIBCALL
);
4142 #ifdef GETF2_LIBCALL
4143 getf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, GETF2_LIBCALL
);
4145 #ifdef LTTF2_LIBCALL
4146 lttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, LTTF2_LIBCALL
);
4148 #ifdef LETF2_LIBCALL
4149 letf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, LETF2_LIBCALL
);
4152 floatsisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsisf");
4153 floatdisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdisf");
4154 floattisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattisf");
4156 floatsidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsidf");
4157 floatdidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdidf");
4158 floattidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattidf");
4160 floatsixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsixf");
4161 floatdixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdixf");
4162 floattixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattixf");
4164 floatsitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsitf");
4165 floatditf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatditf");
4166 floattitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattitf");
4168 fixsfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfsi");
4169 fixsfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfdi");
4170 fixsfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfti");
4172 fixdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfsi");
4173 fixdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfdi");
4174 fixdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfti");
4176 fixxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfsi");
4177 fixxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfdi");
4178 fixxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfti");
4180 fixtfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfsi");
4181 fixtfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfdi");
4182 fixtfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfti");
4184 fixunssfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfsi");
4185 fixunssfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfdi");
4186 fixunssfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfti");
4188 fixunsdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfsi");
4189 fixunsdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfdi");
4190 fixunsdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfti");
4192 fixunsxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfsi");
4193 fixunsxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfdi");
4194 fixunsxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfti");
4196 fixunstfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfsi");
4197 fixunstfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfdi");
4198 fixunstfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfti");
4200 /* Define library calls for quad FP instructions */
4201 #ifdef TRUNCTFSF2_LIBCALL
4202 trunctfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, TRUNCTFSF2_LIBCALL
);
4204 #ifdef TRUNCTFDF2_LIBCALL
4205 trunctfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, TRUNCTFDF2_LIBCALL
);
4207 #ifdef EXTENDSFTF2_LIBCALL
4208 extendsftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, EXTENDSFTF2_LIBCALL
);
4210 #ifdef EXTENDDFTF2_LIBCALL
4211 extenddftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, EXTENDDFTF2_LIBCALL
);
4213 #ifdef FLOATSITF2_LIBCALL
4214 floatsitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, FLOATSITF2_LIBCALL
);
4216 #ifdef FIX_TRUNCTFSI2_LIBCALL
4217 fixtfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, FIX_TRUNCTFSI2_LIBCALL
);
4219 #ifdef FIXUNS_TRUNCTFSI2_LIBCALL
4220 fixunstfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, FIXUNS_TRUNCTFSI2_LIBCALL
);
4223 #ifdef INIT_TARGET_OPTABS
4224 /* Allow the target to add more libcalls or rename some, etc. */
4231 /* SCO 3.2 apparently has a broken ldexp. */
4244 #endif /* BROKEN_LDEXP */