1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92-98, 1999 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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
26 /* Include insn-config.h before expr.h so that HAVE_conditional_move
27 is properly defined. */
28 #include "insn-config.h"
32 #include "insn-flags.h"
33 #include "insn-codes.h"
38 /* Each optab contains info on how this target machine
39 can perform a particular operation
40 for all sizes and kinds of operands.
42 The operation to be performed is often specified
43 by passing one of these optabs as an argument.
45 See expr.h for documentation of these optabs. */
50 optab smul_highpart_optab;
51 optab umul_highpart_optab;
52 optab smul_widen_optab;
53 optab umul_widen_optab;
76 optab movstrict_optab;
87 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
92 /* Tables of patterns for extending one integer mode to another. */
93 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
95 /* Tables of patterns for converting between fixed and floating point. */
96 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
97 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
98 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
100 /* Contains the optab used for each rtx code. */
101 optab code_to_optab[NUM_RTX_CODE + 1];
103 /* SYMBOL_REF rtx's for the library functions that are called
104 implicitly and not via optabs. */
106 rtx extendsfdf2_libfunc;
107 rtx extendsfxf2_libfunc;
108 rtx extendsftf2_libfunc;
109 rtx extenddfxf2_libfunc;
110 rtx extenddftf2_libfunc;
112 rtx truncdfsf2_libfunc;
113 rtx truncxfsf2_libfunc;
114 rtx trunctfsf2_libfunc;
115 rtx truncxfdf2_libfunc;
116 rtx trunctfdf2_libfunc;
128 rtx sjpopnthrow_libfunc;
129 rtx terminate_libfunc;
132 rtx eh_rtime_match_libfunc;
169 rtx floatsisf_libfunc;
170 rtx floatdisf_libfunc;
171 rtx floattisf_libfunc;
173 rtx floatsidf_libfunc;
174 rtx floatdidf_libfunc;
175 rtx floattidf_libfunc;
177 rtx floatsixf_libfunc;
178 rtx floatdixf_libfunc;
179 rtx floattixf_libfunc;
181 rtx floatsitf_libfunc;
182 rtx floatditf_libfunc;
183 rtx floattitf_libfunc;
201 rtx fixunssfsi_libfunc;
202 rtx fixunssfdi_libfunc;
203 rtx fixunssfti_libfunc;
205 rtx fixunsdfsi_libfunc;
206 rtx fixunsdfdi_libfunc;
207 rtx fixunsdfti_libfunc;
209 rtx fixunsxfsi_libfunc;
210 rtx fixunsxfdi_libfunc;
211 rtx fixunsxfti_libfunc;
213 rtx fixunstfsi_libfunc;
214 rtx fixunstfdi_libfunc;
215 rtx fixunstfti_libfunc;
217 rtx chkr_check_addr_libfunc;
218 rtx chkr_set_right_libfunc;
219 rtx chkr_copy_bitmap_libfunc;
220 rtx chkr_check_exec_libfunc;
221 rtx chkr_check_str_libfunc;
223 rtx profile_function_entry_libfunc;
224 rtx profile_function_exit_libfunc;
226 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
227 gives the gen_function to make a branch to test that condition. */
229 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
231 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
232 gives the insn code to make a store-condition insn
233 to test that condition. */
235 enum insn_code setcc_gen_code[NUM_RTX_CODE];
237 #ifdef HAVE_conditional_move
238 /* Indexed by the machine mode, gives the insn code to make a conditional
239 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
240 setcc_gen_code to cut down on the number of named patterns. Consider a day
241 when a lot more rtx codes are conditional (eg: for the ARM). */
243 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
246 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
247 static rtx widen_operand PROTO((rtx, enum machine_mode,
248 enum machine_mode, int, int));
249 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
251 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
253 static rtx ftruncify PROTO((rtx));
254 static optab init_optab PROTO((enum rtx_code));
255 static void init_libfuncs PROTO((optab, int, int, const char *, int));
256 static void init_integral_libfuncs PROTO((optab, const char *, int));
257 static void init_floating_libfuncs PROTO((optab, const char *, int));
258 #ifdef HAVE_conditional_trap
259 static void init_traps PROTO((void));
262 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
263 the result of operation CODE applied to OP0 (and OP1 if it is a binary
266 If the last insn does not set TARGET, don't do anything, but return 1.
268 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
269 don't add the REG_EQUAL note but return 0. Our caller can then try
270 again, ensuring that TARGET is not one of the operands. */
273 add_equal_note (seq, target, code, op0, op1)
283 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
284 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
285 || GET_CODE (seq) != SEQUENCE
286 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
287 || GET_CODE (target) == ZERO_EXTRACT
288 || (! rtx_equal_p (SET_DEST (set), target)
289 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
291 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
292 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
296 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
297 besides the last insn. */
298 if (reg_overlap_mentioned_p (target, op0)
299 || (op1 && reg_overlap_mentioned_p (target, op1)))
300 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
301 if (reg_set_p (target, XVECEXP (seq, 0, i)))
304 if (GET_RTX_CLASS (code) == '1')
305 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
307 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
309 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
314 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
315 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
316 not actually do a sign-extend or zero-extend, but can leave the
317 higher-order bits of the result rtx undefined, for example, in the case
318 of logical operations, but not right shifts. */
321 widen_operand (op, mode, oldmode, unsignedp, no_extend)
323 enum machine_mode mode, oldmode;
329 /* If we must extend do so. If OP is either a constant or a SUBREG
330 for a promoted object, also extend since it will be more efficient to
333 || GET_MODE (op) == VOIDmode
334 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
335 return convert_modes (mode, oldmode, op, unsignedp);
337 /* If MODE is no wider than a single word, we return a paradoxical
339 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
340 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
342 /* Otherwise, get an object of MODE, clobber it, and set the low-order
345 result = gen_reg_rtx (mode);
346 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
347 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
351 /* Generate code to perform an operation specified by BINOPTAB
352 on operands OP0 and OP1, with result having machine-mode MODE.
354 UNSIGNEDP is for the case where we have to widen the operands
355 to perform the operation. It says to use zero-extension.
357 If TARGET is nonzero, the value
358 is generated there, if it is convenient to do so.
359 In all cases an rtx is returned for the locus of the value;
360 this may or may not be TARGET. */
363 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
364 enum machine_mode mode;
369 enum optab_methods methods;
371 enum optab_methods next_methods
372 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
373 ? OPTAB_WIDEN : methods);
374 enum mode_class class;
375 enum machine_mode wider_mode;
377 int commutative_op = 0;
378 int shift_op = (binoptab->code == ASHIFT
379 || binoptab->code == ASHIFTRT
380 || binoptab->code == LSHIFTRT
381 || binoptab->code == ROTATE
382 || binoptab->code == ROTATERT);
383 rtx entry_last = get_last_insn ();
386 class = GET_MODE_CLASS (mode);
388 op0 = protect_from_queue (op0, 0);
389 op1 = protect_from_queue (op1, 0);
391 target = protect_from_queue (target, 1);
395 op0 = force_not_mem (op0);
396 op1 = force_not_mem (op1);
399 /* If subtracting an integer constant, convert this into an addition of
400 the negated constant. */
402 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
404 op1 = negate_rtx (mode, op1);
405 binoptab = add_optab;
408 /* If we are inside an appropriately-short loop and one operand is an
409 expensive constant, force it into a register. */
410 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
411 && rtx_cost (op0, binoptab->code) > 2)
412 op0 = force_reg (mode, op0);
414 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
415 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
416 op1 = force_reg (mode, op1);
418 /* Record where to delete back to if we backtrack. */
419 last = get_last_insn ();
421 /* If operation is commutative,
422 try to make the first operand a register.
423 Even better, try to make it the same as the target.
424 Also try to make the last operand a constant. */
425 if (GET_RTX_CLASS (binoptab->code) == 'c'
426 || binoptab == smul_widen_optab
427 || binoptab == umul_widen_optab
428 || binoptab == smul_highpart_optab
429 || binoptab == umul_highpart_optab)
433 if (((target == 0 || GET_CODE (target) == REG)
434 ? ((GET_CODE (op1) == REG
435 && GET_CODE (op0) != REG)
437 : rtx_equal_p (op1, target))
438 || GET_CODE (op0) == CONST_INT)
446 /* If we can do it with a three-operand insn, do so. */
448 if (methods != OPTAB_MUST_WIDEN
449 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
451 int icode = (int) binoptab->handlers[(int) mode].insn_code;
452 enum machine_mode mode0 = insn_operand_mode[icode][1];
453 enum machine_mode mode1 = insn_operand_mode[icode][2];
455 rtx xop0 = op0, xop1 = op1;
460 temp = gen_reg_rtx (mode);
462 /* If it is a commutative operator and the modes would match
463 if we would swap the operands, we can save the conversions. */
466 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
467 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
471 tmp = op0; op0 = op1; op1 = tmp;
472 tmp = xop0; xop0 = xop1; xop1 = tmp;
476 /* In case the insn wants input operands in modes different from
477 the result, convert the operands. */
479 if (GET_MODE (op0) != VOIDmode
480 && GET_MODE (op0) != mode0
481 && mode0 != VOIDmode)
482 xop0 = convert_to_mode (mode0, xop0, unsignedp);
484 if (GET_MODE (xop1) != VOIDmode
485 && GET_MODE (xop1) != mode1
486 && mode1 != VOIDmode)
487 xop1 = convert_to_mode (mode1, xop1, unsignedp);
489 /* Now, if insn's predicates don't allow our operands, put them into
492 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
493 && mode0 != VOIDmode)
494 xop0 = copy_to_mode_reg (mode0, xop0);
496 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
497 && mode1 != VOIDmode)
498 xop1 = copy_to_mode_reg (mode1, xop1);
500 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
501 temp = gen_reg_rtx (mode);
503 pat = GEN_FCN (icode) (temp, xop0, xop1);
506 /* If PAT is a multi-insn sequence, try to add an appropriate
507 REG_EQUAL note to it. If we can't because TEMP conflicts with an
508 operand, call ourselves again, this time without a target. */
509 if (GET_CODE (pat) == SEQUENCE
510 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
512 delete_insns_since (last);
513 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
521 delete_insns_since (last);
524 /* If this is a multiply, see if we can do a widening operation that
525 takes operands of this mode and makes a wider mode. */
527 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
528 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
529 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
530 != CODE_FOR_nothing))
532 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
533 unsignedp ? umul_widen_optab : smul_widen_optab,
534 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
538 if (GET_MODE_CLASS (mode) == MODE_INT)
539 return gen_lowpart (mode, temp);
541 return convert_to_mode (mode, temp, unsignedp);
545 /* Look for a wider mode of the same class for which we think we
546 can open-code the operation. Check for a widening multiply at the
547 wider mode as well. */
549 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
550 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
551 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
552 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
554 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
555 || (binoptab == smul_optab
556 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
557 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
558 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
559 != CODE_FOR_nothing)))
561 rtx xop0 = op0, xop1 = op1;
564 /* For certain integer operations, we need not actually extend
565 the narrow operands, as long as we will truncate
566 the results to the same narrowness. */
568 if ((binoptab == ior_optab || binoptab == and_optab
569 || binoptab == xor_optab
570 || binoptab == add_optab || binoptab == sub_optab
571 || binoptab == smul_optab || binoptab == ashl_optab)
572 && class == MODE_INT)
575 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
577 /* The second operand of a shift must always be extended. */
578 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
579 no_extend && binoptab != ashl_optab);
581 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
582 unsignedp, OPTAB_DIRECT);
585 if (class != MODE_INT)
588 target = gen_reg_rtx (mode);
589 convert_move (target, temp, 0);
593 return gen_lowpart (mode, temp);
596 delete_insns_since (last);
600 /* These can be done a word at a time. */
601 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
603 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
604 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
610 /* If TARGET is the same as one of the operands, the REG_EQUAL note
611 won't be accurate, so use a new target. */
612 if (target == 0 || target == op0 || target == op1)
613 target = gen_reg_rtx (mode);
617 /* Do the actual arithmetic. */
618 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
620 rtx target_piece = operand_subword (target, i, 1, mode);
621 rtx x = expand_binop (word_mode, binoptab,
622 operand_subword_force (op0, i, mode),
623 operand_subword_force (op1, i, mode),
624 target_piece, unsignedp, next_methods);
629 if (target_piece != x)
630 emit_move_insn (target_piece, x);
633 insns = get_insns ();
636 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
638 if (binoptab->code != UNKNOWN)
640 = gen_rtx_fmt_ee (binoptab->code, mode,
641 copy_rtx (op0), copy_rtx (op1));
645 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
650 /* Synthesize double word shifts from single word shifts. */
651 if ((binoptab == lshr_optab || binoptab == ashl_optab
652 || binoptab == ashr_optab)
654 && GET_CODE (op1) == CONST_INT
655 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
656 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
657 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
658 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
660 rtx insns, inter, equiv_value;
661 rtx into_target, outof_target;
662 rtx into_input, outof_input;
663 int shift_count, left_shift, outof_word;
665 /* If TARGET is the same as one of the operands, the REG_EQUAL note
666 won't be accurate, so use a new target. */
667 if (target == 0 || target == op0 || target == op1)
668 target = gen_reg_rtx (mode);
672 shift_count = INTVAL (op1);
674 /* OUTOF_* is the word we are shifting bits away from, and
675 INTO_* is the word that we are shifting bits towards, thus
676 they differ depending on the direction of the shift and
679 left_shift = binoptab == ashl_optab;
680 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
682 outof_target = operand_subword (target, outof_word, 1, mode);
683 into_target = operand_subword (target, 1 - outof_word, 1, mode);
685 outof_input = operand_subword_force (op0, outof_word, mode);
686 into_input = operand_subword_force (op0, 1 - outof_word, mode);
688 if (shift_count >= BITS_PER_WORD)
690 inter = expand_binop (word_mode, binoptab,
692 GEN_INT (shift_count - BITS_PER_WORD),
693 into_target, unsignedp, next_methods);
695 if (inter != 0 && inter != into_target)
696 emit_move_insn (into_target, inter);
698 /* For a signed right shift, we must fill the word we are shifting
699 out of with copies of the sign bit. Otherwise it is zeroed. */
700 if (inter != 0 && binoptab != ashr_optab)
701 inter = CONST0_RTX (word_mode);
703 inter = expand_binop (word_mode, binoptab,
705 GEN_INT (BITS_PER_WORD - 1),
706 outof_target, unsignedp, next_methods);
708 if (inter != 0 && inter != outof_target)
709 emit_move_insn (outof_target, inter);
714 optab reverse_unsigned_shift, unsigned_shift;
716 /* For a shift of less then BITS_PER_WORD, to compute the carry,
717 we must do a logical shift in the opposite direction of the
720 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
722 /* For a shift of less than BITS_PER_WORD, to compute the word
723 shifted towards, we need to unsigned shift the orig value of
726 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
728 carries = expand_binop (word_mode, reverse_unsigned_shift,
730 GEN_INT (BITS_PER_WORD - shift_count),
731 0, unsignedp, next_methods);
736 inter = expand_binop (word_mode, unsigned_shift, into_input,
737 op1, 0, unsignedp, next_methods);
740 inter = expand_binop (word_mode, ior_optab, carries, inter,
741 into_target, unsignedp, next_methods);
743 if (inter != 0 && inter != into_target)
744 emit_move_insn (into_target, inter);
747 inter = expand_binop (word_mode, binoptab, outof_input,
748 op1, outof_target, unsignedp, next_methods);
750 if (inter != 0 && inter != outof_target)
751 emit_move_insn (outof_target, inter);
754 insns = get_insns ();
759 if (binoptab->code != UNKNOWN)
760 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
764 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
769 /* Synthesize double word rotates from single word shifts. */
770 if ((binoptab == rotl_optab || binoptab == rotr_optab)
772 && GET_CODE (op1) == CONST_INT
773 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
774 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
775 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
777 rtx insns, equiv_value;
778 rtx into_target, outof_target;
779 rtx into_input, outof_input;
781 int shift_count, left_shift, outof_word;
783 /* If TARGET is the same as one of the operands, the REG_EQUAL note
784 won't be accurate, so use a new target. */
785 if (target == 0 || target == op0 || target == op1)
786 target = gen_reg_rtx (mode);
790 shift_count = INTVAL (op1);
792 /* OUTOF_* is the word we are shifting bits away from, and
793 INTO_* is the word that we are shifting bits towards, thus
794 they differ depending on the direction of the shift and
797 left_shift = (binoptab == rotl_optab);
798 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
800 outof_target = operand_subword (target, outof_word, 1, mode);
801 into_target = operand_subword (target, 1 - outof_word, 1, mode);
803 outof_input = operand_subword_force (op0, outof_word, mode);
804 into_input = operand_subword_force (op0, 1 - outof_word, mode);
806 if (shift_count == BITS_PER_WORD)
808 /* This is just a word swap. */
809 emit_move_insn (outof_target, into_input);
810 emit_move_insn (into_target, outof_input);
815 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
816 rtx first_shift_count, second_shift_count;
817 optab reverse_unsigned_shift, unsigned_shift;
819 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
820 ? lshr_optab : ashl_optab);
822 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
823 ? ashl_optab : lshr_optab);
825 if (shift_count > BITS_PER_WORD)
827 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
828 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
832 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
833 second_shift_count = GEN_INT (shift_count);
836 into_temp1 = expand_binop (word_mode, unsigned_shift,
837 outof_input, first_shift_count,
838 NULL_RTX, unsignedp, next_methods);
839 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
840 into_input, second_shift_count,
841 into_target, unsignedp, next_methods);
843 if (into_temp1 != 0 && into_temp2 != 0)
844 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
845 into_target, unsignedp, next_methods);
849 if (inter != 0 && inter != into_target)
850 emit_move_insn (into_target, inter);
852 outof_temp1 = expand_binop (word_mode, unsigned_shift,
853 into_input, first_shift_count,
854 NULL_RTX, unsignedp, next_methods);
855 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
856 outof_input, second_shift_count,
857 outof_target, unsignedp, next_methods);
859 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
860 inter = expand_binop (word_mode, ior_optab,
861 outof_temp1, outof_temp2,
862 outof_target, unsignedp, next_methods);
864 if (inter != 0 && inter != outof_target)
865 emit_move_insn (outof_target, inter);
868 insns = get_insns ();
873 if (binoptab->code != UNKNOWN)
874 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
878 /* We can't make this a no conflict block if this is a word swap,
879 because the word swap case fails if the input and output values
880 are in the same register. */
881 if (shift_count != BITS_PER_WORD)
882 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
891 /* These can be done a word at a time by propagating carries. */
892 if ((binoptab == add_optab || binoptab == sub_optab)
894 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
895 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
898 rtx carry_tmp = gen_reg_rtx (word_mode);
899 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
900 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
901 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
904 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
905 value is one of those, use it. Otherwise, use 1 since it is the
906 one easiest to get. */
907 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
908 int normalizep = STORE_FLAG_VALUE;
913 /* Prepare the operands. */
914 xop0 = force_reg (mode, op0);
915 xop1 = force_reg (mode, op1);
917 if (target == 0 || GET_CODE (target) != REG
918 || target == xop0 || target == xop1)
919 target = gen_reg_rtx (mode);
921 /* Indicate for flow that the entire target reg is being set. */
922 if (GET_CODE (target) == REG)
923 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
925 /* Do the actual arithmetic. */
926 for (i = 0; i < nwords; i++)
928 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
929 rtx target_piece = operand_subword (target, index, 1, mode);
930 rtx op0_piece = operand_subword_force (xop0, index, mode);
931 rtx op1_piece = operand_subword_force (xop1, index, mode);
934 /* Main add/subtract of the input operands. */
935 x = expand_binop (word_mode, binoptab,
936 op0_piece, op1_piece,
937 target_piece, unsignedp, next_methods);
943 /* Store carry from main add/subtract. */
944 carry_out = gen_reg_rtx (word_mode);
945 carry_out = emit_store_flag_force (carry_out,
946 (binoptab == add_optab
949 word_mode, 1, normalizep);
954 /* Add/subtract previous carry to main result. */
955 x = expand_binop (word_mode,
956 normalizep == 1 ? binoptab : otheroptab,
958 target_piece, 1, next_methods);
961 else if (target_piece != x)
962 emit_move_insn (target_piece, x);
966 /* THIS CODE HAS NOT BEEN TESTED. */
967 /* Get out carry from adding/subtracting carry in. */
968 carry_tmp = emit_store_flag_force (carry_tmp,
969 binoptab == add_optab
972 word_mode, 1, normalizep);
974 /* Logical-ior the two poss. carry together. */
975 carry_out = expand_binop (word_mode, ior_optab,
976 carry_out, carry_tmp,
977 carry_out, 0, next_methods);
983 carry_in = carry_out;
986 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
988 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
990 rtx temp = emit_move_insn (target, target);
992 set_unique_reg_note (temp,
994 gen_rtx_fmt_ee (binoptab->code, mode,
1001 delete_insns_since (last);
1004 /* If we want to multiply two two-word values and have normal and widening
1005 multiplies of single-word values, we can do this with three smaller
1006 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1007 because we are not operating on one word at a time.
1009 The multiplication proceeds as follows:
1010 _______________________
1011 [__op0_high_|__op0_low__]
1012 _______________________
1013 * [__op1_high_|__op1_low__]
1014 _______________________________________________
1015 _______________________
1016 (1) [__op0_low__*__op1_low__]
1017 _______________________
1018 (2a) [__op0_low__*__op1_high_]
1019 _______________________
1020 (2b) [__op0_high_*__op1_low__]
1021 _______________________
1022 (3) [__op0_high_*__op1_high_]
1025 This gives a 4-word result. Since we are only interested in the
1026 lower 2 words, partial result (3) and the upper words of (2a) and
1027 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1028 calculated using non-widening multiplication.
1030 (1), however, needs to be calculated with an unsigned widening
1031 multiplication. If this operation is not directly supported we
1032 try using a signed widening multiplication and adjust the result.
1033 This adjustment works as follows:
1035 If both operands are positive then no adjustment is needed.
1037 If the operands have different signs, for example op0_low < 0 and
1038 op1_low >= 0, the instruction treats the most significant bit of
1039 op0_low as a sign bit instead of a bit with significance
1040 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1041 with 2**BITS_PER_WORD - op0_low, and two's complements the
1042 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1045 Similarly, if both operands are negative, we need to add
1046 (op0_low + op1_low) * 2**BITS_PER_WORD.
1048 We use a trick to adjust quickly. We logically shift op0_low right
1049 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1050 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1051 logical shift exists, we do an arithmetic right shift and subtract
1054 if (binoptab == smul_optab
1055 && class == MODE_INT
1056 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1057 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1058 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1059 && ((umul_widen_optab->handlers[(int) mode].insn_code
1060 != CODE_FOR_nothing)
1061 || (smul_widen_optab->handlers[(int) mode].insn_code
1062 != CODE_FOR_nothing)))
1064 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1065 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1066 rtx op0_high = operand_subword_force (op0, high, mode);
1067 rtx op0_low = operand_subword_force (op0, low, mode);
1068 rtx op1_high = operand_subword_force (op1, high, mode);
1069 rtx op1_low = operand_subword_force (op1, low, mode);
1071 rtx op0_xhigh = NULL_RTX;
1072 rtx op1_xhigh = NULL_RTX;
1074 /* If the target is the same as one of the inputs, don't use it. This
1075 prevents problems with the REG_EQUAL note. */
1076 if (target == op0 || target == op1
1077 || (target != 0 && GET_CODE (target) != REG))
1080 /* Multiply the two lower words to get a double-word product.
1081 If unsigned widening multiplication is available, use that;
1082 otherwise use the signed form and compensate. */
1084 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1086 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1087 target, 1, OPTAB_DIRECT);
1089 /* If we didn't succeed, delete everything we did so far. */
1091 delete_insns_since (last);
1093 op0_xhigh = op0_high, op1_xhigh = op1_high;
1097 && smul_widen_optab->handlers[(int) mode].insn_code
1098 != CODE_FOR_nothing)
1100 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1101 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1102 target, 1, OPTAB_DIRECT);
1103 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1104 NULL_RTX, 1, next_methods);
1106 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1107 op0_xhigh, op0_xhigh, 0, next_methods);
1110 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1111 NULL_RTX, 0, next_methods);
1113 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1114 op0_xhigh, op0_xhigh, 0,
1118 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1119 NULL_RTX, 1, next_methods);
1121 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1122 op1_xhigh, op1_xhigh, 0, next_methods);
1125 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1126 NULL_RTX, 0, next_methods);
1128 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1129 op1_xhigh, op1_xhigh, 0,
1134 /* If we have been able to directly compute the product of the
1135 low-order words of the operands and perform any required adjustments
1136 of the operands, we proceed by trying two more multiplications
1137 and then computing the appropriate sum.
1139 We have checked above that the required addition is provided.
1140 Full-word addition will normally always succeed, especially if
1141 it is provided at all, so we don't worry about its failure. The
1142 multiplication may well fail, however, so we do handle that. */
1144 if (product && op0_xhigh && op1_xhigh)
1146 rtx product_high = operand_subword (product, high, 1, mode);
1147 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1148 NULL_RTX, 0, OPTAB_DIRECT);
1151 temp = expand_binop (word_mode, add_optab, temp, product_high,
1152 product_high, 0, next_methods);
1154 if (temp != 0 && temp != product_high)
1155 emit_move_insn (product_high, temp);
1158 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1159 NULL_RTX, 0, OPTAB_DIRECT);
1162 temp = expand_binop (word_mode, add_optab, temp,
1163 product_high, product_high,
1166 if (temp != 0 && temp != product_high)
1167 emit_move_insn (product_high, temp);
1171 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1173 temp = emit_move_insn (product, product);
1174 set_unique_reg_note (temp,
1176 gen_rtx_fmt_ee (MULT, mode,
1184 /* If we get here, we couldn't do it for some reason even though we
1185 originally thought we could. Delete anything we've emitted in
1188 delete_insns_since (last);
1191 /* We need to open-code the complex type operations: '+, -, * and /' */
1193 /* At this point we allow operations between two similar complex
1194 numbers, and also if one of the operands is not a complex number
1195 but rather of MODE_FLOAT or MODE_INT. However, the caller
1196 must make sure that the MODE of the non-complex operand matches
1197 the SUBMODE of the complex operand. */
1199 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1201 rtx real0 = 0, imag0 = 0;
1202 rtx real1 = 0, imag1 = 0;
1203 rtx realr, imagr, res;
1208 /* Find the correct mode for the real and imaginary parts */
1209 enum machine_mode submode
1210 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1211 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1214 if (submode == BLKmode)
1218 target = gen_reg_rtx (mode);
1222 realr = gen_realpart (submode, target);
1223 imagr = gen_imagpart (submode, target);
1225 if (GET_MODE (op0) == mode)
1227 real0 = gen_realpart (submode, op0);
1228 imag0 = gen_imagpart (submode, op0);
1233 if (GET_MODE (op1) == mode)
1235 real1 = gen_realpart (submode, op1);
1236 imag1 = gen_imagpart (submode, op1);
1241 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1244 switch (binoptab->code)
1247 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1249 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1250 res = expand_binop (submode, binoptab, real0, real1,
1251 realr, unsignedp, methods);
1255 else if (res != realr)
1256 emit_move_insn (realr, res);
1259 res = expand_binop (submode, binoptab, imag0, imag1,
1260 imagr, unsignedp, methods);
1263 else if (binoptab->code == MINUS)
1264 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1270 else if (res != imagr)
1271 emit_move_insn (imagr, res);
1277 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1283 /* Don't fetch these from memory more than once. */
1284 real0 = force_reg (submode, real0);
1285 real1 = force_reg (submode, real1);
1286 imag0 = force_reg (submode, imag0);
1287 imag1 = force_reg (submode, imag1);
1289 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1290 unsignedp, methods);
1292 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1293 unsignedp, methods);
1295 if (temp1 == 0 || temp2 == 0)
1298 res = expand_binop (submode, sub_optab, temp1, temp2,
1299 realr, unsignedp, methods);
1303 else if (res != realr)
1304 emit_move_insn (realr, res);
1306 temp1 = expand_binop (submode, binoptab, real0, imag1,
1307 NULL_RTX, unsignedp, methods);
1309 temp2 = expand_binop (submode, binoptab, real1, imag0,
1310 NULL_RTX, unsignedp, methods);
1312 if (temp1 == 0 || temp2 == 0)
1315 res = expand_binop (submode, add_optab, temp1, temp2,
1316 imagr, unsignedp, methods);
1320 else if (res != imagr)
1321 emit_move_insn (imagr, res);
1327 /* Don't fetch these from memory more than once. */
1328 real0 = force_reg (submode, real0);
1329 real1 = force_reg (submode, real1);
1331 res = expand_binop (submode, binoptab, real0, real1,
1332 realr, unsignedp, methods);
1335 else if (res != realr)
1336 emit_move_insn (realr, res);
1339 res = expand_binop (submode, binoptab,
1340 real1, imag0, imagr, unsignedp, methods);
1342 res = expand_binop (submode, binoptab,
1343 real0, imag1, imagr, unsignedp, methods);
1347 else if (res != imagr)
1348 emit_move_insn (imagr, res);
1355 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1359 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1361 /* Don't fetch these from memory more than once. */
1362 real1 = force_reg (submode, real1);
1364 /* Simply divide the real and imaginary parts by `c' */
1365 if (class == MODE_COMPLEX_FLOAT)
1366 res = expand_binop (submode, binoptab, real0, real1,
1367 realr, unsignedp, methods);
1369 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1370 real0, real1, realr, unsignedp);
1374 else if (res != realr)
1375 emit_move_insn (realr, res);
1377 if (class == MODE_COMPLEX_FLOAT)
1378 res = expand_binop (submode, binoptab, imag0, real1,
1379 imagr, unsignedp, methods);
1381 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1382 imag0, real1, imagr, unsignedp);
1386 else if (res != imagr)
1387 emit_move_insn (imagr, res);
1393 /* Divisor is of complex type:
1399 /* Don't fetch these from memory more than once. */
1400 real0 = force_reg (submode, real0);
1401 real1 = force_reg (submode, real1);
1404 imag0 = force_reg (submode, imag0);
1406 imag1 = force_reg (submode, imag1);
1408 /* Divisor: c*c + d*d */
1409 temp1 = expand_binop (submode, smul_optab, real1, real1,
1410 NULL_RTX, unsignedp, methods);
1412 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1413 NULL_RTX, unsignedp, methods);
1415 if (temp1 == 0 || temp2 == 0)
1418 divisor = expand_binop (submode, add_optab, temp1, temp2,
1419 NULL_RTX, unsignedp, methods);
1425 /* ((a)(c-id))/divisor */
1426 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1428 /* Calculate the dividend */
1429 real_t = expand_binop (submode, smul_optab, real0, real1,
1430 NULL_RTX, unsignedp, methods);
1432 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1433 NULL_RTX, unsignedp, methods);
1435 if (real_t == 0 || imag_t == 0)
1438 imag_t = expand_unop (submode, neg_optab, imag_t,
1439 NULL_RTX, unsignedp);
1443 /* ((a+ib)(c-id))/divider */
1444 /* Calculate the dividend */
1445 temp1 = expand_binop (submode, smul_optab, real0, real1,
1446 NULL_RTX, unsignedp, methods);
1448 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1449 NULL_RTX, unsignedp, methods);
1451 if (temp1 == 0 || temp2 == 0)
1454 real_t = expand_binop (submode, add_optab, temp1, temp2,
1455 NULL_RTX, unsignedp, methods);
1457 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1458 NULL_RTX, unsignedp, methods);
1460 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1461 NULL_RTX, unsignedp, methods);
1463 if (temp1 == 0 || temp2 == 0)
1466 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1467 NULL_RTX, unsignedp, methods);
1469 if (real_t == 0 || imag_t == 0)
1473 if (class == MODE_COMPLEX_FLOAT)
1474 res = expand_binop (submode, binoptab, real_t, divisor,
1475 realr, unsignedp, methods);
1477 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1478 real_t, divisor, realr, unsignedp);
1482 else if (res != realr)
1483 emit_move_insn (realr, res);
1485 if (class == MODE_COMPLEX_FLOAT)
1486 res = expand_binop (submode, binoptab, imag_t, divisor,
1487 imagr, unsignedp, methods);
1489 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1490 imag_t, divisor, imagr, unsignedp);
1494 else if (res != imagr)
1495 emit_move_insn (imagr, res);
1510 if (binoptab->code != UNKNOWN)
1512 = gen_rtx_fmt_ee (binoptab->code, mode,
1513 copy_rtx (op0), copy_rtx (op1));
1517 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1523 /* It can't be open-coded in this mode.
1524 Use a library call if one is available and caller says that's ok. */
1526 if (binoptab->handlers[(int) mode].libfunc
1527 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1531 enum machine_mode op1_mode = mode;
1538 op1_mode = word_mode;
1539 /* Specify unsigned here,
1540 since negative shift counts are meaningless. */
1541 op1x = convert_to_mode (word_mode, op1, 1);
1544 if (GET_MODE (op0) != VOIDmode
1545 && GET_MODE (op0) != mode)
1546 op0 = convert_to_mode (mode, op0, unsignedp);
1548 /* Pass 1 for NO_QUEUE so we don't lose any increments
1549 if the libcall is cse'd or moved. */
1550 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1551 NULL_RTX, 1, mode, 2,
1552 op0, mode, op1x, op1_mode);
1554 insns = get_insns ();
1557 target = gen_reg_rtx (mode);
1558 emit_libcall_block (insns, target, value,
1559 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1564 delete_insns_since (last);
1566 /* It can't be done in this mode. Can we do it in a wider mode? */
1568 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1569 || methods == OPTAB_MUST_WIDEN))
1571 /* Caller says, don't even try. */
1572 delete_insns_since (entry_last);
1576 /* Compute the value of METHODS to pass to recursive calls.
1577 Don't allow widening to be tried recursively. */
1579 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1581 /* Look for a wider mode of the same class for which it appears we can do
1584 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1586 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1587 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1589 if ((binoptab->handlers[(int) wider_mode].insn_code
1590 != CODE_FOR_nothing)
1591 || (methods == OPTAB_LIB
1592 && binoptab->handlers[(int) wider_mode].libfunc))
1594 rtx xop0 = op0, xop1 = op1;
1597 /* For certain integer operations, we need not actually extend
1598 the narrow operands, as long as we will truncate
1599 the results to the same narrowness. */
1601 if ((binoptab == ior_optab || binoptab == and_optab
1602 || binoptab == xor_optab
1603 || binoptab == add_optab || binoptab == sub_optab
1604 || binoptab == smul_optab || binoptab == ashl_optab)
1605 && class == MODE_INT)
1608 xop0 = widen_operand (xop0, wider_mode, mode,
1609 unsignedp, no_extend);
1611 /* The second operand of a shift must always be extended. */
1612 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1613 no_extend && binoptab != ashl_optab);
1615 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1616 unsignedp, methods);
1619 if (class != MODE_INT)
1622 target = gen_reg_rtx (mode);
1623 convert_move (target, temp, 0);
1627 return gen_lowpart (mode, temp);
1630 delete_insns_since (last);
1635 delete_insns_since (entry_last);
1639 /* Expand a binary operator which has both signed and unsigned forms.
1640 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1643 If we widen unsigned operands, we may use a signed wider operation instead
1644 of an unsigned wider operation, since the result would be the same. */
1647 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1648 enum machine_mode mode;
1649 optab uoptab, soptab;
1650 rtx op0, op1, target;
1652 enum optab_methods methods;
1655 optab direct_optab = unsignedp ? uoptab : soptab;
1656 struct optab wide_soptab;
1658 /* Do it without widening, if possible. */
1659 temp = expand_binop (mode, direct_optab, op0, op1, target,
1660 unsignedp, OPTAB_DIRECT);
1661 if (temp || methods == OPTAB_DIRECT)
1664 /* Try widening to a signed int. Make a fake signed optab that
1665 hides any signed insn for direct use. */
1666 wide_soptab = *soptab;
1667 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1668 wide_soptab.handlers[(int) mode].libfunc = 0;
1670 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1671 unsignedp, OPTAB_WIDEN);
1673 /* For unsigned operands, try widening to an unsigned int. */
1674 if (temp == 0 && unsignedp)
1675 temp = expand_binop (mode, uoptab, op0, op1, target,
1676 unsignedp, OPTAB_WIDEN);
1677 if (temp || methods == OPTAB_WIDEN)
1680 /* Use the right width lib call if that exists. */
1681 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1682 if (temp || methods == OPTAB_LIB)
1685 /* Must widen and use a lib call, use either signed or unsigned. */
1686 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1687 unsignedp, methods);
1691 return expand_binop (mode, uoptab, op0, op1, target,
1692 unsignedp, methods);
1696 /* Generate code to perform an operation specified by BINOPTAB
1697 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1698 We assume that the order of the operands for the instruction
1699 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1700 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1702 Either TARG0 or TARG1 may be zero, but what that means is that
1703 the result is not actually wanted. We will generate it into
1704 a dummy pseudo-reg and discard it. They may not both be zero.
1706 Returns 1 if this operation can be performed; 0 if not. */
1709 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1715 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1716 enum mode_class class;
1717 enum machine_mode wider_mode;
1718 rtx entry_last = get_last_insn ();
1721 class = GET_MODE_CLASS (mode);
1723 op0 = protect_from_queue (op0, 0);
1724 op1 = protect_from_queue (op1, 0);
1728 op0 = force_not_mem (op0);
1729 op1 = force_not_mem (op1);
1732 /* If we are inside an appropriately-short loop and one operand is an
1733 expensive constant, force it into a register. */
1734 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1735 && rtx_cost (op0, binoptab->code) > 2)
1736 op0 = force_reg (mode, op0);
1738 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1739 && rtx_cost (op1, binoptab->code) > 2)
1740 op1 = force_reg (mode, op1);
1743 targ0 = protect_from_queue (targ0, 1);
1745 targ0 = gen_reg_rtx (mode);
1747 targ1 = protect_from_queue (targ1, 1);
1749 targ1 = gen_reg_rtx (mode);
1751 /* Record where to go back to if we fail. */
1752 last = get_last_insn ();
1754 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1756 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1757 enum machine_mode mode0 = insn_operand_mode[icode][1];
1758 enum machine_mode mode1 = insn_operand_mode[icode][2];
1760 rtx xop0 = op0, xop1 = op1;
1762 /* In case this insn wants input operands in modes different from the
1763 result, convert the operands. */
1764 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1765 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1767 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1768 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1770 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1771 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1772 xop0 = copy_to_mode_reg (mode0, xop0);
1774 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1775 xop1 = copy_to_mode_reg (mode1, xop1);
1777 /* We could handle this, but we should always be called with a pseudo
1778 for our targets and all insns should take them as outputs. */
1779 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1780 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1783 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1790 delete_insns_since (last);
1793 /* It can't be done in this mode. Can we do it in a wider mode? */
1795 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1797 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1798 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1800 if (binoptab->handlers[(int) wider_mode].insn_code
1801 != CODE_FOR_nothing)
1803 register rtx t0 = gen_reg_rtx (wider_mode);
1804 register rtx t1 = gen_reg_rtx (wider_mode);
1806 if (expand_twoval_binop (binoptab,
1807 convert_modes (wider_mode, mode, op0,
1809 convert_modes (wider_mode, mode, op1,
1813 convert_move (targ0, t0, unsignedp);
1814 convert_move (targ1, t1, unsignedp);
1818 delete_insns_since (last);
1823 delete_insns_since (entry_last);
1827 /* Generate code to perform an operation specified by UNOPTAB
1828 on operand OP0, with result having machine-mode MODE.
1830 UNSIGNEDP is for the case where we have to widen the operands
1831 to perform the operation. It says to use zero-extension.
1833 If TARGET is nonzero, the value
1834 is generated there, if it is convenient to do so.
1835 In all cases an rtx is returned for the locus of the value;
1836 this may or may not be TARGET. */
1839 expand_unop (mode, unoptab, op0, target, unsignedp)
1840 enum machine_mode mode;
1846 enum mode_class class;
1847 enum machine_mode wider_mode;
1849 rtx last = get_last_insn ();
1852 class = GET_MODE_CLASS (mode);
1854 op0 = protect_from_queue (op0, 0);
1858 op0 = force_not_mem (op0);
1862 target = protect_from_queue (target, 1);
1864 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1866 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1867 enum machine_mode mode0 = insn_operand_mode[icode][1];
1873 temp = gen_reg_rtx (mode);
1875 if (GET_MODE (xop0) != VOIDmode
1876 && GET_MODE (xop0) != mode0)
1877 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1879 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1881 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1882 xop0 = copy_to_mode_reg (mode0, xop0);
1884 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1885 temp = gen_reg_rtx (mode);
1887 pat = GEN_FCN (icode) (temp, xop0);
1890 if (GET_CODE (pat) == SEQUENCE
1891 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1893 delete_insns_since (last);
1894 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1902 delete_insns_since (last);
1905 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1907 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1908 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1909 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1911 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1915 /* For certain operations, we need not actually extend
1916 the narrow operand, as long as we will truncate the
1917 results to the same narrowness. */
1919 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1920 (unoptab == neg_optab
1921 || unoptab == one_cmpl_optab)
1922 && class == MODE_INT);
1924 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1929 if (class != MODE_INT)
1932 target = gen_reg_rtx (mode);
1933 convert_move (target, temp, 0);
1937 return gen_lowpart (mode, temp);
1940 delete_insns_since (last);
1944 /* These can be done a word at a time. */
1945 if (unoptab == one_cmpl_optab
1946 && class == MODE_INT
1947 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1948 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1953 if (target == 0 || target == op0)
1954 target = gen_reg_rtx (mode);
1958 /* Do the actual arithmetic. */
1959 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1961 rtx target_piece = operand_subword (target, i, 1, mode);
1962 rtx x = expand_unop (word_mode, unoptab,
1963 operand_subword_force (op0, i, mode),
1964 target_piece, unsignedp);
1965 if (target_piece != x)
1966 emit_move_insn (target_piece, x);
1969 insns = get_insns ();
1972 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1973 gen_rtx_fmt_e (unoptab->code, mode,
1978 /* Open-code the complex negation operation. */
1979 else if (unoptab == neg_optab
1980 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1986 /* Find the correct mode for the real and imaginary parts */
1987 enum machine_mode submode
1988 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1989 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1992 if (submode == BLKmode)
1996 target = gen_reg_rtx (mode);
2000 target_piece = gen_imagpart (submode, target);
2001 x = expand_unop (submode, unoptab,
2002 gen_imagpart (submode, op0),
2003 target_piece, unsignedp);
2004 if (target_piece != x)
2005 emit_move_insn (target_piece, x);
2007 target_piece = gen_realpart (submode, target);
2008 x = expand_unop (submode, unoptab,
2009 gen_realpart (submode, op0),
2010 target_piece, unsignedp);
2011 if (target_piece != x)
2012 emit_move_insn (target_piece, x);
2017 emit_no_conflict_block (seq, target, op0, 0,
2018 gen_rtx_fmt_e (unoptab->code, mode,
2023 /* Now try a library call in this mode. */
2024 if (unoptab->handlers[(int) mode].libfunc)
2031 /* Pass 1 for NO_QUEUE so we don't lose any increments
2032 if the libcall is cse'd or moved. */
2033 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2034 NULL_RTX, 1, mode, 1, op0, mode);
2035 insns = get_insns ();
2038 target = gen_reg_rtx (mode);
2039 emit_libcall_block (insns, target, value,
2040 gen_rtx_fmt_e (unoptab->code, mode, op0));
2045 /* It can't be done in this mode. Can we do it in a wider mode? */
2047 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2049 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2050 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2052 if ((unoptab->handlers[(int) wider_mode].insn_code
2053 != CODE_FOR_nothing)
2054 || unoptab->handlers[(int) wider_mode].libfunc)
2058 /* For certain operations, we need not actually extend
2059 the narrow operand, as long as we will truncate the
2060 results to the same narrowness. */
2062 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2063 (unoptab == neg_optab
2064 || unoptab == one_cmpl_optab)
2065 && class == MODE_INT);
2067 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2072 if (class != MODE_INT)
2075 target = gen_reg_rtx (mode);
2076 convert_move (target, temp, 0);
2080 return gen_lowpart (mode, temp);
2083 delete_insns_since (last);
2088 /* If there is no negate operation, try doing a subtract from zero.
2089 The US Software GOFAST library needs this. */
2090 if (unoptab == neg_optab)
2093 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2094 target, unsignedp, OPTAB_LIB_WIDEN);
2102 /* Emit code to compute the absolute value of OP0, with result to
2103 TARGET if convenient. (TARGET may be 0.) The return value says
2104 where the result actually is to be found.
2106 MODE is the mode of the operand; the mode of the result is
2107 different but can be deduced from MODE.
2112 expand_abs (mode, op0, target, safe)
2113 enum machine_mode mode;
2120 /* First try to do it with a special abs instruction. */
2121 temp = expand_unop (mode, abs_optab, op0, target, 0);
2125 /* If this machine has expensive jumps, we can do integer absolute
2126 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2127 where W is the width of MODE. */
2129 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2131 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2132 size_int (GET_MODE_BITSIZE (mode) - 1),
2135 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2138 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2145 /* If that does not win, use conditional jump and negate. */
2147 /* It is safe to use the target if it is the same
2148 as the source if this is also a pseudo register */
2149 if (op0 == target && GET_CODE (op0) == REG
2150 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2153 op1 = gen_label_rtx ();
2154 if (target == 0 || ! safe
2155 || GET_MODE (target) != mode
2156 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2157 || (GET_CODE (target) == REG
2158 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2159 target = gen_reg_rtx (mode);
2161 emit_move_insn (target, op0);
2164 /* If this mode is an integer too wide to compare properly,
2165 compare word by word. Rely on CSE to optimize constant cases. */
2166 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2167 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2171 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2173 if (temp == const1_rtx)
2175 else if (temp != const0_rtx)
2177 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2178 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2184 op0 = expand_unop (mode, neg_optab, target, target, 0);
2186 emit_move_insn (target, op0);
2192 /* Emit code to compute the absolute value of OP0, with result to
2193 TARGET if convenient. (TARGET may be 0.) The return value says
2194 where the result actually is to be found.
2196 MODE is the mode of the operand; the mode of the result is
2197 different but can be deduced from MODE.
2199 UNSIGNEDP is relevant for complex integer modes. */
2202 expand_complex_abs (mode, op0, target, unsignedp)
2203 enum machine_mode mode;
2208 enum mode_class class = GET_MODE_CLASS (mode);
2209 enum machine_mode wider_mode;
2211 rtx entry_last = get_last_insn ();
2215 /* Find the correct mode for the real and imaginary parts. */
2216 enum machine_mode submode
2217 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2218 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2221 if (submode == BLKmode)
2224 op0 = protect_from_queue (op0, 0);
2228 op0 = force_not_mem (op0);
2231 last = get_last_insn ();
2234 target = protect_from_queue (target, 1);
2236 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2238 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2239 enum machine_mode mode0 = insn_operand_mode[icode][1];
2245 temp = gen_reg_rtx (submode);
2247 if (GET_MODE (xop0) != VOIDmode
2248 && GET_MODE (xop0) != mode0)
2249 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2251 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2253 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2254 xop0 = copy_to_mode_reg (mode0, xop0);
2256 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2257 temp = gen_reg_rtx (submode);
2259 pat = GEN_FCN (icode) (temp, xop0);
2262 if (GET_CODE (pat) == SEQUENCE
2263 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2265 delete_insns_since (last);
2266 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2274 delete_insns_since (last);
2277 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2279 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2280 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2282 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2286 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2287 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2291 if (class != MODE_COMPLEX_INT)
2294 target = gen_reg_rtx (submode);
2295 convert_move (target, temp, 0);
2299 return gen_lowpart (submode, temp);
2302 delete_insns_since (last);
2306 /* Open-code the complex absolute-value operation
2307 if we can open-code sqrt. Otherwise it's not worth while. */
2308 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2310 rtx real, imag, total;
2312 real = gen_realpart (submode, op0);
2313 imag = gen_imagpart (submode, op0);
2315 /* Square both parts. */
2316 real = expand_mult (submode, real, real, NULL_RTX, 0);
2317 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2319 /* Sum the parts. */
2320 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2321 0, OPTAB_LIB_WIDEN);
2323 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2324 target = expand_unop (submode, sqrt_optab, total, target, 0);
2326 delete_insns_since (last);
2331 /* Now try a library call in this mode. */
2332 if (abs_optab->handlers[(int) mode].libfunc)
2339 /* Pass 1 for NO_QUEUE so we don't lose any increments
2340 if the libcall is cse'd or moved. */
2341 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2342 NULL_RTX, 1, submode, 1, op0, mode);
2343 insns = get_insns ();
2346 target = gen_reg_rtx (submode);
2347 emit_libcall_block (insns, target, value,
2348 gen_rtx_fmt_e (abs_optab->code, mode, op0));
2353 /* It can't be done in this mode. Can we do it in a wider mode? */
2355 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2356 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2358 if ((abs_optab->handlers[(int) wider_mode].insn_code
2359 != CODE_FOR_nothing)
2360 || abs_optab->handlers[(int) wider_mode].libfunc)
2364 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2366 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2370 if (class != MODE_COMPLEX_INT)
2373 target = gen_reg_rtx (submode);
2374 convert_move (target, temp, 0);
2378 return gen_lowpart (submode, temp);
2381 delete_insns_since (last);
2385 delete_insns_since (entry_last);
2389 /* Generate an instruction whose insn-code is INSN_CODE,
2390 with two operands: an output TARGET and an input OP0.
2391 TARGET *must* be nonzero, and the output is always stored there.
2392 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2393 the value that is stored into TARGET. */
2396 emit_unop_insn (icode, target, op0, code)
2403 enum machine_mode mode0 = insn_operand_mode[icode][1];
2406 temp = target = protect_from_queue (target, 1);
2408 op0 = protect_from_queue (op0, 0);
2410 /* Sign and zero extension from memory is often done specially on
2411 RISC machines, so forcing into a register here can pessimize
2413 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2414 op0 = force_not_mem (op0);
2416 /* Now, if insn does not accept our operands, put them into pseudos. */
2418 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2419 op0 = copy_to_mode_reg (mode0, op0);
2421 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2422 || (flag_force_mem && GET_CODE (temp) == MEM))
2423 temp = gen_reg_rtx (GET_MODE (temp));
2425 pat = GEN_FCN (icode) (temp, op0);
2427 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2428 add_equal_note (pat, temp, code, op0, NULL_RTX);
2433 emit_move_insn (target, temp);
2436 /* Emit code to perform a series of operations on a multi-word quantity, one
2439 Such a block is preceded by a CLOBBER of the output, consists of multiple
2440 insns, each setting one word of the output, and followed by a SET copying
2441 the output to itself.
2443 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2444 note indicating that it doesn't conflict with the (also multi-word)
2445 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2448 INSNS is a block of code generated to perform the operation, not including
2449 the CLOBBER and final copy. All insns that compute intermediate values
2450 are first emitted, followed by the block as described above.
2452 TARGET, OP0, and OP1 are the output and inputs of the operations,
2453 respectively. OP1 may be zero for a unary operation.
2455 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2458 If TARGET is not a register, INSNS is simply emitted with no special
2459 processing. Likewise if anything in INSNS is not an INSN or if
2460 there is a libcall block inside INSNS.
2462 The final insn emitted is returned. */
2465 emit_no_conflict_block (insns, target, op0, op1, equiv)
2471 rtx prev, next, first, last, insn;
2473 if (GET_CODE (target) != REG || reload_in_progress)
2474 return emit_insns (insns);
2476 for (insn = insns; insn; insn = NEXT_INSN (insn))
2477 if (GET_CODE (insn) != INSN
2478 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2479 return emit_insns (insns);
2481 /* First emit all insns that do not store into words of the output and remove
2482 these from the list. */
2483 for (insn = insns; insn; insn = next)
2488 next = NEXT_INSN (insn);
2490 if (GET_CODE (PATTERN (insn)) == SET)
2491 set = PATTERN (insn);
2492 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2494 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2495 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2497 set = XVECEXP (PATTERN (insn), 0, i);
2505 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2507 if (PREV_INSN (insn))
2508 NEXT_INSN (PREV_INSN (insn)) = next;
2513 PREV_INSN (next) = PREV_INSN (insn);
2519 prev = get_last_insn ();
2521 /* Now write the CLOBBER of the output, followed by the setting of each
2522 of the words, followed by the final copy. */
2523 if (target != op0 && target != op1)
2524 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2526 for (insn = insns; insn; insn = next)
2528 next = NEXT_INSN (insn);
2531 if (op1 && GET_CODE (op1) == REG)
2532 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2535 if (op0 && GET_CODE (op0) == REG)
2536 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2540 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2541 != CODE_FOR_nothing)
2543 last = emit_move_insn (target, target);
2545 set_unique_reg_note (last, REG_EQUAL, equiv);
2548 last = get_last_insn ();
2551 first = get_insns ();
2553 first = NEXT_INSN (prev);
2555 /* Encapsulate the block so it gets manipulated as a unit. */
2556 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2558 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2563 /* Emit code to make a call to a constant function or a library call.
2565 INSNS is a list containing all insns emitted in the call.
2566 These insns leave the result in RESULT. Our block is to copy RESULT
2567 to TARGET, which is logically equivalent to EQUIV.
2569 We first emit any insns that set a pseudo on the assumption that these are
2570 loading constants into registers; doing so allows them to be safely cse'ed
2571 between blocks. Then we emit all the other insns in the block, followed by
2572 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2573 note with an operand of EQUIV.
2575 Moving assignments to pseudos outside of the block is done to improve
2576 the generated code, but is not required to generate correct code,
2577 hence being unable to move an assignment is not grounds for not making
2578 a libcall block. There are two reasons why it is safe to leave these
2579 insns inside the block: First, we know that these pseudos cannot be
2580 used in generated RTL outside the block since they are created for
2581 temporary purposes within the block. Second, CSE will not record the
2582 values of anything set inside a libcall block, so we know they must
2583 be dead at the end of the block.
2585 Except for the first group of insns (the ones setting pseudos), the
2586 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2589 emit_libcall_block (insns, target, result, equiv)
2595 rtx prev, next, first, last, insn;
2597 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2598 reg note to indicate that this call cannot throw. (Unless there is
2599 already a REG_EH_REGION note.) */
2601 for (insn = insns; insn; insn = NEXT_INSN (insn))
2603 if (GET_CODE (insn) == CALL_INSN)
2605 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2606 if (note == NULL_RTX)
2607 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2612 /* First emit all insns that set pseudos. Remove them from the list as
2613 we go. Avoid insns that set pseudos which were referenced in previous
2614 insns. These can be generated by move_by_pieces, for example,
2615 to update an address. Similarly, avoid insns that reference things
2616 set in previous insns. */
2618 for (insn = insns; insn; insn = next)
2620 rtx set = single_set (insn);
2622 next = NEXT_INSN (insn);
2624 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2625 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2627 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2628 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2629 && ! modified_in_p (SET_SRC (set), insns)
2630 && ! modified_between_p (SET_SRC (set), insns, insn))))
2632 if (PREV_INSN (insn))
2633 NEXT_INSN (PREV_INSN (insn)) = next;
2638 PREV_INSN (next) = PREV_INSN (insn);
2644 prev = get_last_insn ();
2646 /* Write the remaining insns followed by the final copy. */
2648 for (insn = insns; insn; insn = next)
2650 next = NEXT_INSN (insn);
2655 last = emit_move_insn (target, result);
2656 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2657 != CODE_FOR_nothing)
2658 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2661 first = get_insns ();
2663 first = NEXT_INSN (prev);
2665 /* Encapsulate the block so it gets manipulated as a unit. */
2666 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2668 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2671 /* Generate code to store zero in X. */
2677 emit_move_insn (x, const0_rtx);
2680 /* Generate code to store 1 in X
2681 assuming it contains zero beforehand. */
2684 emit_0_to_1_insn (x)
2687 emit_move_insn (x, const1_rtx);
2690 /* Generate code to compare X with Y
2691 so that the condition codes are set.
2693 MODE is the mode of the inputs (in case they are const_int).
2694 UNSIGNEDP nonzero says that X and Y are unsigned;
2695 this matters if they need to be widened.
2697 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2698 and ALIGN specifies the known shared alignment of X and Y.
2700 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2701 It is ignored for fixed-point and block comparisons;
2702 it is used only for floating-point comparisons. */
2705 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2707 enum rtx_code comparison;
2709 enum machine_mode mode;
2713 enum mode_class class;
2714 enum machine_mode wider_mode;
2716 class = GET_MODE_CLASS (mode);
2718 /* They could both be VOIDmode if both args are immediate constants,
2719 but we should fold that at an earlier stage.
2720 With no special code here, this will call abort,
2721 reminding the programmer to implement such folding. */
2723 if (mode != BLKmode && flag_force_mem)
2725 x = force_not_mem (x);
2726 y = force_not_mem (y);
2729 /* If we are inside an appropriately-short loop and one operand is an
2730 expensive constant, force it into a register. */
2731 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2732 x = force_reg (mode, x);
2734 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2735 y = force_reg (mode, y);
2738 /* Abort if we have a non-canonical comparison. The RTL documentation
2739 states that canonical comparisons are required only for targets which
2741 if (CONSTANT_P (x) && ! CONSTANT_P (y))
2745 /* Don't let both operands fail to indicate the mode. */
2746 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2747 x = force_reg (mode, x);
2749 /* Handle all BLKmode compares. */
2751 if (mode == BLKmode)
2754 x = protect_from_queue (x, 0);
2755 y = protect_from_queue (y, 0);
2759 #ifdef HAVE_cmpstrqi
2761 && GET_CODE (size) == CONST_INT
2762 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2764 enum machine_mode result_mode
2765 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2766 rtx result = gen_reg_rtx (result_mode);
2767 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2768 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2773 #ifdef HAVE_cmpstrhi
2775 && GET_CODE (size) == CONST_INT
2776 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2778 enum machine_mode result_mode
2779 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2780 rtx result = gen_reg_rtx (result_mode);
2781 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2782 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2787 #ifdef HAVE_cmpstrsi
2790 enum machine_mode result_mode
2791 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2792 rtx result = gen_reg_rtx (result_mode);
2793 size = protect_from_queue (size, 0);
2794 emit_insn (gen_cmpstrsi (result, x, y,
2795 convert_to_mode (SImode, size, 1),
2797 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2805 #ifdef TARGET_MEM_FUNCTIONS
2806 emit_library_call (memcmp_libfunc, 0,
2807 TYPE_MODE (integer_type_node), 3,
2808 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2809 convert_to_mode (TYPE_MODE (sizetype), size,
2810 TREE_UNSIGNED (sizetype)),
2811 TYPE_MODE (sizetype));
2813 emit_library_call (bcmp_libfunc, 0,
2814 TYPE_MODE (integer_type_node), 3,
2815 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2816 convert_to_mode (TYPE_MODE (integer_type_node),
2818 TREE_UNSIGNED (integer_type_node)),
2819 TYPE_MODE (integer_type_node));
2822 /* Immediately move the result of the libcall into a pseudo
2823 register so reload doesn't clobber the value if it needs
2824 the return register for a spill reg. */
2825 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
2826 emit_move_insn (result,
2827 hard_libcall_value (TYPE_MODE (integer_type_node)));
2828 emit_cmp_insn (result,
2829 const0_rtx, comparison, NULL_RTX,
2830 TYPE_MODE (integer_type_node), 0, 0);
2835 /* Handle some compares against zero. */
2837 if (y == CONST0_RTX (mode)
2838 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2840 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2843 x = protect_from_queue (x, 0);
2844 y = protect_from_queue (y, 0);
2846 /* Now, if insn does accept these operands, put them into pseudos. */
2847 if (! (*insn_operand_predicate[icode][0])
2848 (x, insn_operand_mode[icode][0]))
2849 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2851 emit_insn (GEN_FCN (icode) (x));
2855 /* Handle compares for which there is a directly suitable insn. */
2857 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2859 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2862 x = protect_from_queue (x, 0);
2863 y = protect_from_queue (y, 0);
2865 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2866 if (! (*insn_operand_predicate[icode][0])
2867 (x, insn_operand_mode[icode][0]))
2868 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2870 if (! (*insn_operand_predicate[icode][1])
2871 (y, insn_operand_mode[icode][1]))
2872 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2874 emit_insn (GEN_FCN (icode) (x, y));
2878 /* Try widening if we can find a direct insn that way. */
2880 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2882 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2883 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2885 if (cmp_optab->handlers[(int) wider_mode].insn_code
2886 != CODE_FOR_nothing)
2888 x = protect_from_queue (x, 0);
2889 y = protect_from_queue (y, 0);
2890 x = convert_modes (wider_mode, mode, x, unsignedp);
2891 y = convert_modes (wider_mode, mode, y, unsignedp);
2892 emit_cmp_insn (x, y, comparison, NULL_RTX,
2893 wider_mode, unsignedp, align);
2899 /* Handle a lib call just for the mode we are using. */
2901 if (cmp_optab->handlers[(int) mode].libfunc
2902 && class != MODE_FLOAT)
2904 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2907 /* If we want unsigned, and this mode has a distinct unsigned
2908 comparison routine, use that. */
2909 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2910 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2912 emit_library_call (libfunc, 1,
2913 word_mode, 2, x, mode, y, mode);
2915 /* Immediately move the result of the libcall into a pseudo
2916 register so reload doesn't clobber the value if it needs
2917 the return register for a spill reg. */
2918 result = gen_reg_rtx (word_mode);
2919 emit_move_insn (result, hard_libcall_value (word_mode));
2921 /* Integer comparison returns a result that must be compared against 1,
2922 so that even if we do an unsigned compare afterward,
2923 there is still a value that can represent the result "less than". */
2924 emit_cmp_insn (result, const1_rtx,
2925 comparison, NULL_RTX, word_mode, unsignedp, 0);
2929 if (class == MODE_FLOAT)
2930 emit_float_lib_cmp (x, y, comparison);
2936 /* Generate code to compare X with Y so that the condition codes are
2937 set and to jump to LABEL if the condition is true. If X is a
2938 constant and Y is not a constant, then the comparison is swapped to
2939 ensure that the comparison RTL has the canonical form.
2941 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
2942 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
2943 the proper branch condition code.
2945 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
2946 and ALIGN specifies the known shared alignment of X and Y.
2948 MODE is the mode of the inputs (in case they are const_int).
2950 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
2951 be passed unchanged to emit_cmp_insn, then potentially converted into an
2952 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
2955 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
2957 enum rtx_code comparison;
2959 enum machine_mode mode;
2969 /* Swap operands and condition to ensure canonical RTL. */
2972 comparison = swap_condition (comparison);
2979 emit_cmp_insn (op0, op1, comparison, size, mode, unsignedp, align);
2982 comparison = unsigned_condition (comparison);
2983 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
2987 /* Nonzero if a compare of mode MODE can be done straightforwardly
2988 (without splitting it into pieces). */
2991 can_compare_p (mode)
2992 enum machine_mode mode;
2996 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2998 mode = GET_MODE_WIDER_MODE (mode);
2999 } while (mode != VOIDmode);
3004 /* Emit a library call comparison between floating point X and Y.
3005 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3008 emit_float_lib_cmp (x, y, comparison)
3010 enum rtx_code comparison;
3012 enum machine_mode mode = GET_MODE (x);
3020 libfunc = eqhf2_libfunc;
3024 libfunc = nehf2_libfunc;
3028 libfunc = gthf2_libfunc;
3032 libfunc = gehf2_libfunc;
3036 libfunc = lthf2_libfunc;
3040 libfunc = lehf2_libfunc;
3046 else if (mode == SFmode)
3050 libfunc = eqsf2_libfunc;
3054 libfunc = nesf2_libfunc;
3058 libfunc = gtsf2_libfunc;
3062 libfunc = gesf2_libfunc;
3066 libfunc = ltsf2_libfunc;
3070 libfunc = lesf2_libfunc;
3076 else if (mode == DFmode)
3080 libfunc = eqdf2_libfunc;
3084 libfunc = nedf2_libfunc;
3088 libfunc = gtdf2_libfunc;
3092 libfunc = gedf2_libfunc;
3096 libfunc = ltdf2_libfunc;
3100 libfunc = ledf2_libfunc;
3106 else if (mode == XFmode)
3110 libfunc = eqxf2_libfunc;
3114 libfunc = nexf2_libfunc;
3118 libfunc = gtxf2_libfunc;
3122 libfunc = gexf2_libfunc;
3126 libfunc = ltxf2_libfunc;
3130 libfunc = lexf2_libfunc;
3136 else if (mode == TFmode)
3140 libfunc = eqtf2_libfunc;
3144 libfunc = netf2_libfunc;
3148 libfunc = gttf2_libfunc;
3152 libfunc = getf2_libfunc;
3156 libfunc = lttf2_libfunc;
3160 libfunc = letf2_libfunc;
3168 enum machine_mode wider_mode;
3170 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3171 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3173 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3174 != CODE_FOR_nothing)
3175 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3177 x = protect_from_queue (x, 0);
3178 y = protect_from_queue (y, 0);
3179 x = convert_to_mode (wider_mode, x, 0);
3180 y = convert_to_mode (wider_mode, y, 0);
3181 emit_float_lib_cmp (x, y, comparison);
3191 emit_library_call (libfunc, 1,
3192 word_mode, 2, x, mode, y, mode);
3194 /* Immediately move the result of the libcall into a pseudo
3195 register so reload doesn't clobber the value if it needs
3196 the return register for a spill reg. */
3197 result = gen_reg_rtx (word_mode);
3198 emit_move_insn (result, hard_libcall_value (word_mode));
3200 emit_cmp_insn (result, const0_rtx, comparison,
3201 NULL_RTX, word_mode, 0, 0);
3204 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3207 emit_indirect_jump (loc)
3210 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3212 loc = copy_to_mode_reg (Pmode, loc);
3214 emit_jump_insn (gen_indirect_jump (loc));
3218 #ifdef HAVE_conditional_move
3220 /* Emit a conditional move instruction if the machine supports one for that
3221 condition and machine mode.
3223 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3224 the mode to use should they be constants. If it is VOIDmode, they cannot
3227 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3228 should be stored there. MODE is the mode to use should they be constants.
3229 If it is VOIDmode, they cannot both be constants.
3231 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3232 is not supported. */
3235 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3240 enum machine_mode cmode;
3242 enum machine_mode mode;
3245 rtx tem, subtarget, comparison, insn;
3246 enum insn_code icode;
3248 /* If one operand is constant, make it the second one. Only do this
3249 if the other operand is not constant as well. */
3251 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3252 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3257 code = swap_condition (code);
3260 if (cmode == VOIDmode)
3261 cmode = GET_MODE (op0);
3263 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3264 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3265 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3266 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3271 code = reverse_condition (code);
3274 if (mode == VOIDmode)
3275 mode = GET_MODE (op2);
3277 icode = movcc_gen_code[mode];
3279 if (icode == CODE_FOR_nothing)
3284 op2 = force_not_mem (op2);
3285 op3 = force_not_mem (op3);
3289 target = protect_from_queue (target, 1);
3291 target = gen_reg_rtx (mode);
3297 op2 = protect_from_queue (op2, 0);
3298 op3 = protect_from_queue (op3, 0);
3300 /* If the insn doesn't accept these operands, put them in pseudos. */
3302 if (! (*insn_operand_predicate[icode][0])
3303 (subtarget, insn_operand_mode[icode][0]))
3304 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3306 if (! (*insn_operand_predicate[icode][2])
3307 (op2, insn_operand_mode[icode][2]))
3308 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3310 if (! (*insn_operand_predicate[icode][3])
3311 (op3, insn_operand_mode[icode][3]))
3312 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3314 /* Everything should now be in the suitable form, so emit the compare insn
3315 and then the conditional move. */
3318 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3320 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3321 if (GET_CODE (comparison) != code)
3322 /* This shouldn't happen. */
3325 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3327 /* If that failed, then give up. */
3333 if (subtarget != target)
3334 convert_move (target, subtarget, 0);
3339 /* Return non-zero if a conditional move of mode MODE is supported.
3341 This function is for combine so it can tell whether an insn that looks
3342 like a conditional move is actually supported by the hardware. If we
3343 guess wrong we lose a bit on optimization, but that's it. */
3344 /* ??? sparc64 supports conditionally moving integers values based on fp
3345 comparisons, and vice versa. How do we handle them? */
3348 can_conditionally_move_p (mode)
3349 enum machine_mode mode;
3351 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3357 #endif /* HAVE_conditional_move */
3359 /* These three functions generate an insn body and return it
3360 rather than emitting the insn.
3362 They do not protect from queued increments,
3363 because they may be used 1) in protect_from_queue itself
3364 and 2) in other passes where there is no queue. */
3366 /* Generate and return an insn body to add Y to X. */
3369 gen_add2_insn (x, y)
3372 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3374 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3375 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3376 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3379 return (GEN_FCN (icode) (x, x, y));
3383 have_add2_insn (mode)
3384 enum machine_mode mode;
3386 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3389 /* Generate and return an insn body to subtract Y from X. */
3392 gen_sub2_insn (x, y)
3395 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3397 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3398 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3399 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3402 return (GEN_FCN (icode) (x, x, y));
3406 have_sub2_insn (mode)
3407 enum machine_mode mode;
3409 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3412 /* Generate the body of an instruction to copy Y into X.
3413 It may be a SEQUENCE, if one insn isn't enough. */
3416 gen_move_insn (x, y)
3419 register enum machine_mode mode = GET_MODE (x);
3420 enum insn_code insn_code;
3423 if (mode == VOIDmode)
3424 mode = GET_MODE (y);
3426 insn_code = mov_optab->handlers[(int) mode].insn_code;
3428 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3429 find a mode to do it in. If we have a movcc, use it. Otherwise,
3430 find the MODE_INT mode of the same width. */
3432 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3434 enum machine_mode tmode = VOIDmode;
3438 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3441 for (tmode = QImode; tmode != VOIDmode;
3442 tmode = GET_MODE_WIDER_MODE (tmode))
3443 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3446 if (tmode == VOIDmode)
3449 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3450 may call change_address which is not appropriate if we were
3451 called when a reload was in progress. We don't have to worry
3452 about changing the address since the size in bytes is supposed to
3453 be the same. Copy the MEM to change the mode and move any
3454 substitutions from the old MEM to the new one. */
3456 if (reload_in_progress)
3458 x = gen_lowpart_common (tmode, x1);
3459 if (x == 0 && GET_CODE (x1) == MEM)
3461 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3462 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3463 MEM_COPY_ATTRIBUTES (x, x1);
3464 copy_replacements (x1, x);
3467 y = gen_lowpart_common (tmode, y1);
3468 if (y == 0 && GET_CODE (y1) == MEM)
3470 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3471 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3472 MEM_COPY_ATTRIBUTES (y, y1);
3473 copy_replacements (y1, y);
3478 x = gen_lowpart (tmode, x);
3479 y = gen_lowpart (tmode, y);
3482 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3483 return (GEN_FCN (insn_code) (x, y));
3487 emit_move_insn_1 (x, y);
3488 seq = gen_sequence ();
3493 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3494 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3495 no such operation exists, CODE_FOR_nothing will be returned. */
3498 can_extend_p (to_mode, from_mode, unsignedp)
3499 enum machine_mode to_mode, from_mode;
3502 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3505 /* Generate the body of an insn to extend Y (with mode MFROM)
3506 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3509 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3511 enum machine_mode mto, mfrom;
3514 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3517 /* can_fix_p and can_float_p say whether the target machine
3518 can directly convert a given fixed point type to
3519 a given floating point type, or vice versa.
3520 The returned value is the CODE_FOR_... value to use,
3521 or CODE_FOR_nothing if these modes cannot be directly converted.
3523 *TRUNCP_PTR is set to 1 if it is necessary to output
3524 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3526 static enum insn_code
3527 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3528 enum machine_mode fltmode, fixmode;
3533 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3534 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3536 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3539 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3541 return CODE_FOR_nothing;
3544 static enum insn_code
3545 can_float_p (fltmode, fixmode, unsignedp)
3546 enum machine_mode fixmode, fltmode;
3549 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3552 /* Generate code to convert FROM to floating point
3553 and store in TO. FROM must be fixed point and not VOIDmode.
3554 UNSIGNEDP nonzero means regard FROM as unsigned.
3555 Normally this is done by correcting the final value
3556 if it is negative. */
3559 expand_float (to, from, unsignedp)
3563 enum insn_code icode;
3564 register rtx target = to;
3565 enum machine_mode fmode, imode;
3567 /* Crash now, because we won't be able to decide which mode to use. */
3568 if (GET_MODE (from) == VOIDmode)
3571 /* Look for an insn to do the conversion. Do it in the specified
3572 modes if possible; otherwise convert either input, output or both to
3573 wider mode. If the integer mode is wider than the mode of FROM,
3574 we can do the conversion signed even if the input is unsigned. */
3576 for (imode = GET_MODE (from); imode != VOIDmode;
3577 imode = GET_MODE_WIDER_MODE (imode))
3578 for (fmode = GET_MODE (to); fmode != VOIDmode;
3579 fmode = GET_MODE_WIDER_MODE (fmode))
3581 int doing_unsigned = unsignedp;
3583 icode = can_float_p (fmode, imode, unsignedp);
3584 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3585 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3587 if (icode != CODE_FOR_nothing)
3589 to = protect_from_queue (to, 1);
3590 from = protect_from_queue (from, 0);
3592 if (imode != GET_MODE (from))
3593 from = convert_to_mode (imode, from, unsignedp);
3595 if (fmode != GET_MODE (to))
3596 target = gen_reg_rtx (fmode);
3598 emit_unop_insn (icode, target, from,
3599 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3602 convert_move (to, target, 0);
3607 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3609 /* Unsigned integer, and no way to convert directly.
3610 Convert as signed, then conditionally adjust the result. */
3613 rtx label = gen_label_rtx ();
3615 REAL_VALUE_TYPE offset;
3619 to = protect_from_queue (to, 1);
3620 from = protect_from_queue (from, 0);
3623 from = force_not_mem (from);
3625 /* Look for a usable floating mode FMODE wider than the source and at
3626 least as wide as the target. Using FMODE will avoid rounding woes
3627 with unsigned values greater than the signed maximum value. */
3629 for (fmode = GET_MODE (to); fmode != VOIDmode;
3630 fmode = GET_MODE_WIDER_MODE (fmode))
3631 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3632 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3635 if (fmode == VOIDmode)
3637 /* There is no such mode. Pretend the target is wide enough. */
3638 fmode = GET_MODE (to);
3640 /* Avoid double-rounding when TO is narrower than FROM. */
3641 if ((significand_size (fmode) + 1)
3642 < GET_MODE_BITSIZE (GET_MODE (from)))
3645 rtx neglabel = gen_label_rtx ();
3647 /* Don't use TARGET if it isn't a register, is a hard register,
3648 or is the wrong mode. */
3649 if (GET_CODE (target) != REG
3650 || REGNO (target) < FIRST_PSEUDO_REGISTER
3651 || GET_MODE (target) != fmode)
3652 target = gen_reg_rtx (fmode);
3654 imode = GET_MODE (from);
3655 do_pending_stack_adjust ();
3657 /* Test whether the sign bit is set. */
3658 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3659 emit_jump_insn (gen_blt (neglabel));
3661 /* The sign bit is not set. Convert as signed. */
3662 expand_float (target, from, 0);
3663 emit_jump_insn (gen_jump (label));
3666 /* The sign bit is set.
3667 Convert to a usable (positive signed) value by shifting right
3668 one bit, while remembering if a nonzero bit was shifted
3669 out; i.e., compute (from & 1) | (from >> 1). */
3671 emit_label (neglabel);
3672 temp = expand_binop (imode, and_optab, from, const1_rtx,
3673 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3674 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3676 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3678 expand_float (target, temp, 0);
3680 /* Multiply by 2 to undo the shift above. */
3681 temp = expand_binop (fmode, add_optab, target, target,
3682 target, 0, OPTAB_LIB_WIDEN);
3684 emit_move_insn (target, temp);
3686 do_pending_stack_adjust ();
3692 /* If we are about to do some arithmetic to correct for an
3693 unsigned operand, do it in a pseudo-register. */
3695 if (GET_MODE (to) != fmode
3696 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3697 target = gen_reg_rtx (fmode);
3699 /* Convert as signed integer to floating. */
3700 expand_float (target, from, 0);
3702 /* If FROM is negative (and therefore TO is negative),
3703 correct its value by 2**bitwidth. */
3705 do_pending_stack_adjust ();
3706 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
3709 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3710 Rather than setting up a dconst_dot_5, let's hope SCO
3712 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3713 temp = expand_binop (fmode, add_optab, target,
3714 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3715 target, 0, OPTAB_LIB_WIDEN);
3717 emit_move_insn (target, temp);
3719 do_pending_stack_adjust ();
3725 /* No hardware instruction available; call a library routine to convert from
3726 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3732 to = protect_from_queue (to, 1);
3733 from = protect_from_queue (from, 0);
3735 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3736 from = convert_to_mode (SImode, from, unsignedp);
3739 from = force_not_mem (from);
3741 if (GET_MODE (to) == SFmode)
3743 if (GET_MODE (from) == SImode)
3744 libfcn = floatsisf_libfunc;
3745 else if (GET_MODE (from) == DImode)
3746 libfcn = floatdisf_libfunc;
3747 else if (GET_MODE (from) == TImode)
3748 libfcn = floattisf_libfunc;
3752 else if (GET_MODE (to) == DFmode)
3754 if (GET_MODE (from) == SImode)
3755 libfcn = floatsidf_libfunc;
3756 else if (GET_MODE (from) == DImode)
3757 libfcn = floatdidf_libfunc;
3758 else if (GET_MODE (from) == TImode)
3759 libfcn = floattidf_libfunc;
3763 else if (GET_MODE (to) == XFmode)
3765 if (GET_MODE (from) == SImode)
3766 libfcn = floatsixf_libfunc;
3767 else if (GET_MODE (from) == DImode)
3768 libfcn = floatdixf_libfunc;
3769 else if (GET_MODE (from) == TImode)
3770 libfcn = floattixf_libfunc;
3774 else if (GET_MODE (to) == TFmode)
3776 if (GET_MODE (from) == SImode)
3777 libfcn = floatsitf_libfunc;
3778 else if (GET_MODE (from) == DImode)
3779 libfcn = floatditf_libfunc;
3780 else if (GET_MODE (from) == TImode)
3781 libfcn = floattitf_libfunc;
3790 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3792 1, from, GET_MODE (from));
3793 insns = get_insns ();
3796 emit_libcall_block (insns, target, value,
3797 gen_rtx_FLOAT (GET_MODE (to), from));
3802 /* Copy result to requested destination
3803 if we have been computing in a temp location. */
3807 if (GET_MODE (target) == GET_MODE (to))
3808 emit_move_insn (to, target);
3810 convert_move (to, target, 0);
3814 /* expand_fix: generate code to convert FROM to fixed point
3815 and store in TO. FROM must be floating point. */
3821 rtx temp = gen_reg_rtx (GET_MODE (x));
3822 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3826 expand_fix (to, from, unsignedp)
3827 register rtx to, from;
3830 enum insn_code icode;
3831 register rtx target = to;
3832 enum machine_mode fmode, imode;
3836 /* We first try to find a pair of modes, one real and one integer, at
3837 least as wide as FROM and TO, respectively, in which we can open-code
3838 this conversion. If the integer mode is wider than the mode of TO,
3839 we can do the conversion either signed or unsigned. */
3841 for (imode = GET_MODE (to); imode != VOIDmode;
3842 imode = GET_MODE_WIDER_MODE (imode))
3843 for (fmode = GET_MODE (from); fmode != VOIDmode;
3844 fmode = GET_MODE_WIDER_MODE (fmode))
3846 int doing_unsigned = unsignedp;
3848 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3849 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3850 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3852 if (icode != CODE_FOR_nothing)
3854 to = protect_from_queue (to, 1);
3855 from = protect_from_queue (from, 0);
3857 if (fmode != GET_MODE (from))
3858 from = convert_to_mode (fmode, from, 0);
3861 from = ftruncify (from);
3863 if (imode != GET_MODE (to))
3864 target = gen_reg_rtx (imode);
3866 emit_unop_insn (icode, target, from,
3867 doing_unsigned ? UNSIGNED_FIX : FIX);
3869 convert_move (to, target, unsignedp);
3874 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3875 /* For an unsigned conversion, there is one more way to do it.
3876 If we have a signed conversion, we generate code that compares
3877 the real value to the largest representable positive number. If if
3878 is smaller, the conversion is done normally. Otherwise, subtract
3879 one plus the highest signed number, convert, and add it back.
3881 We only need to check all real modes, since we know we didn't find
3882 anything with a wider integer mode. */
3884 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3885 for (fmode = GET_MODE (from); fmode != VOIDmode;
3886 fmode = GET_MODE_WIDER_MODE (fmode))
3887 /* Make sure we won't lose significant bits doing this. */
3888 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3889 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3893 REAL_VALUE_TYPE offset;
3894 rtx limit, lab1, lab2, insn;
3896 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3897 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3898 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3899 lab1 = gen_label_rtx ();
3900 lab2 = gen_label_rtx ();
3903 to = protect_from_queue (to, 1);
3904 from = protect_from_queue (from, 0);
3907 from = force_not_mem (from);
3909 if (fmode != GET_MODE (from))
3910 from = convert_to_mode (fmode, from, 0);
3912 /* See if we need to do the subtraction. */
3913 do_pending_stack_adjust ();
3914 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
3917 /* If not, do the signed "fix" and branch around fixup code. */
3918 expand_fix (to, from, 0);
3919 emit_jump_insn (gen_jump (lab2));
3922 /* Otherwise, subtract 2**(N-1), convert to signed number,
3923 then add 2**(N-1). Do the addition using XOR since this
3924 will often generate better code. */
3926 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3927 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3928 expand_fix (to, target, 0);
3929 target = expand_binop (GET_MODE (to), xor_optab, to,
3930 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3931 to, 1, OPTAB_LIB_WIDEN);
3934 emit_move_insn (to, target);
3938 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
3939 != CODE_FOR_nothing)
3941 /* Make a place for a REG_NOTE and add it. */
3942 insn = emit_move_insn (to, to);
3943 set_unique_reg_note (insn,
3945 gen_rtx_fmt_e (UNSIGNED_FIX,
3953 /* We can't do it with an insn, so use a library call. But first ensure
3954 that the mode of TO is at least as wide as SImode, since those are the
3955 only library calls we know about. */
3957 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3959 target = gen_reg_rtx (SImode);
3961 expand_fix (target, from, unsignedp);
3963 else if (GET_MODE (from) == SFmode)
3965 if (GET_MODE (to) == SImode)
3966 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3967 else if (GET_MODE (to) == DImode)
3968 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3969 else if (GET_MODE (to) == TImode)
3970 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3974 else if (GET_MODE (from) == DFmode)
3976 if (GET_MODE (to) == SImode)
3977 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3978 else if (GET_MODE (to) == DImode)
3979 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3980 else if (GET_MODE (to) == TImode)
3981 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3985 else if (GET_MODE (from) == XFmode)
3987 if (GET_MODE (to) == SImode)
3988 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3989 else if (GET_MODE (to) == DImode)
3990 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3991 else if (GET_MODE (to) == TImode)
3992 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3996 else if (GET_MODE (from) == TFmode)
3998 if (GET_MODE (to) == SImode)
3999 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4000 else if (GET_MODE (to) == DImode)
4001 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4002 else if (GET_MODE (to) == TImode)
4003 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4015 to = protect_from_queue (to, 1);
4016 from = protect_from_queue (from, 0);
4019 from = force_not_mem (from);
4023 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
4025 1, from, GET_MODE (from));
4026 insns = get_insns ();
4029 emit_libcall_block (insns, target, value,
4030 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4031 GET_MODE (to), from));
4036 if (GET_MODE (to) == GET_MODE (target))
4037 emit_move_insn (to, target);
4039 convert_move (to, target, 0);
4048 optab op = (optab) xmalloc (sizeof (struct optab));
4050 for (i = 0; i < NUM_MACHINE_MODES; i++)
4052 op->handlers[i].insn_code = CODE_FOR_nothing;
4053 op->handlers[i].libfunc = 0;
4056 if (code != UNKNOWN)
4057 code_to_optab[(int) code] = op;
4062 /* Initialize the libfunc fields of an entire group of entries in some
4063 optab. Each entry is set equal to a string consisting of a leading
4064 pair of underscores followed by a generic operation name followed by
4065 a mode name (downshifted to lower case) followed by a single character
4066 representing the number of operands for the given operation (which is
4067 usually one of the characters '2', '3', or '4').
4069 OPTABLE is the table in which libfunc fields are to be initialized.
4070 FIRST_MODE is the first machine mode index in the given optab to
4072 LAST_MODE is the last machine mode index in the given optab to
4074 OPNAME is the generic (string) name of the operation.
4075 SUFFIX is the character which specifies the number of operands for
4076 the given generic operation.
4080 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4081 register optab optable;
4082 register int first_mode;
4083 register int last_mode;
4084 register const char *opname;
4085 register int suffix;
4088 register unsigned opname_len = strlen (opname);
4090 for (mode = first_mode; (int) mode <= (int) last_mode;
4091 mode = (enum machine_mode) ((int) mode + 1))
4093 register char *mname = mode_name[(int) mode];
4094 register unsigned mname_len = strlen (mname);
4095 register char *libfunc_name
4096 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4098 register const char *q;
4103 for (q = opname; *q; )
4105 for (q = mname; *q; q++)
4106 *p++ = tolower ((unsigned char)*q);
4109 optable->handlers[(int) mode].libfunc
4110 = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
4114 /* Initialize the libfunc fields of an entire group of entries in some
4115 optab which correspond to all integer mode operations. The parameters
4116 have the same meaning as similarly named ones for the `init_libfuncs'
4117 routine. (See above). */
4120 init_integral_libfuncs (optable, opname, suffix)
4121 register optab optable;
4122 register const char *opname;
4123 register int suffix;
4125 init_libfuncs (optable, SImode, TImode, opname, suffix);
4128 /* Initialize the libfunc fields of an entire group of entries in some
4129 optab which correspond to all real mode operations. The parameters
4130 have the same meaning as similarly named ones for the `init_libfuncs'
4131 routine. (See above). */
4134 init_floating_libfuncs (optable, opname, suffix)
4135 register optab optable;
4136 register const char *opname;
4137 register int suffix;
4139 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4143 /* Call this once to initialize the contents of the optabs
4144 appropriately for the current target machine. */
4150 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4156 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4158 for (p = fixtab[0][0];
4159 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4161 *p = CODE_FOR_nothing;
4163 for (p = fixtrunctab[0][0];
4164 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4166 *p = CODE_FOR_nothing;
4168 for (p = floattab[0][0];
4169 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4171 *p = CODE_FOR_nothing;
4173 for (p = extendtab[0][0];
4174 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4176 *p = CODE_FOR_nothing;
4178 for (i = 0; i < NUM_RTX_CODE; i++)
4179 setcc_gen_code[i] = CODE_FOR_nothing;
4181 #ifdef HAVE_conditional_move
4182 for (i = 0; i < NUM_MACHINE_MODES; i++)
4183 movcc_gen_code[i] = CODE_FOR_nothing;
4186 add_optab = init_optab (PLUS);
4187 sub_optab = init_optab (MINUS);
4188 smul_optab = init_optab (MULT);
4189 smul_highpart_optab = init_optab (UNKNOWN);
4190 umul_highpart_optab = init_optab (UNKNOWN);
4191 smul_widen_optab = init_optab (UNKNOWN);
4192 umul_widen_optab = init_optab (UNKNOWN);
4193 sdiv_optab = init_optab (DIV);
4194 sdivmod_optab = init_optab (UNKNOWN);
4195 udiv_optab = init_optab (UDIV);
4196 udivmod_optab = init_optab (UNKNOWN);
4197 smod_optab = init_optab (MOD);
4198 umod_optab = init_optab (UMOD);
4199 flodiv_optab = init_optab (DIV);
4200 ftrunc_optab = init_optab (UNKNOWN);
4201 and_optab = init_optab (AND);
4202 ior_optab = init_optab (IOR);
4203 xor_optab = init_optab (XOR);
4204 ashl_optab = init_optab (ASHIFT);
4205 ashr_optab = init_optab (ASHIFTRT);
4206 lshr_optab = init_optab (LSHIFTRT);
4207 rotl_optab = init_optab (ROTATE);
4208 rotr_optab = init_optab (ROTATERT);
4209 smin_optab = init_optab (SMIN);
4210 smax_optab = init_optab (SMAX);
4211 umin_optab = init_optab (UMIN);
4212 umax_optab = init_optab (UMAX);
4213 mov_optab = init_optab (UNKNOWN);
4214 movstrict_optab = init_optab (UNKNOWN);
4215 cmp_optab = init_optab (UNKNOWN);
4216 ucmp_optab = init_optab (UNKNOWN);
4217 tst_optab = init_optab (UNKNOWN);
4218 neg_optab = init_optab (NEG);
4219 abs_optab = init_optab (ABS);
4220 one_cmpl_optab = init_optab (NOT);
4221 ffs_optab = init_optab (FFS);
4222 sqrt_optab = init_optab (SQRT);
4223 sin_optab = init_optab (UNKNOWN);
4224 cos_optab = init_optab (UNKNOWN);
4225 strlen_optab = init_optab (UNKNOWN);
4227 for (i = 0; i < NUM_MACHINE_MODES; i++)
4229 movstr_optab[i] = CODE_FOR_nothing;
4230 clrstr_optab[i] = CODE_FOR_nothing;
4232 #ifdef HAVE_SECONDARY_RELOADS
4233 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4237 /* Fill in the optabs with the insns we support. */
4240 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4241 /* This flag says the same insns that convert to a signed fixnum
4242 also convert validly to an unsigned one. */
4243 for (i = 0; i < NUM_MACHINE_MODES; i++)
4244 for (j = 0; j < NUM_MACHINE_MODES; j++)
4245 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4248 #ifdef EXTRA_CC_MODES
4252 /* Initialize the optabs with the names of the library functions. */
4253 init_integral_libfuncs (add_optab, "add", '3');
4254 init_floating_libfuncs (add_optab, "add", '3');
4255 init_integral_libfuncs (sub_optab, "sub", '3');
4256 init_floating_libfuncs (sub_optab, "sub", '3');
4257 init_integral_libfuncs (smul_optab, "mul", '3');
4258 init_floating_libfuncs (smul_optab, "mul", '3');
4259 init_integral_libfuncs (sdiv_optab, "div", '3');
4260 init_integral_libfuncs (udiv_optab, "udiv", '3');
4261 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4262 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4263 init_integral_libfuncs (smod_optab, "mod", '3');
4264 init_integral_libfuncs (umod_optab, "umod", '3');
4265 init_floating_libfuncs (flodiv_optab, "div", '3');
4266 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4267 init_integral_libfuncs (and_optab, "and", '3');
4268 init_integral_libfuncs (ior_optab, "ior", '3');
4269 init_integral_libfuncs (xor_optab, "xor", '3');
4270 init_integral_libfuncs (ashl_optab, "ashl", '3');
4271 init_integral_libfuncs (ashr_optab, "ashr", '3');
4272 init_integral_libfuncs (lshr_optab, "lshr", '3');
4273 init_integral_libfuncs (smin_optab, "min", '3');
4274 init_floating_libfuncs (smin_optab, "min", '3');
4275 init_integral_libfuncs (smax_optab, "max", '3');
4276 init_floating_libfuncs (smax_optab, "max", '3');
4277 init_integral_libfuncs (umin_optab, "umin", '3');
4278 init_integral_libfuncs (umax_optab, "umax", '3');
4279 init_integral_libfuncs (neg_optab, "neg", '2');
4280 init_floating_libfuncs (neg_optab, "neg", '2');
4281 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4282 init_integral_libfuncs (ffs_optab, "ffs", '2');
4284 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4285 init_integral_libfuncs (cmp_optab, "cmp", '2');
4286 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4287 init_floating_libfuncs (cmp_optab, "cmp", '2');
4289 #ifdef MULSI3_LIBCALL
4290 smul_optab->handlers[(int) SImode].libfunc
4291 = gen_rtx_SYMBOL_REF (Pmode, MULSI3_LIBCALL);
4293 #ifdef MULDI3_LIBCALL
4294 smul_optab->handlers[(int) DImode].libfunc
4295 = gen_rtx_SYMBOL_REF (Pmode, MULDI3_LIBCALL);
4298 #ifdef DIVSI3_LIBCALL
4299 sdiv_optab->handlers[(int) SImode].libfunc
4300 = gen_rtx_SYMBOL_REF (Pmode, DIVSI3_LIBCALL);
4302 #ifdef DIVDI3_LIBCALL
4303 sdiv_optab->handlers[(int) DImode].libfunc
4304 = gen_rtx_SYMBOL_REF (Pmode, DIVDI3_LIBCALL);
4307 #ifdef UDIVSI3_LIBCALL
4308 udiv_optab->handlers[(int) SImode].libfunc
4309 = gen_rtx_SYMBOL_REF (Pmode, UDIVSI3_LIBCALL);
4311 #ifdef UDIVDI3_LIBCALL
4312 udiv_optab->handlers[(int) DImode].libfunc
4313 = gen_rtx_SYMBOL_REF (Pmode, UDIVDI3_LIBCALL);
4316 #ifdef MODSI3_LIBCALL
4317 smod_optab->handlers[(int) SImode].libfunc
4318 = gen_rtx_SYMBOL_REF (Pmode, MODSI3_LIBCALL);
4320 #ifdef MODDI3_LIBCALL
4321 smod_optab->handlers[(int) DImode].libfunc
4322 = gen_rtx_SYMBOL_REF (Pmode, MODDI3_LIBCALL);
4325 #ifdef UMODSI3_LIBCALL
4326 umod_optab->handlers[(int) SImode].libfunc
4327 = gen_rtx_SYMBOL_REF (Pmode, UMODSI3_LIBCALL);
4329 #ifdef UMODDI3_LIBCALL
4330 umod_optab->handlers[(int) DImode].libfunc
4331 = gen_rtx_SYMBOL_REF (Pmode, UMODDI3_LIBCALL);
4334 /* Use cabs for DC complex abs, since systems generally have cabs.
4335 Don't define any libcall for SCmode, so that cabs will be used. */
4336 abs_optab->handlers[(int) DCmode].libfunc
4337 = gen_rtx_SYMBOL_REF (Pmode, "cabs");
4339 /* The ffs function operates on `int'. */
4340 #ifndef INT_TYPE_SIZE
4341 #define INT_TYPE_SIZE BITS_PER_WORD
4343 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4344 = gen_rtx_SYMBOL_REF (Pmode, "ffs");
4346 extendsfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfdf2");
4347 extendsfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsfxf2");
4348 extendsftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extendsftf2");
4349 extenddfxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddfxf2");
4350 extenddftf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__extenddftf2");
4352 truncdfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncdfsf2");
4353 truncxfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfsf2");
4354 trunctfsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfsf2");
4355 truncxfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__truncxfdf2");
4356 trunctfdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__trunctfdf2");
4358 memcpy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcpy");
4359 bcopy_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bcopy");
4360 memcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memcmp");
4361 bcmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gcc_bcmp");
4362 memset_libfunc = gen_rtx_SYMBOL_REF (Pmode, "memset");
4363 bzero_libfunc = gen_rtx_SYMBOL_REF (Pmode, "bzero");
4365 throw_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__throw");
4366 rethrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__rethrow");
4367 sjthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjthrow");
4368 sjpopnthrow_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__sjpopnthrow");
4369 terminate_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__terminate");
4370 eh_rtime_match_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eh_rtime_match");
4371 #ifndef DONT_USE_BUILTIN_SETJMP
4372 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_setjmp");
4373 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__builtin_longjmp");
4375 setjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "setjmp");
4376 longjmp_libfunc = gen_rtx_SYMBOL_REF (Pmode, "longjmp");
4379 eqhf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqhf2");
4380 nehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nehf2");
4381 gthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gthf2");
4382 gehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gehf2");
4383 lthf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lthf2");
4384 lehf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lehf2");
4386 eqsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqsf2");
4387 nesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nesf2");
4388 gtsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtsf2");
4389 gesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gesf2");
4390 ltsf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltsf2");
4391 lesf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lesf2");
4393 eqdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqdf2");
4394 nedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nedf2");
4395 gtdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtdf2");
4396 gedf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gedf2");
4397 ltdf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltdf2");
4398 ledf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ledf2");
4400 eqxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqxf2");
4401 nexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__nexf2");
4402 gtxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gtxf2");
4403 gexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gexf2");
4404 ltxf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ltxf2");
4405 lexf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lexf2");
4407 eqtf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__eqtf2");
4408 netf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__netf2");
4409 gttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__gttf2");
4410 getf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__getf2");
4411 lttf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__lttf2");
4412 letf2_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__letf2");
4414 floatsisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsisf");
4415 floatdisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdisf");
4416 floattisf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattisf");
4418 floatsidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsidf");
4419 floatdidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdidf");
4420 floattidf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattidf");
4422 floatsixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsixf");
4423 floatdixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatdixf");
4424 floattixf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattixf");
4426 floatsitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatsitf");
4427 floatditf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floatditf");
4428 floattitf_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__floattitf");
4430 fixsfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfsi");
4431 fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfdi");
4432 fixsfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixsfti");
4434 fixdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfsi");
4435 fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfdi");
4436 fixdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixdfti");
4438 fixxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfsi");
4439 fixxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfdi");
4440 fixxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixxfti");
4442 fixtfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfsi");
4443 fixtfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfdi");
4444 fixtfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixtfti");
4446 fixunssfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfsi");
4447 fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfdi");
4448 fixunssfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunssfti");
4450 fixunsdfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfsi");
4451 fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfdi");
4452 fixunsdfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsdfti");
4454 fixunsxfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfsi");
4455 fixunsxfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfdi");
4456 fixunsxfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunsxfti");
4458 fixunstfsi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfsi");
4459 fixunstfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfdi");
4460 fixunstfti_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__fixunstfti");
4462 /* For check-memory-usage. */
4463 chkr_check_addr_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_addr");
4464 chkr_set_right_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_set_right");
4465 chkr_copy_bitmap_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_copy_bitmap");
4466 chkr_check_exec_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_exec");
4467 chkr_check_str_libfunc = gen_rtx_SYMBOL_REF (Pmode, "chkr_check_str");
4469 /* For function entry/exit instrumentation. */
4470 profile_function_entry_libfunc
4471 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_enter");
4472 profile_function_exit_libfunc
4473 = gen_rtx_SYMBOL_REF (Pmode, "__cyg_profile_func_exit");
4475 #ifdef HAVE_conditional_trap
4479 #ifdef INIT_TARGET_OPTABS
4480 /* Allow the target to add more libcalls or rename some, etc. */
4487 /* SCO 3.2 apparently has a broken ldexp. */
4500 #endif /* BROKEN_LDEXP */
4502 #ifdef HAVE_conditional_trap
4503 /* The insn generating function can not take an rtx_code argument.
4504 TRAP_RTX is used as an rtx argument. Its code is replaced with
4505 the code to be used in the trap insn and all other fields are
4508 ??? Will need to change to support garbage collection. */
4509 static rtx trap_rtx;
4514 if (HAVE_conditional_trap)
4515 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4519 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4520 CODE. Return 0 on failure. */
4523 gen_cond_trap (code, op1, op2, tcode)
4524 enum rtx_code code ATTRIBUTE_UNUSED;
4525 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4527 enum machine_mode mode = GET_MODE (op1);
4529 if (mode == VOIDmode)
4532 #ifdef HAVE_conditional_trap
4533 if (HAVE_conditional_trap
4534 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4537 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4538 PUT_CODE (trap_rtx, code);
4539 insn = gen_conditional_trap (trap_rtx, tcode);