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_widen_optab
;
46 optab umul_widen_optab
;
69 optab movstrict_optab
;
80 optab ucmp_optab
; /* Used only for libcalls for unsigned comparisons. */
85 /* Tables of patterns for extending one integer mode to another. */
86 enum insn_code extendtab
[MAX_MACHINE_MODE
][MAX_MACHINE_MODE
][2];
88 /* Tables of patterns for converting between fixed and floating point. */
89 enum insn_code fixtab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
90 enum insn_code fixtrunctab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
91 enum insn_code floattab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
93 /* Contains the optab used for each rtx code. */
94 optab code_to_optab
[NUM_RTX_CODE
+ 1];
96 /* SYMBOL_REF rtx's for the library functions that are called
97 implicitly and not via optabs. */
99 rtx extendsfdf2_libfunc
;
100 rtx extendsfxf2_libfunc
;
101 rtx extendsftf2_libfunc
;
102 rtx extenddfxf2_libfunc
;
103 rtx extenddftf2_libfunc
;
105 rtx truncdfsf2_libfunc
;
106 rtx truncxfsf2_libfunc
;
107 rtx trunctfsf2_libfunc
;
108 rtx truncxfdf2_libfunc
;
109 rtx trunctfdf2_libfunc
;
146 rtx floatsisf_libfunc
;
147 rtx floatdisf_libfunc
;
148 rtx floattisf_libfunc
;
150 rtx floatsidf_libfunc
;
151 rtx floatdidf_libfunc
;
152 rtx floattidf_libfunc
;
154 rtx floatsixf_libfunc
;
155 rtx floatdixf_libfunc
;
156 rtx floattixf_libfunc
;
158 rtx floatsitf_libfunc
;
159 rtx floatditf_libfunc
;
160 rtx floattitf_libfunc
;
178 rtx fixunssfsi_libfunc
;
179 rtx fixunssfdi_libfunc
;
180 rtx fixunssfti_libfunc
;
182 rtx fixunsdfsi_libfunc
;
183 rtx fixunsdfdi_libfunc
;
184 rtx fixunsdfti_libfunc
;
186 rtx fixunsxfsi_libfunc
;
187 rtx fixunsxfdi_libfunc
;
188 rtx fixunsxfti_libfunc
;
190 rtx fixunstfsi_libfunc
;
191 rtx fixunstfdi_libfunc
;
192 rtx fixunstfti_libfunc
;
194 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
195 gives the gen_function to make a branch to test that condition. */
197 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
199 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
200 gives the insn code to make a store-condition insn
201 to test that condition. */
203 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
205 static int add_equal_note
PROTO((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
206 static rtx widen_operand
PROTO((rtx
, enum machine_mode
,
207 enum machine_mode
, int, int));
208 static enum insn_code can_fix_p
PROTO((enum machine_mode
, enum machine_mode
,
210 static enum insn_code can_float_p
PROTO((enum machine_mode
, enum machine_mode
,
212 static rtx ftruncify
PROTO((rtx
));
213 static optab init_optab
PROTO((enum rtx_code
));
214 static void init_libfuncs
PROTO((optab
, int, int, char *, int));
215 static void init_integral_libfuncs
PROTO((optab
, char *, int));
216 static void init_floating_libfuncs
PROTO((optab
, char *, int));
217 static void init_complex_libfuncs
PROTO((optab
, char *, int));
219 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
220 the result of operation CODE applied to OP0 (and OP1 if it is a binary
223 If the last insn does not set TARGET, don't do anything, but return 1.
225 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
226 don't add the REG_EQUAL note but return 0. Our caller can then try
227 again, ensuring that TARGET is not one of the operands. */
230 add_equal_note (seq
, target
, code
, op0
, op1
)
240 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
241 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
242 || GET_CODE (seq
) != SEQUENCE
243 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
244 || GET_CODE (target
) == ZERO_EXTRACT
245 || (! rtx_equal_p (SET_DEST (set
), target
)
246 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
248 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
249 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
253 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
254 besides the last insn. */
255 if (reg_overlap_mentioned_p (target
, op0
)
256 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
257 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
258 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
261 if (GET_RTX_CLASS (code
) == '1')
262 note
= gen_rtx (code
, GET_MODE (target
), copy_rtx (op0
));
264 note
= gen_rtx (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
266 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))
267 = gen_rtx (EXPR_LIST
, REG_EQUAL
, note
,
268 REG_NOTES (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1)));
273 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
274 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
275 not actually do a sign-extend or zero-extend, but can leave the
276 higher-order bits of the result rtx undefined, for example, in the case
277 of logical operations, but not right shifts. */
280 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
282 enum machine_mode mode
, oldmode
;
288 /* If we must extend do so. If OP is either a constant or a SUBREG
289 for a promoted object, also extend since it will be more efficient to
292 || GET_MODE (op
) == VOIDmode
293 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
294 return convert_modes (mode
, oldmode
, op
, unsignedp
);
296 /* If MODE is no wider than a single word, we return a paradoxical
298 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
299 return gen_rtx (SUBREG
, mode
, force_reg (GET_MODE (op
), op
), 0);
301 /* Otherwise, get an object of MODE, clobber it, and set the low-order
304 result
= gen_reg_rtx (mode
);
305 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, result
));
306 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
310 /* Generate code to perform an operation specified by BINOPTAB
311 on operands OP0 and OP1, with result having machine-mode MODE.
313 UNSIGNEDP is for the case where we have to widen the operands
314 to perform the operation. It says to use zero-extension.
316 If TARGET is nonzero, the value
317 is generated there, if it is convenient to do so.
318 In all cases an rtx is returned for the locus of the value;
319 this may or may not be TARGET. */
322 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
323 enum machine_mode mode
;
328 enum optab_methods methods
;
330 enum optab_methods next_methods
331 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
332 ? OPTAB_WIDEN
: methods
);
333 enum mode_class
class;
334 enum machine_mode wider_mode
;
336 int commutative_op
= 0;
337 int shift_op
= (binoptab
->code
== ASHIFT
338 || binoptab
->code
== ASHIFTRT
339 || binoptab
->code
== LSHIFTRT
340 || binoptab
->code
== ROTATE
341 || binoptab
->code
== ROTATERT
);
342 rtx entry_last
= get_last_insn ();
345 class = GET_MODE_CLASS (mode
);
347 op0
= protect_from_queue (op0
, 0);
348 op1
= protect_from_queue (op1
, 0);
350 target
= protect_from_queue (target
, 1);
354 op0
= force_not_mem (op0
);
355 op1
= force_not_mem (op1
);
358 /* If subtracting an integer constant, convert this into an addition of
359 the negated constant. */
361 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
363 op1
= negate_rtx (mode
, op1
);
364 binoptab
= add_optab
;
367 /* If we are inside an appropriately-short loop and one operand is an
368 expensive constant, force it into a register. */
369 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
370 && rtx_cost (op0
, binoptab
->code
) > 2)
371 op0
= force_reg (mode
, op0
);
373 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
374 && rtx_cost (op1
, binoptab
->code
) > 2)
375 op1
= force_reg (shift_op
? word_mode
: mode
, op1
);
377 /* Record where to delete back to if we backtrack. */
378 last
= get_last_insn ();
380 /* If operation is commutative,
381 try to make the first operand a register.
382 Even better, try to make it the same as the target.
383 Also try to make the last operand a constant. */
384 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
385 || binoptab
== smul_widen_optab
386 || binoptab
== umul_widen_optab
)
390 if (((target
== 0 || GET_CODE (target
) == REG
)
391 ? ((GET_CODE (op1
) == REG
392 && GET_CODE (op0
) != REG
)
394 : rtx_equal_p (op1
, target
))
395 || GET_CODE (op0
) == CONST_INT
)
403 /* If we can do it with a three-operand insn, do so. */
405 if (methods
!= OPTAB_MUST_WIDEN
406 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
408 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
409 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
410 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
412 rtx xop0
= op0
, xop1
= op1
;
417 temp
= gen_reg_rtx (mode
);
419 /* If it is a commutative operator and the modes would match
420 if we would swap the operands, we can save the conversions. */
423 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
424 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
428 tmp
= op0
; op0
= op1
; op1
= tmp
;
429 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
433 /* In case the insn wants input operands in modes different from
434 the result, convert the operands. */
436 if (GET_MODE (op0
) != VOIDmode
437 && GET_MODE (op0
) != mode0
)
438 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
440 if (GET_MODE (xop1
) != VOIDmode
441 && GET_MODE (xop1
) != mode1
)
442 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
444 /* Now, if insn's predicates don't allow our operands, put them into
447 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
448 xop0
= copy_to_mode_reg (mode0
, xop0
);
450 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
451 xop1
= copy_to_mode_reg (mode1
, xop1
);
453 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
454 temp
= gen_reg_rtx (mode
);
456 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
459 /* If PAT is a multi-insn sequence, try to add an appropriate
460 REG_EQUAL note to it. If we can't because TEMP conflicts with an
461 operand, call ourselves again, this time without a target. */
462 if (GET_CODE (pat
) == SEQUENCE
463 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
465 delete_insns_since (last
);
466 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
474 delete_insns_since (last
);
477 /* If this is a multiply, see if we can do a widening operation that
478 takes operands of this mode and makes a wider mode. */
480 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
481 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
482 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
483 != CODE_FOR_nothing
))
485 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
486 unsignedp
? umul_widen_optab
: smul_widen_optab
,
487 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
491 if (GET_MODE_CLASS (mode
) == MODE_INT
)
492 return gen_lowpart (mode
, temp
);
494 return convert_to_mode (mode
, temp
, unsignedp
);
498 /* Look for a wider mode of the same class for which we think we
499 can open-code the operation. Check for a widening multiply at the
500 wider mode as well. */
502 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
503 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
504 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
505 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
507 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
508 || (binoptab
== smul_optab
509 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
510 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
511 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
512 != CODE_FOR_nothing
)))
514 rtx xop0
= op0
, xop1
= op1
;
517 /* For certain integer operations, we need not actually extend
518 the narrow operands, as long as we will truncate
519 the results to the same narrowness. */
521 if ((binoptab
== ior_optab
|| binoptab
== and_optab
522 || binoptab
== xor_optab
523 || binoptab
== add_optab
|| binoptab
== sub_optab
524 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
525 && class == MODE_INT
)
528 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
530 /* The second operand of a shift must always be extended. */
531 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
532 no_extend
&& binoptab
!= ashl_optab
);
534 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
535 unsignedp
, OPTAB_DIRECT
);
538 if (class != MODE_INT
)
541 target
= gen_reg_rtx (mode
);
542 convert_move (target
, temp
, 0);
546 return gen_lowpart (mode
, temp
);
549 delete_insns_since (last
);
553 /* These can be done a word at a time. */
554 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
556 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
557 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
563 /* If TARGET is the same as one of the operands, the REG_EQUAL note
564 won't be accurate, so use a new target. */
565 if (target
== 0 || target
== op0
|| target
== op1
)
566 target
= gen_reg_rtx (mode
);
570 /* Do the actual arithmetic. */
571 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
573 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
574 rtx x
= expand_binop (word_mode
, binoptab
,
575 operand_subword_force (op0
, i
, mode
),
576 operand_subword_force (op1
, i
, mode
),
577 target_piece
, unsignedp
, next_methods
);
582 if (target_piece
!= x
)
583 emit_move_insn (target_piece
, x
);
586 insns
= get_insns ();
589 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
591 if (binoptab
->code
!= UNKNOWN
)
593 = gen_rtx (binoptab
->code
, mode
, copy_rtx (op0
), copy_rtx (op1
));
597 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
602 /* Synthesize double word shifts from single word shifts. */
603 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
604 || binoptab
== ashr_optab
)
606 && GET_CODE (op1
) == CONST_INT
607 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
608 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
609 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
610 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
612 rtx insns
, inter
, equiv_value
;
613 rtx into_target
, outof_target
;
614 rtx into_input
, outof_input
;
615 int shift_count
, left_shift
, outof_word
;
617 /* If TARGET is the same as one of the operands, the REG_EQUAL note
618 won't be accurate, so use a new target. */
619 if (target
== 0 || target
== op0
|| target
== op1
)
620 target
= gen_reg_rtx (mode
);
624 shift_count
= INTVAL (op1
);
626 /* OUTOF_* is the word we are shifting bits away from, and
627 INTO_* is the word that we are shifting bits towards, thus
628 they differ depending on the direction of the shift and
631 left_shift
= binoptab
== ashl_optab
;
632 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
634 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
635 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
637 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
638 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
640 if (shift_count
>= BITS_PER_WORD
)
642 inter
= expand_binop (word_mode
, binoptab
,
644 GEN_INT (shift_count
- BITS_PER_WORD
),
645 into_target
, unsignedp
, next_methods
);
647 if (inter
!= 0 && inter
!= into_target
)
648 emit_move_insn (into_target
, inter
);
650 /* For a signed right shift, we must fill the word we are shifting
651 out of with copies of the sign bit. Otherwise it is zeroed. */
652 if (inter
!= 0 && binoptab
!= ashr_optab
)
653 inter
= CONST0_RTX (word_mode
);
655 inter
= expand_binop (word_mode
, binoptab
,
657 GEN_INT (BITS_PER_WORD
- 1),
658 outof_target
, unsignedp
, next_methods
);
660 if (inter
!= 0 && inter
!= outof_target
)
661 emit_move_insn (outof_target
, inter
);
666 optab reverse_unsigned_shift
, unsigned_shift
;
668 /* For a shift of less then BITS_PER_WORD, to compute the carry,
669 we must do a logical shift in the opposite direction of the
672 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
674 /* For a shift of less than BITS_PER_WORD, to compute the word
675 shifted towards, we need to unsigned shift the orig value of
678 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
680 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
682 GEN_INT (BITS_PER_WORD
- shift_count
),
683 0, unsignedp
, next_methods
);
688 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
689 op1
, outof_target
, unsignedp
, next_methods
);
691 if (inter
!= 0 && inter
!= outof_target
)
692 emit_move_insn (outof_target
, inter
);
695 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
696 op1
, 0, unsignedp
, next_methods
);
699 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
700 into_target
, unsignedp
, next_methods
);
702 if (inter
!= 0 && inter
!= into_target
)
703 emit_move_insn (into_target
, inter
);
706 insns
= get_insns ();
711 if (binoptab
->code
!= UNKNOWN
)
712 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
716 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
721 /* Synthesize double word rotates from single word shifts. */
722 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
724 && GET_CODE (op1
) == CONST_INT
725 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
726 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
727 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
729 rtx insns
, equiv_value
;
730 rtx into_target
, outof_target
;
731 rtx into_input
, outof_input
;
733 int shift_count
, left_shift
, outof_word
;
735 /* If TARGET is the same as one of the operands, the REG_EQUAL note
736 won't be accurate, so use a new target. */
737 if (target
== 0 || target
== op0
|| target
== op1
)
738 target
= gen_reg_rtx (mode
);
742 shift_count
= INTVAL (op1
);
744 /* OUTOF_* is the word we are shifting bits away from, and
745 INTO_* is the word that we are shifting bits towards, thus
746 they differ depending on the direction of the shift and
749 left_shift
= (binoptab
== rotl_optab
);
750 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
752 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
753 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
755 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
756 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
758 if (shift_count
== BITS_PER_WORD
)
760 /* This is just a word swap. */
761 emit_move_insn (outof_target
, into_input
);
762 emit_move_insn (into_target
, outof_input
);
767 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
768 rtx first_shift_count
, second_shift_count
;
769 optab reverse_unsigned_shift
, unsigned_shift
;
771 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
772 ? lshr_optab
: ashl_optab
);
774 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
775 ? ashl_optab
: lshr_optab
);
777 if (shift_count
> BITS_PER_WORD
)
779 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
780 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
784 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
785 second_shift_count
= GEN_INT (shift_count
);
788 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
789 outof_input
, first_shift_count
,
790 NULL_RTX
, unsignedp
, next_methods
);
791 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
792 into_input
, second_shift_count
,
793 into_target
, unsignedp
, next_methods
);
795 if (into_temp1
!= 0 && into_temp2
!= 0)
796 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
797 into_target
, unsignedp
, next_methods
);
801 if (inter
!= 0 && inter
!= into_target
)
802 emit_move_insn (into_target
, inter
);
804 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
805 into_input
, first_shift_count
,
806 NULL_RTX
, unsignedp
, next_methods
);
807 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
808 outof_input
, second_shift_count
,
809 outof_target
, unsignedp
, next_methods
);
811 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
812 inter
= expand_binop (word_mode
, ior_optab
,
813 outof_temp1
, outof_temp2
,
814 outof_target
, unsignedp
, next_methods
);
816 if (inter
!= 0 && inter
!= outof_target
)
817 emit_move_insn (outof_target
, inter
);
820 insns
= get_insns ();
825 if (binoptab
->code
!= UNKNOWN
)
826 equiv_value
= gen_rtx (binoptab
->code
, mode
, op0
, op1
);
830 /* We can't make this a no conflict block if this is a word swap,
831 because the word swap case fails if the input and output values
832 are in the same register. */
833 if (shift_count
!= BITS_PER_WORD
)
834 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
843 /* These can be done a word at a time by propagating carries. */
844 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
846 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
847 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
850 rtx carry_tmp
= gen_reg_rtx (word_mode
);
851 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
852 int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
853 rtx carry_in
, carry_out
;
856 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
857 value is one of those, use it. Otherwise, use 1 since it is the
858 one easiest to get. */
859 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
860 int normalizep
= STORE_FLAG_VALUE
;
865 /* Prepare the operands. */
866 xop0
= force_reg (mode
, op0
);
867 xop1
= force_reg (mode
, op1
);
869 if (target
== 0 || GET_CODE (target
) != REG
870 || target
== xop0
|| target
== xop1
)
871 target
= gen_reg_rtx (mode
);
873 /* Indicate for flow that the entire target reg is being set. */
874 if (GET_CODE (target
) == REG
)
875 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, target
));
877 /* Do the actual arithmetic. */
878 for (i
= 0; i
< nwords
; i
++)
880 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
881 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
882 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
883 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
886 /* Main add/subtract of the input operands. */
887 x
= expand_binop (word_mode
, binoptab
,
888 op0_piece
, op1_piece
,
889 target_piece
, unsignedp
, next_methods
);
895 /* Store carry from main add/subtract. */
896 carry_out
= gen_reg_rtx (word_mode
);
897 carry_out
= emit_store_flag (carry_out
,
898 binoptab
== add_optab
? LTU
: GTU
,
900 word_mode
, 1, normalizep
);
907 /* Add/subtract previous carry to main result. */
908 x
= expand_binop (word_mode
,
909 normalizep
== 1 ? binoptab
: otheroptab
,
911 target_piece
, 1, next_methods
);
914 else if (target_piece
!= x
)
915 emit_move_insn (target_piece
, x
);
919 /* THIS CODE HAS NOT BEEN TESTED. */
920 /* Get out carry from adding/subtracting carry in. */
921 carry_tmp
= emit_store_flag (carry_tmp
,
922 binoptab
== add_optab
925 word_mode
, 1, normalizep
);
927 /* Logical-ior the two poss. carry together. */
928 carry_out
= expand_binop (word_mode
, ior_optab
,
929 carry_out
, carry_tmp
,
930 carry_out
, 0, next_methods
);
936 carry_in
= carry_out
;
939 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
941 rtx temp
= emit_move_insn (target
, target
);
943 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
944 gen_rtx (binoptab
->code
, mode
,
951 delete_insns_since (last
);
954 /* If we want to multiply two two-word values and have normal and widening
955 multiplies of single-word values, we can do this with three smaller
956 multiplications. Note that we do not make a REG_NO_CONFLICT block here
957 because we are not operating on one word at a time.
959 The multiplication proceeds as follows:
960 _______________________
961 [__op0_high_|__op0_low__]
962 _______________________
963 * [__op1_high_|__op1_low__]
964 _______________________________________________
965 _______________________
966 (1) [__op0_low__*__op1_low__]
967 _______________________
968 (2a) [__op0_low__*__op1_high_]
969 _______________________
970 (2b) [__op0_high_*__op1_low__]
971 _______________________
972 (3) [__op0_high_*__op1_high_]
975 This gives a 4-word result. Since we are only interested in the
976 lower 2 words, partial result (3) and the upper words of (2a) and
977 (2b) don't need to be calculated. Hence (2a) and (2b) can be
978 calculated using non-widening multiplication.
980 (1), however, needs to be calculated with an unsigned widening
981 multiplication. If this operation is not directly supported we
982 try using a signed widening multiplication and adjust the result.
983 This adjustment works as follows:
985 If both operands are positive then no adjustment is needed.
987 If the operands have different signs, for example op0_low < 0 and
988 op1_low >= 0, the instruction treats the most significant bit of
989 op0_low as a sign bit instead of a bit with significance
990 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
991 with 2**BITS_PER_WORD - op0_low, and two's complements the
992 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
995 Similarly, if both operands are negative, we need to add
996 (op0_low + op1_low) * 2**BITS_PER_WORD.
998 We use a trick to adjust quickly. We logically shift op0_low right
999 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1000 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1001 logical shift exists, we do an arithmetic right shift and subtract
1004 if (binoptab
== smul_optab
1005 && class == MODE_INT
1006 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1007 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1008 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1009 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1010 != CODE_FOR_nothing
)
1011 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1012 != CODE_FOR_nothing
)))
1014 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1015 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1016 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1017 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1018 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1019 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1024 /* If the target is the same as one of the inputs, don't use it. This
1025 prevents problems with the REG_EQUAL note. */
1026 if (target
== op0
|| target
== op1
)
1029 /* Multiply the two lower words to get a double-word product.
1030 If unsigned widening multiplication is available, use that;
1031 otherwise use the signed form and compensate. */
1033 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1035 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1036 target
, 1, OPTAB_DIRECT
);
1038 /* If we didn't succeed, delete everything we did so far. */
1040 delete_insns_since (last
);
1042 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1046 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1047 != CODE_FOR_nothing
)
1049 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1050 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1051 target
, 1, OPTAB_DIRECT
);
1052 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1053 NULL_RTX
, 1, next_methods
);
1055 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1056 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1059 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1060 NULL_RTX
, 0, next_methods
);
1062 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1063 op0_xhigh
, op0_xhigh
, 0,
1067 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1068 NULL_RTX
, 1, next_methods
);
1070 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1071 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1074 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1075 NULL_RTX
, 0, next_methods
);
1077 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1078 op1_xhigh
, op1_xhigh
, 0,
1083 /* If we have been able to directly compute the product of the
1084 low-order words of the operands and perform any required adjustments
1085 of the operands, we proceed by trying two more multiplications
1086 and then computing the appropriate sum.
1088 We have checked above that the required addition is provided.
1089 Full-word addition will normally always succeed, especially if
1090 it is provided at all, so we don't worry about its failure. The
1091 multiplication may well fail, however, so we do handle that. */
1093 if (product
&& op0_xhigh
&& op1_xhigh
)
1095 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1096 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1097 NULL_RTX
, 0, OPTAB_DIRECT
);
1100 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1101 product_high
, 0, next_methods
);
1103 if (temp
!= 0 && temp
!= product_high
)
1104 emit_move_insn (product_high
, temp
);
1107 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1108 NULL_RTX
, 0, OPTAB_DIRECT
);
1111 temp
= expand_binop (word_mode
, add_optab
, temp
,
1112 product_high
, product_high
,
1115 if (temp
!= 0 && temp
!= product_high
)
1116 emit_move_insn (product_high
, temp
);
1120 temp
= emit_move_insn (product
, product
);
1121 REG_NOTES (temp
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
1122 gen_rtx (MULT
, mode
, copy_rtx (op0
),
1130 /* If we get here, we couldn't do it for some reason even though we
1131 originally thought we could. Delete anything we've emitted in
1134 delete_insns_since (last
);
1137 /* We need to open-code the complex type operations: '+, -, * and /' */
1139 /* At this point we allow operations between two similar complex
1140 numbers, and also if one of the operands is not a complex number
1141 but rather of MODE_FLOAT or MODE_INT. However, the caller
1142 must make sure that the MODE of the non-complex operand matches
1143 the SUBMODE of the complex operand. */
1145 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1147 rtx real0
= 0, imag0
= 0;
1148 rtx real1
= 0, imag1
= 0;
1149 rtx realr
, imagr
, res
;
1154 /* Find the correct mode for the real and imaginary parts */
1155 enum machine_mode submode
1156 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1157 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1160 if (submode
== BLKmode
)
1164 target
= gen_reg_rtx (mode
);
1168 realr
= gen_realpart (submode
, target
);
1169 imagr
= gen_imagpart (submode
, target
);
1171 if (GET_MODE (op0
) == mode
)
1173 real0
= gen_realpart (submode
, op0
);
1174 imag0
= gen_imagpart (submode
, op0
);
1179 if (GET_MODE (op1
) == mode
)
1181 real1
= gen_realpart (submode
, op1
);
1182 imag1
= gen_imagpart (submode
, op1
);
1187 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1190 switch (binoptab
->code
)
1193 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1195 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1196 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1197 realr
, unsignedp
, methods
);
1201 else if (res
!= realr
)
1202 emit_move_insn (realr
, res
);
1205 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1206 imagr
, unsignedp
, methods
);
1209 else if (binoptab
->code
== MINUS
)
1210 res
= expand_unop (submode
, neg_optab
, imag1
, imagr
, unsignedp
);
1216 else if (res
!= imagr
)
1217 emit_move_insn (imagr
, res
);
1223 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1229 /* Don't fetch these from memory more than once. */
1230 real0
= force_reg (submode
, real0
);
1231 real1
= force_reg (submode
, real1
);
1232 imag0
= force_reg (submode
, imag0
);
1233 imag1
= force_reg (submode
, imag1
);
1235 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1236 unsignedp
, methods
);
1238 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1239 unsignedp
, methods
);
1241 if (temp1
== 0 || temp2
== 0)
1244 res
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1245 realr
, unsignedp
, methods
);
1249 else if (res
!= realr
)
1250 emit_move_insn (realr
, res
);
1252 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1253 NULL_RTX
, unsignedp
, methods
);
1255 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1256 NULL_RTX
, unsignedp
, methods
);
1258 if (temp1
== 0 || temp2
== 0)
1259 res
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1260 imagr
, unsignedp
, methods
);
1264 else if (res
!= imagr
)
1265 emit_move_insn (imagr
, res
);
1271 /* Don't fetch these from memory more than once. */
1272 real0
= force_reg (submode
, real0
);
1273 real1
= force_reg (submode
, real1
);
1275 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1276 realr
, unsignedp
, methods
);
1279 else if (res
!= realr
)
1280 emit_move_insn (realr
, res
);
1283 res
= expand_binop (submode
, binoptab
,
1284 real1
, imag0
, imagr
, unsignedp
, methods
);
1286 res
= expand_binop (submode
, binoptab
,
1287 real0
, imag1
, imagr
, unsignedp
, methods
);
1291 else if (res
!= imagr
)
1292 emit_move_insn (imagr
, res
);
1299 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1303 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1305 /* Don't fetch these from memory more than once. */
1306 real1
= force_reg (submode
, real1
);
1308 /* Simply divide the real and imaginary parts by `c' */
1309 if (class == MODE_COMPLEX_FLOAT
)
1310 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1311 realr
, unsignedp
, methods
);
1313 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1314 real0
, real1
, realr
, unsignedp
);
1318 else if (res
!= realr
)
1319 emit_move_insn (realr
, res
);
1321 if (class == MODE_COMPLEX_FLOAT
)
1322 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1323 imagr
, unsignedp
, methods
);
1325 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1326 imag0
, real1
, imagr
, unsignedp
);
1330 else if (res
!= imagr
)
1331 emit_move_insn (imagr
, res
);
1337 /* Divisor is of complex type:
1344 /* Don't fetch these from memory more than once. */
1345 real0
= force_reg (submode
, real0
);
1346 real1
= force_reg (submode
, real1
);
1349 imag0
= force_reg (submode
, imag0
);
1351 imag1
= force_reg (submode
, imag1
);
1353 /* Divisor: c*c + d*d */
1354 temp1
= expand_binop (submode
, smul_optab
, real1
, real1
,
1355 NULL_RTX
, unsignedp
, methods
);
1357 temp2
= expand_binop (submode
, smul_optab
, imag1
, imag1
,
1358 NULL_RTX
, unsignedp
, methods
);
1360 if (temp1
== 0 || temp2
== 0)
1363 divisor
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1364 NULL_RTX
, unsignedp
, methods
);
1370 /* ((a)(c-id))/divisor */
1371 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1373 /* Calculate the dividend */
1374 real_t
= expand_binop (submode
, smul_optab
, real0
, real1
,
1375 NULL_RTX
, unsignedp
, methods
);
1377 imag_t
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1378 NULL_RTX
, unsignedp
, methods
);
1380 if (real_t
== 0 || imag_t
== 0)
1383 imag_t
= expand_unop (submode
, neg_optab
, imag_t
,
1384 NULL_RTX
, unsignedp
);
1388 /* ((a+ib)(c-id))/divider */
1389 /* Calculate the dividend */
1390 temp1
= expand_binop (submode
, smul_optab
, real0
, real1
,
1391 NULL_RTX
, unsignedp
, methods
);
1393 temp2
= expand_binop (submode
, smul_optab
, imag0
, imag1
,
1394 NULL_RTX
, unsignedp
, methods
);
1396 if (temp1
== 0 || temp2
== 0)
1399 real_t
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1400 NULL_RTX
, unsignedp
, methods
);
1402 temp1
= expand_binop (submode
, smul_optab
, imag0
, real1
,
1403 NULL_RTX
, unsignedp
, methods
);
1405 temp2
= expand_binop (submode
, smul_optab
, real0
, imag1
,
1406 NULL_RTX
, unsignedp
, methods
);
1408 if (temp1
== 0 || temp2
== 0)
1409 imag_t
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1410 NULL_RTX
, unsignedp
, methods
);
1412 if (real_t
== 0 || imag_t
== 0)
1416 if (class == MODE_COMPLEX_FLOAT
)
1417 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
1418 realr
, unsignedp
, methods
);
1420 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1421 real_t
, divisor
, realr
, unsignedp
);
1425 else if (res
!= realr
)
1426 emit_move_insn (realr
, res
);
1428 if (class == MODE_COMPLEX_FLOAT
)
1429 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
1430 imagr
, unsignedp
, methods
);
1432 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1433 imag_t
, divisor
, imagr
, unsignedp
);
1437 else if (res
!= imagr
)
1438 emit_move_insn (imagr
, res
);
1453 if (binoptab
->code
!= UNKNOWN
)
1455 = gen_rtx (binoptab
->code
, mode
, copy_rtx (op0
), copy_rtx (op1
));
1459 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1465 /* It can't be open-coded in this mode.
1466 Use a library call if one is available and caller says that's ok. */
1468 if (binoptab
->handlers
[(int) mode
].libfunc
1469 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1472 rtx funexp
= binoptab
->handlers
[(int) mode
].libfunc
;
1474 enum machine_mode op1_mode
= mode
;
1481 op1_mode
= word_mode
;
1482 /* Specify unsigned here,
1483 since negative shift counts are meaningless. */
1484 op1x
= convert_to_mode (word_mode
, op1
, 1);
1487 /* Pass 1 for NO_QUEUE so we don't lose any increments
1488 if the libcall is cse'd or moved. */
1489 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1490 NULL_RTX
, 1, mode
, 2,
1491 op0
, mode
, op1x
, op1_mode
);
1493 insns
= get_insns ();
1496 target
= gen_reg_rtx (mode
);
1497 emit_libcall_block (insns
, target
, value
,
1498 gen_rtx (binoptab
->code
, mode
, op0
, op1
));
1503 delete_insns_since (last
);
1505 /* It can't be done in this mode. Can we do it in a wider mode? */
1507 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1508 || methods
== OPTAB_MUST_WIDEN
))
1510 /* Caller says, don't even try. */
1511 delete_insns_since (entry_last
);
1515 /* Compute the value of METHODS to pass to recursive calls.
1516 Don't allow widening to be tried recursively. */
1518 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1520 /* Look for a wider mode of the same class for which it appears we can do
1523 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1525 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1526 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1528 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1529 != CODE_FOR_nothing
)
1530 || (methods
== OPTAB_LIB
1531 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1533 rtx xop0
= op0
, xop1
= op1
;
1536 /* For certain integer operations, we need not actually extend
1537 the narrow operands, as long as we will truncate
1538 the results to the same narrowness. */
1540 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1541 || binoptab
== xor_optab
1542 || binoptab
== add_optab
|| binoptab
== sub_optab
1543 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1544 && class == MODE_INT
)
1547 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1548 unsignedp
, no_extend
);
1550 /* The second operand of a shift must always be extended. */
1551 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1552 no_extend
&& binoptab
!= ashl_optab
);
1554 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1555 unsignedp
, methods
);
1558 if (class != MODE_INT
)
1561 target
= gen_reg_rtx (mode
);
1562 convert_move (target
, temp
, 0);
1566 return gen_lowpart (mode
, temp
);
1569 delete_insns_since (last
);
1574 delete_insns_since (entry_last
);
1578 /* Expand a binary operator which has both signed and unsigned forms.
1579 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1582 If we widen unsigned operands, we may use a signed wider operation instead
1583 of an unsigned wider operation, since the result would be the same. */
1586 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1587 enum machine_mode mode
;
1588 optab uoptab
, soptab
;
1589 rtx op0
, op1
, target
;
1591 enum optab_methods methods
;
1594 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1595 struct optab wide_soptab
;
1597 /* Do it without widening, if possible. */
1598 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1599 unsignedp
, OPTAB_DIRECT
);
1600 if (temp
|| methods
== OPTAB_DIRECT
)
1603 /* Try widening to a signed int. Make a fake signed optab that
1604 hides any signed insn for direct use. */
1605 wide_soptab
= *soptab
;
1606 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1607 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1609 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1610 unsignedp
, OPTAB_WIDEN
);
1612 /* For unsigned operands, try widening to an unsigned int. */
1613 if (temp
== 0 && unsignedp
)
1614 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1615 unsignedp
, OPTAB_WIDEN
);
1616 if (temp
|| methods
== OPTAB_WIDEN
)
1619 /* Use the right width lib call if that exists. */
1620 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1621 if (temp
|| methods
== OPTAB_LIB
)
1624 /* Must widen and use a lib call, use either signed or unsigned. */
1625 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1626 unsignedp
, methods
);
1630 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1631 unsignedp
, methods
);
1635 /* Generate code to perform an operation specified by BINOPTAB
1636 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1637 We assume that the order of the operands for the instruction
1638 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1639 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1641 Either TARG0 or TARG1 may be zero, but what that means is that
1642 that result is not actually wanted. We will generate it into
1643 a dummy pseudo-reg and discard it. They may not both be zero.
1645 Returns 1 if this operation can be performed; 0 if not. */
1648 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1654 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1655 enum mode_class
class;
1656 enum machine_mode wider_mode
;
1657 rtx entry_last
= get_last_insn ();
1660 class = GET_MODE_CLASS (mode
);
1662 op0
= protect_from_queue (op0
, 0);
1663 op1
= protect_from_queue (op1
, 0);
1667 op0
= force_not_mem (op0
);
1668 op1
= force_not_mem (op1
);
1671 /* If we are inside an appropriately-short loop and one operand is an
1672 expensive constant, force it into a register. */
1673 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1674 && rtx_cost (op0
, binoptab
->code
) > 2)
1675 op0
= force_reg (mode
, op0
);
1677 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1678 && rtx_cost (op1
, binoptab
->code
) > 2)
1679 op1
= force_reg (mode
, op1
);
1682 targ0
= protect_from_queue (targ0
, 1);
1684 targ0
= gen_reg_rtx (mode
);
1686 targ1
= protect_from_queue (targ1
, 1);
1688 targ1
= gen_reg_rtx (mode
);
1690 /* Record where to go back to if we fail. */
1691 last
= get_last_insn ();
1693 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1695 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1696 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1697 enum machine_mode mode1
= insn_operand_mode
[icode
][2];
1699 rtx xop0
= op0
, xop1
= op1
;
1701 /* In case this insn wants input operands in modes different from the
1702 result, convert the operands. */
1703 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1704 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1706 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1707 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1709 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1710 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1711 xop0
= copy_to_mode_reg (mode0
, xop0
);
1713 if (! (*insn_operand_predicate
[icode
][2]) (xop1
, mode1
))
1714 xop1
= copy_to_mode_reg (mode1
, xop1
);
1716 /* We could handle this, but we should always be called with a pseudo
1717 for our targets and all insns should take them as outputs. */
1718 if (! (*insn_operand_predicate
[icode
][0]) (targ0
, mode
)
1719 || ! (*insn_operand_predicate
[icode
][3]) (targ1
, mode
))
1722 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1729 delete_insns_since (last
);
1732 /* It can't be done in this mode. Can we do it in a wider mode? */
1734 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1736 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1737 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1739 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1740 != CODE_FOR_nothing
)
1742 register rtx t0
= gen_reg_rtx (wider_mode
);
1743 register rtx t1
= gen_reg_rtx (wider_mode
);
1745 if (expand_twoval_binop (binoptab
,
1746 convert_modes (wider_mode
, mode
, op0
,
1748 convert_modes (wider_mode
, mode
, op1
,
1752 convert_move (targ0
, t0
, unsignedp
);
1753 convert_move (targ1
, t1
, unsignedp
);
1757 delete_insns_since (last
);
1762 delete_insns_since (entry_last
);
1766 /* Generate code to perform an operation specified by UNOPTAB
1767 on operand OP0, with result having machine-mode MODE.
1769 UNSIGNEDP is for the case where we have to widen the operands
1770 to perform the operation. It says to use zero-extension.
1772 If TARGET is nonzero, the value
1773 is generated there, if it is convenient to do so.
1774 In all cases an rtx is returned for the locus of the value;
1775 this may or may not be TARGET. */
1778 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
1779 enum machine_mode mode
;
1785 enum mode_class
class;
1786 enum machine_mode wider_mode
;
1788 rtx last
= get_last_insn ();
1791 class = GET_MODE_CLASS (mode
);
1793 op0
= protect_from_queue (op0
, 0);
1797 op0
= force_not_mem (op0
);
1801 target
= protect_from_queue (target
, 1);
1803 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1805 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
1806 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
1812 temp
= gen_reg_rtx (mode
);
1814 if (GET_MODE (xop0
) != VOIDmode
1815 && GET_MODE (xop0
) != mode0
)
1816 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1818 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1820 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
1821 xop0
= copy_to_mode_reg (mode0
, xop0
);
1823 if (! (*insn_operand_predicate
[icode
][0]) (temp
, mode
))
1824 temp
= gen_reg_rtx (mode
);
1826 pat
= GEN_FCN (icode
) (temp
, xop0
);
1829 if (GET_CODE (pat
) == SEQUENCE
1830 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
1832 delete_insns_since (last
);
1833 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
1841 delete_insns_since (last
);
1844 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1846 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1847 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1848 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1850 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
1854 /* For certain operations, we need not actually extend
1855 the narrow operand, as long as we will truncate the
1856 results to the same narrowness. */
1858 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
1859 (unoptab
== neg_optab
1860 || unoptab
== one_cmpl_optab
)
1861 && class == MODE_INT
);
1863 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
1868 if (class != MODE_INT
)
1871 target
= gen_reg_rtx (mode
);
1872 convert_move (target
, temp
, 0);
1876 return gen_lowpart (mode
, temp
);
1879 delete_insns_since (last
);
1883 /* These can be done a word at a time. */
1884 if (unoptab
== one_cmpl_optab
1885 && class == MODE_INT
1886 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
1887 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1892 if (target
== 0 || target
== op0
)
1893 target
= gen_reg_rtx (mode
);
1897 /* Do the actual arithmetic. */
1898 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
1900 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
1901 rtx x
= expand_unop (word_mode
, unoptab
,
1902 operand_subword_force (op0
, i
, mode
),
1903 target_piece
, unsignedp
);
1904 if (target_piece
!= x
)
1905 emit_move_insn (target_piece
, x
);
1908 insns
= get_insns ();
1911 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
1912 gen_rtx (unoptab
->code
, mode
, copy_rtx (op0
)));
1916 /* Open-code the complex negation operation. */
1917 else if (unoptab
== neg_optab
1918 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
1924 /* Find the correct mode for the real and imaginary parts */
1925 enum machine_mode submode
1926 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1927 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1930 if (submode
== BLKmode
)
1934 target
= gen_reg_rtx (mode
);
1938 target_piece
= gen_imagpart (submode
, target
);
1939 x
= expand_unop (submode
, unoptab
,
1940 gen_imagpart (submode
, op0
),
1941 target_piece
, unsignedp
);
1942 if (target_piece
!= x
)
1943 emit_move_insn (target_piece
, x
);
1945 target_piece
= gen_realpart (submode
, target
);
1946 x
= expand_unop (submode
, unoptab
,
1947 gen_realpart (submode
, op0
),
1948 target_piece
, unsignedp
);
1949 if (target_piece
!= x
)
1950 emit_move_insn (target_piece
, x
);
1955 emit_no_conflict_block (seq
, target
, op0
, 0,
1956 gen_rtx (unoptab
->code
, mode
, copy_rtx (op0
)));
1960 /* Now try a library call in this mode. */
1961 if (unoptab
->handlers
[(int) mode
].libfunc
)
1964 rtx funexp
= unoptab
->handlers
[(int) mode
].libfunc
;
1969 /* Pass 1 for NO_QUEUE so we don't lose any increments
1970 if the libcall is cse'd or moved. */
1971 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
1972 NULL_RTX
, 1, mode
, 1, op0
, mode
);
1973 insns
= get_insns ();
1976 target
= gen_reg_rtx (mode
);
1977 emit_libcall_block (insns
, target
, value
,
1978 gen_rtx (unoptab
->code
, mode
, op0
));
1983 /* It can't be done in this mode. Can we do it in a wider mode? */
1985 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1987 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1988 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1990 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
1991 != CODE_FOR_nothing
)
1992 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
1996 /* For certain operations, we need not actually extend
1997 the narrow operand, as long as we will truncate the
1998 results to the same narrowness. */
2000 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2001 (unoptab
== neg_optab
2002 || unoptab
== one_cmpl_optab
)
2003 && class == MODE_INT
);
2005 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2010 if (class != MODE_INT
)
2013 target
= gen_reg_rtx (mode
);
2014 convert_move (target
, temp
, 0);
2018 return gen_lowpart (mode
, temp
);
2021 delete_insns_since (last
);
2029 /* Emit code to compute the absolute value of OP0, with result to
2030 TARGET if convenient. (TARGET may be 0.) The return value says
2031 where the result actually is to be found.
2033 MODE is the mode of the operand; the mode of the result is
2034 different but can be deduced from MODE.
2036 UNSIGNEDP is relevant for complex integer modes. */
2039 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2040 enum machine_mode mode
;
2045 enum mode_class
class = GET_MODE_CLASS (mode
);
2046 enum machine_mode wider_mode
;
2048 rtx entry_last
= get_last_insn ();
2052 /* Find the correct mode for the real and imaginary parts. */
2053 enum machine_mode submode
2054 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2055 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2058 if (submode
== BLKmode
)
2061 op0
= protect_from_queue (op0
, 0);
2065 op0
= force_not_mem (op0
);
2068 last
= get_last_insn ();
2071 target
= protect_from_queue (target
, 1);
2073 if (abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2075 int icode
= (int) abs_optab
->handlers
[(int) mode
].insn_code
;
2076 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2082 temp
= gen_reg_rtx (submode
);
2084 if (GET_MODE (xop0
) != VOIDmode
2085 && GET_MODE (xop0
) != mode0
)
2086 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2088 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2090 if (! (*insn_operand_predicate
[icode
][1]) (xop0
, mode0
))
2091 xop0
= copy_to_mode_reg (mode0
, xop0
);
2093 if (! (*insn_operand_predicate
[icode
][0]) (temp
, submode
))
2094 temp
= gen_reg_rtx (submode
);
2096 pat
= GEN_FCN (icode
) (temp
, xop0
);
2099 if (GET_CODE (pat
) == SEQUENCE
2100 && ! add_equal_note (pat
, temp
, abs_optab
->code
, xop0
, NULL_RTX
))
2102 delete_insns_since (last
);
2103 return expand_unop (mode
, abs_optab
, op0
, NULL_RTX
, unsignedp
);
2111 delete_insns_since (last
);
2114 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2116 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2117 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2119 if (abs_optab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2123 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2124 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2128 if (class != MODE_COMPLEX_INT
)
2131 target
= gen_reg_rtx (submode
);
2132 convert_move (target
, temp
, 0);
2136 return gen_lowpart (submode
, temp
);
2139 delete_insns_since (last
);
2143 /* Open-code the complex absolute-value operation
2144 if we can open-code sqrt. Otherwise it's not worth while. */
2145 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
)
2147 rtx real
, imag
, total
;
2149 real
= gen_realpart (submode
, op0
);
2150 imag
= gen_imagpart (submode
, op0
);
2152 /* Square both parts. */
2153 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2154 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2156 /* Sum the parts. */
2157 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2158 0, OPTAB_LIB_WIDEN
);
2160 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2161 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2163 delete_insns_since (last
);
2168 /* Now try a library call in this mode. */
2169 if (abs_optab
->handlers
[(int) mode
].libfunc
)
2172 rtx funexp
= abs_optab
->handlers
[(int) mode
].libfunc
;
2177 /* Pass 1 for NO_QUEUE so we don't lose any increments
2178 if the libcall is cse'd or moved. */
2179 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2180 NULL_RTX
, 1, submode
, 1, op0
, mode
);
2181 insns
= get_insns ();
2184 target
= gen_reg_rtx (submode
);
2185 emit_libcall_block (insns
, target
, value
,
2186 gen_rtx (abs_optab
->code
, mode
, op0
));
2191 /* It can't be done in this mode. Can we do it in a wider mode? */
2193 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2194 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2196 if ((abs_optab
->handlers
[(int) wider_mode
].insn_code
2197 != CODE_FOR_nothing
)
2198 || abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2202 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2204 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2208 if (class != MODE_COMPLEX_INT
)
2211 target
= gen_reg_rtx (submode
);
2212 convert_move (target
, temp
, 0);
2216 return gen_lowpart (submode
, temp
);
2219 delete_insns_since (last
);
2223 delete_insns_since (entry_last
);
2227 /* Generate an instruction whose insn-code is INSN_CODE,
2228 with two operands: an output TARGET and an input OP0.
2229 TARGET *must* be nonzero, and the output is always stored there.
2230 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2231 the value that is stored into TARGET. */
2234 emit_unop_insn (icode
, target
, op0
, code
)
2241 enum machine_mode mode0
= insn_operand_mode
[icode
][1];
2244 temp
= target
= protect_from_queue (target
, 1);
2246 op0
= protect_from_queue (op0
, 0);
2249 op0
= force_not_mem (op0
);
2251 /* Now, if insn does not accept our operands, put them into pseudos. */
2253 if (! (*insn_operand_predicate
[icode
][1]) (op0
, mode0
))
2254 op0
= copy_to_mode_reg (mode0
, op0
);
2256 if (! (*insn_operand_predicate
[icode
][0]) (temp
, GET_MODE (temp
))
2257 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2258 temp
= gen_reg_rtx (GET_MODE (temp
));
2260 pat
= GEN_FCN (icode
) (temp
, op0
);
2262 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2263 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2268 emit_move_insn (target
, temp
);
2271 /* Emit code to perform a series of operations on a multi-word quantity, one
2274 Such a block is preceded by a CLOBBER of the output, consists of multiple
2275 insns, each setting one word of the output, and followed by a SET copying
2276 the output to itself.
2278 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2279 note indicating that it doesn't conflict with the (also multi-word)
2280 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2283 INSNS is a block of code generated to perform the operation, not including
2284 the CLOBBER and final copy. All insns that compute intermediate values
2285 are first emitted, followed by the block as described above. Only
2286 INSNs are allowed in the block; no library calls or jumps may be
2289 TARGET, OP0, and OP1 are the output and inputs of the operations,
2290 respectively. OP1 may be zero for a unary operation.
2292 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2295 If TARGET is not a register, INSNS is simply emitted with no special
2298 The final insn emitted is returned. */
2301 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2307 rtx prev
, next
, first
, last
, insn
;
2309 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2310 return emit_insns (insns
);
2312 /* First emit all insns that do not store into words of the output and remove
2313 these from the list. */
2314 for (insn
= insns
; insn
; insn
= next
)
2319 next
= NEXT_INSN (insn
);
2321 if (GET_CODE (insn
) != INSN
)
2324 if (GET_CODE (PATTERN (insn
)) == SET
)
2325 set
= PATTERN (insn
);
2326 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2328 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2329 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2331 set
= XVECEXP (PATTERN (insn
), 0, i
);
2339 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2341 if (PREV_INSN (insn
))
2342 NEXT_INSN (PREV_INSN (insn
)) = next
;
2347 PREV_INSN (next
) = PREV_INSN (insn
);
2353 prev
= get_last_insn ();
2355 /* Now write the CLOBBER of the output, followed by the setting of each
2356 of the words, followed by the final copy. */
2357 if (target
!= op0
&& target
!= op1
)
2358 emit_insn (gen_rtx (CLOBBER
, VOIDmode
, target
));
2360 for (insn
= insns
; insn
; insn
= next
)
2362 next
= NEXT_INSN (insn
);
2365 if (op1
&& GET_CODE (op1
) == REG
)
2366 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op1
,
2369 if (op0
&& GET_CODE (op0
) == REG
)
2370 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_NO_CONFLICT
, op0
,
2374 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2375 != CODE_FOR_nothing
)
2377 last
= emit_move_insn (target
, target
);
2380 = gen_rtx (EXPR_LIST
, REG_EQUAL
, equiv
, REG_NOTES (last
));
2383 last
= get_last_insn ();
2386 first
= get_insns ();
2388 first
= NEXT_INSN (prev
);
2390 /* Encapsulate the block so it gets manipulated as a unit. */
2391 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
2393 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2398 /* Emit code to make a call to a constant function or a library call.
2400 INSNS is a list containing all insns emitted in the call.
2401 These insns leave the result in RESULT. Our block is to copy RESULT
2402 to TARGET, which is logically equivalent to EQUIV.
2404 We first emit any insns that set a pseudo on the assumption that these are
2405 loading constants into registers; doing so allows them to be safely cse'ed
2406 between blocks. Then we emit all the other insns in the block, followed by
2407 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2408 note with an operand of EQUIV.
2410 Moving assignments to pseudos outside of the block is done to improve
2411 the generated code, but is not required to generate correct code,
2412 hence being unable to move an assignment is not grounds for not making
2413 a libcall block. There are two reasons why it is safe to leave these
2414 insns inside the block: First, we know that these pseudos cannot be
2415 used in generated RTL outside the block since they are created for
2416 temporary purposes within the block. Second, CSE will not record the
2417 values of anything set inside a libcall block, so we know they must
2418 be dead at the end of the block.
2420 Except for the first group of insns (the ones setting pseudos), the
2421 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2424 emit_libcall_block (insns
, target
, result
, equiv
)
2430 rtx prev
, next
, first
, last
, insn
;
2432 /* First emit all insns that set pseudos. Remove them from the list as
2433 we go. Avoid insns that set pseudos which were referenced in previous
2434 insns. These can be generated by move_by_pieces, for example,
2435 to update an address. Similarly, avoid insns that reference things
2436 set in previous insns. */
2438 for (insn
= insns
; insn
; insn
= next
)
2440 rtx set
= single_set (insn
);
2442 next
= NEXT_INSN (insn
);
2444 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2445 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2447 || (! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
))
2448 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2449 && ! modified_in_p (SET_SRC (set
), insns
)
2450 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2452 if (PREV_INSN (insn
))
2453 NEXT_INSN (PREV_INSN (insn
)) = next
;
2458 PREV_INSN (next
) = PREV_INSN (insn
);
2464 prev
= get_last_insn ();
2466 /* Write the remaining insns followed by the final copy. */
2468 for (insn
= insns
; insn
; insn
= next
)
2470 next
= NEXT_INSN (insn
);
2475 last
= emit_move_insn (target
, result
);
2476 REG_NOTES (last
) = gen_rtx (EXPR_LIST
,
2477 REG_EQUAL
, copy_rtx (equiv
), REG_NOTES (last
));
2480 first
= get_insns ();
2482 first
= NEXT_INSN (prev
);
2484 /* Encapsulate the block so it gets manipulated as a unit. */
2485 REG_NOTES (first
) = gen_rtx (INSN_LIST
, REG_LIBCALL
, last
,
2487 REG_NOTES (last
) = gen_rtx (INSN_LIST
, REG_RETVAL
, first
, REG_NOTES (last
));
2490 /* Generate code to store zero in X. */
2496 emit_move_insn (x
, const0_rtx
);
2499 /* Generate code to store 1 in X
2500 assuming it contains zero beforehand. */
2503 emit_0_to_1_insn (x
)
2506 emit_move_insn (x
, const1_rtx
);
2509 /* Generate code to compare X with Y
2510 so that the condition codes are set.
2512 MODE is the mode of the inputs (in case they are const_int).
2513 UNSIGNEDP nonzero says that X and Y are unsigned;
2514 this matters if they need to be widened.
2516 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2517 and ALIGN specifies the known shared alignment of X and Y.
2519 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2520 It is ignored for fixed-point and block comparisons;
2521 it is used only for floating-point comparisons. */
2524 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
2526 enum rtx_code comparison
;
2528 enum machine_mode mode
;
2532 enum mode_class
class;
2533 enum machine_mode wider_mode
;
2535 class = GET_MODE_CLASS (mode
);
2537 /* They could both be VOIDmode if both args are immediate constants,
2538 but we should fold that at an earlier stage.
2539 With no special code here, this will call abort,
2540 reminding the programmer to implement such folding. */
2542 if (mode
!= BLKmode
&& flag_force_mem
)
2544 x
= force_not_mem (x
);
2545 y
= force_not_mem (y
);
2548 /* If we are inside an appropriately-short loop and one operand is an
2549 expensive constant, force it into a register. */
2550 if (CONSTANT_P (x
) && preserve_subexpressions_p () && rtx_cost (x
, COMPARE
) > 2)
2551 x
= force_reg (mode
, x
);
2553 if (CONSTANT_P (y
) && preserve_subexpressions_p () && rtx_cost (y
, COMPARE
) > 2)
2554 y
= force_reg (mode
, y
);
2556 /* Don't let both operands fail to indicate the mode. */
2557 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
2558 x
= force_reg (mode
, x
);
2560 /* Handle all BLKmode compares. */
2562 if (mode
== BLKmode
)
2565 x
= protect_from_queue (x
, 0);
2566 y
= protect_from_queue (y
, 0);
2570 #ifdef HAVE_cmpstrqi
2572 && GET_CODE (size
) == CONST_INT
2573 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
2575 enum machine_mode result_mode
2576 = insn_operand_mode
[(int) CODE_FOR_cmpstrqi
][0];
2577 rtx result
= gen_reg_rtx (result_mode
);
2578 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, GEN_INT (align
)));
2579 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2584 #ifdef HAVE_cmpstrhi
2586 && GET_CODE (size
) == CONST_INT
2587 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
2589 enum machine_mode result_mode
2590 = insn_operand_mode
[(int) CODE_FOR_cmpstrhi
][0];
2591 rtx result
= gen_reg_rtx (result_mode
);
2592 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, GEN_INT (align
)));
2593 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2598 #ifdef HAVE_cmpstrsi
2601 enum machine_mode result_mode
2602 = insn_operand_mode
[(int) CODE_FOR_cmpstrsi
][0];
2603 rtx result
= gen_reg_rtx (result_mode
);
2604 size
= protect_from_queue (size
, 0);
2605 emit_insn (gen_cmpstrsi (result
, x
, y
,
2606 convert_to_mode (SImode
, size
, 1),
2608 emit_cmp_insn (result
, const0_rtx
, comparison
, NULL_RTX
,
2614 #ifdef TARGET_MEM_FUNCTIONS
2615 emit_library_call (memcmp_libfunc
, 0,
2616 TYPE_MODE (integer_type_node
), 3,
2617 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2620 emit_library_call (bcmp_libfunc
, 0,
2621 TYPE_MODE (integer_type_node
), 3,
2622 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
2625 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node
)),
2626 const0_rtx
, comparison
, NULL_RTX
,
2627 TYPE_MODE (integer_type_node
), 0, 0);
2632 /* Handle some compares against zero. */
2634 if (y
== CONST0_RTX (mode
)
2635 && tst_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2637 int icode
= (int) tst_optab
->handlers
[(int) mode
].insn_code
;
2640 x
= protect_from_queue (x
, 0);
2641 y
= protect_from_queue (y
, 0);
2643 /* Now, if insn does accept these operands, put them into pseudos. */
2644 if (! (*insn_operand_predicate
[icode
][0])
2645 (x
, insn_operand_mode
[icode
][0]))
2646 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2648 emit_insn (GEN_FCN (icode
) (x
));
2652 /* Handle compares for which there is a directly suitable insn. */
2654 if (cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2656 int icode
= (int) cmp_optab
->handlers
[(int) mode
].insn_code
;
2659 x
= protect_from_queue (x
, 0);
2660 y
= protect_from_queue (y
, 0);
2662 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2663 if (! (*insn_operand_predicate
[icode
][0])
2664 (x
, insn_operand_mode
[icode
][0]))
2665 x
= copy_to_mode_reg (insn_operand_mode
[icode
][0], x
);
2667 if (! (*insn_operand_predicate
[icode
][1])
2668 (y
, insn_operand_mode
[icode
][1]))
2669 y
= copy_to_mode_reg (insn_operand_mode
[icode
][1], y
);
2671 emit_insn (GEN_FCN (icode
) (x
, y
));
2675 /* Try widening if we can find a direct insn that way. */
2677 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2679 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2680 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2682 if (cmp_optab
->handlers
[(int) wider_mode
].insn_code
2683 != CODE_FOR_nothing
)
2685 x
= protect_from_queue (x
, 0);
2686 y
= protect_from_queue (y
, 0);
2687 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
2688 y
= convert_modes (wider_mode
, mode
, y
, unsignedp
);
2689 emit_cmp_insn (x
, y
, comparison
, NULL_RTX
,
2690 wider_mode
, unsignedp
, align
);
2696 /* Handle a lib call just for the mode we are using. */
2698 if (cmp_optab
->handlers
[(int) mode
].libfunc
2699 && class != MODE_FLOAT
)
2701 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
2702 /* If we want unsigned, and this mode has a distinct unsigned
2703 comparison routine, use that. */
2704 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
2705 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
2707 emit_library_call (libfunc
, 1,
2708 word_mode
, 2, x
, mode
, y
, mode
);
2710 /* Integer comparison returns a result that must be compared against 1,
2711 so that even if we do an unsigned compare afterward,
2712 there is still a value that can represent the result "less than". */
2714 emit_cmp_insn (hard_libcall_value (word_mode
), const1_rtx
,
2715 comparison
, NULL_RTX
, word_mode
, unsignedp
, 0);
2719 if (class == MODE_FLOAT
)
2720 emit_float_lib_cmp (x
, y
, comparison
);
2726 /* Nonzero if a compare of mode MODE can be done straightforwardly
2727 (without splitting it into pieces). */
2730 can_compare_p (mode
)
2731 enum machine_mode mode
;
2735 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2737 mode
= GET_MODE_WIDER_MODE (mode
);
2738 } while (mode
!= VOIDmode
);
2743 /* Emit a library call comparison between floating point X and Y.
2744 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2747 emit_float_lib_cmp (x
, y
, comparison
)
2749 enum rtx_code comparison
;
2751 enum machine_mode mode
= GET_MODE (x
);
2758 libfunc
= eqsf2_libfunc
;
2762 libfunc
= nesf2_libfunc
;
2766 libfunc
= gtsf2_libfunc
;
2770 libfunc
= gesf2_libfunc
;
2774 libfunc
= ltsf2_libfunc
;
2778 libfunc
= lesf2_libfunc
;
2781 else if (mode
== DFmode
)
2785 libfunc
= eqdf2_libfunc
;
2789 libfunc
= nedf2_libfunc
;
2793 libfunc
= gtdf2_libfunc
;
2797 libfunc
= gedf2_libfunc
;
2801 libfunc
= ltdf2_libfunc
;
2805 libfunc
= ledf2_libfunc
;
2808 else if (mode
== XFmode
)
2812 libfunc
= eqxf2_libfunc
;
2816 libfunc
= nexf2_libfunc
;
2820 libfunc
= gtxf2_libfunc
;
2824 libfunc
= gexf2_libfunc
;
2828 libfunc
= ltxf2_libfunc
;
2832 libfunc
= lexf2_libfunc
;
2835 else if (mode
== TFmode
)
2839 libfunc
= eqtf2_libfunc
;
2843 libfunc
= netf2_libfunc
;
2847 libfunc
= gttf2_libfunc
;
2851 libfunc
= getf2_libfunc
;
2855 libfunc
= lttf2_libfunc
;
2859 libfunc
= letf2_libfunc
;
2864 enum machine_mode wider_mode
;
2866 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2867 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2869 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
2870 != CODE_FOR_nothing
)
2871 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
2873 x
= protect_from_queue (x
, 0);
2874 y
= protect_from_queue (y
, 0);
2875 x
= convert_to_mode (wider_mode
, x
, 0);
2876 y
= convert_to_mode (wider_mode
, y
, 0);
2877 emit_float_lib_cmp (x
, y
, comparison
);
2887 emit_library_call (libfunc
, 1,
2888 word_mode
, 2, x
, mode
, y
, mode
);
2890 emit_cmp_insn (hard_libcall_value (word_mode
), const0_rtx
, comparison
,
2891 NULL_RTX
, word_mode
, 0, 0);
2894 /* Generate code to indirectly jump to a location given in the rtx LOC. */
2897 emit_indirect_jump (loc
)
2900 if (! ((*insn_operand_predicate
[(int)CODE_FOR_indirect_jump
][0])
2902 loc
= copy_to_mode_reg (Pmode
, loc
);
2904 emit_jump_insn (gen_indirect_jump (loc
));
2908 /* These three functions generate an insn body and return it
2909 rather than emitting the insn.
2911 They do not protect from queued increments,
2912 because they may be used 1) in protect_from_queue itself
2913 and 2) in other passes where there is no queue. */
2915 /* Generate and return an insn body to add Y to X. */
2918 gen_add2_insn (x
, y
)
2921 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
2923 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
2924 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
2925 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
2928 return (GEN_FCN (icode
) (x
, x
, y
));
2932 have_add2_insn (mode
)
2933 enum machine_mode mode
;
2935 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
2938 /* Generate and return an insn body to subtract Y from X. */
2941 gen_sub2_insn (x
, y
)
2944 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
2946 if (! (*insn_operand_predicate
[icode
][0]) (x
, insn_operand_mode
[icode
][0])
2947 || ! (*insn_operand_predicate
[icode
][1]) (x
, insn_operand_mode
[icode
][1])
2948 || ! (*insn_operand_predicate
[icode
][2]) (y
, insn_operand_mode
[icode
][2]))
2951 return (GEN_FCN (icode
) (x
, x
, y
));
2955 have_sub2_insn (mode
)
2956 enum machine_mode mode
;
2958 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
2961 /* Generate the body of an instruction to copy Y into X.
2962 It may be a SEQUENCE, if one insn isn't enough. */
2965 gen_move_insn (x
, y
)
2968 register enum machine_mode mode
= GET_MODE (x
);
2969 enum insn_code insn_code
;
2972 if (mode
== VOIDmode
)
2973 mode
= GET_MODE (y
);
2975 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
2977 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
2978 find a mode to do it in. If we have a movcc, use it. Otherwise,
2979 find the MODE_INT mode of the same width. */
2981 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
2983 enum machine_mode tmode
= VOIDmode
;
2987 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
2990 for (tmode
= QImode
; tmode
!= VOIDmode
;
2991 tmode
= GET_MODE_WIDER_MODE (tmode
))
2992 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
2995 if (tmode
== VOIDmode
)
2998 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
2999 may call change_address which is not appropriate if we were
3000 called when a reload was in progress. We don't have to worry
3001 about changing the address since the size in bytes is supposed to
3002 be the same. Copy the MEM to change the mode and move any
3003 substitutions from the old MEM to the new one. */
3005 if (reload_in_progress
)
3007 x
= gen_lowpart_common (tmode
, x1
);
3008 if (x
== 0 && GET_CODE (x1
) == MEM
)
3010 x
= gen_rtx (MEM
, tmode
, XEXP (x1
, 0));
3011 RTX_UNCHANGING_P (x
) = RTX_UNCHANGING_P (x1
);
3012 MEM_IN_STRUCT_P (x
) = MEM_IN_STRUCT_P (x1
);
3013 MEM_VOLATILE_P (x
) = MEM_VOLATILE_P (x1
);
3014 copy_replacements (x1
, x
);
3017 y
= gen_lowpart_common (tmode
, y1
);
3018 if (y
== 0 && GET_CODE (y1
) == MEM
)
3020 y
= gen_rtx (MEM
, tmode
, XEXP (y1
, 0));
3021 RTX_UNCHANGING_P (y
) = RTX_UNCHANGING_P (y1
);
3022 MEM_IN_STRUCT_P (y
) = MEM_IN_STRUCT_P (y1
);
3023 MEM_VOLATILE_P (y
) = MEM_VOLATILE_P (y1
);
3024 copy_replacements (y1
, y
);
3029 x
= gen_lowpart (tmode
, x
);
3030 y
= gen_lowpart (tmode
, y
);
3033 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3034 return (GEN_FCN (insn_code
) (x
, y
));
3038 emit_move_insn_1 (x
, y
);
3039 seq
= gen_sequence ();
3044 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3045 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3046 no such operation exists, CODE_FOR_nothing will be returned. */
3049 can_extend_p (to_mode
, from_mode
, unsignedp
)
3050 enum machine_mode to_mode
, from_mode
;
3053 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
];
3056 /* Generate the body of an insn to extend Y (with mode MFROM)
3057 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3060 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3062 enum machine_mode mto
, mfrom
;
3065 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
]) (x
, y
));
3068 /* can_fix_p and can_float_p say whether the target machine
3069 can directly convert a given fixed point type to
3070 a given floating point type, or vice versa.
3071 The returned value is the CODE_FOR_... value to use,
3072 or CODE_FOR_nothing if these modes cannot be directly converted.
3074 *TRUNCP_PTR is set to 1 if it is necessary to output
3075 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3077 static enum insn_code
3078 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3079 enum machine_mode fltmode
, fixmode
;
3084 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
] != CODE_FOR_nothing
)
3085 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3087 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3090 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3092 return CODE_FOR_nothing
;
3095 static enum insn_code
3096 can_float_p (fltmode
, fixmode
, unsignedp
)
3097 enum machine_mode fixmode
, fltmode
;
3100 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
];
3103 /* Generate code to convert FROM to floating point
3104 and store in TO. FROM must be fixed point and not VOIDmode.
3105 UNSIGNEDP nonzero means regard FROM as unsigned.
3106 Normally this is done by correcting the final value
3107 if it is negative. */
3110 expand_float (to
, from
, unsignedp
)
3114 enum insn_code icode
;
3115 register rtx target
= to
;
3116 enum machine_mode fmode
, imode
;
3118 /* Crash now, because we won't be able to decide which mode to use. */
3119 if (GET_MODE (from
) == VOIDmode
)
3122 /* Look for an insn to do the conversion. Do it in the specified
3123 modes if possible; otherwise convert either input, output or both to
3124 wider mode. If the integer mode is wider than the mode of FROM,
3125 we can do the conversion signed even if the input is unsigned. */
3127 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3128 imode
= GET_MODE_WIDER_MODE (imode
))
3129 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3130 fmode
= GET_MODE_WIDER_MODE (fmode
))
3132 int doing_unsigned
= unsignedp
;
3134 icode
= can_float_p (fmode
, imode
, unsignedp
);
3135 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3136 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3138 if (icode
!= CODE_FOR_nothing
)
3140 to
= protect_from_queue (to
, 1);
3141 from
= protect_from_queue (from
, 0);
3143 if (imode
!= GET_MODE (from
))
3144 from
= convert_to_mode (imode
, from
, unsignedp
);
3146 if (fmode
!= GET_MODE (to
))
3147 target
= gen_reg_rtx (fmode
);
3149 emit_unop_insn (icode
, target
, from
,
3150 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3153 convert_move (to
, target
, 0);
3158 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3160 /* Unsigned integer, and no way to convert directly.
3161 Convert as signed, then conditionally adjust the result. */
3164 rtx label
= gen_label_rtx ();
3166 REAL_VALUE_TYPE offset
;
3170 to
= protect_from_queue (to
, 1);
3171 from
= protect_from_queue (from
, 0);
3174 from
= force_not_mem (from
);
3176 /* Look for a usable floating mode FMODE wider than the source and at
3177 least as wide as the target. Using FMODE will avoid rounding woes
3178 with unsigned values greater than the signed maximum value. */
3180 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3181 fmode
= GET_MODE_WIDER_MODE (fmode
))
3182 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
3183 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
3186 if (fmode
== VOIDmode
)
3188 /* There is no such mode. Pretend the target is wide enough. */
3189 fmode
= GET_MODE (to
);
3191 /* Avoid double-rounding when TO is narrower than FROM. */
3192 if ((significand_size (fmode
) + 1)
3193 < GET_MODE_BITSIZE (GET_MODE (from
)))
3196 rtx neglabel
= gen_label_rtx ();
3198 /* Don't use TARGET if it isn't a register, is a hard register,
3199 or is the wrong mode. */
3200 if (GET_CODE (target
) != REG
3201 || REGNO (target
) < FIRST_PSEUDO_REGISTER
3202 || GET_MODE (target
) != fmode
)
3203 target
= gen_reg_rtx (fmode
);
3205 imode
= GET_MODE (from
);
3206 do_pending_stack_adjust ();
3208 /* Test whether the sign bit is set. */
3209 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, imode
, 0, 0);
3210 emit_jump_insn (gen_blt (neglabel
));
3212 /* The sign bit is not set. Convert as signed. */
3213 expand_float (target
, from
, 0);
3214 emit_jump_insn (gen_jump (label
));
3216 /* The sign bit is set.
3217 Convert to a usable (positive signed) value by shifting right
3218 one bit, while remembering if a nonzero bit was shifted
3219 out; i.e., compute (from & 1) | (from >> 1). */
3221 emit_label (neglabel
);
3222 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
3223 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3224 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
3226 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
3228 expand_float (target
, temp
, 0);
3230 /* Multiply by 2 to undo the shift above. */
3231 target
= expand_binop (fmode
, add_optab
, target
, target
,
3232 target
, 0, OPTAB_LIB_WIDEN
);
3233 do_pending_stack_adjust ();
3239 /* If we are about to do some arithmetic to correct for an
3240 unsigned operand, do it in a pseudo-register. */
3242 if (GET_MODE (to
) != fmode
3243 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
3244 target
= gen_reg_rtx (fmode
);
3246 /* Convert as signed integer to floating. */
3247 expand_float (target
, from
, 0);
3249 /* If FROM is negative (and therefore TO is negative),
3250 correct its value by 2**bitwidth. */
3252 do_pending_stack_adjust ();
3253 emit_cmp_insn (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3254 emit_jump_insn (gen_bge (label
));
3256 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3257 Rather than setting up a dconst_dot_5, let's hope SCO
3259 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
3260 temp
= expand_binop (fmode
, add_optab
, target
,
3261 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
3262 target
, 0, OPTAB_LIB_WIDEN
);
3264 emit_move_insn (target
, temp
);
3266 do_pending_stack_adjust ();
3272 /* No hardware instruction available; call a library rotine to convert from
3273 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3279 to
= protect_from_queue (to
, 1);
3280 from
= protect_from_queue (from
, 0);
3282 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
3283 from
= convert_to_mode (SImode
, from
, unsignedp
);
3286 from
= force_not_mem (from
);
3288 if (GET_MODE (to
) == SFmode
)
3290 if (GET_MODE (from
) == SImode
)
3291 libfcn
= floatsisf_libfunc
;
3292 else if (GET_MODE (from
) == DImode
)
3293 libfcn
= floatdisf_libfunc
;
3294 else if (GET_MODE (from
) == TImode
)
3295 libfcn
= floattisf_libfunc
;
3299 else if (GET_MODE (to
) == DFmode
)
3301 if (GET_MODE (from
) == SImode
)
3302 libfcn
= floatsidf_libfunc
;
3303 else if (GET_MODE (from
) == DImode
)
3304 libfcn
= floatdidf_libfunc
;
3305 else if (GET_MODE (from
) == TImode
)
3306 libfcn
= floattidf_libfunc
;
3310 else if (GET_MODE (to
) == XFmode
)
3312 if (GET_MODE (from
) == SImode
)
3313 libfcn
= floatsixf_libfunc
;
3314 else if (GET_MODE (from
) == DImode
)
3315 libfcn
= floatdixf_libfunc
;
3316 else if (GET_MODE (from
) == TImode
)
3317 libfcn
= floattixf_libfunc
;
3321 else if (GET_MODE (to
) == TFmode
)
3323 if (GET_MODE (from
) == SImode
)
3324 libfcn
= floatsitf_libfunc
;
3325 else if (GET_MODE (from
) == DImode
)
3326 libfcn
= floatditf_libfunc
;
3327 else if (GET_MODE (from
) == TImode
)
3328 libfcn
= floattitf_libfunc
;
3337 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1,
3339 1, from
, GET_MODE (from
));
3340 insns
= get_insns ();
3343 emit_libcall_block (insns
, target
, value
,
3344 gen_rtx (FLOAT
, GET_MODE (to
), from
));
3349 /* Copy result to requested destination
3350 if we have been computing in a temp location. */
3354 if (GET_MODE (target
) == GET_MODE (to
))
3355 emit_move_insn (to
, target
);
3357 convert_move (to
, target
, 0);
3361 /* expand_fix: generate code to convert FROM to fixed point
3362 and store in TO. FROM must be floating point. */
3368 rtx temp
= gen_reg_rtx (GET_MODE (x
));
3369 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
3373 expand_fix (to
, from
, unsignedp
)
3374 register rtx to
, from
;
3377 enum insn_code icode
;
3378 register rtx target
= to
;
3379 enum machine_mode fmode
, imode
;
3383 /* We first try to find a pair of modes, one real and one integer, at
3384 least as wide as FROM and TO, respectively, in which we can open-code
3385 this conversion. If the integer mode is wider than the mode of TO,
3386 we can do the conversion either signed or unsigned. */
3388 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
3389 imode
= GET_MODE_WIDER_MODE (imode
))
3390 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3391 fmode
= GET_MODE_WIDER_MODE (fmode
))
3393 int doing_unsigned
= unsignedp
;
3395 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
3396 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
3397 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
3399 if (icode
!= CODE_FOR_nothing
)
3401 to
= protect_from_queue (to
, 1);
3402 from
= protect_from_queue (from
, 0);
3404 if (fmode
!= GET_MODE (from
))
3405 from
= convert_to_mode (fmode
, from
, 0);
3408 from
= ftruncify (from
);
3410 if (imode
!= GET_MODE (to
))
3411 target
= gen_reg_rtx (imode
);
3413 emit_unop_insn (icode
, target
, from
,
3414 doing_unsigned
? UNSIGNED_FIX
: FIX
);
3416 convert_move (to
, target
, unsignedp
);
3421 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3422 /* For an unsigned conversion, there is one more way to do it.
3423 If we have a signed conversion, we generate code that compares
3424 the real value to the largest representable positive number. If if
3425 is smaller, the conversion is done normally. Otherwise, subtract
3426 one plus the highest signed number, convert, and add it back.
3428 We only need to check all real modes, since we know we didn't find
3429 anything with a wider integer mode. */
3431 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
3432 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
3433 fmode
= GET_MODE_WIDER_MODE (fmode
))
3434 /* Make sure we won't lose significant bits doing this. */
3435 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
3436 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
3440 REAL_VALUE_TYPE offset
;
3441 rtx limit
, lab1
, lab2
, insn
;
3443 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
3444 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
3445 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
3446 lab1
= gen_label_rtx ();
3447 lab2
= gen_label_rtx ();
3450 to
= protect_from_queue (to
, 1);
3451 from
= protect_from_queue (from
, 0);
3454 from
= force_not_mem (from
);
3456 if (fmode
!= GET_MODE (from
))
3457 from
= convert_to_mode (fmode
, from
, 0);
3459 /* See if we need to do the subtraction. */
3460 do_pending_stack_adjust ();
3461 emit_cmp_insn (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
), 0, 0);
3462 emit_jump_insn (gen_bge (lab1
));
3464 /* If not, do the signed "fix" and branch around fixup code. */
3465 expand_fix (to
, from
, 0);
3466 emit_jump_insn (gen_jump (lab2
));
3469 /* Otherwise, subtract 2**(N-1), convert to signed number,
3470 then add 2**(N-1). Do the addition using XOR since this
3471 will often generate better code. */
3473 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
3474 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
3475 expand_fix (to
, target
, 0);
3476 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
3477 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
3478 to
, 1, OPTAB_LIB_WIDEN
);
3481 emit_move_insn (to
, target
);
3485 /* Make a place for a REG_NOTE and add it. */
3486 insn
= emit_move_insn (to
, to
);
3487 REG_NOTES (insn
) = gen_rtx (EXPR_LIST
, REG_EQUAL
,
3488 gen_rtx (UNSIGNED_FIX
, GET_MODE (to
),
3496 /* We can't do it with an insn, so use a library call. But first ensure
3497 that the mode of TO is at least as wide as SImode, since those are the
3498 only library calls we know about. */
3500 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
3502 target
= gen_reg_rtx (SImode
);
3504 expand_fix (target
, from
, unsignedp
);
3506 else if (GET_MODE (from
) == SFmode
)
3508 if (GET_MODE (to
) == SImode
)
3509 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
3510 else if (GET_MODE (to
) == DImode
)
3511 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
3512 else if (GET_MODE (to
) == TImode
)
3513 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
3517 else if (GET_MODE (from
) == DFmode
)
3519 if (GET_MODE (to
) == SImode
)
3520 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
3521 else if (GET_MODE (to
) == DImode
)
3522 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
3523 else if (GET_MODE (to
) == TImode
)
3524 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
3528 else if (GET_MODE (from
) == XFmode
)
3530 if (GET_MODE (to
) == SImode
)
3531 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
3532 else if (GET_MODE (to
) == DImode
)
3533 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
3534 else if (GET_MODE (to
) == TImode
)
3535 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
3539 else if (GET_MODE (from
) == TFmode
)
3541 if (GET_MODE (to
) == SImode
)
3542 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
3543 else if (GET_MODE (to
) == DImode
)
3544 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
3545 else if (GET_MODE (to
) == TImode
)
3546 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
3557 to
= protect_from_queue (to
, 1);
3558 from
= protect_from_queue (from
, 0);
3561 from
= force_not_mem (from
);
3565 emit_library_call (libfcn
, 1, GET_MODE (to
), 1, from
, GET_MODE (from
));
3566 insns
= get_insns ();
3569 emit_libcall_block (insns
, target
, hard_libcall_value (GET_MODE (to
)),
3570 gen_rtx (unsignedp
? FIX
: UNSIGNED_FIX
,
3571 GET_MODE (to
), from
));
3574 if (GET_MODE (to
) == GET_MODE (target
))
3575 emit_move_insn (to
, target
);
3577 convert_move (to
, target
, 0);
3585 optab op
= (optab
) xmalloc (sizeof (struct optab
));
3587 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3589 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
3590 op
->handlers
[i
].libfunc
= 0;
3593 if (code
!= UNKNOWN
)
3594 code_to_optab
[(int) code
] = op
;
3599 /* Initialize the libfunc fields of an entire group of entries in some
3600 optab. Each entry is set equal to a string consisting of a leading
3601 pair of underscores followed by a generic operation name followed by
3602 a mode name (downshifted to lower case) followed by a single character
3603 representing the number of operands for the given operation (which is
3604 usually one of the characters '2', '3', or '4').
3606 OPTABLE is the table in which libfunc fields are to be initialized.
3607 FIRST_MODE is the first machine mode index in the given optab to
3609 LAST_MODE is the last machine mode index in the given optab to
3611 OPNAME is the generic (string) name of the operation.
3612 SUFFIX is the character which specifies the number of operands for
3613 the given generic operation.
3617 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
3618 register optab optable
;
3619 register int first_mode
;
3620 register int last_mode
;
3621 register char *opname
;
3622 register char suffix
;
3625 register unsigned opname_len
= strlen (opname
);
3627 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
3628 mode
= (enum machine_mode
) ((int) mode
+ 1))
3630 register char *mname
= mode_name
[(int) mode
];
3631 register unsigned mname_len
= strlen (mname
);
3632 register char *libfunc_name
3633 = (char *) xmalloc (2 + opname_len
+ mname_len
+ 1 + 1);
3640 for (q
= opname
; *q
; )
3642 for (q
= mname
; *q
; q
++)
3643 *p
++ = tolower (*q
);
3646 optable
->handlers
[(int) mode
].libfunc
3647 = gen_rtx (SYMBOL_REF
, Pmode
, libfunc_name
);
3651 /* Initialize the libfunc fields of an entire group of entries in some
3652 optab which correspond to all integer mode operations. The parameters
3653 have the same meaning as similarly named ones for the `init_libfuncs'
3654 routine. (See above). */
3657 init_integral_libfuncs (optable
, opname
, suffix
)
3658 register optab optable
;
3659 register char *opname
;
3660 register char suffix
;
3662 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
3665 /* Initialize the libfunc fields of an entire group of entries in some
3666 optab which correspond to all real mode operations. The parameters
3667 have the same meaning as similarly named ones for the `init_libfuncs'
3668 routine. (See above). */
3671 init_floating_libfuncs (optable
, opname
, suffix
)
3672 register optab optable
;
3673 register char *opname
;
3674 register char suffix
;
3676 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
3679 /* Initialize the libfunc fields of an entire group of entries in some
3680 optab which correspond to all complex floating modes. The parameters
3681 have the same meaning as similarly named ones for the `init_libfuncs'
3682 routine. (See above). */
3685 init_complex_libfuncs (optable
, opname
, suffix
)
3686 register optab optable
;
3687 register char *opname
;
3688 register char suffix
;
3690 init_libfuncs (optable
, SCmode
, TCmode
, opname
, suffix
);
3693 /* Call this once to initialize the contents of the optabs
3694 appropriately for the current target machine. */
3702 /* Start by initializing all tables to contain CODE_FOR_nothing. */
3704 for (p
= fixtab
[0][0];
3705 p
< fixtab
[0][0] + sizeof fixtab
/ sizeof (fixtab
[0][0][0]);
3707 *p
= CODE_FOR_nothing
;
3709 for (p
= fixtrunctab
[0][0];
3710 p
< fixtrunctab
[0][0] + sizeof fixtrunctab
/ sizeof (fixtrunctab
[0][0][0]);
3712 *p
= CODE_FOR_nothing
;
3714 for (p
= floattab
[0][0];
3715 p
< floattab
[0][0] + sizeof floattab
/ sizeof (floattab
[0][0][0]);
3717 *p
= CODE_FOR_nothing
;
3719 for (p
= extendtab
[0][0];
3720 p
< extendtab
[0][0] + sizeof extendtab
/ sizeof extendtab
[0][0][0];
3722 *p
= CODE_FOR_nothing
;
3724 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
3725 setcc_gen_code
[i
] = CODE_FOR_nothing
;
3727 add_optab
= init_optab (PLUS
);
3728 sub_optab
= init_optab (MINUS
);
3729 smul_optab
= init_optab (MULT
);
3730 smul_widen_optab
= init_optab (UNKNOWN
);
3731 umul_widen_optab
= init_optab (UNKNOWN
);
3732 sdiv_optab
= init_optab (DIV
);
3733 sdivmod_optab
= init_optab (UNKNOWN
);
3734 udiv_optab
= init_optab (UDIV
);
3735 udivmod_optab
= init_optab (UNKNOWN
);
3736 smod_optab
= init_optab (MOD
);
3737 umod_optab
= init_optab (UMOD
);
3738 flodiv_optab
= init_optab (DIV
);
3739 ftrunc_optab
= init_optab (UNKNOWN
);
3740 and_optab
= init_optab (AND
);
3741 ior_optab
= init_optab (IOR
);
3742 xor_optab
= init_optab (XOR
);
3743 ashl_optab
= init_optab (ASHIFT
);
3744 ashr_optab
= init_optab (ASHIFTRT
);
3745 lshr_optab
= init_optab (LSHIFTRT
);
3746 rotl_optab
= init_optab (ROTATE
);
3747 rotr_optab
= init_optab (ROTATERT
);
3748 smin_optab
= init_optab (SMIN
);
3749 smax_optab
= init_optab (SMAX
);
3750 umin_optab
= init_optab (UMIN
);
3751 umax_optab
= init_optab (UMAX
);
3752 mov_optab
= init_optab (UNKNOWN
);
3753 movstrict_optab
= init_optab (UNKNOWN
);
3754 cmp_optab
= init_optab (UNKNOWN
);
3755 ucmp_optab
= init_optab (UNKNOWN
);
3756 tst_optab
= init_optab (UNKNOWN
);
3757 neg_optab
= init_optab (NEG
);
3758 abs_optab
= init_optab (ABS
);
3759 one_cmpl_optab
= init_optab (NOT
);
3760 ffs_optab
= init_optab (FFS
);
3761 sqrt_optab
= init_optab (SQRT
);
3762 sin_optab
= init_optab (UNKNOWN
);
3763 cos_optab
= init_optab (UNKNOWN
);
3764 strlen_optab
= init_optab (UNKNOWN
);
3766 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3768 movstr_optab
[i
] = CODE_FOR_nothing
;
3770 #ifdef HAVE_SECONDARY_RELOADS
3771 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
3775 /* Fill in the optabs with the insns we support. */
3778 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
3779 /* This flag says the same insns that convert to a signed fixnum
3780 also convert validly to an unsigned one. */
3781 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
3782 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
3783 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
3786 #ifdef EXTRA_CC_MODES
3790 /* Initialize the optabs with the names of the library functions. */
3791 init_integral_libfuncs (add_optab
, "add", '3');
3792 init_floating_libfuncs (add_optab
, "add", '3');
3793 init_integral_libfuncs (sub_optab
, "sub", '3');
3794 init_floating_libfuncs (sub_optab
, "sub", '3');
3795 init_integral_libfuncs (smul_optab
, "mul", '3');
3796 init_floating_libfuncs (smul_optab
, "mul", '3');
3797 init_integral_libfuncs (sdiv_optab
, "div", '3');
3798 init_integral_libfuncs (udiv_optab
, "udiv", '3');
3799 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
3800 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
3801 init_integral_libfuncs (smod_optab
, "mod", '3');
3802 init_integral_libfuncs (umod_optab
, "umod", '3');
3803 init_floating_libfuncs (flodiv_optab
, "div", '3');
3804 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
3805 init_integral_libfuncs (and_optab
, "and", '3');
3806 init_integral_libfuncs (ior_optab
, "ior", '3');
3807 init_integral_libfuncs (xor_optab
, "xor", '3');
3808 init_integral_libfuncs (ashl_optab
, "ashl", '3');
3809 init_integral_libfuncs (ashr_optab
, "ashr", '3');
3810 init_integral_libfuncs (lshr_optab
, "lshr", '3');
3811 init_integral_libfuncs (rotl_optab
, "rotl", '3');
3812 init_integral_libfuncs (rotr_optab
, "rotr", '3');
3813 init_integral_libfuncs (smin_optab
, "min", '3');
3814 init_floating_libfuncs (smin_optab
, "min", '3');
3815 init_integral_libfuncs (smax_optab
, "max", '3');
3816 init_floating_libfuncs (smax_optab
, "max", '3');
3817 init_integral_libfuncs (umin_optab
, "umin", '3');
3818 init_integral_libfuncs (umax_optab
, "umax", '3');
3819 init_integral_libfuncs (neg_optab
, "neg", '2');
3820 init_floating_libfuncs (neg_optab
, "neg", '2');
3821 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
3822 init_integral_libfuncs (ffs_optab
, "ffs", '2');
3824 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
3825 init_integral_libfuncs (cmp_optab
, "cmp", '2');
3826 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
3827 init_floating_libfuncs (cmp_optab
, "cmp", '2');
3829 #ifdef MULSI3_LIBCALL
3830 smul_optab
->handlers
[(int) SImode
].libfunc
3831 = gen_rtx (SYMBOL_REF
, Pmode
, MULSI3_LIBCALL
);
3833 #ifdef MULDI3_LIBCALL
3834 smul_optab
->handlers
[(int) DImode
].libfunc
3835 = gen_rtx (SYMBOL_REF
, Pmode
, MULDI3_LIBCALL
);
3837 #ifdef MULTI3_LIBCALL
3838 smul_optab
->handlers
[(int) TImode
].libfunc
3839 = gen_rtx (SYMBOL_REF
, Pmode
, MULTI3_LIBCALL
);
3842 #ifdef DIVSI3_LIBCALL
3843 sdiv_optab
->handlers
[(int) SImode
].libfunc
3844 = gen_rtx (SYMBOL_REF
, Pmode
, DIVSI3_LIBCALL
);
3846 #ifdef DIVDI3_LIBCALL
3847 sdiv_optab
->handlers
[(int) DImode
].libfunc
3848 = gen_rtx (SYMBOL_REF
, Pmode
, DIVDI3_LIBCALL
);
3850 #ifdef DIVTI3_LIBCALL
3851 sdiv_optab
->handlers
[(int) TImode
].libfunc
3852 = gen_rtx (SYMBOL_REF
, Pmode
, DIVTI3_LIBCALL
);
3855 #ifdef UDIVSI3_LIBCALL
3856 udiv_optab
->handlers
[(int) SImode
].libfunc
3857 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVSI3_LIBCALL
);
3859 #ifdef UDIVDI3_LIBCALL
3860 udiv_optab
->handlers
[(int) DImode
].libfunc
3861 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVDI3_LIBCALL
);
3863 #ifdef UDIVTI3_LIBCALL
3864 udiv_optab
->handlers
[(int) TImode
].libfunc
3865 = gen_rtx (SYMBOL_REF
, Pmode
, UDIVTI3_LIBCALL
);
3869 #ifdef MODSI3_LIBCALL
3870 smod_optab
->handlers
[(int) SImode
].libfunc
3871 = gen_rtx (SYMBOL_REF
, Pmode
, MODSI3_LIBCALL
);
3873 #ifdef MODDI3_LIBCALL
3874 smod_optab
->handlers
[(int) DImode
].libfunc
3875 = gen_rtx (SYMBOL_REF
, Pmode
, MODDI3_LIBCALL
);
3877 #ifdef MODTI3_LIBCALL
3878 smod_optab
->handlers
[(int) TImode
].libfunc
3879 = gen_rtx (SYMBOL_REF
, Pmode
, MODTI3_LIBCALL
);
3883 #ifdef UMODSI3_LIBCALL
3884 umod_optab
->handlers
[(int) SImode
].libfunc
3885 = gen_rtx (SYMBOL_REF
, Pmode
, UMODSI3_LIBCALL
);
3887 #ifdef UMODDI3_LIBCALL
3888 umod_optab
->handlers
[(int) DImode
].libfunc
3889 = gen_rtx (SYMBOL_REF
, Pmode
, UMODDI3_LIBCALL
);
3891 #ifdef UMODTI3_LIBCALL
3892 umod_optab
->handlers
[(int) TImode
].libfunc
3893 = gen_rtx (SYMBOL_REF
, Pmode
, UMODTI3_LIBCALL
);
3896 /* Define library calls for quad FP instructions */
3897 #ifdef ADDTF3_LIBCALL
3898 add_optab
->handlers
[(int) TFmode
].libfunc
3899 = gen_rtx (SYMBOL_REF
, Pmode
, ADDTF3_LIBCALL
);
3901 #ifdef SUBTF3_LIBCALL
3902 sub_optab
->handlers
[(int) TFmode
].libfunc
3903 = gen_rtx (SYMBOL_REF
, Pmode
, SUBTF3_LIBCALL
);
3905 #ifdef MULTF3_LIBCALL
3906 smul_optab
->handlers
[(int) TFmode
].libfunc
3907 = gen_rtx (SYMBOL_REF
, Pmode
, MULTF3_LIBCALL
);
3909 #ifdef DIVTF3_LIBCALL
3910 flodiv_optab
->handlers
[(int) TFmode
].libfunc
3911 = gen_rtx (SYMBOL_REF
, Pmode
, DIVTF3_LIBCALL
);
3913 #ifdef SQRTTF2_LIBCALL
3914 sqrt_optab
->handlers
[(int) TFmode
].libfunc
3915 = gen_rtx (SYMBOL_REF
, Pmode
, SQRTTF2_LIBCALL
);
3918 /* Use cabs for DC complex abs, since systems generally have cabs.
3919 Don't define any libcall for SCmode, so that cabs will be used. */
3920 abs_optab
->handlers
[(int) DCmode
].libfunc
3921 = gen_rtx (SYMBOL_REF
, Pmode
, "cabs");
3923 /* The ffs function operates on `int'. */
3924 #ifndef INT_TYPE_SIZE
3925 #define INT_TYPE_SIZE BITS_PER_WORD
3927 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)] .libfunc
3928 = gen_rtx (SYMBOL_REF
, Pmode
, "ffs");
3930 extendsfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfdf2");
3931 extendsfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsfxf2");
3932 extendsftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extendsftf2");
3933 extenddfxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddfxf2");
3934 extenddftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__extenddftf2");
3936 truncdfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncdfsf2");
3937 truncxfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfsf2");
3938 trunctfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfsf2");
3939 truncxfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__truncxfdf2");
3940 trunctfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__trunctfdf2");
3942 memcpy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcpy");
3943 bcopy_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bcopy");
3944 memcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memcmp");
3945 bcmp_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gcc_bcmp");
3946 memset_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "memset");
3947 bzero_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "bzero");
3949 eqsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqsf2");
3950 nesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nesf2");
3951 gtsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtsf2");
3952 gesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gesf2");
3953 ltsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltsf2");
3954 lesf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lesf2");
3956 eqdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqdf2");
3957 nedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nedf2");
3958 gtdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtdf2");
3959 gedf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gedf2");
3960 ltdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltdf2");
3961 ledf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ledf2");
3963 eqxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqxf2");
3964 nexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__nexf2");
3965 gtxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gtxf2");
3966 gexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gexf2");
3967 ltxf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__ltxf2");
3968 lexf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lexf2");
3970 eqtf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__eqtf2");
3971 netf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__netf2");
3972 gttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__gttf2");
3973 getf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__getf2");
3974 lttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__lttf2");
3975 letf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__letf2");
3977 /* Define library calls for quad FP instructions */
3978 #ifdef EQTF2_LIBCALL
3979 eqtf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, EQTF2_LIBCALL
);
3981 #ifdef NETF2_LIBCALL
3982 netf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, NETF2_LIBCALL
);
3984 #ifdef GTTF2_LIBCALL
3985 gttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, GTTF2_LIBCALL
);
3987 #ifdef GETF2_LIBCALL
3988 getf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, GETF2_LIBCALL
);
3990 #ifdef LTTF2_LIBCALL
3991 lttf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, LTTF2_LIBCALL
);
3993 #ifdef LETF2_LIBCALL
3994 letf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, LETF2_LIBCALL
);
3997 floatsisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsisf");
3998 floatdisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdisf");
3999 floattisf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattisf");
4001 floatsidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsidf");
4002 floatdidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdidf");
4003 floattidf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattidf");
4005 floatsixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsixf");
4006 floatdixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatdixf");
4007 floattixf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattixf");
4009 floatsitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatsitf");
4010 floatditf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floatditf");
4011 floattitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__floattitf");
4013 fixsfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfsi");
4014 fixsfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfdi");
4015 fixsfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixsfti");
4017 fixdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfsi");
4018 fixdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfdi");
4019 fixdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixdfti");
4021 fixxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfsi");
4022 fixxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfdi");
4023 fixxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixxfti");
4025 fixtfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfsi");
4026 fixtfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfdi");
4027 fixtfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixtfti");
4029 fixunssfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfsi");
4030 fixunssfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfdi");
4031 fixunssfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunssfti");
4033 fixunsdfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfsi");
4034 fixunsdfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfdi");
4035 fixunsdfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsdfti");
4037 fixunsxfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfsi");
4038 fixunsxfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfdi");
4039 fixunsxfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunsxfti");
4041 fixunstfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfsi");
4042 fixunstfdi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfdi");
4043 fixunstfti_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, "__fixunstfti");
4045 /* Define library calls for quad FP instructions */
4046 #ifdef TRUNCTFSF2_LIBCALL
4047 trunctfsf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, TRUNCTFSF2_LIBCALL
);
4049 #ifdef TRUNCTFDF2_LIBCALL
4050 trunctfdf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, TRUNCTFDF2_LIBCALL
);
4052 #ifdef EXTENDSFTF2_LIBCALL
4053 extendsftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, EXTENDSFTF2_LIBCALL
);
4055 #ifdef EXTENDDFTF2_LIBCALL
4056 extenddftf2_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, EXTENDDFTF2_LIBCALL
);
4058 #ifdef FLOATSITF2_LIBCALL
4059 floatsitf_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, FLOATSITF2_LIBCALL
);
4061 #ifdef FIX_TRUNCTFSI2_LIBCALL
4062 fixtfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, FIX_TRUNCTFSI2_LIBCALL
);
4064 #ifdef FIXUNS_TRUNCTFSI2_LIBCALL
4065 fixunstfsi_libfunc
= gen_rtx (SYMBOL_REF
, Pmode
, FIXUNS_TRUNCTFSI2_LIBCALL
);
4071 /* SCO 3.2 apparently has a broken ldexp. */
4084 #endif /* BROKEN_LDEXP */