1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
34 #include "insn-flags.h"
35 #include "insn-codes.h"
43 /* Each optab contains info on how this target machine
44 can perform a particular operation
45 for all sizes and kinds of operands.
47 The operation to be performed is often specified
48 by passing one of these optabs as an argument.
50 See expr.h for documentation of these optabs. */
52 optab optab_table
[OTI_MAX
];
54 rtx libfunc_table
[LTI_MAX
];
56 /* Tables of patterns for extending one integer mode to another. */
57 enum insn_code extendtab
[MAX_MACHINE_MODE
][MAX_MACHINE_MODE
][2];
59 /* Tables of patterns for converting between fixed and floating point. */
60 enum insn_code fixtab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
61 enum insn_code fixtrunctab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
62 enum insn_code floattab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
64 /* Contains the optab used for each rtx code. */
65 optab code_to_optab
[NUM_RTX_CODE
+ 1];
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68 gives the gen_function to make a branch to test that condition. */
70 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73 gives the insn code to make a store-condition insn
74 to test that condition. */
76 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
81 setcc_gen_code to cut down on the number of named patterns. Consider a day
82 when a lot more rtx codes are conditional (eg: for the ARM). */
84 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
87 static int add_equal_note
PARAMS ((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
88 static rtx widen_operand
PARAMS ((rtx
, enum machine_mode
,
89 enum machine_mode
, int, int));
90 static int expand_cmplxdiv_straight
PARAMS ((rtx
, rtx
, rtx
, rtx
,
91 rtx
, rtx
, enum machine_mode
,
92 int, enum optab_methods
,
93 enum mode_class
, optab
));
94 static int expand_cmplxdiv_wide
PARAMS ((rtx
, rtx
, rtx
, rtx
,
95 rtx
, rtx
, enum machine_mode
,
96 int, enum optab_methods
,
97 enum mode_class
, optab
));
98 static enum insn_code can_fix_p
PARAMS ((enum machine_mode
, enum machine_mode
,
100 static enum insn_code can_float_p
PARAMS ((enum machine_mode
, enum machine_mode
,
102 static rtx ftruncify
PARAMS ((rtx
));
103 static optab init_optab
PARAMS ((enum rtx_code
));
104 static void init_libfuncs
PARAMS ((optab
, int, int, const char *, int));
105 static void init_integral_libfuncs
PARAMS ((optab
, const char *, int));
106 static void init_floating_libfuncs
PARAMS ((optab
, const char *, int));
107 #ifdef HAVE_conditional_trap
108 static void init_traps
PARAMS ((void));
110 static void emit_cmp_and_jump_insn_1
PARAMS ((rtx
, rtx
, enum machine_mode
,
111 enum rtx_code
, int, rtx
));
112 static void prepare_float_lib_cmp
PARAMS ((rtx
*, rtx
*, enum rtx_code
*,
113 enum machine_mode
*, int *));
115 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
116 the result of operation CODE applied to OP0 (and OP1 if it is a binary
119 If the last insn does not set TARGET, don't do anything, but return 1.
121 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
122 don't add the REG_EQUAL note but return 0. Our caller can then try
123 again, ensuring that TARGET is not one of the operands. */
126 add_equal_note (seq
, target
, code
, op0
, op1
)
136 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
137 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
138 || GET_CODE (seq
) != SEQUENCE
139 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
140 || GET_CODE (target
) == ZERO_EXTRACT
141 || (! rtx_equal_p (SET_DEST (set
), target
)
142 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
144 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
145 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
149 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
150 besides the last insn. */
151 if (reg_overlap_mentioned_p (target
, op0
)
152 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
153 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
154 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
157 if (GET_RTX_CLASS (code
) == '1')
158 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
160 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
162 set_unique_reg_note (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1), REG_EQUAL
, note
);
167 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
168 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
169 not actually do a sign-extend or zero-extend, but can leave the
170 higher-order bits of the result rtx undefined, for example, in the case
171 of logical operations, but not right shifts. */
174 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
176 enum machine_mode mode
, oldmode
;
182 /* If we must extend do so. If OP is either a constant or a SUBREG
183 for a promoted object, also extend since it will be more efficient to
186 || GET_MODE (op
) == VOIDmode
187 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
188 return convert_modes (mode
, oldmode
, op
, unsignedp
);
190 /* If MODE is no wider than a single word, we return a paradoxical
192 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
193 return gen_rtx_SUBREG (mode
, force_reg (GET_MODE (op
), op
), 0);
195 /* Otherwise, get an object of MODE, clobber it, and set the low-order
198 result
= gen_reg_rtx (mode
);
199 emit_insn (gen_rtx_CLOBBER (VOIDmode
, result
));
200 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
204 /* Generate code to perform a straightforward complex divide. */
207 expand_cmplxdiv_straight (real0
, real1
, imag0
, imag1
, realr
, imagr
, submode
,
208 unsignedp
, methods
, class, binoptab
)
209 rtx real0
, real1
, imag0
, imag1
, realr
, imagr
;
210 enum machine_mode submode
;
212 enum optab_methods methods
;
213 enum mode_class
class;
221 /* Don't fetch these from memory more than once. */
222 real0
= force_reg (submode
, real0
);
223 real1
= force_reg (submode
, real1
);
226 imag0
= force_reg (submode
, imag0
);
228 imag1
= force_reg (submode
, imag1
);
230 /* Divisor: c*c + d*d. */
231 temp1
= expand_binop (submode
, smul_optab
, real1
, real1
,
232 NULL_RTX
, unsignedp
, methods
);
234 temp2
= expand_binop (submode
, smul_optab
, imag1
, imag1
,
235 NULL_RTX
, unsignedp
, methods
);
237 if (temp1
== 0 || temp2
== 0)
240 divisor
= expand_binop (submode
, add_optab
, temp1
, temp2
,
241 NULL_RTX
, unsignedp
, methods
);
247 /* Mathematically, ((a)(c-id))/divisor. */
248 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
250 /* Calculate the dividend. */
251 real_t
= expand_binop (submode
, smul_optab
, real0
, real1
,
252 NULL_RTX
, unsignedp
, methods
);
254 imag_t
= expand_binop (submode
, smul_optab
, real0
, imag1
,
255 NULL_RTX
, unsignedp
, methods
);
257 if (real_t
== 0 || imag_t
== 0)
260 imag_t
= expand_unop (submode
, neg_optab
, imag_t
,
261 NULL_RTX
, unsignedp
);
265 /* Mathematically, ((a+ib)(c-id))/divider. */
266 /* Calculate the dividend. */
267 temp1
= expand_binop (submode
, smul_optab
, real0
, real1
,
268 NULL_RTX
, unsignedp
, methods
);
270 temp2
= expand_binop (submode
, smul_optab
, imag0
, imag1
,
271 NULL_RTX
, unsignedp
, methods
);
273 if (temp1
== 0 || temp2
== 0)
276 real_t
= expand_binop (submode
, add_optab
, temp1
, temp2
,
277 NULL_RTX
, unsignedp
, methods
);
279 temp1
= expand_binop (submode
, smul_optab
, imag0
, real1
,
280 NULL_RTX
, unsignedp
, methods
);
282 temp2
= expand_binop (submode
, smul_optab
, real0
, imag1
,
283 NULL_RTX
, unsignedp
, methods
);
285 if (temp1
== 0 || temp2
== 0)
288 imag_t
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
289 NULL_RTX
, unsignedp
, methods
);
291 if (real_t
== 0 || imag_t
== 0)
295 if (class == MODE_COMPLEX_FLOAT
)
296 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
297 realr
, unsignedp
, methods
);
299 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
300 real_t
, divisor
, realr
, unsignedp
);
306 emit_move_insn (realr
, res
);
308 if (class == MODE_COMPLEX_FLOAT
)
309 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
310 imagr
, unsignedp
, methods
);
312 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
313 imag_t
, divisor
, imagr
, unsignedp
);
319 emit_move_insn (imagr
, res
);
324 /* Generate code to perform a wide-input-range-acceptable complex divide. */
327 expand_cmplxdiv_wide (real0
, real1
, imag0
, imag1
, realr
, imagr
, submode
,
328 unsignedp
, methods
, class, binoptab
)
329 rtx real0
, real1
, imag0
, imag1
, realr
, imagr
;
330 enum machine_mode submode
;
332 enum optab_methods methods
;
333 enum mode_class
class;
338 rtx temp1
, temp2
, lab1
, lab2
;
339 enum machine_mode mode
;
343 /* Don't fetch these from memory more than once. */
344 real0
= force_reg (submode
, real0
);
345 real1
= force_reg (submode
, real1
);
348 imag0
= force_reg (submode
, imag0
);
350 imag1
= force_reg (submode
, imag1
);
352 /* XXX What's an "unsigned" complex number? */
360 temp1
= expand_abs (submode
, real1
, NULL_RTX
, 1);
361 temp2
= expand_abs (submode
, imag1
, NULL_RTX
, 1);
364 if (temp1
== 0 || temp2
== 0)
367 mode
= GET_MODE (temp1
);
368 align
= GET_MODE_ALIGNMENT (mode
);
369 lab1
= gen_label_rtx ();
370 emit_cmp_and_jump_insns (temp1
, temp2
, LT
, NULL_RTX
,
371 mode
, unsignedp
, align
, lab1
);
373 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
375 if (class == MODE_COMPLEX_FLOAT
)
376 ratio
= expand_binop (submode
, binoptab
, imag1
, real1
,
377 NULL_RTX
, unsignedp
, methods
);
379 ratio
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
380 imag1
, real1
, NULL_RTX
, unsignedp
);
385 /* Calculate divisor. */
387 temp1
= expand_binop (submode
, smul_optab
, imag1
, ratio
,
388 NULL_RTX
, unsignedp
, methods
);
393 divisor
= expand_binop (submode
, add_optab
, temp1
, real1
,
394 NULL_RTX
, unsignedp
, methods
);
399 /* Calculate dividend. */
405 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
407 imag_t
= expand_binop (submode
, smul_optab
, real0
, ratio
,
408 NULL_RTX
, unsignedp
, methods
);
413 imag_t
= expand_unop (submode
, neg_optab
, imag_t
,
414 NULL_RTX
, unsignedp
);
416 if (real_t
== 0 || imag_t
== 0)
421 /* Compute (a+ib)/(c+id) as
422 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
424 temp1
= expand_binop (submode
, smul_optab
, imag0
, ratio
,
425 NULL_RTX
, unsignedp
, methods
);
430 real_t
= expand_binop (submode
, add_optab
, temp1
, real0
,
431 NULL_RTX
, unsignedp
, methods
);
433 temp1
= expand_binop (submode
, smul_optab
, real0
, ratio
,
434 NULL_RTX
, unsignedp
, methods
);
439 imag_t
= expand_binop (submode
, sub_optab
, imag0
, temp1
,
440 NULL_RTX
, unsignedp
, methods
);
442 if (real_t
== 0 || imag_t
== 0)
446 if (class == MODE_COMPLEX_FLOAT
)
447 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
448 realr
, unsignedp
, methods
);
450 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
451 real_t
, divisor
, realr
, unsignedp
);
457 emit_move_insn (realr
, res
);
459 if (class == MODE_COMPLEX_FLOAT
)
460 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
461 imagr
, unsignedp
, methods
);
463 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
464 imag_t
, divisor
, imagr
, unsignedp
);
470 emit_move_insn (imagr
, res
);
472 lab2
= gen_label_rtx ();
473 emit_jump_insn (gen_jump (lab2
));
478 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
480 if (class == MODE_COMPLEX_FLOAT
)
481 ratio
= expand_binop (submode
, binoptab
, real1
, imag1
,
482 NULL_RTX
, unsignedp
, methods
);
484 ratio
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
485 real1
, imag1
, NULL_RTX
, unsignedp
);
490 /* Calculate divisor. */
492 temp1
= expand_binop (submode
, smul_optab
, real1
, ratio
,
493 NULL_RTX
, unsignedp
, methods
);
498 divisor
= expand_binop (submode
, add_optab
, temp1
, imag1
,
499 NULL_RTX
, unsignedp
, methods
);
504 /* Calculate dividend. */
508 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
510 real_t
= expand_binop (submode
, smul_optab
, real0
, ratio
,
511 NULL_RTX
, unsignedp
, methods
);
513 imag_t
= expand_unop (submode
, neg_optab
, real0
,
514 NULL_RTX
, unsignedp
);
516 if (real_t
== 0 || imag_t
== 0)
521 /* Compute (a+ib)/(c+id) as
522 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
524 temp1
= expand_binop (submode
, smul_optab
, real0
, ratio
,
525 NULL_RTX
, unsignedp
, methods
);
530 real_t
= expand_binop (submode
, add_optab
, temp1
, imag0
,
531 NULL_RTX
, unsignedp
, methods
);
533 temp1
= expand_binop (submode
, smul_optab
, imag0
, ratio
,
534 NULL_RTX
, unsignedp
, methods
);
539 imag_t
= expand_binop (submode
, sub_optab
, temp1
, real0
,
540 NULL_RTX
, unsignedp
, methods
);
542 if (real_t
== 0 || imag_t
== 0)
546 if (class == MODE_COMPLEX_FLOAT
)
547 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
548 realr
, unsignedp
, methods
);
550 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
551 real_t
, divisor
, realr
, unsignedp
);
557 emit_move_insn (realr
, res
);
559 if (class == MODE_COMPLEX_FLOAT
)
560 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
561 imagr
, unsignedp
, methods
);
563 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
564 imag_t
, divisor
, imagr
, unsignedp
);
570 emit_move_insn (imagr
, res
);
577 /* Generate code to perform an operation specified by BINOPTAB
578 on operands OP0 and OP1, with result having machine-mode MODE.
580 UNSIGNEDP is for the case where we have to widen the operands
581 to perform the operation. It says to use zero-extension.
583 If TARGET is nonzero, the value
584 is generated there, if it is convenient to do so.
585 In all cases an rtx is returned for the locus of the value;
586 this may or may not be TARGET. */
589 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
590 enum machine_mode mode
;
595 enum optab_methods methods
;
597 enum optab_methods next_methods
598 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
599 ? OPTAB_WIDEN
: methods
);
600 enum mode_class
class;
601 enum machine_mode wider_mode
;
603 int commutative_op
= 0;
604 int shift_op
= (binoptab
->code
== ASHIFT
605 || binoptab
->code
== ASHIFTRT
606 || binoptab
->code
== LSHIFTRT
607 || binoptab
->code
== ROTATE
608 || binoptab
->code
== ROTATERT
);
609 rtx entry_last
= get_last_insn ();
612 class = GET_MODE_CLASS (mode
);
614 op0
= protect_from_queue (op0
, 0);
615 op1
= protect_from_queue (op1
, 0);
617 target
= protect_from_queue (target
, 1);
621 op0
= force_not_mem (op0
);
622 op1
= force_not_mem (op1
);
625 /* If subtracting an integer constant, convert this into an addition of
626 the negated constant. */
628 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
630 op1
= negate_rtx (mode
, op1
);
631 binoptab
= add_optab
;
634 /* If we are inside an appropriately-short loop and one operand is an
635 expensive constant, force it into a register. */
636 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
637 && rtx_cost (op0
, binoptab
->code
) > 2)
638 op0
= force_reg (mode
, op0
);
640 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
641 && ! shift_op
&& rtx_cost (op1
, binoptab
->code
) > 2)
642 op1
= force_reg (mode
, op1
);
644 /* Record where to delete back to if we backtrack. */
645 last
= get_last_insn ();
647 /* If operation is commutative,
648 try to make the first operand a register.
649 Even better, try to make it the same as the target.
650 Also try to make the last operand a constant. */
651 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
652 || binoptab
== smul_widen_optab
653 || binoptab
== umul_widen_optab
654 || binoptab
== smul_highpart_optab
655 || binoptab
== umul_highpart_optab
)
659 if (((target
== 0 || GET_CODE (target
) == REG
)
660 ? ((GET_CODE (op1
) == REG
661 && GET_CODE (op0
) != REG
)
663 : rtx_equal_p (op1
, target
))
664 || GET_CODE (op0
) == CONST_INT
)
672 /* If we can do it with a three-operand insn, do so. */
674 if (methods
!= OPTAB_MUST_WIDEN
675 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
677 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
678 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
679 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
681 rtx xop0
= op0
, xop1
= op1
;
686 temp
= gen_reg_rtx (mode
);
688 /* If it is a commutative operator and the modes would match
689 if we would swap the operands, we can save the conversions. */
692 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
693 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
697 tmp
= op0
; op0
= op1
; op1
= tmp
;
698 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
702 /* In case the insn wants input operands in modes different from
703 the result, convert the operands. */
705 if (GET_MODE (op0
) != VOIDmode
706 && GET_MODE (op0
) != mode0
707 && mode0
!= VOIDmode
)
708 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
710 if (GET_MODE (xop1
) != VOIDmode
711 && GET_MODE (xop1
) != mode1
712 && mode1
!= VOIDmode
)
713 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
715 /* Now, if insn's predicates don't allow our operands, put them into
718 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
)
719 && mode0
!= VOIDmode
)
720 xop0
= copy_to_mode_reg (mode0
, xop0
);
722 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, mode1
)
723 && mode1
!= VOIDmode
)
724 xop1
= copy_to_mode_reg (mode1
, xop1
);
726 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, mode
))
727 temp
= gen_reg_rtx (mode
);
729 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
732 /* If PAT is a multi-insn sequence, try to add an appropriate
733 REG_EQUAL note to it. If we can't because TEMP conflicts with an
734 operand, call ourselves again, this time without a target. */
735 if (GET_CODE (pat
) == SEQUENCE
736 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
738 delete_insns_since (last
);
739 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
747 delete_insns_since (last
);
750 /* If this is a multiply, see if we can do a widening operation that
751 takes operands of this mode and makes a wider mode. */
753 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
754 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
755 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
756 != CODE_FOR_nothing
))
758 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
759 unsignedp
? umul_widen_optab
: smul_widen_optab
,
760 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
764 if (GET_MODE_CLASS (mode
) == MODE_INT
)
765 return gen_lowpart (mode
, temp
);
767 return convert_to_mode (mode
, temp
, unsignedp
);
771 /* Look for a wider mode of the same class for which we think we
772 can open-code the operation. Check for a widening multiply at the
773 wider mode as well. */
775 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
776 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
777 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
778 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
780 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
781 || (binoptab
== smul_optab
782 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
783 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
784 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
785 != CODE_FOR_nothing
)))
787 rtx xop0
= op0
, xop1
= op1
;
790 /* For certain integer operations, we need not actually extend
791 the narrow operands, as long as we will truncate
792 the results to the same narrowness. */
794 if ((binoptab
== ior_optab
|| binoptab
== and_optab
795 || binoptab
== xor_optab
796 || binoptab
== add_optab
|| binoptab
== sub_optab
797 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
798 && class == MODE_INT
)
801 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
803 /* The second operand of a shift must always be extended. */
804 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
805 no_extend
&& binoptab
!= ashl_optab
);
807 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
808 unsignedp
, OPTAB_DIRECT
);
811 if (class != MODE_INT
)
814 target
= gen_reg_rtx (mode
);
815 convert_move (target
, temp
, 0);
819 return gen_lowpart (mode
, temp
);
822 delete_insns_since (last
);
826 /* These can be done a word at a time. */
827 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
829 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
830 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
836 /* If TARGET is the same as one of the operands, the REG_EQUAL note
837 won't be accurate, so use a new target. */
838 if (target
== 0 || target
== op0
|| target
== op1
)
839 target
= gen_reg_rtx (mode
);
843 /* Do the actual arithmetic. */
844 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
846 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
847 rtx x
= expand_binop (word_mode
, binoptab
,
848 operand_subword_force (op0
, i
, mode
),
849 operand_subword_force (op1
, i
, mode
),
850 target_piece
, unsignedp
, next_methods
);
855 if (target_piece
!= x
)
856 emit_move_insn (target_piece
, x
);
859 insns
= get_insns ();
862 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
864 if (binoptab
->code
!= UNKNOWN
)
866 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
867 copy_rtx (op0
), copy_rtx (op1
));
871 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
876 /* Synthesize double word shifts from single word shifts. */
877 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
878 || binoptab
== ashr_optab
)
880 && GET_CODE (op1
) == CONST_INT
881 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
882 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
883 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
884 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
886 rtx insns
, inter
, equiv_value
;
887 rtx into_target
, outof_target
;
888 rtx into_input
, outof_input
;
889 int shift_count
, left_shift
, outof_word
;
891 /* If TARGET is the same as one of the operands, the REG_EQUAL note
892 won't be accurate, so use a new target. */
893 if (target
== 0 || target
== op0
|| target
== op1
)
894 target
= gen_reg_rtx (mode
);
898 shift_count
= INTVAL (op1
);
900 /* OUTOF_* is the word we are shifting bits away from, and
901 INTO_* is the word that we are shifting bits towards, thus
902 they differ depending on the direction of the shift and
905 left_shift
= binoptab
== ashl_optab
;
906 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
908 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
909 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
911 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
912 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
914 if (shift_count
>= BITS_PER_WORD
)
916 inter
= expand_binop (word_mode
, binoptab
,
918 GEN_INT (shift_count
- BITS_PER_WORD
),
919 into_target
, unsignedp
, next_methods
);
921 if (inter
!= 0 && inter
!= into_target
)
922 emit_move_insn (into_target
, inter
);
924 /* For a signed right shift, we must fill the word we are shifting
925 out of with copies of the sign bit. Otherwise it is zeroed. */
926 if (inter
!= 0 && binoptab
!= ashr_optab
)
927 inter
= CONST0_RTX (word_mode
);
929 inter
= expand_binop (word_mode
, binoptab
,
931 GEN_INT (BITS_PER_WORD
- 1),
932 outof_target
, unsignedp
, next_methods
);
934 if (inter
!= 0 && inter
!= outof_target
)
935 emit_move_insn (outof_target
, inter
);
940 optab reverse_unsigned_shift
, unsigned_shift
;
942 /* For a shift of less then BITS_PER_WORD, to compute the carry,
943 we must do a logical shift in the opposite direction of the
946 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
948 /* For a shift of less than BITS_PER_WORD, to compute the word
949 shifted towards, we need to unsigned shift the orig value of
952 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
954 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
956 GEN_INT (BITS_PER_WORD
- shift_count
),
957 0, unsignedp
, next_methods
);
962 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
963 op1
, 0, unsignedp
, next_methods
);
966 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
967 into_target
, unsignedp
, next_methods
);
969 if (inter
!= 0 && inter
!= into_target
)
970 emit_move_insn (into_target
, inter
);
973 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
974 op1
, outof_target
, unsignedp
, next_methods
);
976 if (inter
!= 0 && inter
!= outof_target
)
977 emit_move_insn (outof_target
, inter
);
980 insns
= get_insns ();
985 if (binoptab
->code
!= UNKNOWN
)
986 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
990 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
995 /* Synthesize double word rotates from single word shifts. */
996 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
998 && GET_CODE (op1
) == CONST_INT
999 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1000 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1001 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1003 rtx insns
, equiv_value
;
1004 rtx into_target
, outof_target
;
1005 rtx into_input
, outof_input
;
1007 int shift_count
, left_shift
, outof_word
;
1009 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1010 won't be accurate, so use a new target. */
1011 if (target
== 0 || target
== op0
|| target
== op1
)
1012 target
= gen_reg_rtx (mode
);
1016 shift_count
= INTVAL (op1
);
1018 /* OUTOF_* is the word we are shifting bits away from, and
1019 INTO_* is the word that we are shifting bits towards, thus
1020 they differ depending on the direction of the shift and
1021 WORDS_BIG_ENDIAN. */
1023 left_shift
= (binoptab
== rotl_optab
);
1024 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1026 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1027 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1029 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1030 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1032 if (shift_count
== BITS_PER_WORD
)
1034 /* This is just a word swap. */
1035 emit_move_insn (outof_target
, into_input
);
1036 emit_move_insn (into_target
, outof_input
);
1041 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1042 rtx first_shift_count
, second_shift_count
;
1043 optab reverse_unsigned_shift
, unsigned_shift
;
1045 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1046 ? lshr_optab
: ashl_optab
);
1048 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1049 ? ashl_optab
: lshr_optab
);
1051 if (shift_count
> BITS_PER_WORD
)
1053 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1054 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
1058 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1059 second_shift_count
= GEN_INT (shift_count
);
1062 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1063 outof_input
, first_shift_count
,
1064 NULL_RTX
, unsignedp
, next_methods
);
1065 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1066 into_input
, second_shift_count
,
1067 into_target
, unsignedp
, next_methods
);
1069 if (into_temp1
!= 0 && into_temp2
!= 0)
1070 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1071 into_target
, unsignedp
, next_methods
);
1075 if (inter
!= 0 && inter
!= into_target
)
1076 emit_move_insn (into_target
, inter
);
1078 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1079 into_input
, first_shift_count
,
1080 NULL_RTX
, unsignedp
, next_methods
);
1081 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1082 outof_input
, second_shift_count
,
1083 outof_target
, unsignedp
, next_methods
);
1085 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1086 inter
= expand_binop (word_mode
, ior_optab
,
1087 outof_temp1
, outof_temp2
,
1088 outof_target
, unsignedp
, next_methods
);
1090 if (inter
!= 0 && inter
!= outof_target
)
1091 emit_move_insn (outof_target
, inter
);
1094 insns
= get_insns ();
1099 if (binoptab
->code
!= UNKNOWN
)
1100 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
1104 /* We can't make this a no conflict block if this is a word swap,
1105 because the word swap case fails if the input and output values
1106 are in the same register. */
1107 if (shift_count
!= BITS_PER_WORD
)
1108 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
1117 /* These can be done a word at a time by propagating carries. */
1118 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1119 && class == MODE_INT
1120 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1121 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1124 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1125 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1126 unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1127 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1130 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1131 value is one of those, use it. Otherwise, use 1 since it is the
1132 one easiest to get. */
1133 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1134 int normalizep
= STORE_FLAG_VALUE
;
1139 /* Prepare the operands. */
1140 xop0
= force_reg (mode
, op0
);
1141 xop1
= force_reg (mode
, op1
);
1143 if (target
== 0 || GET_CODE (target
) != REG
1144 || target
== xop0
|| target
== xop1
)
1145 target
= gen_reg_rtx (mode
);
1147 /* Indicate for flow that the entire target reg is being set. */
1148 if (GET_CODE (target
) == REG
)
1149 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
1151 /* Do the actual arithmetic. */
1152 for (i
= 0; i
< nwords
; i
++)
1154 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1155 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
1156 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1157 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
1160 /* Main add/subtract of the input operands. */
1161 x
= expand_binop (word_mode
, binoptab
,
1162 op0_piece
, op1_piece
,
1163 target_piece
, unsignedp
, next_methods
);
1169 /* Store carry from main add/subtract. */
1170 carry_out
= gen_reg_rtx (word_mode
);
1171 carry_out
= emit_store_flag_force (carry_out
,
1172 (binoptab
== add_optab
1175 word_mode
, 1, normalizep
);
1180 /* Add/subtract previous carry to main result. */
1181 x
= expand_binop (word_mode
,
1182 normalizep
== 1 ? binoptab
: otheroptab
,
1184 target_piece
, 1, next_methods
);
1187 else if (target_piece
!= x
)
1188 emit_move_insn (target_piece
, x
);
1192 /* THIS CODE HAS NOT BEEN TESTED. */
1193 /* Get out carry from adding/subtracting carry in. */
1194 carry_tmp
= emit_store_flag_force (carry_tmp
,
1195 binoptab
== add_optab
1198 word_mode
, 1, normalizep
);
1200 /* Logical-ior the two poss. carry together. */
1201 carry_out
= expand_binop (word_mode
, ior_optab
,
1202 carry_out
, carry_tmp
,
1203 carry_out
, 0, next_methods
);
1209 carry_in
= carry_out
;
1212 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1214 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1216 rtx temp
= emit_move_insn (target
, target
);
1218 set_unique_reg_note (temp
,
1220 gen_rtx_fmt_ee (binoptab
->code
, mode
,
1229 delete_insns_since (last
);
1232 /* If we want to multiply two two-word values and have normal and widening
1233 multiplies of single-word values, we can do this with three smaller
1234 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1235 because we are not operating on one word at a time.
1237 The multiplication proceeds as follows:
1238 _______________________
1239 [__op0_high_|__op0_low__]
1240 _______________________
1241 * [__op1_high_|__op1_low__]
1242 _______________________________________________
1243 _______________________
1244 (1) [__op0_low__*__op1_low__]
1245 _______________________
1246 (2a) [__op0_low__*__op1_high_]
1247 _______________________
1248 (2b) [__op0_high_*__op1_low__]
1249 _______________________
1250 (3) [__op0_high_*__op1_high_]
1253 This gives a 4-word result. Since we are only interested in the
1254 lower 2 words, partial result (3) and the upper words of (2a) and
1255 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1256 calculated using non-widening multiplication.
1258 (1), however, needs to be calculated with an unsigned widening
1259 multiplication. If this operation is not directly supported we
1260 try using a signed widening multiplication and adjust the result.
1261 This adjustment works as follows:
1263 If both operands are positive then no adjustment is needed.
1265 If the operands have different signs, for example op0_low < 0 and
1266 op1_low >= 0, the instruction treats the most significant bit of
1267 op0_low as a sign bit instead of a bit with significance
1268 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1269 with 2**BITS_PER_WORD - op0_low, and two's complements the
1270 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1273 Similarly, if both operands are negative, we need to add
1274 (op0_low + op1_low) * 2**BITS_PER_WORD.
1276 We use a trick to adjust quickly. We logically shift op0_low right
1277 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1278 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1279 logical shift exists, we do an arithmetic right shift and subtract
1282 if (binoptab
== smul_optab
1283 && class == MODE_INT
1284 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1285 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1286 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1287 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1288 != CODE_FOR_nothing
)
1289 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1290 != CODE_FOR_nothing
)))
1292 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1293 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1294 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1295 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1296 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1297 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1299 rtx op0_xhigh
= NULL_RTX
;
1300 rtx op1_xhigh
= NULL_RTX
;
1302 /* If the target is the same as one of the inputs, don't use it. This
1303 prevents problems with the REG_EQUAL note. */
1304 if (target
== op0
|| target
== op1
1305 || (target
!= 0 && GET_CODE (target
) != REG
))
1308 /* Multiply the two lower words to get a double-word product.
1309 If unsigned widening multiplication is available, use that;
1310 otherwise use the signed form and compensate. */
1312 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1314 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1315 target
, 1, OPTAB_DIRECT
);
1317 /* If we didn't succeed, delete everything we did so far. */
1319 delete_insns_since (last
);
1321 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1325 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1326 != CODE_FOR_nothing
)
1328 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1329 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1330 target
, 1, OPTAB_DIRECT
);
1331 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1332 NULL_RTX
, 1, next_methods
);
1334 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1335 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1338 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1339 NULL_RTX
, 0, next_methods
);
1341 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1342 op0_xhigh
, op0_xhigh
, 0,
1346 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1347 NULL_RTX
, 1, next_methods
);
1349 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1350 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1353 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1354 NULL_RTX
, 0, next_methods
);
1356 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1357 op1_xhigh
, op1_xhigh
, 0,
1362 /* If we have been able to directly compute the product of the
1363 low-order words of the operands and perform any required adjustments
1364 of the operands, we proceed by trying two more multiplications
1365 and then computing the appropriate sum.
1367 We have checked above that the required addition is provided.
1368 Full-word addition will normally always succeed, especially if
1369 it is provided at all, so we don't worry about its failure. The
1370 multiplication may well fail, however, so we do handle that. */
1372 if (product
&& op0_xhigh
&& op1_xhigh
)
1374 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1375 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1376 NULL_RTX
, 0, OPTAB_DIRECT
);
1379 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1380 product_high
, 0, next_methods
);
1382 if (temp
!= 0 && temp
!= product_high
)
1383 emit_move_insn (product_high
, temp
);
1386 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1387 NULL_RTX
, 0, OPTAB_DIRECT
);
1390 temp
= expand_binop (word_mode
, add_optab
, temp
,
1391 product_high
, product_high
,
1394 if (temp
!= 0 && temp
!= product_high
)
1395 emit_move_insn (product_high
, temp
);
1399 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1401 temp
= emit_move_insn (product
, product
);
1402 set_unique_reg_note (temp
,
1404 gen_rtx_fmt_ee (MULT
, mode
,
1413 /* If we get here, we couldn't do it for some reason even though we
1414 originally thought we could. Delete anything we've emitted in
1417 delete_insns_since (last
);
1420 /* We need to open-code the complex type operations: '+, -, * and /' */
1422 /* At this point we allow operations between two similar complex
1423 numbers, and also if one of the operands is not a complex number
1424 but rather of MODE_FLOAT or MODE_INT. However, the caller
1425 must make sure that the MODE of the non-complex operand matches
1426 the SUBMODE of the complex operand. */
1428 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1430 rtx real0
= 0, imag0
= 0;
1431 rtx real1
= 0, imag1
= 0;
1432 rtx realr
, imagr
, res
;
1437 /* Find the correct mode for the real and imaginary parts */
1438 enum machine_mode submode
1439 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1440 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1443 if (submode
== BLKmode
)
1447 target
= gen_reg_rtx (mode
);
1451 realr
= gen_realpart (submode
, target
);
1452 imagr
= gen_imagpart (submode
, target
);
1454 if (GET_MODE (op0
) == mode
)
1456 real0
= gen_realpart (submode
, op0
);
1457 imag0
= gen_imagpart (submode
, op0
);
1462 if (GET_MODE (op1
) == mode
)
1464 real1
= gen_realpart (submode
, op1
);
1465 imag1
= gen_imagpart (submode
, op1
);
1470 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1473 switch (binoptab
->code
)
1476 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1478 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1479 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1480 realr
, unsignedp
, methods
);
1484 else if (res
!= realr
)
1485 emit_move_insn (realr
, res
);
1488 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1489 imagr
, unsignedp
, methods
);
1492 else if (binoptab
->code
== MINUS
)
1493 res
= expand_unop (submode
, neg_optab
, imag1
, imagr
, unsignedp
);
1499 else if (res
!= imagr
)
1500 emit_move_insn (imagr
, res
);
1506 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1512 /* Don't fetch these from memory more than once. */
1513 real0
= force_reg (submode
, real0
);
1514 real1
= force_reg (submode
, real1
);
1515 imag0
= force_reg (submode
, imag0
);
1516 imag1
= force_reg (submode
, imag1
);
1518 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1519 unsignedp
, methods
);
1521 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1522 unsignedp
, methods
);
1524 if (temp1
== 0 || temp2
== 0)
1527 res
= expand_binop (submode
, sub_optab
, temp1
, temp2
,
1528 realr
, unsignedp
, methods
);
1532 else if (res
!= realr
)
1533 emit_move_insn (realr
, res
);
1535 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1536 NULL_RTX
, unsignedp
, methods
);
1538 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1539 NULL_RTX
, unsignedp
, methods
);
1541 if (temp1
== 0 || temp2
== 0)
1544 res
= expand_binop (submode
, add_optab
, temp1
, temp2
,
1545 imagr
, unsignedp
, methods
);
1549 else if (res
!= imagr
)
1550 emit_move_insn (imagr
, res
);
1556 /* Don't fetch these from memory more than once. */
1557 real0
= force_reg (submode
, real0
);
1558 real1
= force_reg (submode
, real1
);
1560 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1561 realr
, unsignedp
, methods
);
1564 else if (res
!= realr
)
1565 emit_move_insn (realr
, res
);
1568 res
= expand_binop (submode
, binoptab
,
1569 real1
, imag0
, imagr
, unsignedp
, methods
);
1571 res
= expand_binop (submode
, binoptab
,
1572 real0
, imag1
, imagr
, unsignedp
, methods
);
1576 else if (res
!= imagr
)
1577 emit_move_insn (imagr
, res
);
1584 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1588 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1590 /* Don't fetch these from memory more than once. */
1591 real1
= force_reg (submode
, real1
);
1593 /* Simply divide the real and imaginary parts by `c' */
1594 if (class == MODE_COMPLEX_FLOAT
)
1595 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1596 realr
, unsignedp
, methods
);
1598 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1599 real0
, real1
, realr
, unsignedp
);
1603 else if (res
!= realr
)
1604 emit_move_insn (realr
, res
);
1606 if (class == MODE_COMPLEX_FLOAT
)
1607 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1608 imagr
, unsignedp
, methods
);
1610 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1611 imag0
, real1
, imagr
, unsignedp
);
1615 else if (res
!= imagr
)
1616 emit_move_insn (imagr
, res
);
1622 switch (flag_complex_divide_method
)
1625 ok
= expand_cmplxdiv_straight (real0
, real1
, imag0
, imag1
,
1626 realr
, imagr
, submode
,
1632 ok
= expand_cmplxdiv_wide (real0
, real1
, imag0
, imag1
,
1633 realr
, imagr
, submode
,
1653 if (binoptab
->code
!= UNKNOWN
)
1655 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
1656 copy_rtx (op0
), copy_rtx (op1
));
1660 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1666 /* It can't be open-coded in this mode.
1667 Use a library call if one is available and caller says that's ok. */
1669 if (binoptab
->handlers
[(int) mode
].libfunc
1670 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1674 enum machine_mode op1_mode
= mode
;
1681 op1_mode
= word_mode
;
1682 /* Specify unsigned here,
1683 since negative shift counts are meaningless. */
1684 op1x
= convert_to_mode (word_mode
, op1
, 1);
1687 if (GET_MODE (op0
) != VOIDmode
1688 && GET_MODE (op0
) != mode
)
1689 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1691 /* Pass 1 for NO_QUEUE so we don't lose any increments
1692 if the libcall is cse'd or moved. */
1693 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1694 NULL_RTX
, 1, mode
, 2,
1695 op0
, mode
, op1x
, op1_mode
);
1697 insns
= get_insns ();
1700 target
= gen_reg_rtx (mode
);
1701 emit_libcall_block (insns
, target
, value
,
1702 gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
));
1707 delete_insns_since (last
);
1709 /* It can't be done in this mode. Can we do it in a wider mode? */
1711 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1712 || methods
== OPTAB_MUST_WIDEN
))
1714 /* Caller says, don't even try. */
1715 delete_insns_since (entry_last
);
1719 /* Compute the value of METHODS to pass to recursive calls.
1720 Don't allow widening to be tried recursively. */
1722 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1724 /* Look for a wider mode of the same class for which it appears we can do
1727 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1729 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1730 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1732 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1733 != CODE_FOR_nothing
)
1734 || (methods
== OPTAB_LIB
1735 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1737 rtx xop0
= op0
, xop1
= op1
;
1740 /* For certain integer operations, we need not actually extend
1741 the narrow operands, as long as we will truncate
1742 the results to the same narrowness. */
1744 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1745 || binoptab
== xor_optab
1746 || binoptab
== add_optab
|| binoptab
== sub_optab
1747 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1748 && class == MODE_INT
)
1751 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1752 unsignedp
, no_extend
);
1754 /* The second operand of a shift must always be extended. */
1755 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1756 no_extend
&& binoptab
!= ashl_optab
);
1758 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1759 unsignedp
, methods
);
1762 if (class != MODE_INT
)
1765 target
= gen_reg_rtx (mode
);
1766 convert_move (target
, temp
, 0);
1770 return gen_lowpart (mode
, temp
);
1773 delete_insns_since (last
);
1778 delete_insns_since (entry_last
);
1782 /* Expand a binary operator which has both signed and unsigned forms.
1783 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1786 If we widen unsigned operands, we may use a signed wider operation instead
1787 of an unsigned wider operation, since the result would be the same. */
1790 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1791 enum machine_mode mode
;
1792 optab uoptab
, soptab
;
1793 rtx op0
, op1
, target
;
1795 enum optab_methods methods
;
1798 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1799 struct optab wide_soptab
;
1801 /* Do it without widening, if possible. */
1802 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1803 unsignedp
, OPTAB_DIRECT
);
1804 if (temp
|| methods
== OPTAB_DIRECT
)
1807 /* Try widening to a signed int. Make a fake signed optab that
1808 hides any signed insn for direct use. */
1809 wide_soptab
= *soptab
;
1810 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1811 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1813 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1814 unsignedp
, OPTAB_WIDEN
);
1816 /* For unsigned operands, try widening to an unsigned int. */
1817 if (temp
== 0 && unsignedp
)
1818 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1819 unsignedp
, OPTAB_WIDEN
);
1820 if (temp
|| methods
== OPTAB_WIDEN
)
1823 /* Use the right width lib call if that exists. */
1824 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1825 if (temp
|| methods
== OPTAB_LIB
)
1828 /* Must widen and use a lib call, use either signed or unsigned. */
1829 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1830 unsignedp
, methods
);
1834 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1835 unsignedp
, methods
);
1839 /* Generate code to perform an operation specified by BINOPTAB
1840 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1841 We assume that the order of the operands for the instruction
1842 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1843 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1845 Either TARG0 or TARG1 may be zero, but what that means is that
1846 the result is not actually wanted. We will generate it into
1847 a dummy pseudo-reg and discard it. They may not both be zero.
1849 Returns 1 if this operation can be performed; 0 if not. */
1852 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1858 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1859 enum mode_class
class;
1860 enum machine_mode wider_mode
;
1861 rtx entry_last
= get_last_insn ();
1864 class = GET_MODE_CLASS (mode
);
1866 op0
= protect_from_queue (op0
, 0);
1867 op1
= protect_from_queue (op1
, 0);
1871 op0
= force_not_mem (op0
);
1872 op1
= force_not_mem (op1
);
1875 /* If we are inside an appropriately-short loop and one operand is an
1876 expensive constant, force it into a register. */
1877 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1878 && rtx_cost (op0
, binoptab
->code
) > 2)
1879 op0
= force_reg (mode
, op0
);
1881 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1882 && rtx_cost (op1
, binoptab
->code
) > 2)
1883 op1
= force_reg (mode
, op1
);
1886 targ0
= protect_from_queue (targ0
, 1);
1888 targ0
= gen_reg_rtx (mode
);
1890 targ1
= protect_from_queue (targ1
, 1);
1892 targ1
= gen_reg_rtx (mode
);
1894 /* Record where to go back to if we fail. */
1895 last
= get_last_insn ();
1897 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1899 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1900 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1901 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1903 rtx xop0
= op0
, xop1
= op1
;
1905 /* In case this insn wants input operands in modes different from the
1906 result, convert the operands. */
1907 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1908 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1910 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1911 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1913 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1914 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
1915 xop0
= copy_to_mode_reg (mode0
, xop0
);
1917 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, mode1
))
1918 xop1
= copy_to_mode_reg (mode1
, xop1
);
1920 /* We could handle this, but we should always be called with a pseudo
1921 for our targets and all insns should take them as outputs. */
1922 if (! (*insn_data
[icode
].operand
[0].predicate
) (targ0
, mode
)
1923 || ! (*insn_data
[icode
].operand
[3].predicate
) (targ1
, mode
))
1926 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1933 delete_insns_since (last
);
1936 /* It can't be done in this mode. Can we do it in a wider mode? */
1938 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1940 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1941 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1943 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1944 != CODE_FOR_nothing
)
1946 register rtx t0
= gen_reg_rtx (wider_mode
);
1947 register rtx t1
= gen_reg_rtx (wider_mode
);
1949 if (expand_twoval_binop (binoptab
,
1950 convert_modes (wider_mode
, mode
, op0
,
1952 convert_modes (wider_mode
, mode
, op1
,
1956 convert_move (targ0
, t0
, unsignedp
);
1957 convert_move (targ1
, t1
, unsignedp
);
1961 delete_insns_since (last
);
1966 delete_insns_since (entry_last
);
1970 /* Generate code to perform an operation specified by UNOPTAB
1971 on operand OP0, with result having machine-mode MODE.
1973 UNSIGNEDP is for the case where we have to widen the operands
1974 to perform the operation. It says to use zero-extension.
1976 If TARGET is nonzero, the value
1977 is generated there, if it is convenient to do so.
1978 In all cases an rtx is returned for the locus of the value;
1979 this may or may not be TARGET. */
1982 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
1983 enum machine_mode mode
;
1989 enum mode_class
class;
1990 enum machine_mode wider_mode
;
1992 rtx last
= get_last_insn ();
1995 class = GET_MODE_CLASS (mode
);
1997 op0
= protect_from_queue (op0
, 0);
2001 op0
= force_not_mem (op0
);
2005 target
= protect_from_queue (target
, 1);
2007 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2009 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
2010 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2016 temp
= gen_reg_rtx (mode
);
2018 if (GET_MODE (xop0
) != VOIDmode
2019 && GET_MODE (xop0
) != mode0
)
2020 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2022 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2024 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
2025 xop0
= copy_to_mode_reg (mode0
, xop0
);
2027 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, mode
))
2028 temp
= gen_reg_rtx (mode
);
2030 pat
= GEN_FCN (icode
) (temp
, xop0
);
2033 if (GET_CODE (pat
) == SEQUENCE
2034 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
2036 delete_insns_since (last
);
2037 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2045 delete_insns_since (last
);
2048 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2050 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2051 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2052 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2054 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
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
);
2087 /* These can be done a word at a time. */
2088 if (unoptab
== one_cmpl_optab
2089 && class == MODE_INT
2090 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2091 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
2096 if (target
== 0 || target
== op0
)
2097 target
= gen_reg_rtx (mode
);
2101 /* Do the actual arithmetic. */
2102 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
2104 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
2105 rtx x
= expand_unop (word_mode
, unoptab
,
2106 operand_subword_force (op0
, i
, mode
),
2107 target_piece
, unsignedp
);
2108 if (target_piece
!= x
)
2109 emit_move_insn (target_piece
, x
);
2112 insns
= get_insns ();
2115 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
2116 gen_rtx_fmt_e (unoptab
->code
, mode
,
2121 /* Open-code the complex negation operation. */
2122 else if (unoptab
== neg_optab
2123 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
2129 /* Find the correct mode for the real and imaginary parts */
2130 enum machine_mode submode
2131 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2132 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2135 if (submode
== BLKmode
)
2139 target
= gen_reg_rtx (mode
);
2143 target_piece
= gen_imagpart (submode
, target
);
2144 x
= expand_unop (submode
, unoptab
,
2145 gen_imagpart (submode
, op0
),
2146 target_piece
, unsignedp
);
2147 if (target_piece
!= x
)
2148 emit_move_insn (target_piece
, x
);
2150 target_piece
= gen_realpart (submode
, target
);
2151 x
= expand_unop (submode
, unoptab
,
2152 gen_realpart (submode
, op0
),
2153 target_piece
, unsignedp
);
2154 if (target_piece
!= x
)
2155 emit_move_insn (target_piece
, x
);
2160 emit_no_conflict_block (seq
, target
, op0
, 0,
2161 gen_rtx_fmt_e (unoptab
->code
, mode
,
2166 /* Now try a library call in this mode. */
2167 if (unoptab
->handlers
[(int) mode
].libfunc
)
2174 /* Pass 1 for NO_QUEUE so we don't lose any increments
2175 if the libcall is cse'd or moved. */
2176 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
2177 NULL_RTX
, 1, mode
, 1, op0
, mode
);
2178 insns
= get_insns ();
2181 target
= gen_reg_rtx (mode
);
2182 emit_libcall_block (insns
, target
, value
,
2183 gen_rtx_fmt_e (unoptab
->code
, mode
, op0
));
2188 /* It can't be done in this mode. Can we do it in a wider mode? */
2190 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2192 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2193 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2195 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
2196 != CODE_FOR_nothing
)
2197 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
2201 /* For certain operations, we need not actually extend
2202 the narrow operand, as long as we will truncate the
2203 results to the same narrowness. */
2205 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2206 (unoptab
== neg_optab
2207 || unoptab
== one_cmpl_optab
)
2208 && class == MODE_INT
);
2210 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2215 if (class != MODE_INT
)
2218 target
= gen_reg_rtx (mode
);
2219 convert_move (target
, temp
, 0);
2223 return gen_lowpart (mode
, temp
);
2226 delete_insns_since (last
);
2231 /* If there is no negate operation, try doing a subtract from zero.
2232 The US Software GOFAST library needs this. */
2233 if (unoptab
== neg_optab
)
2236 temp
= expand_binop (mode
, sub_optab
, CONST0_RTX (mode
), op0
,
2237 target
, unsignedp
, OPTAB_LIB_WIDEN
);
2245 /* Emit code to compute the absolute value of OP0, with result to
2246 TARGET if convenient. (TARGET may be 0.) The return value says
2247 where the result actually is to be found.
2249 MODE is the mode of the operand; the mode of the result is
2250 different but can be deduced from MODE.
2255 expand_abs (mode
, op0
, target
, safe
)
2256 enum machine_mode mode
;
2263 /* First try to do it with a special abs instruction. */
2264 temp
= expand_unop (mode
, abs_optab
, op0
, target
, 0);
2268 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2269 if (smax_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2271 rtx last
= get_last_insn ();
2273 temp
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, 0);
2275 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
2281 delete_insns_since (last
);
2284 /* If this machine has expensive jumps, we can do integer absolute
2285 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2286 where W is the width of MODE. But don't do this if the machine has
2287 conditional arithmetic since the branches will be converted into
2288 a conditional negation insn. */
2290 #ifndef HAVE_conditional_arithmetic
2291 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
2293 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
2294 size_int (GET_MODE_BITSIZE (mode
) - 1),
2297 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
2300 temp
= expand_binop (mode
, sub_optab
, temp
, extended
, target
, 0,
2308 /* If that does not win, use conditional jump and negate. */
2310 /* It is safe to use the target if it is the same
2311 as the source if this is also a pseudo register */
2312 if (op0
== target
&& GET_CODE (op0
) == REG
2313 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
2316 op1
= gen_label_rtx ();
2317 if (target
== 0 || ! safe
2318 || GET_MODE (target
) != mode
2319 || (GET_CODE (target
) == MEM
&& MEM_VOLATILE_P (target
))
2320 || (GET_CODE (target
) == REG
2321 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
2322 target
= gen_reg_rtx (mode
);
2324 emit_move_insn (target
, op0
);
2327 /* If this mode is an integer too wide to compare properly,
2328 compare word by word. Rely on CSE to optimize constant cases. */
2329 if (GET_MODE_CLASS (mode
) == MODE_INT
2330 && ! can_compare_p (GE
, mode
, ccp_jump
))
2331 do_jump_by_parts_greater_rtx (mode
, 0, target
, const0_rtx
,
2334 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
2335 NULL_RTX
, 0, NULL_RTX
, op1
);
2337 op0
= expand_unop (mode
, neg_optab
, target
, target
, 0);
2339 emit_move_insn (target
, op0
);
2345 /* Emit code to compute the absolute value of OP0, with result to
2346 TARGET if convenient. (TARGET may be 0.) The return value says
2347 where the result actually is to be found.
2349 MODE is the mode of the operand; the mode of the result is
2350 different but can be deduced from MODE.
2352 UNSIGNEDP is relevant for complex integer modes. */
2355 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2356 enum machine_mode mode
;
2361 enum mode_class
class = GET_MODE_CLASS (mode
);
2362 enum machine_mode wider_mode
;
2364 rtx entry_last
= get_last_insn ();
2368 /* Find the correct mode for the real and imaginary parts. */
2369 enum machine_mode submode
2370 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2371 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2374 if (submode
== BLKmode
)
2377 op0
= protect_from_queue (op0
, 0);
2381 op0
= force_not_mem (op0
);
2384 last
= get_last_insn ();
2387 target
= protect_from_queue (target
, 1);
2389 if (abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2391 int icode
= (int) abs_optab
->handlers
[(int) mode
].insn_code
;
2392 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2398 temp
= gen_reg_rtx (submode
);
2400 if (GET_MODE (xop0
) != VOIDmode
2401 && GET_MODE (xop0
) != mode0
)
2402 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2404 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2406 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
2407 xop0
= copy_to_mode_reg (mode0
, xop0
);
2409 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, submode
))
2410 temp
= gen_reg_rtx (submode
);
2412 pat
= GEN_FCN (icode
) (temp
, xop0
);
2415 if (GET_CODE (pat
) == SEQUENCE
2416 && ! add_equal_note (pat
, temp
, abs_optab
->code
, xop0
, NULL_RTX
))
2418 delete_insns_since (last
);
2419 return expand_unop (mode
, abs_optab
, op0
, NULL_RTX
, unsignedp
);
2427 delete_insns_since (last
);
2430 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2432 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2433 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2435 if (abs_optab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2439 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2440 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2444 if (class != MODE_COMPLEX_INT
)
2447 target
= gen_reg_rtx (submode
);
2448 convert_move (target
, temp
, 0);
2452 return gen_lowpart (submode
, temp
);
2455 delete_insns_since (last
);
2459 /* Open-code the complex absolute-value operation
2460 if we can open-code sqrt. Otherwise it's not worth while. */
2461 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
)
2463 rtx real
, imag
, total
;
2465 real
= gen_realpart (submode
, op0
);
2466 imag
= gen_imagpart (submode
, op0
);
2468 /* Square both parts. */
2469 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2470 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2472 /* Sum the parts. */
2473 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2474 0, OPTAB_LIB_WIDEN
);
2476 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2477 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2479 delete_insns_since (last
);
2484 /* Now try a library call in this mode. */
2485 if (abs_optab
->handlers
[(int) mode
].libfunc
)
2492 /* Pass 1 for NO_QUEUE so we don't lose any increments
2493 if the libcall is cse'd or moved. */
2494 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2495 NULL_RTX
, 1, submode
, 1, op0
, mode
);
2496 insns
= get_insns ();
2499 target
= gen_reg_rtx (submode
);
2500 emit_libcall_block (insns
, target
, value
,
2501 gen_rtx_fmt_e (abs_optab
->code
, mode
, op0
));
2506 /* It can't be done in this mode. Can we do it in a wider mode? */
2508 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2509 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2511 if ((abs_optab
->handlers
[(int) wider_mode
].insn_code
2512 != CODE_FOR_nothing
)
2513 || abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2517 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2519 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2523 if (class != MODE_COMPLEX_INT
)
2526 target
= gen_reg_rtx (submode
);
2527 convert_move (target
, temp
, 0);
2531 return gen_lowpart (submode
, temp
);
2534 delete_insns_since (last
);
2538 delete_insns_since (entry_last
);
2542 /* Generate an instruction whose insn-code is INSN_CODE,
2543 with two operands: an output TARGET and an input OP0.
2544 TARGET *must* be nonzero, and the output is always stored there.
2545 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2546 the value that is stored into TARGET. */
2549 emit_unop_insn (icode
, target
, op0
, code
)
2556 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2559 temp
= target
= protect_from_queue (target
, 1);
2561 op0
= protect_from_queue (op0
, 0);
2563 /* Sign and zero extension from memory is often done specially on
2564 RISC machines, so forcing into a register here can pessimize
2566 if (flag_force_mem
&& code
!= SIGN_EXTEND
&& code
!= ZERO_EXTEND
)
2567 op0
= force_not_mem (op0
);
2569 /* Now, if insn does not accept our operands, put them into pseudos. */
2571 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2572 op0
= copy_to_mode_reg (mode0
, op0
);
2574 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, GET_MODE (temp
))
2575 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2576 temp
= gen_reg_rtx (GET_MODE (temp
));
2578 pat
= GEN_FCN (icode
) (temp
, op0
);
2580 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2581 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2586 emit_move_insn (target
, temp
);
2589 /* Emit code to perform a series of operations on a multi-word quantity, one
2592 Such a block is preceded by a CLOBBER of the output, consists of multiple
2593 insns, each setting one word of the output, and followed by a SET copying
2594 the output to itself.
2596 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2597 note indicating that it doesn't conflict with the (also multi-word)
2598 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2601 INSNS is a block of code generated to perform the operation, not including
2602 the CLOBBER and final copy. All insns that compute intermediate values
2603 are first emitted, followed by the block as described above.
2605 TARGET, OP0, and OP1 are the output and inputs of the operations,
2606 respectively. OP1 may be zero for a unary operation.
2608 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2611 If TARGET is not a register, INSNS is simply emitted with no special
2612 processing. Likewise if anything in INSNS is not an INSN or if
2613 there is a libcall block inside INSNS.
2615 The final insn emitted is returned. */
2618 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2624 rtx prev
, next
, first
, last
, insn
;
2626 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2627 return emit_insns (insns
);
2629 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2630 if (GET_CODE (insn
) != INSN
2631 || find_reg_note (insn
, REG_LIBCALL
, NULL_RTX
))
2632 return emit_insns (insns
);
2634 /* First emit all insns that do not store into words of the output and remove
2635 these from the list. */
2636 for (insn
= insns
; insn
; insn
= next
)
2641 next
= NEXT_INSN (insn
);
2643 if (GET_CODE (PATTERN (insn
)) == SET
|| GET_CODE (PATTERN (insn
)) == USE
2644 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
2645 set
= PATTERN (insn
);
2646 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2648 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2649 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2651 set
= XVECEXP (PATTERN (insn
), 0, i
);
2659 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2661 if (PREV_INSN (insn
))
2662 NEXT_INSN (PREV_INSN (insn
)) = next
;
2667 PREV_INSN (next
) = PREV_INSN (insn
);
2673 prev
= get_last_insn ();
2675 /* Now write the CLOBBER of the output, followed by the setting of each
2676 of the words, followed by the final copy. */
2677 if (target
!= op0
&& target
!= op1
)
2678 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
2680 for (insn
= insns
; insn
; insn
= next
)
2682 next
= NEXT_INSN (insn
);
2685 if (op1
&& GET_CODE (op1
) == REG
)
2686 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op1
,
2689 if (op0
&& GET_CODE (op0
) == REG
)
2690 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op0
,
2694 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2695 != CODE_FOR_nothing
)
2697 last
= emit_move_insn (target
, target
);
2699 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
2703 last
= get_last_insn ();
2705 /* Remove any existing REG_EQUAL note from "last", or else it will
2706 be mistaken for a note referring to the full contents of the
2707 alleged libcall value when found together with the REG_RETVAL
2708 note added below. An existing note can come from an insn
2709 expansion at "last". */
2710 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
2714 first
= get_insns ();
2716 first
= NEXT_INSN (prev
);
2718 /* Encapsulate the block so it gets manipulated as a unit. */
2719 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2721 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2726 /* Emit code to make a call to a constant function or a library call.
2728 INSNS is a list containing all insns emitted in the call.
2729 These insns leave the result in RESULT. Our block is to copy RESULT
2730 to TARGET, which is logically equivalent to EQUIV.
2732 We first emit any insns that set a pseudo on the assumption that these are
2733 loading constants into registers; doing so allows them to be safely cse'ed
2734 between blocks. Then we emit all the other insns in the block, followed by
2735 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2736 note with an operand of EQUIV.
2738 Moving assignments to pseudos outside of the block is done to improve
2739 the generated code, but is not required to generate correct code,
2740 hence being unable to move an assignment is not grounds for not making
2741 a libcall block. There are two reasons why it is safe to leave these
2742 insns inside the block: First, we know that these pseudos cannot be
2743 used in generated RTL outside the block since they are created for
2744 temporary purposes within the block. Second, CSE will not record the
2745 values of anything set inside a libcall block, so we know they must
2746 be dead at the end of the block.
2748 Except for the first group of insns (the ones setting pseudos), the
2749 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2752 emit_libcall_block (insns
, target
, result
, equiv
)
2758 rtx prev
, next
, first
, last
, insn
;
2760 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2761 reg note to indicate that this call cannot throw or execute a nonlocal
2762 goto. (Unless there is already a REG_EH_REGION note, in which case
2765 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2766 if (GET_CODE (insn
) == CALL_INSN
)
2768 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
2771 XEXP (note
, 0) = GEN_INT (-1);
2773 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_EH_REGION
, GEN_INT (-1),
2777 /* First emit all insns that set pseudos. Remove them from the list as
2778 we go. Avoid insns that set pseudos which were referenced in previous
2779 insns. These can be generated by move_by_pieces, for example,
2780 to update an address. Similarly, avoid insns that reference things
2781 set in previous insns. */
2783 for (insn
= insns
; insn
; insn
= next
)
2785 rtx set
= single_set (insn
);
2787 next
= NEXT_INSN (insn
);
2789 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2790 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2792 || ((! INSN_P(insns
)
2793 || ! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
)))
2794 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2795 && ! modified_in_p (SET_SRC (set
), insns
)
2796 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2798 if (PREV_INSN (insn
))
2799 NEXT_INSN (PREV_INSN (insn
)) = next
;
2804 PREV_INSN (next
) = PREV_INSN (insn
);
2810 prev
= get_last_insn ();
2812 /* Write the remaining insns followed by the final copy. */
2814 for (insn
= insns
; insn
; insn
= next
)
2816 next
= NEXT_INSN (insn
);
2821 last
= emit_move_insn (target
, result
);
2822 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2823 != CODE_FOR_nothing
)
2824 set_unique_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
));
2827 /* Remove any existing REG_EQUAL note from "last", or else it will
2828 be mistaken for a note referring to the full contents of the
2829 libcall value when found together with the REG_RETVAL note added
2830 below. An existing note can come from an insn expansion at
2832 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
2836 first
= get_insns ();
2838 first
= NEXT_INSN (prev
);
2840 /* Encapsulate the block so it gets manipulated as a unit. */
2841 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2843 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2846 /* Generate code to store zero in X. */
2852 emit_move_insn (x
, const0_rtx
);
2855 /* Generate code to store 1 in X
2856 assuming it contains zero beforehand. */
2859 emit_0_to_1_insn (x
)
2862 emit_move_insn (x
, const1_rtx
);
2865 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2866 PURPOSE describes how this comparison will be used. CODE is the rtx
2867 comparison code we will be using.
2869 ??? Actually, CODE is slightly weaker than that. A target is still
2870 required to implement all of the normal bcc operations, but not
2871 required to implement all (or any) of the unordered bcc operations. */
2874 can_compare_p (code
, mode
, purpose
)
2876 enum machine_mode mode
;
2877 enum can_compare_purpose purpose
;
2881 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2883 if (purpose
== ccp_jump
)
2884 return bcc_gen_fctn
[(int)code
] != NULL
;
2885 else if (purpose
== ccp_store_flag
)
2886 return setcc_gen_code
[(int)code
] != CODE_FOR_nothing
;
2888 /* There's only one cmov entry point, and it's allowed to fail. */
2891 if (purpose
== ccp_jump
2892 && cbranch_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2894 if (purpose
== ccp_cmov
2895 && cmov_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2897 if (purpose
== ccp_store_flag
2898 && cstore_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2901 mode
= GET_MODE_WIDER_MODE (mode
);
2903 while (mode
!= VOIDmode
);
2908 /* This function is called when we are going to emit a compare instruction that
2909 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2911 *PMODE is the mode of the inputs (in case they are const_int).
2912 *PUNSIGNEDP nonzero says that the operands are unsigned;
2913 this matters if they need to be widened.
2915 If they have mode BLKmode, then SIZE specifies the size of both operands,
2916 and ALIGN specifies the known shared alignment of the operands.
2918 This function performs all the setup necessary so that the caller only has
2919 to emit a single comparison insn. This setup can involve doing a BLKmode
2920 comparison or emitting a library call to perform the comparison if no insn
2921 is available to handle it.
2922 The values which are passed in through pointers can be modified; the caller
2923 should perform the comparison on the modified values. */
2926 prepare_cmp_insn (px
, py
, pcomparison
, size
, pmode
, punsignedp
, align
,
2929 enum rtx_code
*pcomparison
;
2931 enum machine_mode
*pmode
;
2933 int align ATTRIBUTE_UNUSED
;
2934 enum can_compare_purpose purpose
;
2936 enum machine_mode mode
= *pmode
;
2937 rtx x
= *px
, y
= *py
;
2938 int unsignedp
= *punsignedp
;
2939 enum mode_class
class;
2940 rtx opalign ATTRIBUTE_UNUSED
= GEN_INT (align
/ BITS_PER_UNIT
);;
2942 class = GET_MODE_CLASS (mode
);
2944 /* They could both be VOIDmode if both args are immediate constants,
2945 but we should fold that at an earlier stage.
2946 With no special code here, this will call abort,
2947 reminding the programmer to implement such folding. */
2949 if (mode
!= BLKmode
&& flag_force_mem
)
2951 x
= force_not_mem (x
);
2952 y
= force_not_mem (y
);
2955 /* If we are inside an appropriately-short loop and one operand is an
2956 expensive constant, force it into a register. */
2957 if (CONSTANT_P (x
) && preserve_subexpressions_p ()
2958 && rtx_cost (x
, COMPARE
) > 2)
2959 x
= force_reg (mode
, x
);
2961 if (CONSTANT_P (y
) && preserve_subexpressions_p ()
2962 && rtx_cost (y
, COMPARE
) > 2)
2963 y
= force_reg (mode
, y
);
2966 /* Abort if we have a non-canonical comparison. The RTL documentation
2967 states that canonical comparisons are required only for targets which
2969 if (CONSTANT_P (x
) && ! CONSTANT_P (y
))
2973 /* Don't let both operands fail to indicate the mode. */
2974 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
2975 x
= force_reg (mode
, x
);
2977 /* Handle all BLKmode compares. */
2979 if (mode
== BLKmode
)
2982 enum machine_mode result_mode
;
2985 x
= protect_from_queue (x
, 0);
2986 y
= protect_from_queue (y
, 0);
2990 #ifdef HAVE_cmpstrqi
2992 && GET_CODE (size
) == CONST_INT
2993 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
2995 result_mode
= insn_data
[(int) CODE_FOR_cmpstrqi
].operand
[0].mode
;
2996 result
= gen_reg_rtx (result_mode
);
2997 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, opalign
));
3001 #ifdef HAVE_cmpstrhi
3003 && GET_CODE (size
) == CONST_INT
3004 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
3006 result_mode
= insn_data
[(int) CODE_FOR_cmpstrhi
].operand
[0].mode
;
3007 result
= gen_reg_rtx (result_mode
);
3008 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, opalign
));
3012 #ifdef HAVE_cmpstrsi
3015 result_mode
= insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3016 result
= gen_reg_rtx (result_mode
);
3017 size
= protect_from_queue (size
, 0);
3018 emit_insn (gen_cmpstrsi (result
, x
, y
,
3019 convert_to_mode (SImode
, size
, 1),
3025 #ifdef TARGET_MEM_FUNCTIONS
3026 emit_library_call (memcmp_libfunc
, 2,
3027 TYPE_MODE (integer_type_node
), 3,
3028 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
3029 convert_to_mode (TYPE_MODE (sizetype
), size
,
3030 TREE_UNSIGNED (sizetype
)),
3031 TYPE_MODE (sizetype
));
3033 emit_library_call (bcmp_libfunc
, 2,
3034 TYPE_MODE (integer_type_node
), 3,
3035 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
3036 convert_to_mode (TYPE_MODE (integer_type_node
),
3038 TREE_UNSIGNED (integer_type_node
)),
3039 TYPE_MODE (integer_type_node
));
3042 /* Immediately move the result of the libcall into a pseudo
3043 register so reload doesn't clobber the value if it needs
3044 the return register for a spill reg. */
3045 result
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
3046 result_mode
= TYPE_MODE (integer_type_node
);
3047 emit_move_insn (result
,
3048 hard_libcall_value (result_mode
));
3052 *pmode
= result_mode
;
3058 if (can_compare_p (*pcomparison
, mode
, purpose
))
3061 /* Handle a lib call just for the mode we are using. */
3063 if (cmp_optab
->handlers
[(int) mode
].libfunc
&& class != MODE_FLOAT
)
3065 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
3068 /* If we want unsigned, and this mode has a distinct unsigned
3069 comparison routine, use that. */
3070 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
3071 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
3073 emit_library_call (libfunc
, 1,
3074 word_mode
, 2, x
, mode
, y
, mode
);
3076 /* Immediately move the result of the libcall into a pseudo
3077 register so reload doesn't clobber the value if it needs
3078 the return register for a spill reg. */
3079 result
= gen_reg_rtx (word_mode
);
3080 emit_move_insn (result
, hard_libcall_value (word_mode
));
3082 /* Integer comparison returns a result that must be compared against 1,
3083 so that even if we do an unsigned compare afterward,
3084 there is still a value that can represent the result "less than". */
3091 if (class == MODE_FLOAT
)
3092 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
);
3098 /* Before emitting an insn with code ICODE, make sure that X, which is going
3099 to be used for operand OPNUM of the insn, is converted from mode MODE to
3100 WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3101 that it is accepted by the operand predicate. Return the new value. */
3104 prepare_operand (icode
, x
, opnum
, mode
, wider_mode
, unsignedp
)
3108 enum machine_mode mode
, wider_mode
;
3111 x
= protect_from_queue (x
, 0);
3113 if (mode
!= wider_mode
)
3114 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
3116 if (! (*insn_data
[icode
].operand
[opnum
].predicate
)
3117 (x
, insn_data
[icode
].operand
[opnum
].mode
))
3118 x
= copy_to_mode_reg (insn_data
[icode
].operand
[opnum
].mode
, x
);
3122 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3123 we can do the comparison.
3124 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3125 be NULL_RTX which indicates that only a comparison is to be generated. */
3128 emit_cmp_and_jump_insn_1 (x
, y
, mode
, comparison
, unsignedp
, label
)
3130 enum machine_mode mode
;
3131 enum rtx_code comparison
;
3135 rtx test
= gen_rtx_fmt_ee (comparison
, mode
, x
, y
);
3136 enum mode_class
class = GET_MODE_CLASS (mode
);
3137 enum machine_mode wider_mode
= mode
;
3139 /* Try combined insns first. */
3142 enum insn_code icode
;
3143 PUT_MODE (test
, wider_mode
);
3147 icode
= cbranch_optab
->handlers
[(int)wider_mode
].insn_code
;
3149 if (icode
!= CODE_FOR_nothing
3150 && (*insn_data
[icode
].operand
[0].predicate
) (test
, wider_mode
))
3152 x
= prepare_operand (icode
, x
, 1, mode
, wider_mode
, unsignedp
);
3153 y
= prepare_operand (icode
, y
, 2, mode
, wider_mode
, unsignedp
);
3154 emit_jump_insn (GEN_FCN (icode
) (test
, x
, y
, label
));
3159 /* Handle some compares against zero. */
3160 icode
= (int) tst_optab
->handlers
[(int) wider_mode
].insn_code
;
3161 if (y
== CONST0_RTX (mode
) && icode
!= CODE_FOR_nothing
)
3163 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
3164 emit_insn (GEN_FCN (icode
) (x
));
3166 emit_jump_insn ((*bcc_gen_fctn
[(int) comparison
]) (label
));
3170 /* Handle compares for which there is a directly suitable insn. */
3172 icode
= (int) cmp_optab
->handlers
[(int) wider_mode
].insn_code
;
3173 if (icode
!= CODE_FOR_nothing
)
3175 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
3176 y
= prepare_operand (icode
, y
, 1, mode
, wider_mode
, unsignedp
);
3177 emit_insn (GEN_FCN (icode
) (x
, y
));
3179 emit_jump_insn ((*bcc_gen_fctn
[(int) comparison
]) (label
));
3183 if (class != MODE_INT
&& class != MODE_FLOAT
3184 && class != MODE_COMPLEX_FLOAT
)
3187 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
);
3188 } while (wider_mode
!= VOIDmode
);
3193 /* Generate code to compare X with Y so that the condition codes are
3194 set and to jump to LABEL if the condition is true. If X is a
3195 constant and Y is not a constant, then the comparison is swapped to
3196 ensure that the comparison RTL has the canonical form.
3198 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3199 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3200 the proper branch condition code.
3202 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3203 and ALIGN specifies the known shared alignment of X and Y.
3205 MODE is the mode of the inputs (in case they are const_int).
3207 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3208 be passed unchanged to emit_cmp_insn, then potentially converted into an
3209 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3212 emit_cmp_and_jump_insns (x
, y
, comparison
, size
, mode
, unsignedp
, align
, label
)
3214 enum rtx_code comparison
;
3216 enum machine_mode mode
;
3224 if ((CONSTANT_P (x
) && ! CONSTANT_P (y
))
3225 || (GET_CODE (x
) == CONST_INT
&& GET_CODE (y
) != CONST_INT
))
3227 /* Swap operands and condition to ensure canonical RTL. */
3230 comparison
= swap_condition (comparison
);
3239 /* If OP0 is still a constant, then both X and Y must be constants. Force
3240 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3242 if (CONSTANT_P (op0
))
3243 op0
= force_reg (mode
, op0
);
3248 comparison
= unsigned_condition (comparison
);
3249 prepare_cmp_insn (&op0
, &op1
, &comparison
, size
, &mode
, &unsignedp
, align
,
3251 emit_cmp_and_jump_insn_1 (op0
, op1
, mode
, comparison
, unsignedp
, label
);
3254 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3257 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
3259 enum rtx_code comparison
;
3261 enum machine_mode mode
;
3265 emit_cmp_and_jump_insns (x
, y
, comparison
, size
, mode
, unsignedp
, align
, 0);
3268 /* Emit a library call comparison between floating point X and Y.
3269 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3272 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
)
3274 enum rtx_code
*pcomparison
;
3275 enum machine_mode
*pmode
;
3278 enum rtx_code comparison
= *pcomparison
;
3279 rtx x
= *px
= protect_from_queue (*px
, 0);
3280 rtx y
= *py
= protect_from_queue (*py
, 0);
3281 enum machine_mode mode
= GET_MODE (x
);
3289 libfunc
= eqhf2_libfunc
;
3293 libfunc
= nehf2_libfunc
;
3297 libfunc
= gthf2_libfunc
;
3301 libfunc
= gehf2_libfunc
;
3305 libfunc
= lthf2_libfunc
;
3309 libfunc
= lehf2_libfunc
;
3313 libfunc
= unordhf2_libfunc
;
3319 else if (mode
== SFmode
)
3323 libfunc
= eqsf2_libfunc
;
3327 libfunc
= nesf2_libfunc
;
3331 libfunc
= gtsf2_libfunc
;
3335 libfunc
= gesf2_libfunc
;
3339 libfunc
= ltsf2_libfunc
;
3343 libfunc
= lesf2_libfunc
;
3347 libfunc
= unordsf2_libfunc
;
3353 else if (mode
== DFmode
)
3357 libfunc
= eqdf2_libfunc
;
3361 libfunc
= nedf2_libfunc
;
3365 libfunc
= gtdf2_libfunc
;
3369 libfunc
= gedf2_libfunc
;
3373 libfunc
= ltdf2_libfunc
;
3377 libfunc
= ledf2_libfunc
;
3381 libfunc
= unorddf2_libfunc
;
3387 else if (mode
== XFmode
)
3391 libfunc
= eqxf2_libfunc
;
3395 libfunc
= nexf2_libfunc
;
3399 libfunc
= gtxf2_libfunc
;
3403 libfunc
= gexf2_libfunc
;
3407 libfunc
= ltxf2_libfunc
;
3411 libfunc
= lexf2_libfunc
;
3415 libfunc
= unordxf2_libfunc
;
3421 else if (mode
== TFmode
)
3425 libfunc
= eqtf2_libfunc
;
3429 libfunc
= netf2_libfunc
;
3433 libfunc
= gttf2_libfunc
;
3437 libfunc
= getf2_libfunc
;
3441 libfunc
= lttf2_libfunc
;
3445 libfunc
= letf2_libfunc
;
3449 libfunc
= unordtf2_libfunc
;
3457 enum machine_mode wider_mode
;
3459 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
3460 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3462 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
3463 != CODE_FOR_nothing
)
3464 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
3466 x
= protect_from_queue (x
, 0);
3467 y
= protect_from_queue (y
, 0);
3468 *px
= convert_to_mode (wider_mode
, x
, 0);
3469 *py
= convert_to_mode (wider_mode
, y
, 0);
3470 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
);
3480 emit_library_call (libfunc
, 1, word_mode
, 2, x
, mode
, y
, mode
);
3482 /* Immediately move the result of the libcall into a pseudo
3483 register so reload doesn't clobber the value if it needs
3484 the return register for a spill reg. */
3485 result
= gen_reg_rtx (word_mode
);
3486 emit_move_insn (result
, hard_libcall_value (word_mode
));
3490 if (comparison
== UNORDERED
)
3492 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3493 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
3499 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3502 emit_indirect_jump (loc
)
3505 if (! ((*insn_data
[(int)CODE_FOR_indirect_jump
].operand
[0].predicate
)
3507 loc
= copy_to_mode_reg (Pmode
, loc
);
3509 emit_jump_insn (gen_indirect_jump (loc
));
3513 #ifdef HAVE_conditional_move
3515 /* Emit a conditional move instruction if the machine supports one for that
3516 condition and machine mode.
3518 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3519 the mode to use should they be constants. If it is VOIDmode, they cannot
3522 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3523 should be stored there. MODE is the mode to use should they be constants.
3524 If it is VOIDmode, they cannot both be constants.
3526 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3527 is not supported. */
3530 emit_conditional_move (target
, code
, op0
, op1
, cmode
, op2
, op3
, mode
,
3535 enum machine_mode cmode
;
3537 enum machine_mode mode
;
3540 rtx tem
, subtarget
, comparison
, insn
;
3541 enum insn_code icode
;
3543 /* If one operand is constant, make it the second one. Only do this
3544 if the other operand is not constant as well. */
3546 if ((CONSTANT_P (op0
) && ! CONSTANT_P (op1
))
3547 || (GET_CODE (op0
) == CONST_INT
&& GET_CODE (op1
) != CONST_INT
))
3552 code
= swap_condition (code
);
3555 /* get_condition will prefer to generate LT and GT even if the old
3556 comparison was against zero, so undo that canonicalization here since
3557 comparisons against zero are cheaper. */
3558 if (code
== LT
&& GET_CODE (op1
) == CONST_INT
&& INTVAL (op1
) == 1)
3559 code
= LE
, op1
= const0_rtx
;
3560 else if (code
== GT
&& GET_CODE (op1
) == CONST_INT
&& INTVAL (op1
) == -1)
3561 code
= GE
, op1
= const0_rtx
;
3563 if (cmode
== VOIDmode
)
3564 cmode
= GET_MODE (op0
);
3566 if (((CONSTANT_P (op2
) && ! CONSTANT_P (op3
))
3567 || (GET_CODE (op2
) == CONST_INT
&& GET_CODE (op3
) != CONST_INT
))
3568 && (GET_MODE_CLASS (GET_MODE (op1
)) != MODE_FLOAT
3569 || TARGET_FLOAT_FORMAT
!= IEEE_FLOAT_FORMAT
|| flag_fast_math
))
3574 code
= reverse_condition (code
);
3577 if (mode
== VOIDmode
)
3578 mode
= GET_MODE (op2
);
3580 icode
= movcc_gen_code
[mode
];
3582 if (icode
== CODE_FOR_nothing
)
3587 op2
= force_not_mem (op2
);
3588 op3
= force_not_mem (op3
);
3592 target
= protect_from_queue (target
, 1);
3594 target
= gen_reg_rtx (mode
);
3600 op2
= protect_from_queue (op2
, 0);
3601 op3
= protect_from_queue (op3
, 0);
3603 /* If the insn doesn't accept these operands, put them in pseudos. */
3605 if (! (*insn_data
[icode
].operand
[0].predicate
)
3606 (subtarget
, insn_data
[icode
].operand
[0].mode
))
3607 subtarget
= gen_reg_rtx (insn_data
[icode
].operand
[0].mode
);
3609 if (! (*insn_data
[icode
].operand
[2].predicate
)
3610 (op2
, insn_data
[icode
].operand
[2].mode
))
3611 op2
= copy_to_mode_reg (insn_data
[icode
].operand
[2].mode
, op2
);
3613 if (! (*insn_data
[icode
].operand
[3].predicate
)
3614 (op3
, insn_data
[icode
].operand
[3].mode
))
3615 op3
= copy_to_mode_reg (insn_data
[icode
].operand
[3].mode
, op3
);
3617 /* Everything should now be in the suitable form, so emit the compare insn
3618 and then the conditional move. */
3621 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
, 0);
3623 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3624 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3625 return NULL and let the caller figure out how best to deal with this
3627 if (GET_CODE (comparison
) != code
)
3630 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
3632 /* If that failed, then give up. */
3638 if (subtarget
!= target
)
3639 convert_move (target
, subtarget
, 0);
3644 /* Return non-zero if a conditional move of mode MODE is supported.
3646 This function is for combine so it can tell whether an insn that looks
3647 like a conditional move is actually supported by the hardware. If we
3648 guess wrong we lose a bit on optimization, but that's it. */
3649 /* ??? sparc64 supports conditionally moving integers values based on fp
3650 comparisons, and vice versa. How do we handle them? */
3653 can_conditionally_move_p (mode
)
3654 enum machine_mode mode
;
3656 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
3662 #endif /* HAVE_conditional_move */
3664 /* These three functions generate an insn body and return it
3665 rather than emitting the insn.
3667 They do not protect from queued increments,
3668 because they may be used 1) in protect_from_queue itself
3669 and 2) in other passes where there is no queue. */
3671 /* Generate and return an insn body to add Y to X. */
3674 gen_add2_insn (x
, y
)
3677 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3679 if (! ((*insn_data
[icode
].operand
[0].predicate
)
3680 (x
, insn_data
[icode
].operand
[0].mode
))
3681 || ! ((*insn_data
[icode
].operand
[1].predicate
)
3682 (x
, insn_data
[icode
].operand
[1].mode
))
3683 || ! ((*insn_data
[icode
].operand
[2].predicate
)
3684 (y
, insn_data
[icode
].operand
[2].mode
)))
3687 return (GEN_FCN (icode
) (x
, x
, y
));
3691 have_add2_insn (mode
)
3692 enum machine_mode mode
;
3694 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3697 /* Generate and return an insn body to subtract Y from X. */
3700 gen_sub2_insn (x
, y
)
3703 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3705 if (! ((*insn_data
[icode
].operand
[0].predicate
)
3706 (x
, insn_data
[icode
].operand
[0].mode
))
3707 || ! ((*insn_data
[icode
].operand
[1].predicate
)
3708 (x
, insn_data
[icode
].operand
[1].mode
))
3709 || ! ((*insn_data
[icode
].operand
[2].predicate
)
3710 (y
, insn_data
[icode
].operand
[2].mode
)))
3713 return (GEN_FCN (icode
) (x
, x
, y
));
3717 have_sub2_insn (mode
)
3718 enum machine_mode mode
;
3720 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3723 /* Generate the body of an instruction to copy Y into X.
3724 It may be a SEQUENCE, if one insn isn't enough. */
3727 gen_move_insn (x
, y
)
3730 register enum machine_mode mode
= GET_MODE (x
);
3731 enum insn_code insn_code
;
3734 if (mode
== VOIDmode
)
3735 mode
= GET_MODE (y
);
3737 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
3739 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3740 find a mode to do it in. If we have a movcc, use it. Otherwise,
3741 find the MODE_INT mode of the same width. */
3743 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
3745 enum machine_mode tmode
= VOIDmode
;
3749 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
3752 for (tmode
= QImode
; tmode
!= VOIDmode
;
3753 tmode
= GET_MODE_WIDER_MODE (tmode
))
3754 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
3757 if (tmode
== VOIDmode
)
3760 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3761 may call change_address which is not appropriate if we were
3762 called when a reload was in progress. We don't have to worry
3763 about changing the address since the size in bytes is supposed to
3764 be the same. Copy the MEM to change the mode and move any
3765 substitutions from the old MEM to the new one. */
3767 if (reload_in_progress
)
3769 x
= gen_lowpart_common (tmode
, x1
);
3770 if (x
== 0 && GET_CODE (x1
) == MEM
)
3772 x
= gen_rtx_MEM (tmode
, XEXP (x1
, 0));
3773 MEM_COPY_ATTRIBUTES (x
, x1
);
3774 copy_replacements (x1
, x
);
3777 y
= gen_lowpart_common (tmode
, y1
);
3778 if (y
== 0 && GET_CODE (y1
) == MEM
)
3780 y
= gen_rtx_MEM (tmode
, XEXP (y1
, 0));
3781 MEM_COPY_ATTRIBUTES (y
, y1
);
3782 copy_replacements (y1
, y
);
3787 x
= gen_lowpart (tmode
, x
);
3788 y
= gen_lowpart (tmode
, y
);
3791 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3792 return (GEN_FCN (insn_code
) (x
, y
));
3796 emit_move_insn_1 (x
, y
);
3797 seq
= gen_sequence ();
3802 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3803 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3804 no such operation exists, CODE_FOR_nothing will be returned. */
3807 can_extend_p (to_mode
, from_mode
, unsignedp
)
3808 enum machine_mode to_mode
, from_mode
;
3811 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
!= 0];
3814 /* Generate the body of an insn to extend Y (with mode MFROM)
3815 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3818 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3820 enum machine_mode mto
, mfrom
;
3823 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
!= 0]) (x
, y
));
3826 /* can_fix_p and can_float_p say whether the target machine
3827 can directly convert a given fixed point type to
3828 a given floating point type, or vice versa.
3829 The returned value is the CODE_FOR_... value to use,
3830 or CODE_FOR_nothing if these modes cannot be directly converted.
3832 *TRUNCP_PTR is set to 1 if it is necessary to output
3833 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3835 static enum insn_code
3836 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3837 enum machine_mode fltmode
, fixmode
;
3842 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0]
3843 != CODE_FOR_nothing
)
3844 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3846 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3849 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3851 return CODE_FOR_nothing
;
3854 static enum insn_code
3855 can_float_p (fltmode
, fixmode
, unsignedp
)
3856 enum machine_mode fixmode
, fltmode
;
3859 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3862 /* Generate code to convert FROM to floating point
3863 and store in TO. FROM must be fixed point and not VOIDmode.
3864 UNSIGNEDP nonzero means regard FROM as unsigned.
3865 Normally this is done by correcting the final value
3866 if it is negative. */
3869 expand_float (to
, from
, unsignedp
)
3873 enum insn_code icode
;
3874 register rtx target
= to
;
3875 enum machine_mode fmode
, imode
;
3877 /* Crash now, because we won't be able to decide which mode to use. */
3878 if (GET_MODE (from
) == VOIDmode
)
3881 /* Look for an insn to do the conversion. Do it in the specified
3882 modes if possible; otherwise convert either input, output or both to
3883 wider mode. If the integer mode is wider than the mode of FROM,
3884 we can do the conversion signed even if the input is unsigned. */
3886 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3887 imode
= GET_MODE_WIDER_MODE (imode
))
3888 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3889 fmode
= GET_MODE_WIDER_MODE (fmode
))
3891 int doing_unsigned
= unsignedp
;
3893 if (fmode
!= GET_MODE (to
)
3894 && significand_size (fmode
) < GET_MODE_BITSIZE (GET_MODE (from
)))
3897 icode
= can_float_p (fmode
, imode
, unsignedp
);
3898 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3899 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3901 if (icode
!= CODE_FOR_nothing
)
3903 to
= protect_from_queue (to
, 1);
3904 from
= protect_from_queue (from
, 0);
3906 if (imode
!= GET_MODE (from
))
3907 from
= convert_to_mode (imode
, from
, unsignedp
);
3909 if (fmode
!= GET_MODE (to
))
3910 target
= gen_reg_rtx (fmode
);
3912 emit_unop_insn (icode
, target
, from
,
3913 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3916 convert_move (to
, target
, 0);
3921 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3923 /* Unsigned integer, and no way to convert directly.
3924 Convert as signed, then conditionally adjust the result. */
3927 rtx label
= gen_label_rtx ();
3929 REAL_VALUE_TYPE offset
;
3933 to
= protect_from_queue (to
, 1);
3934 from
= protect_from_queue (from
, 0);
3937 from
= force_not_mem (from
);
3939 /* Look for a usable floating mode FMODE wider than the source and at
3940 least as wide as the target. Using FMODE will avoid rounding woes
3941 with unsigned values greater than the signed maximum value. */
3943 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3944 fmode
= GET_MODE_WIDER_MODE (fmode
))
3945 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
3946 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
3949 if (fmode
== VOIDmode
)
3951 /* There is no such mode. Pretend the target is wide enough. */
3952 fmode
= GET_MODE (to
);
3954 /* Avoid double-rounding when TO is narrower than FROM. */
3955 if ((significand_size (fmode
) + 1)
3956 < GET_MODE_BITSIZE (GET_MODE (from
)))
3959 rtx neglabel
= gen_label_rtx ();
3961 /* Don't use TARGET if it isn't a register, is a hard register,
3962 or is the wrong mode. */
3963 if (GET_CODE (target
) != REG
3964 || REGNO (target
) < FIRST_PSEUDO_REGISTER
3965 || GET_MODE (target
) != fmode
)
3966 target
= gen_reg_rtx (fmode
);
3968 imode
= GET_MODE (from
);
3969 do_pending_stack_adjust ();
3971 /* Test whether the sign bit is set. */
3972 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
3975 /* The sign bit is not set. Convert as signed. */
3976 expand_float (target
, from
, 0);
3977 emit_jump_insn (gen_jump (label
));
3980 /* The sign bit is set.
3981 Convert to a usable (positive signed) value by shifting right
3982 one bit, while remembering if a nonzero bit was shifted
3983 out; i.e., compute (from & 1) | (from >> 1). */
3985 emit_label (neglabel
);
3986 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
3987 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
3988 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
3990 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
3992 expand_float (target
, temp
, 0);
3994 /* Multiply by 2 to undo the shift above. */
3995 temp
= expand_binop (fmode
, add_optab
, target
, target
,
3996 target
, 0, OPTAB_LIB_WIDEN
);
3998 emit_move_insn (target
, temp
);
4000 do_pending_stack_adjust ();
4006 /* If we are about to do some arithmetic to correct for an
4007 unsigned operand, do it in a pseudo-register. */
4009 if (GET_MODE (to
) != fmode
4010 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
4011 target
= gen_reg_rtx (fmode
);
4013 /* Convert as signed integer to floating. */
4014 expand_float (target
, from
, 0);
4016 /* If FROM is negative (and therefore TO is negative),
4017 correct its value by 2**bitwidth. */
4019 do_pending_stack_adjust ();
4020 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
4023 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4024 Rather than setting up a dconst_dot_5, let's hope SCO
4026 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
4027 temp
= expand_binop (fmode
, add_optab
, target
,
4028 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
4029 target
, 0, OPTAB_LIB_WIDEN
);
4031 emit_move_insn (target
, temp
);
4033 do_pending_stack_adjust ();
4039 /* No hardware instruction available; call a library routine to convert from
4040 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4046 to
= protect_from_queue (to
, 1);
4047 from
= protect_from_queue (from
, 0);
4049 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
4050 from
= convert_to_mode (SImode
, from
, unsignedp
);
4053 from
= force_not_mem (from
);
4055 if (GET_MODE (to
) == SFmode
)
4057 if (GET_MODE (from
) == SImode
)
4058 libfcn
= floatsisf_libfunc
;
4059 else if (GET_MODE (from
) == DImode
)
4060 libfcn
= floatdisf_libfunc
;
4061 else if (GET_MODE (from
) == TImode
)
4062 libfcn
= floattisf_libfunc
;
4066 else if (GET_MODE (to
) == DFmode
)
4068 if (GET_MODE (from
) == SImode
)
4069 libfcn
= floatsidf_libfunc
;
4070 else if (GET_MODE (from
) == DImode
)
4071 libfcn
= floatdidf_libfunc
;
4072 else if (GET_MODE (from
) == TImode
)
4073 libfcn
= floattidf_libfunc
;
4077 else if (GET_MODE (to
) == XFmode
)
4079 if (GET_MODE (from
) == SImode
)
4080 libfcn
= floatsixf_libfunc
;
4081 else if (GET_MODE (from
) == DImode
)
4082 libfcn
= floatdixf_libfunc
;
4083 else if (GET_MODE (from
) == TImode
)
4084 libfcn
= floattixf_libfunc
;
4088 else if (GET_MODE (to
) == TFmode
)
4090 if (GET_MODE (from
) == SImode
)
4091 libfcn
= floatsitf_libfunc
;
4092 else if (GET_MODE (from
) == DImode
)
4093 libfcn
= floatditf_libfunc
;
4094 else if (GET_MODE (from
) == TImode
)
4095 libfcn
= floattitf_libfunc
;
4104 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1,
4106 1, from
, GET_MODE (from
));
4107 insns
= get_insns ();
4110 emit_libcall_block (insns
, target
, value
,
4111 gen_rtx_FLOAT (GET_MODE (to
), from
));
4116 /* Copy result to requested destination
4117 if we have been computing in a temp location. */
4121 if (GET_MODE (target
) == GET_MODE (to
))
4122 emit_move_insn (to
, target
);
4124 convert_move (to
, target
, 0);
4128 /* expand_fix: generate code to convert FROM to fixed point
4129 and store in TO. FROM must be floating point. */
4135 rtx temp
= gen_reg_rtx (GET_MODE (x
));
4136 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
4140 expand_fix (to
, from
, unsignedp
)
4141 register rtx to
, from
;
4144 enum insn_code icode
;
4145 register rtx target
= to
;
4146 enum machine_mode fmode
, imode
;
4150 /* We first try to find a pair of modes, one real and one integer, at
4151 least as wide as FROM and TO, respectively, in which we can open-code
4152 this conversion. If the integer mode is wider than the mode of TO,
4153 we can do the conversion either signed or unsigned. */
4155 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
4156 imode
= GET_MODE_WIDER_MODE (imode
))
4157 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4158 fmode
= GET_MODE_WIDER_MODE (fmode
))
4160 int doing_unsigned
= unsignedp
;
4162 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
4163 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
4164 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
4166 if (icode
!= CODE_FOR_nothing
)
4168 to
= protect_from_queue (to
, 1);
4169 from
= protect_from_queue (from
, 0);
4171 if (fmode
!= GET_MODE (from
))
4172 from
= convert_to_mode (fmode
, from
, 0);
4175 from
= ftruncify (from
);
4177 if (imode
!= GET_MODE (to
))
4178 target
= gen_reg_rtx (imode
);
4180 emit_unop_insn (icode
, target
, from
,
4181 doing_unsigned
? UNSIGNED_FIX
: FIX
);
4183 convert_move (to
, target
, unsignedp
);
4188 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4189 /* For an unsigned conversion, there is one more way to do it.
4190 If we have a signed conversion, we generate code that compares
4191 the real value to the largest representable positive number. If if
4192 is smaller, the conversion is done normally. Otherwise, subtract
4193 one plus the highest signed number, convert, and add it back.
4195 We only need to check all real modes, since we know we didn't find
4196 anything with a wider integer mode. */
4198 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
4199 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4200 fmode
= GET_MODE_WIDER_MODE (fmode
))
4201 /* Make sure we won't lose significant bits doing this. */
4202 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
4203 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
4207 REAL_VALUE_TYPE offset
;
4208 rtx limit
, lab1
, lab2
, insn
;
4210 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
4211 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
4212 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
4213 lab1
= gen_label_rtx ();
4214 lab2
= gen_label_rtx ();
4217 to
= protect_from_queue (to
, 1);
4218 from
= protect_from_queue (from
, 0);
4221 from
= force_not_mem (from
);
4223 if (fmode
!= GET_MODE (from
))
4224 from
= convert_to_mode (fmode
, from
, 0);
4226 /* See if we need to do the subtraction. */
4227 do_pending_stack_adjust ();
4228 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
4231 /* If not, do the signed "fix" and branch around fixup code. */
4232 expand_fix (to
, from
, 0);
4233 emit_jump_insn (gen_jump (lab2
));
4236 /* Otherwise, subtract 2**(N-1), convert to signed number,
4237 then add 2**(N-1). Do the addition using XOR since this
4238 will often generate better code. */
4240 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
4241 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4242 expand_fix (to
, target
, 0);
4243 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
4244 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
4245 to
, 1, OPTAB_LIB_WIDEN
);
4248 emit_move_insn (to
, target
);
4252 if (mov_optab
->handlers
[(int) GET_MODE (to
)].insn_code
4253 != CODE_FOR_nothing
)
4255 /* Make a place for a REG_NOTE and add it. */
4256 insn
= emit_move_insn (to
, to
);
4257 set_unique_reg_note (insn
,
4259 gen_rtx_fmt_e (UNSIGNED_FIX
,
4268 /* We can't do it with an insn, so use a library call. But first ensure
4269 that the mode of TO is at least as wide as SImode, since those are the
4270 only library calls we know about. */
4272 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
4274 target
= gen_reg_rtx (SImode
);
4276 expand_fix (target
, from
, unsignedp
);
4278 else if (GET_MODE (from
) == SFmode
)
4280 if (GET_MODE (to
) == SImode
)
4281 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
4282 else if (GET_MODE (to
) == DImode
)
4283 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
4284 else if (GET_MODE (to
) == TImode
)
4285 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
4289 else if (GET_MODE (from
) == DFmode
)
4291 if (GET_MODE (to
) == SImode
)
4292 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
4293 else if (GET_MODE (to
) == DImode
)
4294 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
4295 else if (GET_MODE (to
) == TImode
)
4296 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
4300 else if (GET_MODE (from
) == XFmode
)
4302 if (GET_MODE (to
) == SImode
)
4303 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
4304 else if (GET_MODE (to
) == DImode
)
4305 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
4306 else if (GET_MODE (to
) == TImode
)
4307 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
4311 else if (GET_MODE (from
) == TFmode
)
4313 if (GET_MODE (to
) == SImode
)
4314 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
4315 else if (GET_MODE (to
) == DImode
)
4316 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
4317 else if (GET_MODE (to
) == TImode
)
4318 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
4330 to
= protect_from_queue (to
, 1);
4331 from
= protect_from_queue (from
, 0);
4334 from
= force_not_mem (from
);
4338 value
= emit_library_call_value (libfcn
, NULL_RTX
, 1, GET_MODE (to
),
4340 1, from
, GET_MODE (from
));
4341 insns
= get_insns ();
4344 emit_libcall_block (insns
, target
, value
,
4345 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
4346 GET_MODE (to
), from
));
4351 if (GET_MODE (to
) == GET_MODE (target
))
4352 emit_move_insn (to
, target
);
4354 convert_move (to
, target
, 0);
4363 optab op
= (optab
) xmalloc (sizeof (struct optab
));
4365 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4367 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
4368 op
->handlers
[i
].libfunc
= 0;
4371 if (code
!= UNKNOWN
)
4372 code_to_optab
[(int) code
] = op
;
4377 /* Initialize the libfunc fields of an entire group of entries in some
4378 optab. Each entry is set equal to a string consisting of a leading
4379 pair of underscores followed by a generic operation name followed by
4380 a mode name (downshifted to lower case) followed by a single character
4381 representing the number of operands for the given operation (which is
4382 usually one of the characters '2', '3', or '4').
4384 OPTABLE is the table in which libfunc fields are to be initialized.
4385 FIRST_MODE is the first machine mode index in the given optab to
4387 LAST_MODE is the last machine mode index in the given optab to
4389 OPNAME is the generic (string) name of the operation.
4390 SUFFIX is the character which specifies the number of operands for
4391 the given generic operation.
4395 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
4396 register optab optable
;
4397 register int first_mode
;
4398 register int last_mode
;
4399 register const char *opname
;
4400 register int suffix
;
4403 register unsigned opname_len
= strlen (opname
);
4405 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
4406 mode
= (enum machine_mode
) ((int) mode
+ 1))
4408 register const char *mname
= GET_MODE_NAME(mode
);
4409 register unsigned mname_len
= strlen (mname
);
4410 register char *libfunc_name
4411 = ggc_alloc_string (NULL
, 2 + opname_len
+ mname_len
+ 1 + 1);
4413 register const char *q
;
4418 for (q
= opname
; *q
; )
4420 for (q
= mname
; *q
; q
++)
4421 *p
++ = TOLOWER (*q
);
4425 optable
->handlers
[(int) mode
].libfunc
4426 = gen_rtx_SYMBOL_REF (Pmode
, libfunc_name
);
4430 /* Initialize the libfunc fields of an entire group of entries in some
4431 optab which correspond to all integer mode operations. The parameters
4432 have the same meaning as similarly named ones for the `init_libfuncs'
4433 routine. (See above). */
4436 init_integral_libfuncs (optable
, opname
, suffix
)
4437 register optab optable
;
4438 register const char *opname
;
4439 register int suffix
;
4441 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
4444 /* Initialize the libfunc fields of an entire group of entries in some
4445 optab which correspond to all real mode operations. The parameters
4446 have the same meaning as similarly named ones for the `init_libfuncs'
4447 routine. (See above). */
4450 init_floating_libfuncs (optable
, opname
, suffix
)
4451 register optab optable
;
4452 register const char *opname
;
4453 register int suffix
;
4455 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
4459 init_one_libfunc (name
)
4460 register const char *name
;
4463 name
= ggc_alloc_string (name
, -1);
4465 return gen_rtx_SYMBOL_REF (Pmode
, name
);
4468 /* Mark ARG (which is really an OPTAB *) for GC. */
4474 optab o
= *(optab
*) arg
;
4477 for (i
= 0; i
< NUM_MACHINE_MODES
; ++i
)
4478 ggc_mark_rtx (o
->handlers
[i
].libfunc
);
4481 /* Call this once to initialize the contents of the optabs
4482 appropriately for the current target machine. */
4488 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4494 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4496 for (p
= fixtab
[0][0];
4497 p
< fixtab
[0][0] + sizeof fixtab
/ sizeof (fixtab
[0][0][0]);
4499 *p
= CODE_FOR_nothing
;
4501 for (p
= fixtrunctab
[0][0];
4502 p
< fixtrunctab
[0][0] + sizeof fixtrunctab
/ sizeof (fixtrunctab
[0][0][0]);
4504 *p
= CODE_FOR_nothing
;
4506 for (p
= floattab
[0][0];
4507 p
< floattab
[0][0] + sizeof floattab
/ sizeof (floattab
[0][0][0]);
4509 *p
= CODE_FOR_nothing
;
4511 for (p
= extendtab
[0][0];
4512 p
< extendtab
[0][0] + sizeof extendtab
/ sizeof extendtab
[0][0][0];
4514 *p
= CODE_FOR_nothing
;
4516 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
4517 setcc_gen_code
[i
] = CODE_FOR_nothing
;
4519 #ifdef HAVE_conditional_move
4520 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4521 movcc_gen_code
[i
] = CODE_FOR_nothing
;
4524 add_optab
= init_optab (PLUS
);
4525 sub_optab
= init_optab (MINUS
);
4526 smul_optab
= init_optab (MULT
);
4527 smul_highpart_optab
= init_optab (UNKNOWN
);
4528 umul_highpart_optab
= init_optab (UNKNOWN
);
4529 smul_widen_optab
= init_optab (UNKNOWN
);
4530 umul_widen_optab
= init_optab (UNKNOWN
);
4531 sdiv_optab
= init_optab (DIV
);
4532 sdivmod_optab
= init_optab (UNKNOWN
);
4533 udiv_optab
= init_optab (UDIV
);
4534 udivmod_optab
= init_optab (UNKNOWN
);
4535 smod_optab
= init_optab (MOD
);
4536 umod_optab
= init_optab (UMOD
);
4537 flodiv_optab
= init_optab (DIV
);
4538 ftrunc_optab
= init_optab (UNKNOWN
);
4539 and_optab
= init_optab (AND
);
4540 ior_optab
= init_optab (IOR
);
4541 xor_optab
= init_optab (XOR
);
4542 ashl_optab
= init_optab (ASHIFT
);
4543 ashr_optab
= init_optab (ASHIFTRT
);
4544 lshr_optab
= init_optab (LSHIFTRT
);
4545 rotl_optab
= init_optab (ROTATE
);
4546 rotr_optab
= init_optab (ROTATERT
);
4547 smin_optab
= init_optab (SMIN
);
4548 smax_optab
= init_optab (SMAX
);
4549 umin_optab
= init_optab (UMIN
);
4550 umax_optab
= init_optab (UMAX
);
4551 mov_optab
= init_optab (UNKNOWN
);
4552 movstrict_optab
= init_optab (UNKNOWN
);
4553 cmp_optab
= init_optab (UNKNOWN
);
4554 ucmp_optab
= init_optab (UNKNOWN
);
4555 tst_optab
= init_optab (UNKNOWN
);
4556 neg_optab
= init_optab (NEG
);
4557 abs_optab
= init_optab (ABS
);
4558 one_cmpl_optab
= init_optab (NOT
);
4559 ffs_optab
= init_optab (FFS
);
4560 sqrt_optab
= init_optab (SQRT
);
4561 sin_optab
= init_optab (UNKNOWN
);
4562 cos_optab
= init_optab (UNKNOWN
);
4563 strlen_optab
= init_optab (UNKNOWN
);
4564 cbranch_optab
= init_optab (UNKNOWN
);
4565 cmov_optab
= init_optab (UNKNOWN
);
4566 cstore_optab
= init_optab (UNKNOWN
);
4568 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4570 movstr_optab
[i
] = CODE_FOR_nothing
;
4571 clrstr_optab
[i
] = CODE_FOR_nothing
;
4573 #ifdef HAVE_SECONDARY_RELOADS
4574 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
4578 /* Fill in the optabs with the insns we support. */
4581 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4582 /* This flag says the same insns that convert to a signed fixnum
4583 also convert validly to an unsigned one. */
4584 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4585 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
4586 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
4589 /* Initialize the optabs with the names of the library functions. */
4590 init_integral_libfuncs (add_optab
, "add", '3');
4591 init_floating_libfuncs (add_optab
, "add", '3');
4592 init_integral_libfuncs (sub_optab
, "sub", '3');
4593 init_floating_libfuncs (sub_optab
, "sub", '3');
4594 init_integral_libfuncs (smul_optab
, "mul", '3');
4595 init_floating_libfuncs (smul_optab
, "mul", '3');
4596 init_integral_libfuncs (sdiv_optab
, "div", '3');
4597 init_integral_libfuncs (udiv_optab
, "udiv", '3');
4598 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
4599 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
4600 init_integral_libfuncs (smod_optab
, "mod", '3');
4601 init_integral_libfuncs (umod_optab
, "umod", '3');
4602 init_floating_libfuncs (flodiv_optab
, "div", '3');
4603 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
4604 init_integral_libfuncs (and_optab
, "and", '3');
4605 init_integral_libfuncs (ior_optab
, "ior", '3');
4606 init_integral_libfuncs (xor_optab
, "xor", '3');
4607 init_integral_libfuncs (ashl_optab
, "ashl", '3');
4608 init_integral_libfuncs (ashr_optab
, "ashr", '3');
4609 init_integral_libfuncs (lshr_optab
, "lshr", '3');
4610 init_integral_libfuncs (smin_optab
, "min", '3');
4611 init_floating_libfuncs (smin_optab
, "min", '3');
4612 init_integral_libfuncs (smax_optab
, "max", '3');
4613 init_floating_libfuncs (smax_optab
, "max", '3');
4614 init_integral_libfuncs (umin_optab
, "umin", '3');
4615 init_integral_libfuncs (umax_optab
, "umax", '3');
4616 init_integral_libfuncs (neg_optab
, "neg", '2');
4617 init_floating_libfuncs (neg_optab
, "neg", '2');
4618 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
4619 init_integral_libfuncs (ffs_optab
, "ffs", '2');
4621 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4622 init_integral_libfuncs (cmp_optab
, "cmp", '2');
4623 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
4624 init_floating_libfuncs (cmp_optab
, "cmp", '2');
4626 #ifdef MULSI3_LIBCALL
4627 smul_optab
->handlers
[(int) SImode
].libfunc
4628 = init_one_libfunc (MULSI3_LIBCALL
);
4630 #ifdef MULDI3_LIBCALL
4631 smul_optab
->handlers
[(int) DImode
].libfunc
4632 = init_one_libfunc (MULDI3_LIBCALL
);
4635 #ifdef DIVSI3_LIBCALL
4636 sdiv_optab
->handlers
[(int) SImode
].libfunc
4637 = init_one_libfunc (DIVSI3_LIBCALL
);
4639 #ifdef DIVDI3_LIBCALL
4640 sdiv_optab
->handlers
[(int) DImode
].libfunc
4641 = init_one_libfunc (DIVDI3_LIBCALL
);
4644 #ifdef UDIVSI3_LIBCALL
4645 udiv_optab
->handlers
[(int) SImode
].libfunc
4646 = init_one_libfunc (UDIVSI3_LIBCALL
);
4648 #ifdef UDIVDI3_LIBCALL
4649 udiv_optab
->handlers
[(int) DImode
].libfunc
4650 = init_one_libfunc (UDIVDI3_LIBCALL
);
4653 #ifdef MODSI3_LIBCALL
4654 smod_optab
->handlers
[(int) SImode
].libfunc
4655 = init_one_libfunc (MODSI3_LIBCALL
);
4657 #ifdef MODDI3_LIBCALL
4658 smod_optab
->handlers
[(int) DImode
].libfunc
4659 = init_one_libfunc (MODDI3_LIBCALL
);
4662 #ifdef UMODSI3_LIBCALL
4663 umod_optab
->handlers
[(int) SImode
].libfunc
4664 = init_one_libfunc (UMODSI3_LIBCALL
);
4666 #ifdef UMODDI3_LIBCALL
4667 umod_optab
->handlers
[(int) DImode
].libfunc
4668 = init_one_libfunc (UMODDI3_LIBCALL
);
4671 /* Use cabs for DC complex abs, since systems generally have cabs.
4672 Don't define any libcall for SCmode, so that cabs will be used. */
4673 abs_optab
->handlers
[(int) DCmode
].libfunc
4674 = init_one_libfunc ("cabs");
4676 /* The ffs function operates on `int'. */
4677 #ifndef INT_TYPE_SIZE
4678 #define INT_TYPE_SIZE BITS_PER_WORD
4680 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)].libfunc
4681 = init_one_libfunc ("ffs");
4683 extendsfdf2_libfunc
= init_one_libfunc ("__extendsfdf2");
4684 extendsfxf2_libfunc
= init_one_libfunc ("__extendsfxf2");
4685 extendsftf2_libfunc
= init_one_libfunc ("__extendsftf2");
4686 extenddfxf2_libfunc
= init_one_libfunc ("__extenddfxf2");
4687 extenddftf2_libfunc
= init_one_libfunc ("__extenddftf2");
4689 truncdfsf2_libfunc
= init_one_libfunc ("__truncdfsf2");
4690 truncxfsf2_libfunc
= init_one_libfunc ("__truncxfsf2");
4691 trunctfsf2_libfunc
= init_one_libfunc ("__trunctfsf2");
4692 truncxfdf2_libfunc
= init_one_libfunc ("__truncxfdf2");
4693 trunctfdf2_libfunc
= init_one_libfunc ("__trunctfdf2");
4695 memcpy_libfunc
= init_one_libfunc ("memcpy");
4696 bcopy_libfunc
= init_one_libfunc ("bcopy");
4697 memcmp_libfunc
= init_one_libfunc ("memcmp");
4698 bcmp_libfunc
= init_one_libfunc ("__gcc_bcmp");
4699 memset_libfunc
= init_one_libfunc ("memset");
4700 bzero_libfunc
= init_one_libfunc ("bzero");
4702 throw_libfunc
= init_one_libfunc ("__throw");
4703 rethrow_libfunc
= init_one_libfunc ("__rethrow");
4704 sjthrow_libfunc
= init_one_libfunc ("__sjthrow");
4705 sjpopnthrow_libfunc
= init_one_libfunc ("__sjpopnthrow");
4706 terminate_libfunc
= init_one_libfunc ("__terminate");
4707 eh_rtime_match_libfunc
= init_one_libfunc ("__eh_rtime_match");
4708 #ifndef DONT_USE_BUILTIN_SETJMP
4709 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
4710 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
4712 setjmp_libfunc
= init_one_libfunc ("setjmp");
4713 longjmp_libfunc
= init_one_libfunc ("longjmp");
4716 eqhf2_libfunc
= init_one_libfunc ("__eqhf2");
4717 nehf2_libfunc
= init_one_libfunc ("__nehf2");
4718 gthf2_libfunc
= init_one_libfunc ("__gthf2");
4719 gehf2_libfunc
= init_one_libfunc ("__gehf2");
4720 lthf2_libfunc
= init_one_libfunc ("__lthf2");
4721 lehf2_libfunc
= init_one_libfunc ("__lehf2");
4722 unordhf2_libfunc
= init_one_libfunc ("__unordhf2");
4724 eqsf2_libfunc
= init_one_libfunc ("__eqsf2");
4725 nesf2_libfunc
= init_one_libfunc ("__nesf2");
4726 gtsf2_libfunc
= init_one_libfunc ("__gtsf2");
4727 gesf2_libfunc
= init_one_libfunc ("__gesf2");
4728 ltsf2_libfunc
= init_one_libfunc ("__ltsf2");
4729 lesf2_libfunc
= init_one_libfunc ("__lesf2");
4730 unordsf2_libfunc
= init_one_libfunc ("__unordsf2");
4732 eqdf2_libfunc
= init_one_libfunc ("__eqdf2");
4733 nedf2_libfunc
= init_one_libfunc ("__nedf2");
4734 gtdf2_libfunc
= init_one_libfunc ("__gtdf2");
4735 gedf2_libfunc
= init_one_libfunc ("__gedf2");
4736 ltdf2_libfunc
= init_one_libfunc ("__ltdf2");
4737 ledf2_libfunc
= init_one_libfunc ("__ledf2");
4738 unorddf2_libfunc
= init_one_libfunc ("__unorddf2");
4740 eqxf2_libfunc
= init_one_libfunc ("__eqxf2");
4741 nexf2_libfunc
= init_one_libfunc ("__nexf2");
4742 gtxf2_libfunc
= init_one_libfunc ("__gtxf2");
4743 gexf2_libfunc
= init_one_libfunc ("__gexf2");
4744 ltxf2_libfunc
= init_one_libfunc ("__ltxf2");
4745 lexf2_libfunc
= init_one_libfunc ("__lexf2");
4746 unordxf2_libfunc
= init_one_libfunc ("__unordxf2");
4748 eqtf2_libfunc
= init_one_libfunc ("__eqtf2");
4749 netf2_libfunc
= init_one_libfunc ("__netf2");
4750 gttf2_libfunc
= init_one_libfunc ("__gttf2");
4751 getf2_libfunc
= init_one_libfunc ("__getf2");
4752 lttf2_libfunc
= init_one_libfunc ("__lttf2");
4753 letf2_libfunc
= init_one_libfunc ("__letf2");
4754 unordtf2_libfunc
= init_one_libfunc ("__unordtf2");
4756 floatsisf_libfunc
= init_one_libfunc ("__floatsisf");
4757 floatdisf_libfunc
= init_one_libfunc ("__floatdisf");
4758 floattisf_libfunc
= init_one_libfunc ("__floattisf");
4760 floatsidf_libfunc
= init_one_libfunc ("__floatsidf");
4761 floatdidf_libfunc
= init_one_libfunc ("__floatdidf");
4762 floattidf_libfunc
= init_one_libfunc ("__floattidf");
4764 floatsixf_libfunc
= init_one_libfunc ("__floatsixf");
4765 floatdixf_libfunc
= init_one_libfunc ("__floatdixf");
4766 floattixf_libfunc
= init_one_libfunc ("__floattixf");
4768 floatsitf_libfunc
= init_one_libfunc ("__floatsitf");
4769 floatditf_libfunc
= init_one_libfunc ("__floatditf");
4770 floattitf_libfunc
= init_one_libfunc ("__floattitf");
4772 fixsfsi_libfunc
= init_one_libfunc ("__fixsfsi");
4773 fixsfdi_libfunc
= init_one_libfunc ("__fixsfdi");
4774 fixsfti_libfunc
= init_one_libfunc ("__fixsfti");
4776 fixdfsi_libfunc
= init_one_libfunc ("__fixdfsi");
4777 fixdfdi_libfunc
= init_one_libfunc ("__fixdfdi");
4778 fixdfti_libfunc
= init_one_libfunc ("__fixdfti");
4780 fixxfsi_libfunc
= init_one_libfunc ("__fixxfsi");
4781 fixxfdi_libfunc
= init_one_libfunc ("__fixxfdi");
4782 fixxfti_libfunc
= init_one_libfunc ("__fixxfti");
4784 fixtfsi_libfunc
= init_one_libfunc ("__fixtfsi");
4785 fixtfdi_libfunc
= init_one_libfunc ("__fixtfdi");
4786 fixtfti_libfunc
= init_one_libfunc ("__fixtfti");
4788 fixunssfsi_libfunc
= init_one_libfunc ("__fixunssfsi");
4789 fixunssfdi_libfunc
= init_one_libfunc ("__fixunssfdi");
4790 fixunssfti_libfunc
= init_one_libfunc ("__fixunssfti");
4792 fixunsdfsi_libfunc
= init_one_libfunc ("__fixunsdfsi");
4793 fixunsdfdi_libfunc
= init_one_libfunc ("__fixunsdfdi");
4794 fixunsdfti_libfunc
= init_one_libfunc ("__fixunsdfti");
4796 fixunsxfsi_libfunc
= init_one_libfunc ("__fixunsxfsi");
4797 fixunsxfdi_libfunc
= init_one_libfunc ("__fixunsxfdi");
4798 fixunsxfti_libfunc
= init_one_libfunc ("__fixunsxfti");
4800 fixunstfsi_libfunc
= init_one_libfunc ("__fixunstfsi");
4801 fixunstfdi_libfunc
= init_one_libfunc ("__fixunstfdi");
4802 fixunstfti_libfunc
= init_one_libfunc ("__fixunstfti");
4804 /* For check-memory-usage. */
4805 chkr_check_addr_libfunc
= init_one_libfunc ("chkr_check_addr");
4806 chkr_set_right_libfunc
= init_one_libfunc ("chkr_set_right");
4807 chkr_copy_bitmap_libfunc
= init_one_libfunc ("chkr_copy_bitmap");
4808 chkr_check_exec_libfunc
= init_one_libfunc ("chkr_check_exec");
4809 chkr_check_str_libfunc
= init_one_libfunc ("chkr_check_str");
4811 /* For function entry/exit instrumentation. */
4812 profile_function_entry_libfunc
4813 = init_one_libfunc ("__cyg_profile_func_enter");
4814 profile_function_exit_libfunc
4815 = init_one_libfunc ("__cyg_profile_func_exit");
4817 #ifdef HAVE_conditional_trap
4821 #ifdef INIT_TARGET_OPTABS
4822 /* Allow the target to add more libcalls or rename some, etc. */
4826 /* Add these GC roots. */
4827 ggc_add_root (optab_table
, OTI_MAX
, sizeof(optab
), mark_optab
);
4828 ggc_add_rtx_root (libfunc_table
, LTI_MAX
);
4833 /* SCO 3.2 apparently has a broken ldexp. */
4846 #endif /* BROKEN_LDEXP */
4848 #ifdef HAVE_conditional_trap
4849 /* The insn generating function can not take an rtx_code argument.
4850 TRAP_RTX is used as an rtx argument. Its code is replaced with
4851 the code to be used in the trap insn and all other fields are
4853 static rtx trap_rtx
;
4858 if (HAVE_conditional_trap
)
4860 trap_rtx
= gen_rtx_fmt_ee (EQ
, VOIDmode
, NULL_RTX
, NULL_RTX
);
4861 ggc_add_rtx_root (&trap_rtx
, 1);
4866 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4867 CODE. Return 0 on failure. */
4870 gen_cond_trap (code
, op1
, op2
, tcode
)
4871 enum rtx_code code ATTRIBUTE_UNUSED
;
4872 rtx op1
, op2 ATTRIBUTE_UNUSED
, tcode ATTRIBUTE_UNUSED
;
4874 enum machine_mode mode
= GET_MODE (op1
);
4876 if (mode
== VOIDmode
)
4879 #ifdef HAVE_conditional_trap
4880 if (HAVE_conditional_trap
4881 && cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
4885 emit_insn (GEN_FCN (cmp_optab
->handlers
[(int) mode
].insn_code
) (op1
, op2
));
4886 PUT_CODE (trap_rtx
, code
);
4887 insn
= gen_conditional_trap (trap_rtx
, tcode
);
4891 insn
= gen_sequence ();