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, 2001 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"
41 /* Each optab contains info on how this target machine
42 can perform a particular operation
43 for all sizes and kinds of operands.
45 The operation to be performed is often specified
46 by passing one of these optabs as an argument.
48 See expr.h for documentation of these optabs. */
50 optab optab_table
[OTI_MAX
];
52 rtx libfunc_table
[LTI_MAX
];
54 /* Tables of patterns for extending one integer mode to another. */
55 enum insn_code extendtab
[MAX_MACHINE_MODE
][MAX_MACHINE_MODE
][2];
57 /* Tables of patterns for converting between fixed and floating point. */
58 enum insn_code fixtab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
59 enum insn_code fixtrunctab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
60 enum insn_code floattab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
62 /* Contains the optab used for each rtx code. */
63 optab code_to_optab
[NUM_RTX_CODE
+ 1];
65 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
66 gives the gen_function to make a branch to test that condition. */
68 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
70 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
71 gives the insn code to make a store-condition insn
72 to test that condition. */
74 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
76 #ifdef HAVE_conditional_move
77 /* Indexed by the machine mode, gives the insn code to make a conditional
78 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
79 setcc_gen_code to cut down on the number of named patterns. Consider a day
80 when a lot more rtx codes are conditional (eg: for the ARM). */
82 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
85 static int add_equal_note
PARAMS ((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
86 static rtx widen_operand
PARAMS ((rtx
, enum machine_mode
,
87 enum machine_mode
, int, int));
88 static int expand_cmplxdiv_straight
PARAMS ((rtx
, rtx
, rtx
, rtx
,
89 rtx
, rtx
, enum machine_mode
,
90 int, enum optab_methods
,
91 enum mode_class
, optab
));
92 static int expand_cmplxdiv_wide
PARAMS ((rtx
, rtx
, rtx
, rtx
,
93 rtx
, rtx
, enum machine_mode
,
94 int, enum optab_methods
,
95 enum mode_class
, optab
));
96 static enum insn_code can_fix_p
PARAMS ((enum machine_mode
, enum machine_mode
,
98 static enum insn_code can_float_p
PARAMS ((enum machine_mode
, enum machine_mode
,
100 static rtx ftruncify
PARAMS ((rtx
));
101 static optab init_optab
PARAMS ((enum rtx_code
));
102 static void init_libfuncs
PARAMS ((optab
, int, int, const char *, int));
103 static void init_integral_libfuncs
PARAMS ((optab
, const char *, int));
104 static void init_floating_libfuncs
PARAMS ((optab
, const char *, int));
105 #ifdef HAVE_conditional_trap
106 static void init_traps
PARAMS ((void));
108 static void emit_cmp_and_jump_insn_1
PARAMS ((rtx
, rtx
, enum machine_mode
,
109 enum rtx_code
, int, rtx
));
110 static void prepare_float_lib_cmp
PARAMS ((rtx
*, rtx
*, enum rtx_code
*,
111 enum machine_mode
*, int *));
113 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
114 the result of operation CODE applied to OP0 (and OP1 if it is a binary
117 If the last insn does not set TARGET, don't do anything, but return 1.
119 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
120 don't add the REG_EQUAL note but return 0. Our caller can then try
121 again, ensuring that TARGET is not one of the operands. */
124 add_equal_note (seq
, target
, code
, op0
, op1
)
134 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
135 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
136 || GET_CODE (seq
) != SEQUENCE
137 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
138 || GET_CODE (target
) == ZERO_EXTRACT
139 || (! rtx_equal_p (SET_DEST (set
), target
)
140 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
142 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
143 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
147 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
148 besides the last insn. */
149 if (reg_overlap_mentioned_p (target
, op0
)
150 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
151 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
152 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
155 if (GET_RTX_CLASS (code
) == '1')
156 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
158 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
160 set_unique_reg_note (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1), REG_EQUAL
, note
);
165 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
166 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
167 not actually do a sign-extend or zero-extend, but can leave the
168 higher-order bits of the result rtx undefined, for example, in the case
169 of logical operations, but not right shifts. */
172 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
174 enum machine_mode mode
, oldmode
;
180 /* If we must extend do so. If OP is either a constant or a SUBREG
181 for a promoted object, also extend since it will be more efficient to
184 || GET_MODE (op
) == VOIDmode
185 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
186 return convert_modes (mode
, oldmode
, op
, unsignedp
);
188 /* If MODE is no wider than a single word, we return a paradoxical
190 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
191 return gen_rtx_SUBREG (mode
, force_reg (GET_MODE (op
), op
), 0);
193 /* Otherwise, get an object of MODE, clobber it, and set the low-order
196 result
= gen_reg_rtx (mode
);
197 emit_insn (gen_rtx_CLOBBER (VOIDmode
, result
));
198 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
202 /* Generate code to perform a straightforward complex divide. */
205 expand_cmplxdiv_straight (real0
, real1
, imag0
, imag1
, realr
, imagr
, submode
,
206 unsignedp
, methods
, class, binoptab
)
207 rtx real0
, real1
, imag0
, imag1
, realr
, imagr
;
208 enum machine_mode submode
;
210 enum optab_methods methods
;
211 enum mode_class
class;
218 optab this_add_optab
= add_optab
;
219 optab this_sub_optab
= sub_optab
;
220 optab this_neg_optab
= neg_optab
;
221 optab this_mul_optab
= smul_optab
;
223 if (binoptab
== sdivv_optab
)
225 this_add_optab
= addv_optab
;
226 this_sub_optab
= subv_optab
;
227 this_neg_optab
= negv_optab
;
228 this_mul_optab
= smulv_optab
;
231 /* Don't fetch these from memory more than once. */
232 real0
= force_reg (submode
, real0
);
233 real1
= force_reg (submode
, real1
);
236 imag0
= force_reg (submode
, imag0
);
238 imag1
= force_reg (submode
, imag1
);
240 /* Divisor: c*c + d*d. */
241 temp1
= expand_binop (submode
, this_mul_optab
, real1
, real1
,
242 NULL_RTX
, unsignedp
, methods
);
244 temp2
= expand_binop (submode
, this_mul_optab
, imag1
, imag1
,
245 NULL_RTX
, unsignedp
, methods
);
247 if (temp1
== 0 || temp2
== 0)
250 divisor
= expand_binop (submode
, this_add_optab
, temp1
, temp2
,
251 NULL_RTX
, unsignedp
, methods
);
257 /* Mathematically, ((a)(c-id))/divisor. */
258 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
260 /* Calculate the dividend. */
261 real_t
= expand_binop (submode
, this_mul_optab
, real0
, real1
,
262 NULL_RTX
, unsignedp
, methods
);
264 imag_t
= expand_binop (submode
, this_mul_optab
, real0
, imag1
,
265 NULL_RTX
, unsignedp
, methods
);
267 if (real_t
== 0 || imag_t
== 0)
270 imag_t
= expand_unop (submode
, this_neg_optab
, imag_t
,
271 NULL_RTX
, unsignedp
);
275 /* Mathematically, ((a+ib)(c-id))/divider. */
276 /* Calculate the dividend. */
277 temp1
= expand_binop (submode
, this_mul_optab
, real0
, real1
,
278 NULL_RTX
, unsignedp
, methods
);
280 temp2
= expand_binop (submode
, this_mul_optab
, imag0
, imag1
,
281 NULL_RTX
, unsignedp
, methods
);
283 if (temp1
== 0 || temp2
== 0)
286 real_t
= expand_binop (submode
, this_add_optab
, temp1
, temp2
,
287 NULL_RTX
, unsignedp
, methods
);
289 temp1
= expand_binop (submode
, this_mul_optab
, imag0
, real1
,
290 NULL_RTX
, unsignedp
, methods
);
292 temp2
= expand_binop (submode
, this_mul_optab
, real0
, imag1
,
293 NULL_RTX
, unsignedp
, methods
);
295 if (temp1
== 0 || temp2
== 0)
298 imag_t
= expand_binop (submode
, this_sub_optab
, temp1
, temp2
,
299 NULL_RTX
, unsignedp
, methods
);
301 if (real_t
== 0 || imag_t
== 0)
305 if (class == MODE_COMPLEX_FLOAT
)
306 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
307 realr
, unsignedp
, methods
);
309 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
310 real_t
, divisor
, realr
, unsignedp
);
316 emit_move_insn (realr
, res
);
318 if (class == MODE_COMPLEX_FLOAT
)
319 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
320 imagr
, unsignedp
, methods
);
322 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
323 imag_t
, divisor
, imagr
, unsignedp
);
329 emit_move_insn (imagr
, res
);
334 /* Generate code to perform a wide-input-range-acceptable complex divide. */
337 expand_cmplxdiv_wide (real0
, real1
, imag0
, imag1
, realr
, imagr
, submode
,
338 unsignedp
, methods
, class, binoptab
)
339 rtx real0
, real1
, imag0
, imag1
, realr
, imagr
;
340 enum machine_mode submode
;
342 enum optab_methods methods
;
343 enum mode_class
class;
348 rtx temp1
, temp2
, lab1
, lab2
;
349 enum machine_mode mode
;
352 optab this_add_optab
= add_optab
;
353 optab this_sub_optab
= sub_optab
;
354 optab this_neg_optab
= neg_optab
;
355 optab this_mul_optab
= smul_optab
;
357 if (binoptab
== sdivv_optab
)
359 this_add_optab
= addv_optab
;
360 this_sub_optab
= subv_optab
;
361 this_neg_optab
= negv_optab
;
362 this_mul_optab
= smulv_optab
;
365 /* Don't fetch these from memory more than once. */
366 real0
= force_reg (submode
, real0
);
367 real1
= force_reg (submode
, real1
);
370 imag0
= force_reg (submode
, imag0
);
372 imag1
= force_reg (submode
, imag1
);
374 /* XXX What's an "unsigned" complex number? */
382 temp1
= expand_abs (submode
, real1
, NULL_RTX
, unsignedp
, 1);
383 temp2
= expand_abs (submode
, imag1
, NULL_RTX
, unsignedp
, 1);
386 if (temp1
== 0 || temp2
== 0)
389 mode
= GET_MODE (temp1
);
390 align
= GET_MODE_ALIGNMENT (mode
);
391 lab1
= gen_label_rtx ();
392 emit_cmp_and_jump_insns (temp1
, temp2
, LT
, NULL_RTX
,
393 mode
, unsignedp
, align
, lab1
);
395 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
397 if (class == MODE_COMPLEX_FLOAT
)
398 ratio
= expand_binop (submode
, binoptab
, imag1
, real1
,
399 NULL_RTX
, unsignedp
, methods
);
401 ratio
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
402 imag1
, real1
, NULL_RTX
, unsignedp
);
407 /* Calculate divisor. */
409 temp1
= expand_binop (submode
, this_mul_optab
, imag1
, ratio
,
410 NULL_RTX
, unsignedp
, methods
);
415 divisor
= expand_binop (submode
, this_add_optab
, temp1
, real1
,
416 NULL_RTX
, unsignedp
, methods
);
421 /* Calculate dividend. */
427 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
429 imag_t
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
430 NULL_RTX
, unsignedp
, methods
);
435 imag_t
= expand_unop (submode
, this_neg_optab
, imag_t
,
436 NULL_RTX
, unsignedp
);
438 if (real_t
== 0 || imag_t
== 0)
443 /* Compute (a+ib)/(c+id) as
444 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
446 temp1
= expand_binop (submode
, this_mul_optab
, imag0
, ratio
,
447 NULL_RTX
, unsignedp
, methods
);
452 real_t
= expand_binop (submode
, this_add_optab
, temp1
, real0
,
453 NULL_RTX
, unsignedp
, methods
);
455 temp1
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
456 NULL_RTX
, unsignedp
, methods
);
461 imag_t
= expand_binop (submode
, this_sub_optab
, imag0
, temp1
,
462 NULL_RTX
, unsignedp
, methods
);
464 if (real_t
== 0 || imag_t
== 0)
468 if (class == MODE_COMPLEX_FLOAT
)
469 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
470 realr
, unsignedp
, methods
);
472 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
473 real_t
, divisor
, realr
, unsignedp
);
479 emit_move_insn (realr
, res
);
481 if (class == MODE_COMPLEX_FLOAT
)
482 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
483 imagr
, unsignedp
, methods
);
485 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
486 imag_t
, divisor
, imagr
, unsignedp
);
492 emit_move_insn (imagr
, res
);
494 lab2
= gen_label_rtx ();
495 emit_jump_insn (gen_jump (lab2
));
500 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
502 if (class == MODE_COMPLEX_FLOAT
)
503 ratio
= expand_binop (submode
, binoptab
, real1
, imag1
,
504 NULL_RTX
, unsignedp
, methods
);
506 ratio
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
507 real1
, imag1
, NULL_RTX
, unsignedp
);
512 /* Calculate divisor. */
514 temp1
= expand_binop (submode
, this_mul_optab
, real1
, ratio
,
515 NULL_RTX
, unsignedp
, methods
);
520 divisor
= expand_binop (submode
, this_add_optab
, temp1
, imag1
,
521 NULL_RTX
, unsignedp
, methods
);
526 /* Calculate dividend. */
530 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
532 real_t
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
533 NULL_RTX
, unsignedp
, methods
);
535 imag_t
= expand_unop (submode
, this_neg_optab
, real0
,
536 NULL_RTX
, unsignedp
);
538 if (real_t
== 0 || imag_t
== 0)
543 /* Compute (a+ib)/(c+id) as
544 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
546 temp1
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
547 NULL_RTX
, unsignedp
, methods
);
552 real_t
= expand_binop (submode
, this_add_optab
, temp1
, imag0
,
553 NULL_RTX
, unsignedp
, methods
);
555 temp1
= expand_binop (submode
, this_mul_optab
, imag0
, ratio
,
556 NULL_RTX
, unsignedp
, methods
);
561 imag_t
= expand_binop (submode
, this_sub_optab
, temp1
, real0
,
562 NULL_RTX
, unsignedp
, methods
);
564 if (real_t
== 0 || imag_t
== 0)
568 if (class == MODE_COMPLEX_FLOAT
)
569 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
570 realr
, unsignedp
, methods
);
572 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
573 real_t
, divisor
, realr
, unsignedp
);
579 emit_move_insn (realr
, res
);
581 if (class == MODE_COMPLEX_FLOAT
)
582 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
583 imagr
, unsignedp
, methods
);
585 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
586 imag_t
, divisor
, imagr
, unsignedp
);
592 emit_move_insn (imagr
, res
);
599 /* Generate code to perform an operation specified by BINOPTAB
600 on operands OP0 and OP1, with result having machine-mode MODE.
602 UNSIGNEDP is for the case where we have to widen the operands
603 to perform the operation. It says to use zero-extension.
605 If TARGET is nonzero, the value
606 is generated there, if it is convenient to do so.
607 In all cases an rtx is returned for the locus of the value;
608 this may or may not be TARGET. */
611 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
612 enum machine_mode mode
;
617 enum optab_methods methods
;
619 enum optab_methods next_methods
620 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
621 ? OPTAB_WIDEN
: methods
);
622 enum mode_class
class;
623 enum machine_mode wider_mode
;
625 int commutative_op
= 0;
626 int shift_op
= (binoptab
->code
== ASHIFT
627 || binoptab
->code
== ASHIFTRT
628 || binoptab
->code
== LSHIFTRT
629 || binoptab
->code
== ROTATE
630 || binoptab
->code
== ROTATERT
);
631 rtx entry_last
= get_last_insn ();
634 class = GET_MODE_CLASS (mode
);
636 op0
= protect_from_queue (op0
, 0);
637 op1
= protect_from_queue (op1
, 0);
639 target
= protect_from_queue (target
, 1);
643 op0
= force_not_mem (op0
);
644 op1
= force_not_mem (op1
);
647 /* If subtracting an integer constant, convert this into an addition of
648 the negated constant. */
650 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
652 op1
= negate_rtx (mode
, op1
);
653 binoptab
= add_optab
;
656 /* If we are inside an appropriately-short loop and one operand is an
657 expensive constant, force it into a register. */
658 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
659 && rtx_cost (op0
, binoptab
->code
) > COSTS_N_INSNS (1))
660 op0
= force_reg (mode
, op0
);
662 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
663 && ! shift_op
&& rtx_cost (op1
, binoptab
->code
) > COSTS_N_INSNS (1))
664 op1
= force_reg (mode
, op1
);
666 /* Record where to delete back to if we backtrack. */
667 last
= get_last_insn ();
669 /* If operation is commutative,
670 try to make the first operand a register.
671 Even better, try to make it the same as the target.
672 Also try to make the last operand a constant. */
673 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
674 || binoptab
== smul_widen_optab
675 || binoptab
== umul_widen_optab
676 || binoptab
== smul_highpart_optab
677 || binoptab
== umul_highpart_optab
)
681 if (((target
== 0 || GET_CODE (target
) == REG
)
682 ? ((GET_CODE (op1
) == REG
683 && GET_CODE (op0
) != REG
)
685 : rtx_equal_p (op1
, target
))
686 || GET_CODE (op0
) == CONST_INT
)
694 /* If we can do it with a three-operand insn, do so. */
696 if (methods
!= OPTAB_MUST_WIDEN
697 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
699 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
700 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
701 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
703 rtx xop0
= op0
, xop1
= op1
;
708 temp
= gen_reg_rtx (mode
);
710 /* If it is a commutative operator and the modes would match
711 if we would swap the operands, we can save the conversions. */
714 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
715 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
719 tmp
= op0
; op0
= op1
; op1
= tmp
;
720 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
724 /* In case the insn wants input operands in modes different from
725 the result, convert the operands. */
727 if (GET_MODE (op0
) != VOIDmode
728 && GET_MODE (op0
) != mode0
729 && mode0
!= VOIDmode
)
730 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
732 if (GET_MODE (xop1
) != VOIDmode
733 && GET_MODE (xop1
) != mode1
734 && mode1
!= VOIDmode
)
735 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
737 /* Now, if insn's predicates don't allow our operands, put them into
740 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
)
741 && mode0
!= VOIDmode
)
742 xop0
= copy_to_mode_reg (mode0
, xop0
);
744 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, mode1
)
745 && mode1
!= VOIDmode
)
746 xop1
= copy_to_mode_reg (mode1
, xop1
);
748 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, mode
))
749 temp
= gen_reg_rtx (mode
);
751 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
754 /* If PAT is a multi-insn sequence, try to add an appropriate
755 REG_EQUAL note to it. If we can't because TEMP conflicts with an
756 operand, call ourselves again, this time without a target. */
757 if (GET_CODE (pat
) == SEQUENCE
758 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
760 delete_insns_since (last
);
761 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
769 delete_insns_since (last
);
772 /* If this is a multiply, see if we can do a widening operation that
773 takes operands of this mode and makes a wider mode. */
775 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
776 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
777 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
778 != CODE_FOR_nothing
))
780 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
781 unsignedp
? umul_widen_optab
: smul_widen_optab
,
782 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
786 if (GET_MODE_CLASS (mode
) == MODE_INT
)
787 return gen_lowpart (mode
, temp
);
789 return convert_to_mode (mode
, temp
, unsignedp
);
793 /* Look for a wider mode of the same class for which we think we
794 can open-code the operation. Check for a widening multiply at the
795 wider mode as well. */
797 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
798 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
799 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
800 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
802 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
803 || (binoptab
== smul_optab
804 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
805 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
806 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
807 != CODE_FOR_nothing
)))
809 rtx xop0
= op0
, xop1
= op1
;
812 /* For certain integer operations, we need not actually extend
813 the narrow operands, as long as we will truncate
814 the results to the same narrowness. */
816 if ((binoptab
== ior_optab
|| binoptab
== and_optab
817 || binoptab
== xor_optab
818 || binoptab
== add_optab
|| binoptab
== sub_optab
819 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
820 && class == MODE_INT
)
823 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
825 /* The second operand of a shift must always be extended. */
826 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
827 no_extend
&& binoptab
!= ashl_optab
);
829 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
830 unsignedp
, OPTAB_DIRECT
);
833 if (class != MODE_INT
)
836 target
= gen_reg_rtx (mode
);
837 convert_move (target
, temp
, 0);
841 return gen_lowpart (mode
, temp
);
844 delete_insns_since (last
);
848 /* These can be done a word at a time. */
849 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
851 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
852 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
858 /* If TARGET is the same as one of the operands, the REG_EQUAL note
859 won't be accurate, so use a new target. */
860 if (target
== 0 || target
== op0
|| target
== op1
)
861 target
= gen_reg_rtx (mode
);
865 /* Do the actual arithmetic. */
866 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
868 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
869 rtx x
= expand_binop (word_mode
, binoptab
,
870 operand_subword_force (op0
, i
, mode
),
871 operand_subword_force (op1
, i
, mode
),
872 target_piece
, unsignedp
, next_methods
);
877 if (target_piece
!= x
)
878 emit_move_insn (target_piece
, x
);
881 insns
= get_insns ();
884 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
886 if (binoptab
->code
!= UNKNOWN
)
888 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
889 copy_rtx (op0
), copy_rtx (op1
));
893 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
898 /* Synthesize double word shifts from single word shifts. */
899 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
900 || binoptab
== ashr_optab
)
902 && GET_CODE (op1
) == CONST_INT
903 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
904 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
905 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
906 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
908 rtx insns
, inter
, equiv_value
;
909 rtx into_target
, outof_target
;
910 rtx into_input
, outof_input
;
911 int shift_count
, left_shift
, outof_word
;
913 /* If TARGET is the same as one of the operands, the REG_EQUAL note
914 won't be accurate, so use a new target. */
915 if (target
== 0 || target
== op0
|| target
== op1
)
916 target
= gen_reg_rtx (mode
);
920 shift_count
= INTVAL (op1
);
922 /* OUTOF_* is the word we are shifting bits away from, and
923 INTO_* is the word that we are shifting bits towards, thus
924 they differ depending on the direction of the shift and
927 left_shift
= binoptab
== ashl_optab
;
928 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
930 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
931 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
933 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
934 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
936 if (shift_count
>= BITS_PER_WORD
)
938 inter
= expand_binop (word_mode
, binoptab
,
940 GEN_INT (shift_count
- BITS_PER_WORD
),
941 into_target
, unsignedp
, next_methods
);
943 if (inter
!= 0 && inter
!= into_target
)
944 emit_move_insn (into_target
, inter
);
946 /* For a signed right shift, we must fill the word we are shifting
947 out of with copies of the sign bit. Otherwise it is zeroed. */
948 if (inter
!= 0 && binoptab
!= ashr_optab
)
949 inter
= CONST0_RTX (word_mode
);
951 inter
= expand_binop (word_mode
, binoptab
,
953 GEN_INT (BITS_PER_WORD
- 1),
954 outof_target
, unsignedp
, next_methods
);
956 if (inter
!= 0 && inter
!= outof_target
)
957 emit_move_insn (outof_target
, inter
);
962 optab reverse_unsigned_shift
, unsigned_shift
;
964 /* For a shift of less then BITS_PER_WORD, to compute the carry,
965 we must do a logical shift in the opposite direction of the
968 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
970 /* For a shift of less than BITS_PER_WORD, to compute the word
971 shifted towards, we need to unsigned shift the orig value of
974 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
976 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
978 GEN_INT (BITS_PER_WORD
- shift_count
),
979 0, unsignedp
, next_methods
);
984 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
985 op1
, 0, unsignedp
, next_methods
);
988 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
989 into_target
, unsignedp
, next_methods
);
991 if (inter
!= 0 && inter
!= into_target
)
992 emit_move_insn (into_target
, inter
);
995 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
996 op1
, outof_target
, unsignedp
, next_methods
);
998 if (inter
!= 0 && inter
!= outof_target
)
999 emit_move_insn (outof_target
, inter
);
1002 insns
= get_insns ();
1007 if (binoptab
->code
!= UNKNOWN
)
1008 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
1012 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
1017 /* Synthesize double word rotates from single word shifts. */
1018 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1019 && class == MODE_INT
1020 && GET_CODE (op1
) == CONST_INT
1021 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1022 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1023 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1025 rtx insns
, equiv_value
;
1026 rtx into_target
, outof_target
;
1027 rtx into_input
, outof_input
;
1029 int shift_count
, left_shift
, outof_word
;
1031 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1032 won't be accurate, so use a new target. */
1033 if (target
== 0 || target
== op0
|| target
== op1
)
1034 target
= gen_reg_rtx (mode
);
1038 shift_count
= INTVAL (op1
);
1040 /* OUTOF_* is the word we are shifting bits away from, and
1041 INTO_* is the word that we are shifting bits towards, thus
1042 they differ depending on the direction of the shift and
1043 WORDS_BIG_ENDIAN. */
1045 left_shift
= (binoptab
== rotl_optab
);
1046 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1048 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1049 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1051 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1052 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1054 if (shift_count
== BITS_PER_WORD
)
1056 /* This is just a word swap. */
1057 emit_move_insn (outof_target
, into_input
);
1058 emit_move_insn (into_target
, outof_input
);
1063 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1064 rtx first_shift_count
, second_shift_count
;
1065 optab reverse_unsigned_shift
, unsigned_shift
;
1067 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1068 ? lshr_optab
: ashl_optab
);
1070 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1071 ? ashl_optab
: lshr_optab
);
1073 if (shift_count
> BITS_PER_WORD
)
1075 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1076 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
1080 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1081 second_shift_count
= GEN_INT (shift_count
);
1084 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1085 outof_input
, first_shift_count
,
1086 NULL_RTX
, unsignedp
, next_methods
);
1087 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1088 into_input
, second_shift_count
,
1089 into_target
, unsignedp
, next_methods
);
1091 if (into_temp1
!= 0 && into_temp2
!= 0)
1092 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1093 into_target
, unsignedp
, next_methods
);
1097 if (inter
!= 0 && inter
!= into_target
)
1098 emit_move_insn (into_target
, inter
);
1100 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1101 into_input
, first_shift_count
,
1102 NULL_RTX
, unsignedp
, next_methods
);
1103 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1104 outof_input
, second_shift_count
,
1105 outof_target
, unsignedp
, next_methods
);
1107 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1108 inter
= expand_binop (word_mode
, ior_optab
,
1109 outof_temp1
, outof_temp2
,
1110 outof_target
, unsignedp
, next_methods
);
1112 if (inter
!= 0 && inter
!= outof_target
)
1113 emit_move_insn (outof_target
, inter
);
1116 insns
= get_insns ();
1121 if (binoptab
->code
!= UNKNOWN
)
1122 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
1126 /* We can't make this a no conflict block if this is a word swap,
1127 because the word swap case fails if the input and output values
1128 are in the same register. */
1129 if (shift_count
!= BITS_PER_WORD
)
1130 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
1139 /* These can be done a word at a time by propagating carries. */
1140 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1141 && class == MODE_INT
1142 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1143 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1146 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1147 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1148 unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1149 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1152 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1153 value is one of those, use it. Otherwise, use 1 since it is the
1154 one easiest to get. */
1155 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1156 int normalizep
= STORE_FLAG_VALUE
;
1161 /* Prepare the operands. */
1162 xop0
= force_reg (mode
, op0
);
1163 xop1
= force_reg (mode
, op1
);
1165 if (target
== 0 || GET_CODE (target
) != REG
1166 || target
== xop0
|| target
== xop1
)
1167 target
= gen_reg_rtx (mode
);
1169 /* Indicate for flow that the entire target reg is being set. */
1170 if (GET_CODE (target
) == REG
)
1171 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
1173 /* Do the actual arithmetic. */
1174 for (i
= 0; i
< nwords
; i
++)
1176 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1177 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
1178 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1179 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
1182 /* Main add/subtract of the input operands. */
1183 x
= expand_binop (word_mode
, binoptab
,
1184 op0_piece
, op1_piece
,
1185 target_piece
, unsignedp
, next_methods
);
1191 /* Store carry from main add/subtract. */
1192 carry_out
= gen_reg_rtx (word_mode
);
1193 carry_out
= emit_store_flag_force (carry_out
,
1194 (binoptab
== add_optab
1197 word_mode
, 1, normalizep
);
1202 /* Add/subtract previous carry to main result. */
1203 x
= expand_binop (word_mode
,
1204 normalizep
== 1 ? binoptab
: otheroptab
,
1206 target_piece
, 1, next_methods
);
1209 else if (target_piece
!= x
)
1210 emit_move_insn (target_piece
, x
);
1214 /* THIS CODE HAS NOT BEEN TESTED. */
1215 /* Get out carry from adding/subtracting carry in. */
1216 carry_tmp
= emit_store_flag_force (carry_tmp
,
1217 binoptab
== add_optab
1220 word_mode
, 1, normalizep
);
1222 /* Logical-ior the two poss. carry together. */
1223 carry_out
= expand_binop (word_mode
, ior_optab
,
1224 carry_out
, carry_tmp
,
1225 carry_out
, 0, next_methods
);
1231 carry_in
= carry_out
;
1234 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1236 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1238 rtx temp
= emit_move_insn (target
, target
);
1240 set_unique_reg_note (temp
,
1242 gen_rtx_fmt_ee (binoptab
->code
, mode
,
1251 delete_insns_since (last
);
1254 /* If we want to multiply two two-word values and have normal and widening
1255 multiplies of single-word values, we can do this with three smaller
1256 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1257 because we are not operating on one word at a time.
1259 The multiplication proceeds as follows:
1260 _______________________
1261 [__op0_high_|__op0_low__]
1262 _______________________
1263 * [__op1_high_|__op1_low__]
1264 _______________________________________________
1265 _______________________
1266 (1) [__op0_low__*__op1_low__]
1267 _______________________
1268 (2a) [__op0_low__*__op1_high_]
1269 _______________________
1270 (2b) [__op0_high_*__op1_low__]
1271 _______________________
1272 (3) [__op0_high_*__op1_high_]
1275 This gives a 4-word result. Since we are only interested in the
1276 lower 2 words, partial result (3) and the upper words of (2a) and
1277 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1278 calculated using non-widening multiplication.
1280 (1), however, needs to be calculated with an unsigned widening
1281 multiplication. If this operation is not directly supported we
1282 try using a signed widening multiplication and adjust the result.
1283 This adjustment works as follows:
1285 If both operands are positive then no adjustment is needed.
1287 If the operands have different signs, for example op0_low < 0 and
1288 op1_low >= 0, the instruction treats the most significant bit of
1289 op0_low as a sign bit instead of a bit with significance
1290 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1291 with 2**BITS_PER_WORD - op0_low, and two's complements the
1292 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1295 Similarly, if both operands are negative, we need to add
1296 (op0_low + op1_low) * 2**BITS_PER_WORD.
1298 We use a trick to adjust quickly. We logically shift op0_low right
1299 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1300 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1301 logical shift exists, we do an arithmetic right shift and subtract
1304 if (binoptab
== smul_optab
1305 && class == MODE_INT
1306 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1307 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1308 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1309 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1310 != CODE_FOR_nothing
)
1311 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1312 != CODE_FOR_nothing
)))
1314 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1315 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1316 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1317 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1318 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1319 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1321 rtx op0_xhigh
= NULL_RTX
;
1322 rtx op1_xhigh
= NULL_RTX
;
1324 /* If the target is the same as one of the inputs, don't use it. This
1325 prevents problems with the REG_EQUAL note. */
1326 if (target
== op0
|| target
== op1
1327 || (target
!= 0 && GET_CODE (target
) != REG
))
1330 /* Multiply the two lower words to get a double-word product.
1331 If unsigned widening multiplication is available, use that;
1332 otherwise use the signed form and compensate. */
1334 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1336 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1337 target
, 1, OPTAB_DIRECT
);
1339 /* If we didn't succeed, delete everything we did so far. */
1341 delete_insns_since (last
);
1343 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1347 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1348 != CODE_FOR_nothing
)
1350 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1351 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1352 target
, 1, OPTAB_DIRECT
);
1353 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1354 NULL_RTX
, 1, next_methods
);
1356 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1357 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1360 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1361 NULL_RTX
, 0, next_methods
);
1363 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1364 op0_xhigh
, op0_xhigh
, 0,
1368 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1369 NULL_RTX
, 1, next_methods
);
1371 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1372 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1375 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1376 NULL_RTX
, 0, next_methods
);
1378 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1379 op1_xhigh
, op1_xhigh
, 0,
1384 /* If we have been able to directly compute the product of the
1385 low-order words of the operands and perform any required adjustments
1386 of the operands, we proceed by trying two more multiplications
1387 and then computing the appropriate sum.
1389 We have checked above that the required addition is provided.
1390 Full-word addition will normally always succeed, especially if
1391 it is provided at all, so we don't worry about its failure. The
1392 multiplication may well fail, however, so we do handle that. */
1394 if (product
&& op0_xhigh
&& op1_xhigh
)
1396 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1397 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1398 NULL_RTX
, 0, OPTAB_DIRECT
);
1401 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1402 product_high
, 0, next_methods
);
1404 if (temp
!= 0 && temp
!= product_high
)
1405 emit_move_insn (product_high
, temp
);
1408 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1409 NULL_RTX
, 0, OPTAB_DIRECT
);
1412 temp
= expand_binop (word_mode
, add_optab
, temp
,
1413 product_high
, product_high
,
1416 if (temp
!= 0 && temp
!= product_high
)
1417 emit_move_insn (product_high
, temp
);
1421 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1423 temp
= emit_move_insn (product
, product
);
1424 set_unique_reg_note (temp
,
1426 gen_rtx_fmt_ee (MULT
, mode
,
1435 /* If we get here, we couldn't do it for some reason even though we
1436 originally thought we could. Delete anything we've emitted in
1439 delete_insns_since (last
);
1442 /* We need to open-code the complex type operations: '+, -, * and /' */
1444 /* At this point we allow operations between two similar complex
1445 numbers, and also if one of the operands is not a complex number
1446 but rather of MODE_FLOAT or MODE_INT. However, the caller
1447 must make sure that the MODE of the non-complex operand matches
1448 the SUBMODE of the complex operand. */
1450 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1452 rtx real0
= 0, imag0
= 0;
1453 rtx real1
= 0, imag1
= 0;
1454 rtx realr
, imagr
, res
;
1459 /* Find the correct mode for the real and imaginary parts */
1460 enum machine_mode submode
1461 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1462 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1465 if (submode
== BLKmode
)
1469 target
= gen_reg_rtx (mode
);
1473 realr
= gen_realpart (submode
, target
);
1474 imagr
= gen_imagpart (submode
, target
);
1476 if (GET_MODE (op0
) == mode
)
1478 real0
= gen_realpart (submode
, op0
);
1479 imag0
= gen_imagpart (submode
, op0
);
1484 if (GET_MODE (op1
) == mode
)
1486 real1
= gen_realpart (submode
, op1
);
1487 imag1
= gen_imagpart (submode
, op1
);
1492 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1495 switch (binoptab
->code
)
1498 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1500 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1501 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1502 realr
, unsignedp
, methods
);
1506 else if (res
!= realr
)
1507 emit_move_insn (realr
, res
);
1510 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1511 imagr
, unsignedp
, methods
);
1514 else if (binoptab
->code
== MINUS
)
1515 res
= expand_unop (submode
,
1516 binoptab
== subv_optab
? negv_optab
: neg_optab
,
1517 imag1
, imagr
, unsignedp
);
1523 else if (res
!= imagr
)
1524 emit_move_insn (imagr
, res
);
1530 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1536 /* Don't fetch these from memory more than once. */
1537 real0
= force_reg (submode
, real0
);
1538 real1
= force_reg (submode
, real1
);
1539 imag0
= force_reg (submode
, imag0
);
1540 imag1
= force_reg (submode
, imag1
);
1542 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1543 unsignedp
, methods
);
1545 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1546 unsignedp
, methods
);
1548 if (temp1
== 0 || temp2
== 0)
1553 binoptab
== smulv_optab
? subv_optab
: sub_optab
,
1554 temp1
, temp2
, realr
, unsignedp
, methods
));
1558 else if (res
!= realr
)
1559 emit_move_insn (realr
, res
);
1561 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1562 NULL_RTX
, unsignedp
, methods
);
1564 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1565 NULL_RTX
, unsignedp
, methods
);
1567 if (temp1
== 0 || temp2
== 0)
1572 binoptab
== smulv_optab
? addv_optab
: add_optab
,
1573 temp1
, temp2
, imagr
, unsignedp
, methods
));
1577 else if (res
!= imagr
)
1578 emit_move_insn (imagr
, res
);
1584 /* Don't fetch these from memory more than once. */
1585 real0
= force_reg (submode
, real0
);
1586 real1
= force_reg (submode
, real1
);
1588 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1589 realr
, unsignedp
, methods
);
1592 else if (res
!= realr
)
1593 emit_move_insn (realr
, res
);
1596 res
= expand_binop (submode
, binoptab
,
1597 real1
, imag0
, imagr
, unsignedp
, methods
);
1599 res
= expand_binop (submode
, binoptab
,
1600 real0
, imag1
, imagr
, unsignedp
, methods
);
1604 else if (res
!= imagr
)
1605 emit_move_insn (imagr
, res
);
1612 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1616 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1618 /* Don't fetch these from memory more than once. */
1619 real1
= force_reg (submode
, real1
);
1621 /* Simply divide the real and imaginary parts by `c' */
1622 if (class == MODE_COMPLEX_FLOAT
)
1623 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1624 realr
, unsignedp
, methods
);
1626 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1627 real0
, real1
, realr
, unsignedp
);
1631 else if (res
!= realr
)
1632 emit_move_insn (realr
, res
);
1634 if (class == MODE_COMPLEX_FLOAT
)
1635 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1636 imagr
, unsignedp
, methods
);
1638 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1639 imag0
, real1
, imagr
, unsignedp
);
1643 else if (res
!= imagr
)
1644 emit_move_insn (imagr
, res
);
1650 switch (flag_complex_divide_method
)
1653 ok
= expand_cmplxdiv_straight (real0
, real1
, imag0
, imag1
,
1654 realr
, imagr
, submode
,
1660 ok
= expand_cmplxdiv_wide (real0
, real1
, imag0
, imag1
,
1661 realr
, imagr
, submode
,
1681 if (binoptab
->code
!= UNKNOWN
)
1683 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
1684 copy_rtx (op0
), copy_rtx (op1
));
1688 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1694 /* It can't be open-coded in this mode.
1695 Use a library call if one is available and caller says that's ok. */
1697 if (binoptab
->handlers
[(int) mode
].libfunc
1698 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1702 enum machine_mode op1_mode
= mode
;
1709 op1_mode
= word_mode
;
1710 /* Specify unsigned here,
1711 since negative shift counts are meaningless. */
1712 op1x
= convert_to_mode (word_mode
, op1
, 1);
1715 if (GET_MODE (op0
) != VOIDmode
1716 && GET_MODE (op0
) != mode
)
1717 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1719 /* Pass 1 for NO_QUEUE so we don't lose any increments
1720 if the libcall is cse'd or moved. */
1721 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1722 NULL_RTX
, LCT_CONST
, mode
, 2,
1723 op0
, mode
, op1x
, op1_mode
);
1725 insns
= get_insns ();
1728 target
= gen_reg_rtx (mode
);
1729 emit_libcall_block (insns
, target
, value
,
1730 gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
));
1735 delete_insns_since (last
);
1737 /* It can't be done in this mode. Can we do it in a wider mode? */
1739 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1740 || methods
== OPTAB_MUST_WIDEN
))
1742 /* Caller says, don't even try. */
1743 delete_insns_since (entry_last
);
1747 /* Compute the value of METHODS to pass to recursive calls.
1748 Don't allow widening to be tried recursively. */
1750 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1752 /* Look for a wider mode of the same class for which it appears we can do
1755 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1757 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1758 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1760 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1761 != CODE_FOR_nothing
)
1762 || (methods
== OPTAB_LIB
1763 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1765 rtx xop0
= op0
, xop1
= op1
;
1768 /* For certain integer operations, we need not actually extend
1769 the narrow operands, as long as we will truncate
1770 the results to the same narrowness. */
1772 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1773 || binoptab
== xor_optab
1774 || binoptab
== add_optab
|| binoptab
== sub_optab
1775 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1776 && class == MODE_INT
)
1779 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1780 unsignedp
, no_extend
);
1782 /* The second operand of a shift must always be extended. */
1783 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1784 no_extend
&& binoptab
!= ashl_optab
);
1786 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1787 unsignedp
, methods
);
1790 if (class != MODE_INT
)
1793 target
= gen_reg_rtx (mode
);
1794 convert_move (target
, temp
, 0);
1798 return gen_lowpart (mode
, temp
);
1801 delete_insns_since (last
);
1806 delete_insns_since (entry_last
);
1810 /* Expand a binary operator which has both signed and unsigned forms.
1811 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1814 If we widen unsigned operands, we may use a signed wider operation instead
1815 of an unsigned wider operation, since the result would be the same. */
1818 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1819 enum machine_mode mode
;
1820 optab uoptab
, soptab
;
1821 rtx op0
, op1
, target
;
1823 enum optab_methods methods
;
1826 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1827 struct optab wide_soptab
;
1829 /* Do it without widening, if possible. */
1830 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1831 unsignedp
, OPTAB_DIRECT
);
1832 if (temp
|| methods
== OPTAB_DIRECT
)
1835 /* Try widening to a signed int. Make a fake signed optab that
1836 hides any signed insn for direct use. */
1837 wide_soptab
= *soptab
;
1838 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1839 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1841 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1842 unsignedp
, OPTAB_WIDEN
);
1844 /* For unsigned operands, try widening to an unsigned int. */
1845 if (temp
== 0 && unsignedp
)
1846 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1847 unsignedp
, OPTAB_WIDEN
);
1848 if (temp
|| methods
== OPTAB_WIDEN
)
1851 /* Use the right width lib call if that exists. */
1852 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1853 if (temp
|| methods
== OPTAB_LIB
)
1856 /* Must widen and use a lib call, use either signed or unsigned. */
1857 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1858 unsignedp
, methods
);
1862 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1863 unsignedp
, methods
);
1867 /* Generate code to perform an operation specified by BINOPTAB
1868 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1869 We assume that the order of the operands for the instruction
1870 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1871 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1873 Either TARG0 or TARG1 may be zero, but what that means is that
1874 the result is not actually wanted. We will generate it into
1875 a dummy pseudo-reg and discard it. They may not both be zero.
1877 Returns 1 if this operation can be performed; 0 if not. */
1880 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1886 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1887 enum mode_class
class;
1888 enum machine_mode wider_mode
;
1889 rtx entry_last
= get_last_insn ();
1892 class = GET_MODE_CLASS (mode
);
1894 op0
= protect_from_queue (op0
, 0);
1895 op1
= protect_from_queue (op1
, 0);
1899 op0
= force_not_mem (op0
);
1900 op1
= force_not_mem (op1
);
1903 /* If we are inside an appropriately-short loop and one operand is an
1904 expensive constant, force it into a register. */
1905 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1906 && rtx_cost (op0
, binoptab
->code
) > COSTS_N_INSNS (1))
1907 op0
= force_reg (mode
, op0
);
1909 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1910 && rtx_cost (op1
, binoptab
->code
) > COSTS_N_INSNS (1))
1911 op1
= force_reg (mode
, op1
);
1914 targ0
= protect_from_queue (targ0
, 1);
1916 targ0
= gen_reg_rtx (mode
);
1918 targ1
= protect_from_queue (targ1
, 1);
1920 targ1
= gen_reg_rtx (mode
);
1922 /* Record where to go back to if we fail. */
1923 last
= get_last_insn ();
1925 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1927 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1928 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1929 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1931 rtx xop0
= op0
, xop1
= op1
;
1933 /* In case this insn wants input operands in modes different from the
1934 result, convert the operands. */
1935 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1936 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1938 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1939 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1941 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1942 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
1943 xop0
= copy_to_mode_reg (mode0
, xop0
);
1945 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, mode1
))
1946 xop1
= copy_to_mode_reg (mode1
, xop1
);
1948 /* We could handle this, but we should always be called with a pseudo
1949 for our targets and all insns should take them as outputs. */
1950 if (! (*insn_data
[icode
].operand
[0].predicate
) (targ0
, mode
)
1951 || ! (*insn_data
[icode
].operand
[3].predicate
) (targ1
, mode
))
1954 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1961 delete_insns_since (last
);
1964 /* It can't be done in this mode. Can we do it in a wider mode? */
1966 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1968 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1969 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1971 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1972 != CODE_FOR_nothing
)
1974 register rtx t0
= gen_reg_rtx (wider_mode
);
1975 register rtx t1
= gen_reg_rtx (wider_mode
);
1977 if (expand_twoval_binop (binoptab
,
1978 convert_modes (wider_mode
, mode
, op0
,
1980 convert_modes (wider_mode
, mode
, op1
,
1984 convert_move (targ0
, t0
, unsignedp
);
1985 convert_move (targ1
, t1
, unsignedp
);
1989 delete_insns_since (last
);
1994 delete_insns_since (entry_last
);
1998 /* Generate code to perform an operation specified by UNOPTAB
1999 on operand OP0, with result having machine-mode MODE.
2001 UNSIGNEDP is for the case where we have to widen the operands
2002 to perform the operation. It says to use zero-extension.
2004 If TARGET is nonzero, the value
2005 is generated there, if it is convenient to do so.
2006 In all cases an rtx is returned for the locus of the value;
2007 this may or may not be TARGET. */
2010 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
2011 enum machine_mode mode
;
2017 enum mode_class
class;
2018 enum machine_mode wider_mode
;
2020 rtx last
= get_last_insn ();
2023 class = GET_MODE_CLASS (mode
);
2025 op0
= protect_from_queue (op0
, 0);
2029 op0
= force_not_mem (op0
);
2033 target
= protect_from_queue (target
, 1);
2035 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2037 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
2038 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2044 temp
= gen_reg_rtx (mode
);
2046 if (GET_MODE (xop0
) != VOIDmode
2047 && GET_MODE (xop0
) != mode0
)
2048 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2050 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2052 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
2053 xop0
= copy_to_mode_reg (mode0
, xop0
);
2055 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, mode
))
2056 temp
= gen_reg_rtx (mode
);
2058 pat
= GEN_FCN (icode
) (temp
, xop0
);
2061 if (GET_CODE (pat
) == SEQUENCE
2062 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
2064 delete_insns_since (last
);
2065 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2073 delete_insns_since (last
);
2076 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2078 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2079 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2080 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2082 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2086 /* For certain operations, we need not actually extend
2087 the narrow operand, as long as we will truncate the
2088 results to the same narrowness. */
2090 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2091 (unoptab
== neg_optab
2092 || unoptab
== one_cmpl_optab
)
2093 && class == MODE_INT
);
2095 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2100 if (class != MODE_INT
)
2103 target
= gen_reg_rtx (mode
);
2104 convert_move (target
, temp
, 0);
2108 return gen_lowpart (mode
, temp
);
2111 delete_insns_since (last
);
2115 /* These can be done a word at a time. */
2116 if (unoptab
== one_cmpl_optab
2117 && class == MODE_INT
2118 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2119 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
2124 if (target
== 0 || target
== op0
)
2125 target
= gen_reg_rtx (mode
);
2129 /* Do the actual arithmetic. */
2130 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
2132 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
2133 rtx x
= expand_unop (word_mode
, unoptab
,
2134 operand_subword_force (op0
, i
, mode
),
2135 target_piece
, unsignedp
);
2136 if (target_piece
!= x
)
2137 emit_move_insn (target_piece
, x
);
2140 insns
= get_insns ();
2143 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
2144 gen_rtx_fmt_e (unoptab
->code
, mode
,
2149 /* Open-code the complex negation operation. */
2150 else if (unoptab
->code
== NEG
2151 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
2157 /* Find the correct mode for the real and imaginary parts */
2158 enum machine_mode submode
2159 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2160 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2163 if (submode
== BLKmode
)
2167 target
= gen_reg_rtx (mode
);
2171 target_piece
= gen_imagpart (submode
, target
);
2172 x
= expand_unop (submode
, unoptab
,
2173 gen_imagpart (submode
, op0
),
2174 target_piece
, unsignedp
);
2175 if (target_piece
!= x
)
2176 emit_move_insn (target_piece
, x
);
2178 target_piece
= gen_realpart (submode
, target
);
2179 x
= expand_unop (submode
, unoptab
,
2180 gen_realpart (submode
, op0
),
2181 target_piece
, unsignedp
);
2182 if (target_piece
!= x
)
2183 emit_move_insn (target_piece
, x
);
2188 emit_no_conflict_block (seq
, target
, op0
, 0,
2189 gen_rtx_fmt_e (unoptab
->code
, mode
,
2194 /* Now try a library call in this mode. */
2195 if (unoptab
->handlers
[(int) mode
].libfunc
)
2202 /* Pass 1 for NO_QUEUE so we don't lose any increments
2203 if the libcall is cse'd or moved. */
2204 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
2205 NULL_RTX
, LCT_CONST
, mode
, 1, op0
, mode
);
2206 insns
= get_insns ();
2209 target
= gen_reg_rtx (mode
);
2210 emit_libcall_block (insns
, target
, value
,
2211 gen_rtx_fmt_e (unoptab
->code
, mode
, op0
));
2216 /* It can't be done in this mode. Can we do it in a wider mode? */
2218 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2220 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2221 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2223 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
2224 != CODE_FOR_nothing
)
2225 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
2229 /* For certain operations, we need not actually extend
2230 the narrow operand, as long as we will truncate the
2231 results to the same narrowness. */
2233 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2234 (unoptab
== neg_optab
2235 || unoptab
== one_cmpl_optab
)
2236 && class == MODE_INT
);
2238 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2243 if (class != MODE_INT
)
2246 target
= gen_reg_rtx (mode
);
2247 convert_move (target
, temp
, 0);
2251 return gen_lowpart (mode
, temp
);
2254 delete_insns_since (last
);
2259 /* If there is no negate operation, try doing a subtract from zero.
2260 The US Software GOFAST library needs this. */
2261 if (unoptab
->code
== NEG
)
2264 temp
= expand_binop (mode
,
2265 unoptab
== negv_optab
? subv_optab
: sub_optab
,
2266 CONST0_RTX (mode
), op0
,
2267 target
, unsignedp
, OPTAB_LIB_WIDEN
);
2275 /* Emit code to compute the absolute value of OP0, with result to
2276 TARGET if convenient. (TARGET may be 0.) The return value says
2277 where the result actually is to be found.
2279 MODE is the mode of the operand; the mode of the result is
2280 different but can be deduced from MODE.
2285 expand_abs (mode
, op0
, target
, result_unsignedp
, safe
)
2286 enum machine_mode mode
;
2289 int result_unsignedp
;
2295 result_unsignedp
= 1;
2297 /* First try to do it with a special abs instruction. */
2298 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
2303 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2304 if (smax_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2306 rtx last
= get_last_insn ();
2308 temp
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, 0);
2310 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
2316 delete_insns_since (last
);
2319 /* If this machine has expensive jumps, we can do integer absolute
2320 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2321 where W is the width of MODE. */
2323 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
2325 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
2326 size_int (GET_MODE_BITSIZE (mode
) - 1),
2329 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
2332 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
2333 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
2339 /* If that does not win, use conditional jump and negate. */
2341 /* It is safe to use the target if it is the same
2342 as the source if this is also a pseudo register */
2343 if (op0
== target
&& GET_CODE (op0
) == REG
2344 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
2347 op1
= gen_label_rtx ();
2348 if (target
== 0 || ! safe
2349 || GET_MODE (target
) != mode
2350 || (GET_CODE (target
) == MEM
&& MEM_VOLATILE_P (target
))
2351 || (GET_CODE (target
) == REG
2352 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
2353 target
= gen_reg_rtx (mode
);
2355 emit_move_insn (target
, op0
);
2358 /* If this mode is an integer too wide to compare properly,
2359 compare word by word. Rely on CSE to optimize constant cases. */
2360 if (GET_MODE_CLASS (mode
) == MODE_INT
2361 && ! can_compare_p (GE
, mode
, ccp_jump
))
2362 do_jump_by_parts_greater_rtx (mode
, 0, target
, const0_rtx
,
2365 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
2366 NULL_RTX
, 0, NULL_RTX
, op1
);
2368 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
2371 emit_move_insn (target
, op0
);
2377 /* Emit code to compute the absolute value of OP0, with result to
2378 TARGET if convenient. (TARGET may be 0.) The return value says
2379 where the result actually is to be found.
2381 MODE is the mode of the operand; the mode of the result is
2382 different but can be deduced from MODE.
2384 UNSIGNEDP is relevant for complex integer modes. */
2387 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2388 enum machine_mode mode
;
2393 enum mode_class
class = GET_MODE_CLASS (mode
);
2394 enum machine_mode wider_mode
;
2396 rtx entry_last
= get_last_insn ();
2399 optab this_abs_optab
;
2401 /* Find the correct mode for the real and imaginary parts. */
2402 enum machine_mode submode
2403 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2404 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2407 if (submode
== BLKmode
)
2410 op0
= protect_from_queue (op0
, 0);
2414 op0
= force_not_mem (op0
);
2417 last
= get_last_insn ();
2420 target
= protect_from_queue (target
, 1);
2422 this_abs_optab
= ! unsignedp
&& flag_trapv
2423 && (GET_MODE_CLASS(mode
) == MODE_INT
)
2424 ? absv_optab
: abs_optab
;
2426 if (this_abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2428 int icode
= (int) this_abs_optab
->handlers
[(int) mode
].insn_code
;
2429 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2435 temp
= gen_reg_rtx (submode
);
2437 if (GET_MODE (xop0
) != VOIDmode
2438 && GET_MODE (xop0
) != mode0
)
2439 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2441 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2443 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
2444 xop0
= copy_to_mode_reg (mode0
, xop0
);
2446 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, submode
))
2447 temp
= gen_reg_rtx (submode
);
2449 pat
= GEN_FCN (icode
) (temp
, xop0
);
2452 if (GET_CODE (pat
) == SEQUENCE
2453 && ! add_equal_note (pat
, temp
, this_abs_optab
->code
, xop0
,
2456 delete_insns_since (last
);
2457 return expand_unop (mode
, this_abs_optab
, op0
, NULL_RTX
,
2466 delete_insns_since (last
);
2469 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2471 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2472 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2474 if (this_abs_optab
->handlers
[(int) wider_mode
].insn_code
2475 != CODE_FOR_nothing
)
2479 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2480 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2484 if (class != MODE_COMPLEX_INT
)
2487 target
= gen_reg_rtx (submode
);
2488 convert_move (target
, temp
, 0);
2492 return gen_lowpart (submode
, temp
);
2495 delete_insns_since (last
);
2499 /* Open-code the complex absolute-value operation
2500 if we can open-code sqrt. Otherwise it's not worth while. */
2501 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
2504 rtx real
, imag
, total
;
2506 real
= gen_realpart (submode
, op0
);
2507 imag
= gen_imagpart (submode
, op0
);
2509 /* Square both parts. */
2510 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2511 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2513 /* Sum the parts. */
2514 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2515 0, OPTAB_LIB_WIDEN
);
2517 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2518 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2520 delete_insns_since (last
);
2525 /* Now try a library call in this mode. */
2526 if (this_abs_optab
->handlers
[(int) mode
].libfunc
)
2533 /* Pass 1 for NO_QUEUE so we don't lose any increments
2534 if the libcall is cse'd or moved. */
2535 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2536 NULL_RTX
, LCT_CONST
, submode
, 1, op0
, mode
);
2537 insns
= get_insns ();
2540 target
= gen_reg_rtx (submode
);
2541 emit_libcall_block (insns
, target
, value
,
2542 gen_rtx_fmt_e (this_abs_optab
->code
, mode
, op0
));
2547 /* It can't be done in this mode. Can we do it in a wider mode? */
2549 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2550 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2552 if ((this_abs_optab
->handlers
[(int) wider_mode
].insn_code
2553 != CODE_FOR_nothing
)
2554 || this_abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2558 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2560 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2564 if (class != MODE_COMPLEX_INT
)
2567 target
= gen_reg_rtx (submode
);
2568 convert_move (target
, temp
, 0);
2572 return gen_lowpart (submode
, temp
);
2575 delete_insns_since (last
);
2579 delete_insns_since (entry_last
);
2583 /* Generate an instruction whose insn-code is INSN_CODE,
2584 with two operands: an output TARGET and an input OP0.
2585 TARGET *must* be nonzero, and the output is always stored there.
2586 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2587 the value that is stored into TARGET. */
2590 emit_unop_insn (icode
, target
, op0
, code
)
2597 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2600 temp
= target
= protect_from_queue (target
, 1);
2602 op0
= protect_from_queue (op0
, 0);
2604 /* Sign and zero extension from memory is often done specially on
2605 RISC machines, so forcing into a register here can pessimize
2607 if (flag_force_mem
&& code
!= SIGN_EXTEND
&& code
!= ZERO_EXTEND
)
2608 op0
= force_not_mem (op0
);
2610 /* Now, if insn does not accept our operands, put them into pseudos. */
2612 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2613 op0
= copy_to_mode_reg (mode0
, op0
);
2615 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, GET_MODE (temp
))
2616 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2617 temp
= gen_reg_rtx (GET_MODE (temp
));
2619 pat
= GEN_FCN (icode
) (temp
, op0
);
2621 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2622 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2627 emit_move_insn (target
, temp
);
2630 /* Emit code to perform a series of operations on a multi-word quantity, one
2633 Such a block is preceded by a CLOBBER of the output, consists of multiple
2634 insns, each setting one word of the output, and followed by a SET copying
2635 the output to itself.
2637 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2638 note indicating that it doesn't conflict with the (also multi-word)
2639 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2642 INSNS is a block of code generated to perform the operation, not including
2643 the CLOBBER and final copy. All insns that compute intermediate values
2644 are first emitted, followed by the block as described above.
2646 TARGET, OP0, and OP1 are the output and inputs of the operations,
2647 respectively. OP1 may be zero for a unary operation.
2649 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2652 If TARGET is not a register, INSNS is simply emitted with no special
2653 processing. Likewise if anything in INSNS is not an INSN or if
2654 there is a libcall block inside INSNS.
2656 The final insn emitted is returned. */
2659 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2665 rtx prev
, next
, first
, last
, insn
;
2667 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2668 return emit_insns (insns
);
2670 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2671 if (GET_CODE (insn
) != INSN
2672 || find_reg_note (insn
, REG_LIBCALL
, NULL_RTX
))
2673 return emit_insns (insns
);
2675 /* First emit all insns that do not store into words of the output and remove
2676 these from the list. */
2677 for (insn
= insns
; insn
; insn
= next
)
2682 next
= NEXT_INSN (insn
);
2684 if (GET_CODE (PATTERN (insn
)) == SET
|| GET_CODE (PATTERN (insn
)) == USE
2685 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
2686 set
= PATTERN (insn
);
2687 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2689 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2690 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2692 set
= XVECEXP (PATTERN (insn
), 0, i
);
2700 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2702 if (PREV_INSN (insn
))
2703 NEXT_INSN (PREV_INSN (insn
)) = next
;
2708 PREV_INSN (next
) = PREV_INSN (insn
);
2714 prev
= get_last_insn ();
2716 /* Now write the CLOBBER of the output, followed by the setting of each
2717 of the words, followed by the final copy. */
2718 if (target
!= op0
&& target
!= op1
)
2719 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
2721 for (insn
= insns
; insn
; insn
= next
)
2723 next
= NEXT_INSN (insn
);
2726 if (op1
&& GET_CODE (op1
) == REG
)
2727 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op1
,
2730 if (op0
&& GET_CODE (op0
) == REG
)
2731 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op0
,
2735 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2736 != CODE_FOR_nothing
)
2738 last
= emit_move_insn (target
, target
);
2740 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
2744 last
= get_last_insn ();
2746 /* Remove any existing REG_EQUAL note from "last", or else it will
2747 be mistaken for a note referring to the full contents of the
2748 alleged libcall value when found together with the REG_RETVAL
2749 note added below. An existing note can come from an insn
2750 expansion at "last". */
2751 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
2755 first
= get_insns ();
2757 first
= NEXT_INSN (prev
);
2759 /* Encapsulate the block so it gets manipulated as a unit. */
2760 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2762 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2767 /* Emit code to make a call to a constant function or a library call.
2769 INSNS is a list containing all insns emitted in the call.
2770 These insns leave the result in RESULT. Our block is to copy RESULT
2771 to TARGET, which is logically equivalent to EQUIV.
2773 We first emit any insns that set a pseudo on the assumption that these are
2774 loading constants into registers; doing so allows them to be safely cse'ed
2775 between blocks. Then we emit all the other insns in the block, followed by
2776 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2777 note with an operand of EQUIV.
2779 Moving assignments to pseudos outside of the block is done to improve
2780 the generated code, but is not required to generate correct code,
2781 hence being unable to move an assignment is not grounds for not making
2782 a libcall block. There are two reasons why it is safe to leave these
2783 insns inside the block: First, we know that these pseudos cannot be
2784 used in generated RTL outside the block since they are created for
2785 temporary purposes within the block. Second, CSE will not record the
2786 values of anything set inside a libcall block, so we know they must
2787 be dead at the end of the block.
2789 Except for the first group of insns (the ones setting pseudos), the
2790 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2793 emit_libcall_block (insns
, target
, result
, equiv
)
2799 rtx final_dest
= target
;
2800 rtx prev
, next
, first
, last
, insn
;
2802 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2803 into a MEM later. Protect the libcall block from this change. */
2804 if (! REG_P (target
) || REG_USERVAR_P (target
))
2805 target
= gen_reg_rtx (GET_MODE (target
));
2807 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2808 reg note to indicate that this call cannot throw or execute a nonlocal
2809 goto (unless there is already a REG_EH_REGION note, in which case
2810 we update it). Also set the CONST_CALL_P flag. */
2812 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2813 if (GET_CODE (insn
) == CALL_INSN
)
2815 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
2817 CONST_CALL_P (insn
) = 1;
2819 XEXP (note
, 0) = GEN_INT (-1);
2821 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_EH_REGION
, GEN_INT (-1),
2825 /* First emit all insns that set pseudos. Remove them from the list as
2826 we go. Avoid insns that set pseudos which were referenced in previous
2827 insns. These can be generated by move_by_pieces, for example,
2828 to update an address. Similarly, avoid insns that reference things
2829 set in previous insns. */
2831 for (insn
= insns
; insn
; insn
= next
)
2833 rtx set
= single_set (insn
);
2835 next
= NEXT_INSN (insn
);
2837 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2838 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2840 || ((! INSN_P(insns
)
2841 || ! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
)))
2842 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2843 && ! modified_in_p (SET_SRC (set
), insns
)
2844 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2846 if (PREV_INSN (insn
))
2847 NEXT_INSN (PREV_INSN (insn
)) = next
;
2852 PREV_INSN (next
) = PREV_INSN (insn
);
2858 prev
= get_last_insn ();
2860 /* Write the remaining insns followed by the final copy. */
2862 for (insn
= insns
; insn
; insn
= next
)
2864 next
= NEXT_INSN (insn
);
2869 last
= emit_move_insn (target
, result
);
2870 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2871 != CODE_FOR_nothing
)
2872 set_unique_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
));
2875 /* Remove any existing REG_EQUAL note from "last", or else it will
2876 be mistaken for a note referring to the full contents of the
2877 libcall value when found together with the REG_RETVAL note added
2878 below. An existing note can come from an insn expansion at
2880 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
2883 if (final_dest
!= target
)
2884 emit_move_insn (final_dest
, target
);
2887 first
= get_insns ();
2889 first
= NEXT_INSN (prev
);
2891 /* Encapsulate the block so it gets manipulated as a unit. */
2892 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2894 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2897 /* Generate code to store zero in X. */
2903 emit_move_insn (x
, const0_rtx
);
2906 /* Generate code to store 1 in X
2907 assuming it contains zero beforehand. */
2910 emit_0_to_1_insn (x
)
2913 emit_move_insn (x
, const1_rtx
);
2916 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2917 PURPOSE describes how this comparison will be used. CODE is the rtx
2918 comparison code we will be using.
2920 ??? Actually, CODE is slightly weaker than that. A target is still
2921 required to implement all of the normal bcc operations, but not
2922 required to implement all (or any) of the unordered bcc operations. */
2925 can_compare_p (code
, mode
, purpose
)
2927 enum machine_mode mode
;
2928 enum can_compare_purpose purpose
;
2932 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2934 if (purpose
== ccp_jump
)
2935 return bcc_gen_fctn
[(int)code
] != NULL
;
2936 else if (purpose
== ccp_store_flag
)
2937 return setcc_gen_code
[(int)code
] != CODE_FOR_nothing
;
2939 /* There's only one cmov entry point, and it's allowed to fail. */
2942 if (purpose
== ccp_jump
2943 && cbranch_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2945 if (purpose
== ccp_cmov
2946 && cmov_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2948 if (purpose
== ccp_store_flag
2949 && cstore_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2952 mode
= GET_MODE_WIDER_MODE (mode
);
2954 while (mode
!= VOIDmode
);
2959 /* This function is called when we are going to emit a compare instruction that
2960 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2962 *PMODE is the mode of the inputs (in case they are const_int).
2963 *PUNSIGNEDP nonzero says that the operands are unsigned;
2964 this matters if they need to be widened.
2966 If they have mode BLKmode, then SIZE specifies the size of both operands,
2967 and ALIGN specifies the known shared alignment of the operands.
2969 This function performs all the setup necessary so that the caller only has
2970 to emit a single comparison insn. This setup can involve doing a BLKmode
2971 comparison or emitting a library call to perform the comparison if no insn
2972 is available to handle it.
2973 The values which are passed in through pointers can be modified; the caller
2974 should perform the comparison on the modified values. */
2977 prepare_cmp_insn (px
, py
, pcomparison
, size
, pmode
, punsignedp
, align
,
2980 enum rtx_code
*pcomparison
;
2982 enum machine_mode
*pmode
;
2984 int align ATTRIBUTE_UNUSED
;
2985 enum can_compare_purpose purpose
;
2987 enum machine_mode mode
= *pmode
;
2988 rtx x
= *px
, y
= *py
;
2989 int unsignedp
= *punsignedp
;
2990 enum mode_class
class;
2991 rtx opalign ATTRIBUTE_UNUSED
= GEN_INT (align
/ BITS_PER_UNIT
);;
2993 class = GET_MODE_CLASS (mode
);
2995 /* They could both be VOIDmode if both args are immediate constants,
2996 but we should fold that at an earlier stage.
2997 With no special code here, this will call abort,
2998 reminding the programmer to implement such folding. */
3000 if (mode
!= BLKmode
&& flag_force_mem
)
3002 x
= force_not_mem (x
);
3003 y
= force_not_mem (y
);
3006 /* If we are inside an appropriately-short loop and one operand is an
3007 expensive constant, force it into a register. */
3008 if (CONSTANT_P (x
) && preserve_subexpressions_p ()
3009 && rtx_cost (x
, COMPARE
) > COSTS_N_INSNS (1))
3010 x
= force_reg (mode
, x
);
3012 if (CONSTANT_P (y
) && preserve_subexpressions_p ()
3013 && rtx_cost (y
, COMPARE
) > COSTS_N_INSNS (1))
3014 y
= force_reg (mode
, y
);
3017 /* Abort if we have a non-canonical comparison. The RTL documentation
3018 states that canonical comparisons are required only for targets which
3020 if (CONSTANT_P (x
) && ! CONSTANT_P (y
))
3024 /* Don't let both operands fail to indicate the mode. */
3025 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
3026 x
= force_reg (mode
, x
);
3028 /* Handle all BLKmode compares. */
3030 if (mode
== BLKmode
)
3033 enum machine_mode result_mode
;
3036 x
= protect_from_queue (x
, 0);
3037 y
= protect_from_queue (y
, 0);
3041 #ifdef HAVE_cmpstrqi
3043 && GET_CODE (size
) == CONST_INT
3044 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
3046 result_mode
= insn_data
[(int) CODE_FOR_cmpstrqi
].operand
[0].mode
;
3047 result
= gen_reg_rtx (result_mode
);
3048 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, opalign
));
3052 #ifdef HAVE_cmpstrhi
3054 && GET_CODE (size
) == CONST_INT
3055 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
3057 result_mode
= insn_data
[(int) CODE_FOR_cmpstrhi
].operand
[0].mode
;
3058 result
= gen_reg_rtx (result_mode
);
3059 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, opalign
));
3063 #ifdef HAVE_cmpstrsi
3066 result_mode
= insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3067 result
= gen_reg_rtx (result_mode
);
3068 size
= protect_from_queue (size
, 0);
3069 emit_insn (gen_cmpstrsi (result
, x
, y
,
3070 convert_to_mode (SImode
, size
, 1),
3076 #ifdef TARGET_MEM_FUNCTIONS
3077 emit_library_call (memcmp_libfunc
, LCT_PURE_MAKE_BLOCK
,
3078 TYPE_MODE (integer_type_node
), 3,
3079 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
3080 convert_to_mode (TYPE_MODE (sizetype
), size
,
3081 TREE_UNSIGNED (sizetype
)),
3082 TYPE_MODE (sizetype
));
3084 emit_library_call (bcmp_libfunc
, LCT_PURE_MAKE_BLOCK
,
3085 TYPE_MODE (integer_type_node
), 3,
3086 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
3087 convert_to_mode (TYPE_MODE (integer_type_node
),
3089 TREE_UNSIGNED (integer_type_node
)),
3090 TYPE_MODE (integer_type_node
));
3093 /* Immediately move the result of the libcall into a pseudo
3094 register so reload doesn't clobber the value if it needs
3095 the return register for a spill reg. */
3096 result
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
3097 result_mode
= TYPE_MODE (integer_type_node
);
3098 emit_move_insn (result
,
3099 hard_libcall_value (result_mode
));
3103 *pmode
= result_mode
;
3109 if (can_compare_p (*pcomparison
, mode
, purpose
))
3112 /* Handle a lib call just for the mode we are using. */
3114 if (cmp_optab
->handlers
[(int) mode
].libfunc
&& class != MODE_FLOAT
)
3116 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
3119 /* If we want unsigned, and this mode has a distinct unsigned
3120 comparison routine, use that. */
3121 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
3122 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
3124 emit_library_call (libfunc
, 1,
3125 word_mode
, 2, x
, mode
, y
, mode
);
3127 /* Immediately move the result of the libcall into a pseudo
3128 register so reload doesn't clobber the value if it needs
3129 the return register for a spill reg. */
3130 result
= gen_reg_rtx (word_mode
);
3131 emit_move_insn (result
, hard_libcall_value (word_mode
));
3133 /* Integer comparison returns a result that must be compared against 1,
3134 so that even if we do an unsigned compare afterward,
3135 there is still a value that can represent the result "less than". */
3142 if (class == MODE_FLOAT
)
3143 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
);
3149 /* Before emitting an insn with code ICODE, make sure that X, which is going
3150 to be used for operand OPNUM of the insn, is converted from mode MODE to
3151 WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3152 that it is accepted by the operand predicate. Return the new value. */
3155 prepare_operand (icode
, x
, opnum
, mode
, wider_mode
, unsignedp
)
3159 enum machine_mode mode
, wider_mode
;
3162 x
= protect_from_queue (x
, 0);
3164 if (mode
!= wider_mode
)
3165 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
3167 if (! (*insn_data
[icode
].operand
[opnum
].predicate
)
3168 (x
, insn_data
[icode
].operand
[opnum
].mode
))
3169 x
= copy_to_mode_reg (insn_data
[icode
].operand
[opnum
].mode
, x
);
3173 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3174 we can do the comparison.
3175 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3176 be NULL_RTX which indicates that only a comparison is to be generated. */
3179 emit_cmp_and_jump_insn_1 (x
, y
, mode
, comparison
, unsignedp
, label
)
3181 enum machine_mode mode
;
3182 enum rtx_code comparison
;
3186 rtx test
= gen_rtx_fmt_ee (comparison
, mode
, x
, y
);
3187 enum mode_class
class = GET_MODE_CLASS (mode
);
3188 enum machine_mode wider_mode
= mode
;
3190 /* Try combined insns first. */
3193 enum insn_code icode
;
3194 PUT_MODE (test
, wider_mode
);
3198 icode
= cbranch_optab
->handlers
[(int)wider_mode
].insn_code
;
3200 if (icode
!= CODE_FOR_nothing
3201 && (*insn_data
[icode
].operand
[0].predicate
) (test
, wider_mode
))
3203 x
= prepare_operand (icode
, x
, 1, mode
, wider_mode
, unsignedp
);
3204 y
= prepare_operand (icode
, y
, 2, mode
, wider_mode
, unsignedp
);
3205 emit_jump_insn (GEN_FCN (icode
) (test
, x
, y
, label
));
3210 /* Handle some compares against zero. */
3211 icode
= (int) tst_optab
->handlers
[(int) wider_mode
].insn_code
;
3212 if (y
== CONST0_RTX (mode
) && icode
!= CODE_FOR_nothing
)
3214 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
3215 emit_insn (GEN_FCN (icode
) (x
));
3217 emit_jump_insn ((*bcc_gen_fctn
[(int) comparison
]) (label
));
3221 /* Handle compares for which there is a directly suitable insn. */
3223 icode
= (int) cmp_optab
->handlers
[(int) wider_mode
].insn_code
;
3224 if (icode
!= CODE_FOR_nothing
)
3226 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
3227 y
= prepare_operand (icode
, y
, 1, mode
, wider_mode
, unsignedp
);
3228 emit_insn (GEN_FCN (icode
) (x
, y
));
3230 emit_jump_insn ((*bcc_gen_fctn
[(int) comparison
]) (label
));
3234 if (class != MODE_INT
&& class != MODE_FLOAT
3235 && class != MODE_COMPLEX_FLOAT
)
3238 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
);
3239 } while (wider_mode
!= VOIDmode
);
3244 /* Generate code to compare X with Y so that the condition codes are
3245 set and to jump to LABEL if the condition is true. If X is a
3246 constant and Y is not a constant, then the comparison is swapped to
3247 ensure that the comparison RTL has the canonical form.
3249 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3250 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3251 the proper branch condition code.
3253 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3254 and ALIGN specifies the known shared alignment of X and Y.
3256 MODE is the mode of the inputs (in case they are const_int).
3258 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3259 be passed unchanged to emit_cmp_insn, then potentially converted into an
3260 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3263 emit_cmp_and_jump_insns (x
, y
, comparison
, size
, mode
, unsignedp
, align
, label
)
3265 enum rtx_code comparison
;
3267 enum machine_mode mode
;
3275 if ((CONSTANT_P (x
) && ! CONSTANT_P (y
))
3276 || (GET_CODE (x
) == CONST_INT
&& GET_CODE (y
) != CONST_INT
))
3278 /* Swap operands and condition to ensure canonical RTL. */
3281 comparison
= swap_condition (comparison
);
3290 /* If OP0 is still a constant, then both X and Y must be constants. Force
3291 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3293 if (CONSTANT_P (op0
))
3294 op0
= force_reg (mode
, op0
);
3299 comparison
= unsigned_condition (comparison
);
3300 prepare_cmp_insn (&op0
, &op1
, &comparison
, size
, &mode
, &unsignedp
, align
,
3302 emit_cmp_and_jump_insn_1 (op0
, op1
, mode
, comparison
, unsignedp
, label
);
3305 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3308 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
3310 enum rtx_code comparison
;
3312 enum machine_mode mode
;
3316 emit_cmp_and_jump_insns (x
, y
, comparison
, size
, mode
, unsignedp
, align
, 0);
3319 /* Emit a library call comparison between floating point X and Y.
3320 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3323 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
)
3325 enum rtx_code
*pcomparison
;
3326 enum machine_mode
*pmode
;
3329 enum rtx_code comparison
= *pcomparison
;
3330 rtx x
= *px
= protect_from_queue (*px
, 0);
3331 rtx y
= *py
= protect_from_queue (*py
, 0);
3332 enum machine_mode mode
= GET_MODE (x
);
3340 libfunc
= eqhf2_libfunc
;
3344 libfunc
= nehf2_libfunc
;
3348 libfunc
= gthf2_libfunc
;
3352 libfunc
= gehf2_libfunc
;
3356 libfunc
= lthf2_libfunc
;
3360 libfunc
= lehf2_libfunc
;
3364 libfunc
= unordhf2_libfunc
;
3370 else if (mode
== SFmode
)
3374 libfunc
= eqsf2_libfunc
;
3378 libfunc
= nesf2_libfunc
;
3382 libfunc
= gtsf2_libfunc
;
3386 libfunc
= gesf2_libfunc
;
3390 libfunc
= ltsf2_libfunc
;
3394 libfunc
= lesf2_libfunc
;
3398 libfunc
= unordsf2_libfunc
;
3404 else if (mode
== DFmode
)
3408 libfunc
= eqdf2_libfunc
;
3412 libfunc
= nedf2_libfunc
;
3416 libfunc
= gtdf2_libfunc
;
3420 libfunc
= gedf2_libfunc
;
3424 libfunc
= ltdf2_libfunc
;
3428 libfunc
= ledf2_libfunc
;
3432 libfunc
= unorddf2_libfunc
;
3438 else if (mode
== XFmode
)
3442 libfunc
= eqxf2_libfunc
;
3446 libfunc
= nexf2_libfunc
;
3450 libfunc
= gtxf2_libfunc
;
3454 libfunc
= gexf2_libfunc
;
3458 libfunc
= ltxf2_libfunc
;
3462 libfunc
= lexf2_libfunc
;
3466 libfunc
= unordxf2_libfunc
;
3472 else if (mode
== TFmode
)
3476 libfunc
= eqtf2_libfunc
;
3480 libfunc
= netf2_libfunc
;
3484 libfunc
= gttf2_libfunc
;
3488 libfunc
= getf2_libfunc
;
3492 libfunc
= lttf2_libfunc
;
3496 libfunc
= letf2_libfunc
;
3500 libfunc
= unordtf2_libfunc
;
3508 enum machine_mode wider_mode
;
3510 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
3511 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3513 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
3514 != CODE_FOR_nothing
)
3515 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
3517 x
= protect_from_queue (x
, 0);
3518 y
= protect_from_queue (y
, 0);
3519 *px
= convert_to_mode (wider_mode
, x
, 0);
3520 *py
= convert_to_mode (wider_mode
, y
, 0);
3521 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
);
3531 emit_library_call (libfunc
, LCT_CONST_MAKE_BLOCK
, word_mode
, 2, x
, mode
, y
,
3534 /* Immediately move the result of the libcall into a pseudo
3535 register so reload doesn't clobber the value if it needs
3536 the return register for a spill reg. */
3537 result
= gen_reg_rtx (word_mode
);
3538 emit_move_insn (result
, hard_libcall_value (word_mode
));
3542 if (comparison
== UNORDERED
)
3544 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3545 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
3551 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3554 emit_indirect_jump (loc
)
3557 if (! ((*insn_data
[(int)CODE_FOR_indirect_jump
].operand
[0].predicate
)
3559 loc
= copy_to_mode_reg (Pmode
, loc
);
3561 emit_jump_insn (gen_indirect_jump (loc
));
3565 #ifdef HAVE_conditional_move
3567 /* Emit a conditional move instruction if the machine supports one for that
3568 condition and machine mode.
3570 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3571 the mode to use should they be constants. If it is VOIDmode, they cannot
3574 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3575 should be stored there. MODE is the mode to use should they be constants.
3576 If it is VOIDmode, they cannot both be constants.
3578 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3579 is not supported. */
3582 emit_conditional_move (target
, code
, op0
, op1
, cmode
, op2
, op3
, mode
,
3587 enum machine_mode cmode
;
3589 enum machine_mode mode
;
3592 rtx tem
, subtarget
, comparison
, insn
;
3593 enum insn_code icode
;
3595 /* If one operand is constant, make it the second one. Only do this
3596 if the other operand is not constant as well. */
3598 if ((CONSTANT_P (op0
) && ! CONSTANT_P (op1
))
3599 || (GET_CODE (op0
) == CONST_INT
&& GET_CODE (op1
) != CONST_INT
))
3604 code
= swap_condition (code
);
3607 /* get_condition will prefer to generate LT and GT even if the old
3608 comparison was against zero, so undo that canonicalization here since
3609 comparisons against zero are cheaper. */
3610 if (code
== LT
&& GET_CODE (op1
) == CONST_INT
&& INTVAL (op1
) == 1)
3611 code
= LE
, op1
= const0_rtx
;
3612 else if (code
== GT
&& GET_CODE (op1
) == CONST_INT
&& INTVAL (op1
) == -1)
3613 code
= GE
, op1
= const0_rtx
;
3615 if (cmode
== VOIDmode
)
3616 cmode
= GET_MODE (op0
);
3618 if (((CONSTANT_P (op2
) && ! CONSTANT_P (op3
))
3619 || (GET_CODE (op2
) == CONST_INT
&& GET_CODE (op3
) != CONST_INT
))
3620 && (GET_MODE_CLASS (GET_MODE (op1
)) != MODE_FLOAT
3621 || TARGET_FLOAT_FORMAT
!= IEEE_FLOAT_FORMAT
3622 || flag_unsafe_math_optimizations
))
3627 code
= reverse_condition (code
);
3630 if (mode
== VOIDmode
)
3631 mode
= GET_MODE (op2
);
3633 icode
= movcc_gen_code
[mode
];
3635 if (icode
== CODE_FOR_nothing
)
3640 op2
= force_not_mem (op2
);
3641 op3
= force_not_mem (op3
);
3645 target
= protect_from_queue (target
, 1);
3647 target
= gen_reg_rtx (mode
);
3653 op2
= protect_from_queue (op2
, 0);
3654 op3
= protect_from_queue (op3
, 0);
3656 /* If the insn doesn't accept these operands, put them in pseudos. */
3658 if (! (*insn_data
[icode
].operand
[0].predicate
)
3659 (subtarget
, insn_data
[icode
].operand
[0].mode
))
3660 subtarget
= gen_reg_rtx (insn_data
[icode
].operand
[0].mode
);
3662 if (! (*insn_data
[icode
].operand
[2].predicate
)
3663 (op2
, insn_data
[icode
].operand
[2].mode
))
3664 op2
= copy_to_mode_reg (insn_data
[icode
].operand
[2].mode
, op2
);
3666 if (! (*insn_data
[icode
].operand
[3].predicate
)
3667 (op3
, insn_data
[icode
].operand
[3].mode
))
3668 op3
= copy_to_mode_reg (insn_data
[icode
].operand
[3].mode
, op3
);
3670 /* Everything should now be in the suitable form, so emit the compare insn
3671 and then the conditional move. */
3674 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
, 0);
3676 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3677 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3678 return NULL and let the caller figure out how best to deal with this
3680 if (GET_CODE (comparison
) != code
)
3683 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
3685 /* If that failed, then give up. */
3691 if (subtarget
!= target
)
3692 convert_move (target
, subtarget
, 0);
3697 /* Return non-zero if a conditional move of mode MODE is supported.
3699 This function is for combine so it can tell whether an insn that looks
3700 like a conditional move is actually supported by the hardware. If we
3701 guess wrong we lose a bit on optimization, but that's it. */
3702 /* ??? sparc64 supports conditionally moving integers values based on fp
3703 comparisons, and vice versa. How do we handle them? */
3706 can_conditionally_move_p (mode
)
3707 enum machine_mode mode
;
3709 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
3715 #endif /* HAVE_conditional_move */
3717 /* These three functions generate an insn body and return it
3718 rather than emitting the insn.
3720 They do not protect from queued increments,
3721 because they may be used 1) in protect_from_queue itself
3722 and 2) in other passes where there is no queue. */
3724 /* Generate and return an insn body to add Y to X. */
3727 gen_add2_insn (x
, y
)
3730 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3732 if (! ((*insn_data
[icode
].operand
[0].predicate
)
3733 (x
, insn_data
[icode
].operand
[0].mode
))
3734 || ! ((*insn_data
[icode
].operand
[1].predicate
)
3735 (x
, insn_data
[icode
].operand
[1].mode
))
3736 || ! ((*insn_data
[icode
].operand
[2].predicate
)
3737 (y
, insn_data
[icode
].operand
[2].mode
)))
3740 return (GEN_FCN (icode
) (x
, x
, y
));
3744 have_add2_insn (mode
)
3745 enum machine_mode mode
;
3747 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3750 /* Generate and return an insn body to subtract Y from X. */
3753 gen_sub2_insn (x
, y
)
3756 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3758 if (! ((*insn_data
[icode
].operand
[0].predicate
)
3759 (x
, insn_data
[icode
].operand
[0].mode
))
3760 || ! ((*insn_data
[icode
].operand
[1].predicate
)
3761 (x
, insn_data
[icode
].operand
[1].mode
))
3762 || ! ((*insn_data
[icode
].operand
[2].predicate
)
3763 (y
, insn_data
[icode
].operand
[2].mode
)))
3766 return (GEN_FCN (icode
) (x
, x
, y
));
3770 have_sub2_insn (mode
)
3771 enum machine_mode mode
;
3773 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3776 /* Generate the body of an instruction to copy Y into X.
3777 It may be a SEQUENCE, if one insn isn't enough. */
3780 gen_move_insn (x
, y
)
3783 register enum machine_mode mode
= GET_MODE (x
);
3784 enum insn_code insn_code
;
3787 if (mode
== VOIDmode
)
3788 mode
= GET_MODE (y
);
3790 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
3792 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3793 find a mode to do it in. If we have a movcc, use it. Otherwise,
3794 find the MODE_INT mode of the same width. */
3796 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
3798 enum machine_mode tmode
= VOIDmode
;
3802 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
3805 for (tmode
= QImode
; tmode
!= VOIDmode
;
3806 tmode
= GET_MODE_WIDER_MODE (tmode
))
3807 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
3810 if (tmode
== VOIDmode
)
3813 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3814 may call change_address which is not appropriate if we were
3815 called when a reload was in progress. We don't have to worry
3816 about changing the address since the size in bytes is supposed to
3817 be the same. Copy the MEM to change the mode and move any
3818 substitutions from the old MEM to the new one. */
3820 if (reload_in_progress
)
3822 x
= gen_lowpart_common (tmode
, x1
);
3823 if (x
== 0 && GET_CODE (x1
) == MEM
)
3825 x
= gen_rtx_MEM (tmode
, XEXP (x1
, 0));
3826 MEM_COPY_ATTRIBUTES (x
, x1
);
3827 copy_replacements (x1
, x
);
3830 y
= gen_lowpart_common (tmode
, y1
);
3831 if (y
== 0 && GET_CODE (y1
) == MEM
)
3833 y
= gen_rtx_MEM (tmode
, XEXP (y1
, 0));
3834 MEM_COPY_ATTRIBUTES (y
, y1
);
3835 copy_replacements (y1
, y
);
3840 x
= gen_lowpart (tmode
, x
);
3841 y
= gen_lowpart (tmode
, y
);
3844 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3845 return (GEN_FCN (insn_code
) (x
, y
));
3849 emit_move_insn_1 (x
, y
);
3850 seq
= gen_sequence ();
3855 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3856 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3857 no such operation exists, CODE_FOR_nothing will be returned. */
3860 can_extend_p (to_mode
, from_mode
, unsignedp
)
3861 enum machine_mode to_mode
, from_mode
;
3864 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
!= 0];
3867 /* Generate the body of an insn to extend Y (with mode MFROM)
3868 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3871 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3873 enum machine_mode mto
, mfrom
;
3876 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
!= 0]) (x
, y
));
3879 /* can_fix_p and can_float_p say whether the target machine
3880 can directly convert a given fixed point type to
3881 a given floating point type, or vice versa.
3882 The returned value is the CODE_FOR_... value to use,
3883 or CODE_FOR_nothing if these modes cannot be directly converted.
3885 *TRUNCP_PTR is set to 1 if it is necessary to output
3886 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3888 static enum insn_code
3889 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3890 enum machine_mode fltmode
, fixmode
;
3895 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0]
3896 != CODE_FOR_nothing
)
3897 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3899 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3902 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3904 return CODE_FOR_nothing
;
3907 static enum insn_code
3908 can_float_p (fltmode
, fixmode
, unsignedp
)
3909 enum machine_mode fixmode
, fltmode
;
3912 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3915 /* Generate code to convert FROM to floating point
3916 and store in TO. FROM must be fixed point and not VOIDmode.
3917 UNSIGNEDP nonzero means regard FROM as unsigned.
3918 Normally this is done by correcting the final value
3919 if it is negative. */
3922 expand_float (to
, from
, unsignedp
)
3926 enum insn_code icode
;
3927 register rtx target
= to
;
3928 enum machine_mode fmode
, imode
;
3930 /* Crash now, because we won't be able to decide which mode to use. */
3931 if (GET_MODE (from
) == VOIDmode
)
3934 /* Look for an insn to do the conversion. Do it in the specified
3935 modes if possible; otherwise convert either input, output or both to
3936 wider mode. If the integer mode is wider than the mode of FROM,
3937 we can do the conversion signed even if the input is unsigned. */
3939 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3940 imode
= GET_MODE_WIDER_MODE (imode
))
3941 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3942 fmode
= GET_MODE_WIDER_MODE (fmode
))
3944 int doing_unsigned
= unsignedp
;
3946 if (fmode
!= GET_MODE (to
)
3947 && significand_size (fmode
) < GET_MODE_BITSIZE (GET_MODE (from
)))
3950 icode
= can_float_p (fmode
, imode
, unsignedp
);
3951 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3952 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3954 if (icode
!= CODE_FOR_nothing
)
3956 to
= protect_from_queue (to
, 1);
3957 from
= protect_from_queue (from
, 0);
3959 if (imode
!= GET_MODE (from
))
3960 from
= convert_to_mode (imode
, from
, unsignedp
);
3962 if (fmode
!= GET_MODE (to
))
3963 target
= gen_reg_rtx (fmode
);
3965 emit_unop_insn (icode
, target
, from
,
3966 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3969 convert_move (to
, target
, 0);
3974 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3976 /* Unsigned integer, and no way to convert directly.
3977 Convert as signed, then conditionally adjust the result. */
3980 rtx label
= gen_label_rtx ();
3982 REAL_VALUE_TYPE offset
;
3986 to
= protect_from_queue (to
, 1);
3987 from
= protect_from_queue (from
, 0);
3990 from
= force_not_mem (from
);
3992 /* Look for a usable floating mode FMODE wider than the source and at
3993 least as wide as the target. Using FMODE will avoid rounding woes
3994 with unsigned values greater than the signed maximum value. */
3996 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3997 fmode
= GET_MODE_WIDER_MODE (fmode
))
3998 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
3999 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
4002 if (fmode
== VOIDmode
)
4004 /* There is no such mode. Pretend the target is wide enough. */
4005 fmode
= GET_MODE (to
);
4007 /* Avoid double-rounding when TO is narrower than FROM. */
4008 if ((significand_size (fmode
) + 1)
4009 < GET_MODE_BITSIZE (GET_MODE (from
)))
4012 rtx neglabel
= gen_label_rtx ();
4014 /* Don't use TARGET if it isn't a register, is a hard register,
4015 or is the wrong mode. */
4016 if (GET_CODE (target
) != REG
4017 || REGNO (target
) < FIRST_PSEUDO_REGISTER
4018 || GET_MODE (target
) != fmode
)
4019 target
= gen_reg_rtx (fmode
);
4021 imode
= GET_MODE (from
);
4022 do_pending_stack_adjust ();
4024 /* Test whether the sign bit is set. */
4025 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
4028 /* The sign bit is not set. Convert as signed. */
4029 expand_float (target
, from
, 0);
4030 emit_jump_insn (gen_jump (label
));
4033 /* The sign bit is set.
4034 Convert to a usable (positive signed) value by shifting right
4035 one bit, while remembering if a nonzero bit was shifted
4036 out; i.e., compute (from & 1) | (from >> 1). */
4038 emit_label (neglabel
);
4039 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
4040 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
4041 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
4043 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
4045 expand_float (target
, temp
, 0);
4047 /* Multiply by 2 to undo the shift above. */
4048 temp
= expand_binop (fmode
, add_optab
, target
, target
,
4049 target
, 0, OPTAB_LIB_WIDEN
);
4051 emit_move_insn (target
, temp
);
4053 do_pending_stack_adjust ();
4059 /* If we are about to do some arithmetic to correct for an
4060 unsigned operand, do it in a pseudo-register. */
4062 if (GET_MODE (to
) != fmode
4063 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
4064 target
= gen_reg_rtx (fmode
);
4066 /* Convert as signed integer to floating. */
4067 expand_float (target
, from
, 0);
4069 /* If FROM is negative (and therefore TO is negative),
4070 correct its value by 2**bitwidth. */
4072 do_pending_stack_adjust ();
4073 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
4076 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4077 Rather than setting up a dconst_dot_5, let's hope SCO
4079 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
4080 temp
= expand_binop (fmode
, add_optab
, target
,
4081 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
4082 target
, 0, OPTAB_LIB_WIDEN
);
4084 emit_move_insn (target
, temp
);
4086 do_pending_stack_adjust ();
4092 /* No hardware instruction available; call a library routine to convert from
4093 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4099 to
= protect_from_queue (to
, 1);
4100 from
= protect_from_queue (from
, 0);
4102 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
4103 from
= convert_to_mode (SImode
, from
, unsignedp
);
4106 from
= force_not_mem (from
);
4108 if (GET_MODE (to
) == SFmode
)
4110 if (GET_MODE (from
) == SImode
)
4111 libfcn
= floatsisf_libfunc
;
4112 else if (GET_MODE (from
) == DImode
)
4113 libfcn
= floatdisf_libfunc
;
4114 else if (GET_MODE (from
) == TImode
)
4115 libfcn
= floattisf_libfunc
;
4119 else if (GET_MODE (to
) == DFmode
)
4121 if (GET_MODE (from
) == SImode
)
4122 libfcn
= floatsidf_libfunc
;
4123 else if (GET_MODE (from
) == DImode
)
4124 libfcn
= floatdidf_libfunc
;
4125 else if (GET_MODE (from
) == TImode
)
4126 libfcn
= floattidf_libfunc
;
4130 else if (GET_MODE (to
) == XFmode
)
4132 if (GET_MODE (from
) == SImode
)
4133 libfcn
= floatsixf_libfunc
;
4134 else if (GET_MODE (from
) == DImode
)
4135 libfcn
= floatdixf_libfunc
;
4136 else if (GET_MODE (from
) == TImode
)
4137 libfcn
= floattixf_libfunc
;
4141 else if (GET_MODE (to
) == TFmode
)
4143 if (GET_MODE (from
) == SImode
)
4144 libfcn
= floatsitf_libfunc
;
4145 else if (GET_MODE (from
) == DImode
)
4146 libfcn
= floatditf_libfunc
;
4147 else if (GET_MODE (from
) == TImode
)
4148 libfcn
= floattitf_libfunc
;
4157 value
= emit_library_call_value (libfcn
, NULL_RTX
, LCT_CONST
,
4158 GET_MODE (to
), 1, from
,
4160 insns
= get_insns ();
4163 emit_libcall_block (insns
, target
, value
,
4164 gen_rtx_FLOAT (GET_MODE (to
), from
));
4169 /* Copy result to requested destination
4170 if we have been computing in a temp location. */
4174 if (GET_MODE (target
) == GET_MODE (to
))
4175 emit_move_insn (to
, target
);
4177 convert_move (to
, target
, 0);
4181 /* expand_fix: generate code to convert FROM to fixed point
4182 and store in TO. FROM must be floating point. */
4188 rtx temp
= gen_reg_rtx (GET_MODE (x
));
4189 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
4193 expand_fix (to
, from
, unsignedp
)
4194 register rtx to
, from
;
4197 enum insn_code icode
;
4198 register rtx target
= to
;
4199 enum machine_mode fmode
, imode
;
4203 /* We first try to find a pair of modes, one real and one integer, at
4204 least as wide as FROM and TO, respectively, in which we can open-code
4205 this conversion. If the integer mode is wider than the mode of TO,
4206 we can do the conversion either signed or unsigned. */
4208 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
4209 imode
= GET_MODE_WIDER_MODE (imode
))
4210 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4211 fmode
= GET_MODE_WIDER_MODE (fmode
))
4213 int doing_unsigned
= unsignedp
;
4215 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
4216 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
4217 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
4219 if (icode
!= CODE_FOR_nothing
)
4221 to
= protect_from_queue (to
, 1);
4222 from
= protect_from_queue (from
, 0);
4224 if (fmode
!= GET_MODE (from
))
4225 from
= convert_to_mode (fmode
, from
, 0);
4228 from
= ftruncify (from
);
4230 if (imode
!= GET_MODE (to
))
4231 target
= gen_reg_rtx (imode
);
4233 emit_unop_insn (icode
, target
, from
,
4234 doing_unsigned
? UNSIGNED_FIX
: FIX
);
4236 convert_move (to
, target
, unsignedp
);
4241 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4242 /* For an unsigned conversion, there is one more way to do it.
4243 If we have a signed conversion, we generate code that compares
4244 the real value to the largest representable positive number. If if
4245 is smaller, the conversion is done normally. Otherwise, subtract
4246 one plus the highest signed number, convert, and add it back.
4248 We only need to check all real modes, since we know we didn't find
4249 anything with a wider integer mode. */
4251 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
4252 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4253 fmode
= GET_MODE_WIDER_MODE (fmode
))
4254 /* Make sure we won't lose significant bits doing this. */
4255 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
4256 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
4260 REAL_VALUE_TYPE offset
;
4261 rtx limit
, lab1
, lab2
, insn
;
4263 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
4264 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
4265 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
4266 lab1
= gen_label_rtx ();
4267 lab2
= gen_label_rtx ();
4270 to
= protect_from_queue (to
, 1);
4271 from
= protect_from_queue (from
, 0);
4274 from
= force_not_mem (from
);
4276 if (fmode
!= GET_MODE (from
))
4277 from
= convert_to_mode (fmode
, from
, 0);
4279 /* See if we need to do the subtraction. */
4280 do_pending_stack_adjust ();
4281 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
4284 /* If not, do the signed "fix" and branch around fixup code. */
4285 expand_fix (to
, from
, 0);
4286 emit_jump_insn (gen_jump (lab2
));
4289 /* Otherwise, subtract 2**(N-1), convert to signed number,
4290 then add 2**(N-1). Do the addition using XOR since this
4291 will often generate better code. */
4293 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
4294 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4295 expand_fix (to
, target
, 0);
4296 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
4297 GEN_INT ((HOST_WIDE_INT
) 1 << (bitsize
- 1)),
4298 to
, 1, OPTAB_LIB_WIDEN
);
4301 emit_move_insn (to
, target
);
4305 if (mov_optab
->handlers
[(int) GET_MODE (to
)].insn_code
4306 != CODE_FOR_nothing
)
4308 /* Make a place for a REG_NOTE and add it. */
4309 insn
= emit_move_insn (to
, to
);
4310 set_unique_reg_note (insn
,
4312 gen_rtx_fmt_e (UNSIGNED_FIX
,
4321 /* We can't do it with an insn, so use a library call. But first ensure
4322 that the mode of TO is at least as wide as SImode, since those are the
4323 only library calls we know about. */
4325 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
4327 target
= gen_reg_rtx (SImode
);
4329 expand_fix (target
, from
, unsignedp
);
4331 else if (GET_MODE (from
) == SFmode
)
4333 if (GET_MODE (to
) == SImode
)
4334 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
4335 else if (GET_MODE (to
) == DImode
)
4336 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
4337 else if (GET_MODE (to
) == TImode
)
4338 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
4342 else if (GET_MODE (from
) == DFmode
)
4344 if (GET_MODE (to
) == SImode
)
4345 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
4346 else if (GET_MODE (to
) == DImode
)
4347 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
4348 else if (GET_MODE (to
) == TImode
)
4349 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
4353 else if (GET_MODE (from
) == XFmode
)
4355 if (GET_MODE (to
) == SImode
)
4356 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
4357 else if (GET_MODE (to
) == DImode
)
4358 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
4359 else if (GET_MODE (to
) == TImode
)
4360 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
4364 else if (GET_MODE (from
) == TFmode
)
4366 if (GET_MODE (to
) == SImode
)
4367 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
4368 else if (GET_MODE (to
) == DImode
)
4369 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
4370 else if (GET_MODE (to
) == TImode
)
4371 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
4383 to
= protect_from_queue (to
, 1);
4384 from
= protect_from_queue (from
, 0);
4387 from
= force_not_mem (from
);
4391 value
= emit_library_call_value (libfcn
, NULL_RTX
, LCT_CONST
,
4392 GET_MODE (to
), 1, from
,
4394 insns
= get_insns ();
4397 emit_libcall_block (insns
, target
, value
,
4398 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
4399 GET_MODE (to
), from
));
4404 if (GET_MODE (to
) == GET_MODE (target
))
4405 emit_move_insn (to
, target
);
4407 convert_move (to
, target
, 0);
4416 optab op
= (optab
) xmalloc (sizeof (struct optab
));
4418 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4420 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
4421 op
->handlers
[i
].libfunc
= 0;
4424 if (code
!= UNKNOWN
)
4425 code_to_optab
[(int) code
] = op
;
4430 /* Initialize the libfunc fields of an entire group of entries in some
4431 optab. Each entry is set equal to a string consisting of a leading
4432 pair of underscores followed by a generic operation name followed by
4433 a mode name (downshifted to lower case) followed by a single character
4434 representing the number of operands for the given operation (which is
4435 usually one of the characters '2', '3', or '4').
4437 OPTABLE is the table in which libfunc fields are to be initialized.
4438 FIRST_MODE is the first machine mode index in the given optab to
4440 LAST_MODE is the last machine mode index in the given optab to
4442 OPNAME is the generic (string) name of the operation.
4443 SUFFIX is the character which specifies the number of operands for
4444 the given generic operation.
4448 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
4449 register optab optable
;
4450 register int first_mode
;
4451 register int last_mode
;
4452 register const char *opname
;
4453 register int suffix
;
4456 register unsigned opname_len
= strlen (opname
);
4458 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
4459 mode
= (enum machine_mode
) ((int) mode
+ 1))
4461 register const char *mname
= GET_MODE_NAME(mode
);
4462 register unsigned mname_len
= strlen (mname
);
4463 register char *libfunc_name
= alloca (2 + opname_len
+ mname_len
+ 1 + 1);
4465 register const char *q
;
4470 for (q
= opname
; *q
; )
4472 for (q
= mname
; *q
; q
++)
4473 *p
++ = TOLOWER (*q
);
4477 optable
->handlers
[(int) mode
].libfunc
4478 = gen_rtx_SYMBOL_REF (Pmode
, ggc_alloc_string (libfunc_name
,
4483 /* Initialize the libfunc fields of an entire group of entries in some
4484 optab which correspond to all integer mode operations. The parameters
4485 have the same meaning as similarly named ones for the `init_libfuncs'
4486 routine. (See above). */
4489 init_integral_libfuncs (optable
, opname
, suffix
)
4490 register optab optable
;
4491 register const char *opname
;
4492 register int suffix
;
4494 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
4497 /* Initialize the libfunc fields of an entire group of entries in some
4498 optab which correspond to all real mode operations. The parameters
4499 have the same meaning as similarly named ones for the `init_libfuncs'
4500 routine. (See above). */
4503 init_floating_libfuncs (optable
, opname
, suffix
)
4504 register optab optable
;
4505 register const char *opname
;
4506 register int suffix
;
4508 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
4512 init_one_libfunc (name
)
4513 register const char *name
;
4515 name
= ggc_strdup (name
);
4517 return gen_rtx_SYMBOL_REF (Pmode
, name
);
4520 /* Mark ARG (which is really an OPTAB *) for GC. */
4526 optab o
= *(optab
*) arg
;
4529 for (i
= 0; i
< NUM_MACHINE_MODES
; ++i
)
4530 ggc_mark_rtx (o
->handlers
[i
].libfunc
);
4533 /* Call this once to initialize the contents of the optabs
4534 appropriately for the current target machine. */
4539 unsigned int i
, j
, k
;
4541 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4543 for (i
= 0; i
< ARRAY_SIZE (fixtab
); i
++)
4544 for (j
= 0; j
< ARRAY_SIZE (fixtab
[0]); j
++)
4545 for (k
= 0; k
< ARRAY_SIZE (fixtab
[0][0]); k
++)
4546 fixtab
[i
][j
][k
] = CODE_FOR_nothing
;
4548 for (i
= 0; i
< ARRAY_SIZE (fixtrunctab
); i
++)
4549 for (j
= 0; j
< ARRAY_SIZE (fixtrunctab
[0]); j
++)
4550 for (k
= 0; k
< ARRAY_SIZE (fixtrunctab
[0][0]); k
++)
4551 fixtrunctab
[i
][j
][k
] = CODE_FOR_nothing
;
4553 for (i
= 0; i
< ARRAY_SIZE (floattab
); i
++)
4554 for (j
= 0; j
< ARRAY_SIZE (floattab
[0]); j
++)
4555 for (k
= 0; k
< ARRAY_SIZE (floattab
[0][0]); k
++)
4556 floattab
[i
][j
][k
] = CODE_FOR_nothing
;
4558 for (i
= 0; i
< ARRAY_SIZE (extendtab
); i
++)
4559 for (j
= 0; j
< ARRAY_SIZE (extendtab
[0]); j
++)
4560 for (k
= 0; k
< ARRAY_SIZE (extendtab
[0][0]); k
++)
4561 extendtab
[i
][j
][k
] = CODE_FOR_nothing
;
4563 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
4564 setcc_gen_code
[i
] = CODE_FOR_nothing
;
4566 #ifdef HAVE_conditional_move
4567 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4568 movcc_gen_code
[i
] = CODE_FOR_nothing
;
4571 add_optab
= init_optab (PLUS
);
4572 addv_optab
= init_optab (PLUS
);
4573 sub_optab
= init_optab (MINUS
);
4574 subv_optab
= init_optab (MINUS
);
4575 smul_optab
= init_optab (MULT
);
4576 smulv_optab
= init_optab (MULT
);
4577 smul_highpart_optab
= init_optab (UNKNOWN
);
4578 umul_highpart_optab
= init_optab (UNKNOWN
);
4579 smul_widen_optab
= init_optab (UNKNOWN
);
4580 umul_widen_optab
= init_optab (UNKNOWN
);
4581 sdiv_optab
= init_optab (DIV
);
4582 sdivv_optab
= init_optab (DIV
);
4583 sdivmod_optab
= init_optab (UNKNOWN
);
4584 udiv_optab
= init_optab (UDIV
);
4585 udivmod_optab
= init_optab (UNKNOWN
);
4586 smod_optab
= init_optab (MOD
);
4587 umod_optab
= init_optab (UMOD
);
4588 flodiv_optab
= init_optab (DIV
);
4589 ftrunc_optab
= init_optab (UNKNOWN
);
4590 and_optab
= init_optab (AND
);
4591 ior_optab
= init_optab (IOR
);
4592 xor_optab
= init_optab (XOR
);
4593 ashl_optab
= init_optab (ASHIFT
);
4594 ashr_optab
= init_optab (ASHIFTRT
);
4595 lshr_optab
= init_optab (LSHIFTRT
);
4596 rotl_optab
= init_optab (ROTATE
);
4597 rotr_optab
= init_optab (ROTATERT
);
4598 smin_optab
= init_optab (SMIN
);
4599 smax_optab
= init_optab (SMAX
);
4600 umin_optab
= init_optab (UMIN
);
4601 umax_optab
= init_optab (UMAX
);
4602 mov_optab
= init_optab (UNKNOWN
);
4603 movstrict_optab
= init_optab (UNKNOWN
);
4604 cmp_optab
= init_optab (UNKNOWN
);
4605 ucmp_optab
= init_optab (UNKNOWN
);
4606 tst_optab
= init_optab (UNKNOWN
);
4607 neg_optab
= init_optab (NEG
);
4608 negv_optab
= init_optab (NEG
);
4609 abs_optab
= init_optab (ABS
);
4610 absv_optab
= init_optab (ABS
);
4611 one_cmpl_optab
= init_optab (NOT
);
4612 ffs_optab
= init_optab (FFS
);
4613 sqrt_optab
= init_optab (SQRT
);
4614 sin_optab
= init_optab (UNKNOWN
);
4615 cos_optab
= init_optab (UNKNOWN
);
4616 strlen_optab
= init_optab (UNKNOWN
);
4617 cbranch_optab
= init_optab (UNKNOWN
);
4618 cmov_optab
= init_optab (UNKNOWN
);
4619 cstore_optab
= init_optab (UNKNOWN
);
4621 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4623 movstr_optab
[i
] = CODE_FOR_nothing
;
4624 clrstr_optab
[i
] = CODE_FOR_nothing
;
4626 #ifdef HAVE_SECONDARY_RELOADS
4627 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
4631 /* Fill in the optabs with the insns we support. */
4634 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4635 /* This flag says the same insns that convert to a signed fixnum
4636 also convert validly to an unsigned one. */
4637 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4638 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
4639 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
4642 /* Initialize the optabs with the names of the library functions. */
4643 init_integral_libfuncs (add_optab
, "add", '3');
4644 init_floating_libfuncs (add_optab
, "add", '3');
4645 init_integral_libfuncs (addv_optab
, "addv", '3');
4646 init_floating_libfuncs (addv_optab
, "add", '3');
4647 init_integral_libfuncs (sub_optab
, "sub", '3');
4648 init_floating_libfuncs (sub_optab
, "sub", '3');
4649 init_integral_libfuncs (subv_optab
, "subv", '3');
4650 init_floating_libfuncs (subv_optab
, "sub", '3');
4651 init_integral_libfuncs (smul_optab
, "mul", '3');
4652 init_floating_libfuncs (smul_optab
, "mul", '3');
4653 init_integral_libfuncs (smulv_optab
, "mulv", '3');
4654 init_floating_libfuncs (smulv_optab
, "mul", '3');
4655 init_integral_libfuncs (sdiv_optab
, "div", '3');
4656 init_integral_libfuncs (sdivv_optab
, "divv", '3');
4657 init_integral_libfuncs (udiv_optab
, "udiv", '3');
4658 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
4659 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
4660 init_integral_libfuncs (smod_optab
, "mod", '3');
4661 init_integral_libfuncs (umod_optab
, "umod", '3');
4662 init_floating_libfuncs (flodiv_optab
, "div", '3');
4663 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
4664 init_integral_libfuncs (and_optab
, "and", '3');
4665 init_integral_libfuncs (ior_optab
, "ior", '3');
4666 init_integral_libfuncs (xor_optab
, "xor", '3');
4667 init_integral_libfuncs (ashl_optab
, "ashl", '3');
4668 init_integral_libfuncs (ashr_optab
, "ashr", '3');
4669 init_integral_libfuncs (lshr_optab
, "lshr", '3');
4670 init_integral_libfuncs (smin_optab
, "min", '3');
4671 init_floating_libfuncs (smin_optab
, "min", '3');
4672 init_integral_libfuncs (smax_optab
, "max", '3');
4673 init_floating_libfuncs (smax_optab
, "max", '3');
4674 init_integral_libfuncs (umin_optab
, "umin", '3');
4675 init_integral_libfuncs (umax_optab
, "umax", '3');
4676 init_integral_libfuncs (neg_optab
, "neg", '2');
4677 init_floating_libfuncs (neg_optab
, "neg", '2');
4678 init_integral_libfuncs (negv_optab
, "negv", '2');
4679 init_floating_libfuncs (negv_optab
, "neg", '2');
4680 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
4681 init_integral_libfuncs (ffs_optab
, "ffs", '2');
4683 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4684 init_integral_libfuncs (cmp_optab
, "cmp", '2');
4685 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
4686 init_floating_libfuncs (cmp_optab
, "cmp", '2');
4688 #ifdef MULSI3_LIBCALL
4689 smul_optab
->handlers
[(int) SImode
].libfunc
4690 = init_one_libfunc (MULSI3_LIBCALL
);
4692 #ifdef MULDI3_LIBCALL
4693 smul_optab
->handlers
[(int) DImode
].libfunc
4694 = init_one_libfunc (MULDI3_LIBCALL
);
4697 #ifdef DIVSI3_LIBCALL
4698 sdiv_optab
->handlers
[(int) SImode
].libfunc
4699 = init_one_libfunc (DIVSI3_LIBCALL
);
4701 #ifdef DIVDI3_LIBCALL
4702 sdiv_optab
->handlers
[(int) DImode
].libfunc
4703 = init_one_libfunc (DIVDI3_LIBCALL
);
4706 #ifdef UDIVSI3_LIBCALL
4707 udiv_optab
->handlers
[(int) SImode
].libfunc
4708 = init_one_libfunc (UDIVSI3_LIBCALL
);
4710 #ifdef UDIVDI3_LIBCALL
4711 udiv_optab
->handlers
[(int) DImode
].libfunc
4712 = init_one_libfunc (UDIVDI3_LIBCALL
);
4715 #ifdef MODSI3_LIBCALL
4716 smod_optab
->handlers
[(int) SImode
].libfunc
4717 = init_one_libfunc (MODSI3_LIBCALL
);
4719 #ifdef MODDI3_LIBCALL
4720 smod_optab
->handlers
[(int) DImode
].libfunc
4721 = init_one_libfunc (MODDI3_LIBCALL
);
4724 #ifdef UMODSI3_LIBCALL
4725 umod_optab
->handlers
[(int) SImode
].libfunc
4726 = init_one_libfunc (UMODSI3_LIBCALL
);
4728 #ifdef UMODDI3_LIBCALL
4729 umod_optab
->handlers
[(int) DImode
].libfunc
4730 = init_one_libfunc (UMODDI3_LIBCALL
);
4733 /* Use cabs for DC complex abs, since systems generally have cabs.
4734 Don't define any libcall for SCmode, so that cabs will be used. */
4735 abs_optab
->handlers
[(int) DCmode
].libfunc
4736 = init_one_libfunc ("cabs");
4738 /* The ffs function operates on `int'. */
4739 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)].libfunc
4740 = init_one_libfunc ("ffs");
4742 extendsfdf2_libfunc
= init_one_libfunc ("__extendsfdf2");
4743 extendsfxf2_libfunc
= init_one_libfunc ("__extendsfxf2");
4744 extendsftf2_libfunc
= init_one_libfunc ("__extendsftf2");
4745 extenddfxf2_libfunc
= init_one_libfunc ("__extenddfxf2");
4746 extenddftf2_libfunc
= init_one_libfunc ("__extenddftf2");
4748 truncdfsf2_libfunc
= init_one_libfunc ("__truncdfsf2");
4749 truncxfsf2_libfunc
= init_one_libfunc ("__truncxfsf2");
4750 trunctfsf2_libfunc
= init_one_libfunc ("__trunctfsf2");
4751 truncxfdf2_libfunc
= init_one_libfunc ("__truncxfdf2");
4752 trunctfdf2_libfunc
= init_one_libfunc ("__trunctfdf2");
4754 memcpy_libfunc
= init_one_libfunc ("memcpy");
4755 bcopy_libfunc
= init_one_libfunc ("bcopy");
4756 memcmp_libfunc
= init_one_libfunc ("memcmp");
4757 bcmp_libfunc
= init_one_libfunc ("__gcc_bcmp");
4758 memset_libfunc
= init_one_libfunc ("memset");
4759 bzero_libfunc
= init_one_libfunc ("bzero");
4761 throw_libfunc
= init_one_libfunc ("__throw");
4762 rethrow_libfunc
= init_one_libfunc ("__rethrow");
4763 sjthrow_libfunc
= init_one_libfunc ("__sjthrow");
4764 sjpopnthrow_libfunc
= init_one_libfunc ("__sjpopnthrow");
4765 terminate_libfunc
= init_one_libfunc ("__terminate");
4766 eh_rtime_match_libfunc
= init_one_libfunc ("__eh_rtime_match");
4767 #ifndef DONT_USE_BUILTIN_SETJMP
4768 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
4769 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
4771 setjmp_libfunc
= init_one_libfunc ("setjmp");
4772 longjmp_libfunc
= init_one_libfunc ("longjmp");
4775 eqhf2_libfunc
= init_one_libfunc ("__eqhf2");
4776 nehf2_libfunc
= init_one_libfunc ("__nehf2");
4777 gthf2_libfunc
= init_one_libfunc ("__gthf2");
4778 gehf2_libfunc
= init_one_libfunc ("__gehf2");
4779 lthf2_libfunc
= init_one_libfunc ("__lthf2");
4780 lehf2_libfunc
= init_one_libfunc ("__lehf2");
4781 unordhf2_libfunc
= init_one_libfunc ("__unordhf2");
4783 eqsf2_libfunc
= init_one_libfunc ("__eqsf2");
4784 nesf2_libfunc
= init_one_libfunc ("__nesf2");
4785 gtsf2_libfunc
= init_one_libfunc ("__gtsf2");
4786 gesf2_libfunc
= init_one_libfunc ("__gesf2");
4787 ltsf2_libfunc
= init_one_libfunc ("__ltsf2");
4788 lesf2_libfunc
= init_one_libfunc ("__lesf2");
4789 unordsf2_libfunc
= init_one_libfunc ("__unordsf2");
4791 eqdf2_libfunc
= init_one_libfunc ("__eqdf2");
4792 nedf2_libfunc
= init_one_libfunc ("__nedf2");
4793 gtdf2_libfunc
= init_one_libfunc ("__gtdf2");
4794 gedf2_libfunc
= init_one_libfunc ("__gedf2");
4795 ltdf2_libfunc
= init_one_libfunc ("__ltdf2");
4796 ledf2_libfunc
= init_one_libfunc ("__ledf2");
4797 unorddf2_libfunc
= init_one_libfunc ("__unorddf2");
4799 eqxf2_libfunc
= init_one_libfunc ("__eqxf2");
4800 nexf2_libfunc
= init_one_libfunc ("__nexf2");
4801 gtxf2_libfunc
= init_one_libfunc ("__gtxf2");
4802 gexf2_libfunc
= init_one_libfunc ("__gexf2");
4803 ltxf2_libfunc
= init_one_libfunc ("__ltxf2");
4804 lexf2_libfunc
= init_one_libfunc ("__lexf2");
4805 unordxf2_libfunc
= init_one_libfunc ("__unordxf2");
4807 eqtf2_libfunc
= init_one_libfunc ("__eqtf2");
4808 netf2_libfunc
= init_one_libfunc ("__netf2");
4809 gttf2_libfunc
= init_one_libfunc ("__gttf2");
4810 getf2_libfunc
= init_one_libfunc ("__getf2");
4811 lttf2_libfunc
= init_one_libfunc ("__lttf2");
4812 letf2_libfunc
= init_one_libfunc ("__letf2");
4813 unordtf2_libfunc
= init_one_libfunc ("__unordtf2");
4815 floatsisf_libfunc
= init_one_libfunc ("__floatsisf");
4816 floatdisf_libfunc
= init_one_libfunc ("__floatdisf");
4817 floattisf_libfunc
= init_one_libfunc ("__floattisf");
4819 floatsidf_libfunc
= init_one_libfunc ("__floatsidf");
4820 floatdidf_libfunc
= init_one_libfunc ("__floatdidf");
4821 floattidf_libfunc
= init_one_libfunc ("__floattidf");
4823 floatsixf_libfunc
= init_one_libfunc ("__floatsixf");
4824 floatdixf_libfunc
= init_one_libfunc ("__floatdixf");
4825 floattixf_libfunc
= init_one_libfunc ("__floattixf");
4827 floatsitf_libfunc
= init_one_libfunc ("__floatsitf");
4828 floatditf_libfunc
= init_one_libfunc ("__floatditf");
4829 floattitf_libfunc
= init_one_libfunc ("__floattitf");
4831 fixsfsi_libfunc
= init_one_libfunc ("__fixsfsi");
4832 fixsfdi_libfunc
= init_one_libfunc ("__fixsfdi");
4833 fixsfti_libfunc
= init_one_libfunc ("__fixsfti");
4835 fixdfsi_libfunc
= init_one_libfunc ("__fixdfsi");
4836 fixdfdi_libfunc
= init_one_libfunc ("__fixdfdi");
4837 fixdfti_libfunc
= init_one_libfunc ("__fixdfti");
4839 fixxfsi_libfunc
= init_one_libfunc ("__fixxfsi");
4840 fixxfdi_libfunc
= init_one_libfunc ("__fixxfdi");
4841 fixxfti_libfunc
= init_one_libfunc ("__fixxfti");
4843 fixtfsi_libfunc
= init_one_libfunc ("__fixtfsi");
4844 fixtfdi_libfunc
= init_one_libfunc ("__fixtfdi");
4845 fixtfti_libfunc
= init_one_libfunc ("__fixtfti");
4847 fixunssfsi_libfunc
= init_one_libfunc ("__fixunssfsi");
4848 fixunssfdi_libfunc
= init_one_libfunc ("__fixunssfdi");
4849 fixunssfti_libfunc
= init_one_libfunc ("__fixunssfti");
4851 fixunsdfsi_libfunc
= init_one_libfunc ("__fixunsdfsi");
4852 fixunsdfdi_libfunc
= init_one_libfunc ("__fixunsdfdi");
4853 fixunsdfti_libfunc
= init_one_libfunc ("__fixunsdfti");
4855 fixunsxfsi_libfunc
= init_one_libfunc ("__fixunsxfsi");
4856 fixunsxfdi_libfunc
= init_one_libfunc ("__fixunsxfdi");
4857 fixunsxfti_libfunc
= init_one_libfunc ("__fixunsxfti");
4859 fixunstfsi_libfunc
= init_one_libfunc ("__fixunstfsi");
4860 fixunstfdi_libfunc
= init_one_libfunc ("__fixunstfdi");
4861 fixunstfti_libfunc
= init_one_libfunc ("__fixunstfti");
4863 /* For check-memory-usage. */
4864 chkr_check_addr_libfunc
= init_one_libfunc ("chkr_check_addr");
4865 chkr_set_right_libfunc
= init_one_libfunc ("chkr_set_right");
4866 chkr_copy_bitmap_libfunc
= init_one_libfunc ("chkr_copy_bitmap");
4867 chkr_check_exec_libfunc
= init_one_libfunc ("chkr_check_exec");
4868 chkr_check_str_libfunc
= init_one_libfunc ("chkr_check_str");
4870 /* For function entry/exit instrumentation. */
4871 profile_function_entry_libfunc
4872 = init_one_libfunc ("__cyg_profile_func_enter");
4873 profile_function_exit_libfunc
4874 = init_one_libfunc ("__cyg_profile_func_exit");
4876 #ifdef HAVE_conditional_trap
4880 #ifdef INIT_TARGET_OPTABS
4881 /* Allow the target to add more libcalls or rename some, etc. */
4885 /* Add these GC roots. */
4886 ggc_add_root (optab_table
, OTI_MAX
, sizeof(optab
), mark_optab
);
4887 ggc_add_rtx_root (libfunc_table
, LTI_MAX
);
4892 /* SCO 3.2 apparently has a broken ldexp. */
4905 #endif /* BROKEN_LDEXP */
4907 #ifdef HAVE_conditional_trap
4908 /* The insn generating function can not take an rtx_code argument.
4909 TRAP_RTX is used as an rtx argument. Its code is replaced with
4910 the code to be used in the trap insn and all other fields are
4912 static rtx trap_rtx
;
4917 if (HAVE_conditional_trap
)
4919 trap_rtx
= gen_rtx_fmt_ee (EQ
, VOIDmode
, NULL_RTX
, NULL_RTX
);
4920 ggc_add_rtx_root (&trap_rtx
, 1);
4925 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4926 CODE. Return 0 on failure. */
4929 gen_cond_trap (code
, op1
, op2
, tcode
)
4930 enum rtx_code code ATTRIBUTE_UNUSED
;
4931 rtx op1
, op2 ATTRIBUTE_UNUSED
, tcode ATTRIBUTE_UNUSED
;
4933 enum machine_mode mode
= GET_MODE (op1
);
4935 if (mode
== VOIDmode
)
4938 #ifdef HAVE_conditional_trap
4939 if (HAVE_conditional_trap
4940 && cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
4944 emit_insn (GEN_FCN (cmp_optab
->handlers
[(int) mode
].insn_code
) (op1
, op2
));
4945 PUT_CODE (trap_rtx
, code
);
4946 insn
= gen_conditional_trap (trap_rtx
, tcode
);
4950 insn
= gen_sequence ();