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"
42 /* Each optab contains info on how this target machine
43 can perform a particular operation
44 for all sizes and kinds of operands.
46 The operation to be performed is often specified
47 by passing one of these optabs as an argument.
49 See expr.h for documentation of these optabs. */
51 optab optab_table
[OTI_MAX
];
53 rtx libfunc_table
[LTI_MAX
];
55 /* Tables of patterns for extending one integer mode to another. */
56 enum insn_code extendtab
[MAX_MACHINE_MODE
][MAX_MACHINE_MODE
][2];
58 /* Tables of patterns for converting between fixed and floating point. */
59 enum insn_code fixtab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
60 enum insn_code fixtrunctab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
61 enum insn_code floattab
[NUM_MACHINE_MODES
][NUM_MACHINE_MODES
][2];
63 /* Contains the optab used for each rtx code. */
64 optab code_to_optab
[NUM_RTX_CODE
+ 1];
66 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
67 gives the gen_function to make a branch to test that condition. */
69 rtxfun bcc_gen_fctn
[NUM_RTX_CODE
];
71 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
72 gives the insn code to make a store-condition insn
73 to test that condition. */
75 enum insn_code setcc_gen_code
[NUM_RTX_CODE
];
77 #ifdef HAVE_conditional_move
78 /* Indexed by the machine mode, gives the insn code to make a conditional
79 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
80 setcc_gen_code to cut down on the number of named patterns. Consider a day
81 when a lot more rtx codes are conditional (eg: for the ARM). */
83 enum insn_code movcc_gen_code
[NUM_MACHINE_MODES
];
86 static int add_equal_note
PARAMS ((rtx
, rtx
, enum rtx_code
, rtx
, rtx
));
87 static rtx widen_operand
PARAMS ((rtx
, enum machine_mode
,
88 enum machine_mode
, int, int));
89 static int expand_cmplxdiv_straight
PARAMS ((rtx
, rtx
, rtx
, rtx
,
90 rtx
, rtx
, enum machine_mode
,
91 int, enum optab_methods
,
92 enum mode_class
, optab
));
93 static int expand_cmplxdiv_wide
PARAMS ((rtx
, rtx
, rtx
, rtx
,
94 rtx
, rtx
, enum machine_mode
,
95 int, enum optab_methods
,
96 enum mode_class
, optab
));
97 static enum insn_code can_fix_p
PARAMS ((enum machine_mode
, enum machine_mode
,
99 static enum insn_code can_float_p
PARAMS ((enum machine_mode
, enum machine_mode
,
101 static rtx ftruncify
PARAMS ((rtx
));
102 static optab init_optab
PARAMS ((enum rtx_code
));
103 static void init_libfuncs
PARAMS ((optab
, int, int, const char *, int));
104 static void init_integral_libfuncs
PARAMS ((optab
, const char *, int));
105 static void init_floating_libfuncs
PARAMS ((optab
, const char *, int));
106 #ifdef HAVE_conditional_trap
107 static void init_traps
PARAMS ((void));
109 static void emit_cmp_and_jump_insn_1
PARAMS ((rtx
, rtx
, enum machine_mode
,
110 enum rtx_code
, int, rtx
));
111 static void prepare_float_lib_cmp
PARAMS ((rtx
*, rtx
*, enum rtx_code
*,
112 enum machine_mode
*, int *));
114 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
115 the result of operation CODE applied to OP0 (and OP1 if it is a binary
118 If the last insn does not set TARGET, don't do anything, but return 1.
120 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
121 don't add the REG_EQUAL note but return 0. Our caller can then try
122 again, ensuring that TARGET is not one of the operands. */
125 add_equal_note (seq
, target
, code
, op0
, op1
)
135 if ((GET_RTX_CLASS (code
) != '1' && GET_RTX_CLASS (code
) != '2'
136 && GET_RTX_CLASS (code
) != 'c' && GET_RTX_CLASS (code
) != '<')
137 || GET_CODE (seq
) != SEQUENCE
138 || (set
= single_set (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1))) == 0
139 || GET_CODE (target
) == ZERO_EXTRACT
140 || (! rtx_equal_p (SET_DEST (set
), target
)
141 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
143 && (GET_CODE (SET_DEST (set
)) != STRICT_LOW_PART
144 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set
), 0)),
148 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
149 besides the last insn. */
150 if (reg_overlap_mentioned_p (target
, op0
)
151 || (op1
&& reg_overlap_mentioned_p (target
, op1
)))
152 for (i
= XVECLEN (seq
, 0) - 2; i
>= 0; i
--)
153 if (reg_set_p (target
, XVECEXP (seq
, 0, i
)))
156 if (GET_RTX_CLASS (code
) == '1')
157 note
= gen_rtx_fmt_e (code
, GET_MODE (target
), copy_rtx (op0
));
159 note
= gen_rtx_fmt_ee (code
, GET_MODE (target
), copy_rtx (op0
), copy_rtx (op1
));
161 set_unique_reg_note (XVECEXP (seq
, 0, XVECLEN (seq
, 0) - 1), REG_EQUAL
, note
);
166 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
167 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
168 not actually do a sign-extend or zero-extend, but can leave the
169 higher-order bits of the result rtx undefined, for example, in the case
170 of logical operations, but not right shifts. */
173 widen_operand (op
, mode
, oldmode
, unsignedp
, no_extend
)
175 enum machine_mode mode
, oldmode
;
181 /* If we must extend do so. If OP is either a constant or a SUBREG
182 for a promoted object, also extend since it will be more efficient to
185 || GET_MODE (op
) == VOIDmode
186 || (GET_CODE (op
) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op
)))
187 return convert_modes (mode
, oldmode
, op
, unsignedp
);
189 /* If MODE is no wider than a single word, we return a paradoxical
191 if (GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
192 return gen_rtx_SUBREG (mode
, force_reg (GET_MODE (op
), op
), 0);
194 /* Otherwise, get an object of MODE, clobber it, and set the low-order
197 result
= gen_reg_rtx (mode
);
198 emit_insn (gen_rtx_CLOBBER (VOIDmode
, result
));
199 emit_move_insn (gen_lowpart (GET_MODE (op
), result
), op
);
203 /* Generate code to perform a straightforward complex divide. */
206 expand_cmplxdiv_straight (real0
, real1
, imag0
, imag1
, realr
, imagr
, submode
,
207 unsignedp
, methods
, class, binoptab
)
208 rtx real0
, real1
, imag0
, imag1
, realr
, imagr
;
209 enum machine_mode submode
;
211 enum optab_methods methods
;
212 enum mode_class
class;
219 optab this_add_optab
= add_optab
;
220 optab this_sub_optab
= sub_optab
;
221 optab this_neg_optab
= neg_optab
;
222 optab this_mul_optab
= smul_optab
;
224 if (binoptab
== sdivv_optab
)
226 this_add_optab
= addv_optab
;
227 this_sub_optab
= subv_optab
;
228 this_neg_optab
= negv_optab
;
229 this_mul_optab
= smulv_optab
;
232 /* Don't fetch these from memory more than once. */
233 real0
= force_reg (submode
, real0
);
234 real1
= force_reg (submode
, real1
);
237 imag0
= force_reg (submode
, imag0
);
239 imag1
= force_reg (submode
, imag1
);
241 /* Divisor: c*c + d*d. */
242 temp1
= expand_binop (submode
, this_mul_optab
, real1
, real1
,
243 NULL_RTX
, unsignedp
, methods
);
245 temp2
= expand_binop (submode
, this_mul_optab
, imag1
, imag1
,
246 NULL_RTX
, unsignedp
, methods
);
248 if (temp1
== 0 || temp2
== 0)
251 divisor
= expand_binop (submode
, this_add_optab
, temp1
, temp2
,
252 NULL_RTX
, unsignedp
, methods
);
258 /* Mathematically, ((a)(c-id))/divisor. */
259 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
261 /* Calculate the dividend. */
262 real_t
= expand_binop (submode
, this_mul_optab
, real0
, real1
,
263 NULL_RTX
, unsignedp
, methods
);
265 imag_t
= expand_binop (submode
, this_mul_optab
, real0
, imag1
,
266 NULL_RTX
, unsignedp
, methods
);
268 if (real_t
== 0 || imag_t
== 0)
271 imag_t
= expand_unop (submode
, this_neg_optab
, imag_t
,
272 NULL_RTX
, unsignedp
);
276 /* Mathematically, ((a+ib)(c-id))/divider. */
277 /* Calculate the dividend. */
278 temp1
= expand_binop (submode
, this_mul_optab
, real0
, real1
,
279 NULL_RTX
, unsignedp
, methods
);
281 temp2
= expand_binop (submode
, this_mul_optab
, imag0
, imag1
,
282 NULL_RTX
, unsignedp
, methods
);
284 if (temp1
== 0 || temp2
== 0)
287 real_t
= expand_binop (submode
, this_add_optab
, temp1
, temp2
,
288 NULL_RTX
, unsignedp
, methods
);
290 temp1
= expand_binop (submode
, this_mul_optab
, imag0
, real1
,
291 NULL_RTX
, unsignedp
, methods
);
293 temp2
= expand_binop (submode
, this_mul_optab
, real0
, imag1
,
294 NULL_RTX
, unsignedp
, methods
);
296 if (temp1
== 0 || temp2
== 0)
299 imag_t
= expand_binop (submode
, this_sub_optab
, temp1
, temp2
,
300 NULL_RTX
, unsignedp
, methods
);
302 if (real_t
== 0 || imag_t
== 0)
306 if (class == MODE_COMPLEX_FLOAT
)
307 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
308 realr
, unsignedp
, methods
);
310 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
311 real_t
, divisor
, realr
, unsignedp
);
317 emit_move_insn (realr
, res
);
319 if (class == MODE_COMPLEX_FLOAT
)
320 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
321 imagr
, unsignedp
, methods
);
323 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
324 imag_t
, divisor
, imagr
, unsignedp
);
330 emit_move_insn (imagr
, res
);
335 /* Generate code to perform a wide-input-range-acceptable complex divide. */
338 expand_cmplxdiv_wide (real0
, real1
, imag0
, imag1
, realr
, imagr
, submode
,
339 unsignedp
, methods
, class, binoptab
)
340 rtx real0
, real1
, imag0
, imag1
, realr
, imagr
;
341 enum machine_mode submode
;
343 enum optab_methods methods
;
344 enum mode_class
class;
349 rtx temp1
, temp2
, lab1
, lab2
;
350 enum machine_mode mode
;
353 optab this_add_optab
= add_optab
;
354 optab this_sub_optab
= sub_optab
;
355 optab this_neg_optab
= neg_optab
;
356 optab this_mul_optab
= smul_optab
;
358 if (binoptab
== sdivv_optab
)
360 this_add_optab
= addv_optab
;
361 this_sub_optab
= subv_optab
;
362 this_neg_optab
= negv_optab
;
363 this_mul_optab
= smulv_optab
;
366 /* Don't fetch these from memory more than once. */
367 real0
= force_reg (submode
, real0
);
368 real1
= force_reg (submode
, real1
);
371 imag0
= force_reg (submode
, imag0
);
373 imag1
= force_reg (submode
, imag1
);
375 /* XXX What's an "unsigned" complex number? */
383 temp1
= expand_abs (submode
, real1
, NULL_RTX
, unsignedp
, 1);
384 temp2
= expand_abs (submode
, imag1
, NULL_RTX
, unsignedp
, 1);
387 if (temp1
== 0 || temp2
== 0)
390 mode
= GET_MODE (temp1
);
391 align
= GET_MODE_ALIGNMENT (mode
);
392 lab1
= gen_label_rtx ();
393 emit_cmp_and_jump_insns (temp1
, temp2
, LT
, NULL_RTX
,
394 mode
, unsignedp
, align
, lab1
);
396 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
398 if (class == MODE_COMPLEX_FLOAT
)
399 ratio
= expand_binop (submode
, binoptab
, imag1
, real1
,
400 NULL_RTX
, unsignedp
, methods
);
402 ratio
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
403 imag1
, real1
, NULL_RTX
, unsignedp
);
408 /* Calculate divisor. */
410 temp1
= expand_binop (submode
, this_mul_optab
, imag1
, ratio
,
411 NULL_RTX
, unsignedp
, methods
);
416 divisor
= expand_binop (submode
, this_add_optab
, temp1
, real1
,
417 NULL_RTX
, unsignedp
, methods
);
422 /* Calculate dividend. */
428 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
430 imag_t
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
431 NULL_RTX
, unsignedp
, methods
);
436 imag_t
= expand_unop (submode
, this_neg_optab
, imag_t
,
437 NULL_RTX
, unsignedp
);
439 if (real_t
== 0 || imag_t
== 0)
444 /* Compute (a+ib)/(c+id) as
445 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
447 temp1
= expand_binop (submode
, this_mul_optab
, imag0
, ratio
,
448 NULL_RTX
, unsignedp
, methods
);
453 real_t
= expand_binop (submode
, this_add_optab
, temp1
, real0
,
454 NULL_RTX
, unsignedp
, methods
);
456 temp1
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
457 NULL_RTX
, unsignedp
, methods
);
462 imag_t
= expand_binop (submode
, this_sub_optab
, imag0
, temp1
,
463 NULL_RTX
, unsignedp
, methods
);
465 if (real_t
== 0 || imag_t
== 0)
469 if (class == MODE_COMPLEX_FLOAT
)
470 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
471 realr
, unsignedp
, methods
);
473 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
474 real_t
, divisor
, realr
, unsignedp
);
480 emit_move_insn (realr
, res
);
482 if (class == MODE_COMPLEX_FLOAT
)
483 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
484 imagr
, unsignedp
, methods
);
486 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
487 imag_t
, divisor
, imagr
, unsignedp
);
493 emit_move_insn (imagr
, res
);
495 lab2
= gen_label_rtx ();
496 emit_jump_insn (gen_jump (lab2
));
501 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
503 if (class == MODE_COMPLEX_FLOAT
)
504 ratio
= expand_binop (submode
, binoptab
, real1
, imag1
,
505 NULL_RTX
, unsignedp
, methods
);
507 ratio
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
508 real1
, imag1
, NULL_RTX
, unsignedp
);
513 /* Calculate divisor. */
515 temp1
= expand_binop (submode
, this_mul_optab
, real1
, ratio
,
516 NULL_RTX
, unsignedp
, methods
);
521 divisor
= expand_binop (submode
, this_add_optab
, temp1
, imag1
,
522 NULL_RTX
, unsignedp
, methods
);
527 /* Calculate dividend. */
531 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
533 real_t
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
534 NULL_RTX
, unsignedp
, methods
);
536 imag_t
= expand_unop (submode
, this_neg_optab
, real0
,
537 NULL_RTX
, unsignedp
);
539 if (real_t
== 0 || imag_t
== 0)
544 /* Compute (a+ib)/(c+id) as
545 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
547 temp1
= expand_binop (submode
, this_mul_optab
, real0
, ratio
,
548 NULL_RTX
, unsignedp
, methods
);
553 real_t
= expand_binop (submode
, this_add_optab
, temp1
, imag0
,
554 NULL_RTX
, unsignedp
, methods
);
556 temp1
= expand_binop (submode
, this_mul_optab
, imag0
, ratio
,
557 NULL_RTX
, unsignedp
, methods
);
562 imag_t
= expand_binop (submode
, this_sub_optab
, temp1
, real0
,
563 NULL_RTX
, unsignedp
, methods
);
565 if (real_t
== 0 || imag_t
== 0)
569 if (class == MODE_COMPLEX_FLOAT
)
570 res
= expand_binop (submode
, binoptab
, real_t
, divisor
,
571 realr
, unsignedp
, methods
);
573 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
574 real_t
, divisor
, realr
, unsignedp
);
580 emit_move_insn (realr
, res
);
582 if (class == MODE_COMPLEX_FLOAT
)
583 res
= expand_binop (submode
, binoptab
, imag_t
, divisor
,
584 imagr
, unsignedp
, methods
);
586 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
587 imag_t
, divisor
, imagr
, unsignedp
);
593 emit_move_insn (imagr
, res
);
600 /* Generate code to perform an operation specified by BINOPTAB
601 on operands OP0 and OP1, with result having machine-mode MODE.
603 UNSIGNEDP is for the case where we have to widen the operands
604 to perform the operation. It says to use zero-extension.
606 If TARGET is nonzero, the value
607 is generated there, if it is convenient to do so.
608 In all cases an rtx is returned for the locus of the value;
609 this may or may not be TARGET. */
612 expand_binop (mode
, binoptab
, op0
, op1
, target
, unsignedp
, methods
)
613 enum machine_mode mode
;
618 enum optab_methods methods
;
620 enum optab_methods next_methods
621 = (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
622 ? OPTAB_WIDEN
: methods
);
623 enum mode_class
class;
624 enum machine_mode wider_mode
;
626 int commutative_op
= 0;
627 int shift_op
= (binoptab
->code
== ASHIFT
628 || binoptab
->code
== ASHIFTRT
629 || binoptab
->code
== LSHIFTRT
630 || binoptab
->code
== ROTATE
631 || binoptab
->code
== ROTATERT
);
632 rtx entry_last
= get_last_insn ();
635 class = GET_MODE_CLASS (mode
);
637 op0
= protect_from_queue (op0
, 0);
638 op1
= protect_from_queue (op1
, 0);
640 target
= protect_from_queue (target
, 1);
644 op0
= force_not_mem (op0
);
645 op1
= force_not_mem (op1
);
648 /* If subtracting an integer constant, convert this into an addition of
649 the negated constant. */
651 if (binoptab
== sub_optab
&& GET_CODE (op1
) == CONST_INT
)
653 op1
= negate_rtx (mode
, op1
);
654 binoptab
= add_optab
;
657 /* If we are inside an appropriately-short loop and one operand is an
658 expensive constant, force it into a register. */
659 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
660 && rtx_cost (op0
, binoptab
->code
) > COSTS_N_INSNS (1))
661 op0
= force_reg (mode
, op0
);
663 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
664 && ! shift_op
&& rtx_cost (op1
, binoptab
->code
) > COSTS_N_INSNS (1))
665 op1
= force_reg (mode
, op1
);
667 /* Record where to delete back to if we backtrack. */
668 last
= get_last_insn ();
670 /* If operation is commutative,
671 try to make the first operand a register.
672 Even better, try to make it the same as the target.
673 Also try to make the last operand a constant. */
674 if (GET_RTX_CLASS (binoptab
->code
) == 'c'
675 || binoptab
== smul_widen_optab
676 || binoptab
== umul_widen_optab
677 || binoptab
== smul_highpart_optab
678 || binoptab
== umul_highpart_optab
)
682 if (((target
== 0 || GET_CODE (target
) == REG
)
683 ? ((GET_CODE (op1
) == REG
684 && GET_CODE (op0
) != REG
)
686 : rtx_equal_p (op1
, target
))
687 || GET_CODE (op0
) == CONST_INT
)
695 /* If we can do it with a three-operand insn, do so. */
697 if (methods
!= OPTAB_MUST_WIDEN
698 && binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
700 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
701 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
702 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
704 rtx xop0
= op0
, xop1
= op1
;
709 temp
= gen_reg_rtx (mode
);
711 /* If it is a commutative operator and the modes would match
712 if we would swap the operands, we can save the conversions. */
715 if (GET_MODE (op0
) != mode0
&& GET_MODE (op1
) != mode1
716 && GET_MODE (op0
) == mode1
&& GET_MODE (op1
) == mode0
)
720 tmp
= op0
; op0
= op1
; op1
= tmp
;
721 tmp
= xop0
; xop0
= xop1
; xop1
= tmp
;
725 /* In case the insn wants input operands in modes different from
726 the result, convert the operands. It would seem that we
727 don't need to convert CONST_INTs, but we do, so that they're
728 a properly sign-extended for their modes. */
730 if (GET_MODE (op0
) != mode0
731 && mode0
!= VOIDmode
)
732 xop0
= convert_modes (mode0
,
733 GET_MODE (op0
) != VOIDmode
738 if (GET_MODE (xop1
) != mode1
739 && mode1
!= VOIDmode
)
740 xop1
= convert_modes (mode1
,
741 GET_MODE (op1
) != VOIDmode
746 /* Now, if insn's predicates don't allow our operands, put them into
749 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
)
750 && mode0
!= VOIDmode
)
751 xop0
= copy_to_mode_reg (mode0
, xop0
);
753 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, mode1
)
754 && mode1
!= VOIDmode
)
755 xop1
= copy_to_mode_reg (mode1
, xop1
);
757 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, mode
))
758 temp
= gen_reg_rtx (mode
);
760 pat
= GEN_FCN (icode
) (temp
, xop0
, xop1
);
763 /* If PAT is a multi-insn sequence, try to add an appropriate
764 REG_EQUAL note to it. If we can't because TEMP conflicts with an
765 operand, call ourselves again, this time without a target. */
766 if (GET_CODE (pat
) == SEQUENCE
767 && ! add_equal_note (pat
, temp
, binoptab
->code
, xop0
, xop1
))
769 delete_insns_since (last
);
770 return expand_binop (mode
, binoptab
, op0
, op1
, NULL_RTX
,
778 delete_insns_since (last
);
781 /* If this is a multiply, see if we can do a widening operation that
782 takes operands of this mode and makes a wider mode. */
784 if (binoptab
== smul_optab
&& GET_MODE_WIDER_MODE (mode
) != VOIDmode
785 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
786 ->handlers
[(int) GET_MODE_WIDER_MODE (mode
)].insn_code
)
787 != CODE_FOR_nothing
))
789 temp
= expand_binop (GET_MODE_WIDER_MODE (mode
),
790 unsignedp
? umul_widen_optab
: smul_widen_optab
,
791 op0
, op1
, NULL_RTX
, unsignedp
, OPTAB_DIRECT
);
795 if (GET_MODE_CLASS (mode
) == MODE_INT
)
796 return gen_lowpart (mode
, temp
);
798 return convert_to_mode (mode
, temp
, unsignedp
);
802 /* Look for a wider mode of the same class for which we think we
803 can open-code the operation. Check for a widening multiply at the
804 wider mode as well. */
806 if ((class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
807 && methods
!= OPTAB_DIRECT
&& methods
!= OPTAB_LIB
)
808 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
809 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
811 if (binoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
812 || (binoptab
== smul_optab
813 && GET_MODE_WIDER_MODE (wider_mode
) != VOIDmode
814 && (((unsignedp
? umul_widen_optab
: smul_widen_optab
)
815 ->handlers
[(int) GET_MODE_WIDER_MODE (wider_mode
)].insn_code
)
816 != CODE_FOR_nothing
)))
818 rtx xop0
= op0
, xop1
= op1
;
821 /* For certain integer operations, we need not actually extend
822 the narrow operands, as long as we will truncate
823 the results to the same narrowness. */
825 if ((binoptab
== ior_optab
|| binoptab
== and_optab
826 || binoptab
== xor_optab
827 || binoptab
== add_optab
|| binoptab
== sub_optab
828 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
829 && class == MODE_INT
)
832 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
, no_extend
);
834 /* The second operand of a shift must always be extended. */
835 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
836 no_extend
&& binoptab
!= ashl_optab
);
838 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
839 unsignedp
, OPTAB_DIRECT
);
842 if (class != MODE_INT
)
845 target
= gen_reg_rtx (mode
);
846 convert_move (target
, temp
, 0);
850 return gen_lowpart (mode
, temp
);
853 delete_insns_since (last
);
857 /* These can be done a word at a time. */
858 if ((binoptab
== and_optab
|| binoptab
== ior_optab
|| binoptab
== xor_optab
)
860 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
861 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
867 /* If TARGET is the same as one of the operands, the REG_EQUAL note
868 won't be accurate, so use a new target. */
869 if (target
== 0 || target
== op0
|| target
== op1
)
870 target
= gen_reg_rtx (mode
);
874 /* Do the actual arithmetic. */
875 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
877 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
878 rtx x
= expand_binop (word_mode
, binoptab
,
879 operand_subword_force (op0
, i
, mode
),
880 operand_subword_force (op1
, i
, mode
),
881 target_piece
, unsignedp
, next_methods
);
886 if (target_piece
!= x
)
887 emit_move_insn (target_piece
, x
);
890 insns
= get_insns ();
893 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
895 if (binoptab
->code
!= UNKNOWN
)
897 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
898 copy_rtx (op0
), copy_rtx (op1
));
902 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
907 /* Synthesize double word shifts from single word shifts. */
908 if ((binoptab
== lshr_optab
|| binoptab
== ashl_optab
909 || binoptab
== ashr_optab
)
911 && GET_CODE (op1
) == CONST_INT
912 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
913 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
914 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
915 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
917 rtx insns
, inter
, equiv_value
;
918 rtx into_target
, outof_target
;
919 rtx into_input
, outof_input
;
920 int shift_count
, left_shift
, outof_word
;
922 /* If TARGET is the same as one of the operands, the REG_EQUAL note
923 won't be accurate, so use a new target. */
924 if (target
== 0 || target
== op0
|| target
== op1
)
925 target
= gen_reg_rtx (mode
);
929 shift_count
= INTVAL (op1
);
931 /* OUTOF_* is the word we are shifting bits away from, and
932 INTO_* is the word that we are shifting bits towards, thus
933 they differ depending on the direction of the shift and
936 left_shift
= binoptab
== ashl_optab
;
937 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
939 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
940 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
942 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
943 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
945 if (shift_count
>= BITS_PER_WORD
)
947 inter
= expand_binop (word_mode
, binoptab
,
949 GEN_INT (shift_count
- BITS_PER_WORD
),
950 into_target
, unsignedp
, next_methods
);
952 if (inter
!= 0 && inter
!= into_target
)
953 emit_move_insn (into_target
, inter
);
955 /* For a signed right shift, we must fill the word we are shifting
956 out of with copies of the sign bit. Otherwise it is zeroed. */
957 if (inter
!= 0 && binoptab
!= ashr_optab
)
958 inter
= CONST0_RTX (word_mode
);
960 inter
= expand_binop (word_mode
, binoptab
,
962 GEN_INT (BITS_PER_WORD
- 1),
963 outof_target
, unsignedp
, next_methods
);
965 if (inter
!= 0 && inter
!= outof_target
)
966 emit_move_insn (outof_target
, inter
);
971 optab reverse_unsigned_shift
, unsigned_shift
;
973 /* For a shift of less then BITS_PER_WORD, to compute the carry,
974 we must do a logical shift in the opposite direction of the
977 reverse_unsigned_shift
= (left_shift
? lshr_optab
: ashl_optab
);
979 /* For a shift of less than BITS_PER_WORD, to compute the word
980 shifted towards, we need to unsigned shift the orig value of
983 unsigned_shift
= (left_shift
? ashl_optab
: lshr_optab
);
985 carries
= expand_binop (word_mode
, reverse_unsigned_shift
,
987 GEN_INT (BITS_PER_WORD
- shift_count
),
988 0, unsignedp
, next_methods
);
993 inter
= expand_binop (word_mode
, unsigned_shift
, into_input
,
994 op1
, 0, unsignedp
, next_methods
);
997 inter
= expand_binop (word_mode
, ior_optab
, carries
, inter
,
998 into_target
, unsignedp
, next_methods
);
1000 if (inter
!= 0 && inter
!= into_target
)
1001 emit_move_insn (into_target
, inter
);
1004 inter
= expand_binop (word_mode
, binoptab
, outof_input
,
1005 op1
, outof_target
, unsignedp
, next_methods
);
1007 if (inter
!= 0 && inter
!= outof_target
)
1008 emit_move_insn (outof_target
, inter
);
1011 insns
= get_insns ();
1016 if (binoptab
->code
!= UNKNOWN
)
1017 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
1021 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
1026 /* Synthesize double word rotates from single word shifts. */
1027 if ((binoptab
== rotl_optab
|| binoptab
== rotr_optab
)
1028 && class == MODE_INT
1029 && GET_CODE (op1
) == CONST_INT
1030 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1031 && ashl_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1032 && lshr_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1034 rtx insns
, equiv_value
;
1035 rtx into_target
, outof_target
;
1036 rtx into_input
, outof_input
;
1038 int shift_count
, left_shift
, outof_word
;
1040 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1041 won't be accurate, so use a new target. */
1042 if (target
== 0 || target
== op0
|| target
== op1
)
1043 target
= gen_reg_rtx (mode
);
1047 shift_count
= INTVAL (op1
);
1049 /* OUTOF_* is the word we are shifting bits away from, and
1050 INTO_* is the word that we are shifting bits towards, thus
1051 they differ depending on the direction of the shift and
1052 WORDS_BIG_ENDIAN. */
1054 left_shift
= (binoptab
== rotl_optab
);
1055 outof_word
= left_shift
^ ! WORDS_BIG_ENDIAN
;
1057 outof_target
= operand_subword (target
, outof_word
, 1, mode
);
1058 into_target
= operand_subword (target
, 1 - outof_word
, 1, mode
);
1060 outof_input
= operand_subword_force (op0
, outof_word
, mode
);
1061 into_input
= operand_subword_force (op0
, 1 - outof_word
, mode
);
1063 if (shift_count
== BITS_PER_WORD
)
1065 /* This is just a word swap. */
1066 emit_move_insn (outof_target
, into_input
);
1067 emit_move_insn (into_target
, outof_input
);
1072 rtx into_temp1
, into_temp2
, outof_temp1
, outof_temp2
;
1073 rtx first_shift_count
, second_shift_count
;
1074 optab reverse_unsigned_shift
, unsigned_shift
;
1076 reverse_unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1077 ? lshr_optab
: ashl_optab
);
1079 unsigned_shift
= (left_shift
^ (shift_count
< BITS_PER_WORD
)
1080 ? ashl_optab
: lshr_optab
);
1082 if (shift_count
> BITS_PER_WORD
)
1084 first_shift_count
= GEN_INT (shift_count
- BITS_PER_WORD
);
1085 second_shift_count
= GEN_INT (2*BITS_PER_WORD
- shift_count
);
1089 first_shift_count
= GEN_INT (BITS_PER_WORD
- shift_count
);
1090 second_shift_count
= GEN_INT (shift_count
);
1093 into_temp1
= expand_binop (word_mode
, unsigned_shift
,
1094 outof_input
, first_shift_count
,
1095 NULL_RTX
, unsignedp
, next_methods
);
1096 into_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1097 into_input
, second_shift_count
,
1098 into_target
, unsignedp
, next_methods
);
1100 if (into_temp1
!= 0 && into_temp2
!= 0)
1101 inter
= expand_binop (word_mode
, ior_optab
, into_temp1
, into_temp2
,
1102 into_target
, unsignedp
, next_methods
);
1106 if (inter
!= 0 && inter
!= into_target
)
1107 emit_move_insn (into_target
, inter
);
1109 outof_temp1
= expand_binop (word_mode
, unsigned_shift
,
1110 into_input
, first_shift_count
,
1111 NULL_RTX
, unsignedp
, next_methods
);
1112 outof_temp2
= expand_binop (word_mode
, reverse_unsigned_shift
,
1113 outof_input
, second_shift_count
,
1114 outof_target
, unsignedp
, next_methods
);
1116 if (inter
!= 0 && outof_temp1
!= 0 && outof_temp2
!= 0)
1117 inter
= expand_binop (word_mode
, ior_optab
,
1118 outof_temp1
, outof_temp2
,
1119 outof_target
, unsignedp
, next_methods
);
1121 if (inter
!= 0 && inter
!= outof_target
)
1122 emit_move_insn (outof_target
, inter
);
1125 insns
= get_insns ();
1130 if (binoptab
->code
!= UNKNOWN
)
1131 equiv_value
= gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
);
1135 /* We can't make this a no conflict block if this is a word swap,
1136 because the word swap case fails if the input and output values
1137 are in the same register. */
1138 if (shift_count
!= BITS_PER_WORD
)
1139 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv_value
);
1148 /* These can be done a word at a time by propagating carries. */
1149 if ((binoptab
== add_optab
|| binoptab
== sub_optab
)
1150 && class == MODE_INT
1151 && GET_MODE_SIZE (mode
) >= 2 * UNITS_PER_WORD
1152 && binoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
1155 rtx carry_tmp
= gen_reg_rtx (word_mode
);
1156 optab otheroptab
= binoptab
== add_optab
? sub_optab
: add_optab
;
1157 unsigned int nwords
= GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
;
1158 rtx carry_in
= NULL_RTX
, carry_out
= NULL_RTX
;
1161 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1162 value is one of those, use it. Otherwise, use 1 since it is the
1163 one easiest to get. */
1164 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1165 int normalizep
= STORE_FLAG_VALUE
;
1170 /* Prepare the operands. */
1171 xop0
= force_reg (mode
, op0
);
1172 xop1
= force_reg (mode
, op1
);
1174 if (target
== 0 || GET_CODE (target
) != REG
1175 || target
== xop0
|| target
== xop1
)
1176 target
= gen_reg_rtx (mode
);
1178 /* Indicate for flow that the entire target reg is being set. */
1179 if (GET_CODE (target
) == REG
)
1180 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
1182 /* Do the actual arithmetic. */
1183 for (i
= 0; i
< nwords
; i
++)
1185 int index
= (WORDS_BIG_ENDIAN
? nwords
- i
- 1 : i
);
1186 rtx target_piece
= operand_subword (target
, index
, 1, mode
);
1187 rtx op0_piece
= operand_subword_force (xop0
, index
, mode
);
1188 rtx op1_piece
= operand_subword_force (xop1
, index
, mode
);
1191 /* Main add/subtract of the input operands. */
1192 x
= expand_binop (word_mode
, binoptab
,
1193 op0_piece
, op1_piece
,
1194 target_piece
, unsignedp
, next_methods
);
1200 /* Store carry from main add/subtract. */
1201 carry_out
= gen_reg_rtx (word_mode
);
1202 carry_out
= emit_store_flag_force (carry_out
,
1203 (binoptab
== add_optab
1206 word_mode
, 1, normalizep
);
1211 /* Add/subtract previous carry to main result. */
1212 x
= expand_binop (word_mode
,
1213 normalizep
== 1 ? binoptab
: otheroptab
,
1215 target_piece
, 1, next_methods
);
1218 else if (target_piece
!= x
)
1219 emit_move_insn (target_piece
, x
);
1223 /* THIS CODE HAS NOT BEEN TESTED. */
1224 /* Get out carry from adding/subtracting carry in. */
1225 carry_tmp
= emit_store_flag_force (carry_tmp
,
1226 binoptab
== add_optab
1229 word_mode
, 1, normalizep
);
1231 /* Logical-ior the two poss. carry together. */
1232 carry_out
= expand_binop (word_mode
, ior_optab
,
1233 carry_out
, carry_tmp
,
1234 carry_out
, 0, next_methods
);
1240 carry_in
= carry_out
;
1243 if (i
== GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
)
1245 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1247 rtx temp
= emit_move_insn (target
, target
);
1249 set_unique_reg_note (temp
,
1251 gen_rtx_fmt_ee (binoptab
->code
, mode
,
1260 delete_insns_since (last
);
1263 /* If we want to multiply two two-word values and have normal and widening
1264 multiplies of single-word values, we can do this with three smaller
1265 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1266 because we are not operating on one word at a time.
1268 The multiplication proceeds as follows:
1269 _______________________
1270 [__op0_high_|__op0_low__]
1271 _______________________
1272 * [__op1_high_|__op1_low__]
1273 _______________________________________________
1274 _______________________
1275 (1) [__op0_low__*__op1_low__]
1276 _______________________
1277 (2a) [__op0_low__*__op1_high_]
1278 _______________________
1279 (2b) [__op0_high_*__op1_low__]
1280 _______________________
1281 (3) [__op0_high_*__op1_high_]
1284 This gives a 4-word result. Since we are only interested in the
1285 lower 2 words, partial result (3) and the upper words of (2a) and
1286 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1287 calculated using non-widening multiplication.
1289 (1), however, needs to be calculated with an unsigned widening
1290 multiplication. If this operation is not directly supported we
1291 try using a signed widening multiplication and adjust the result.
1292 This adjustment works as follows:
1294 If both operands are positive then no adjustment is needed.
1296 If the operands have different signs, for example op0_low < 0 and
1297 op1_low >= 0, the instruction treats the most significant bit of
1298 op0_low as a sign bit instead of a bit with significance
1299 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1300 with 2**BITS_PER_WORD - op0_low, and two's complements the
1301 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1304 Similarly, if both operands are negative, we need to add
1305 (op0_low + op1_low) * 2**BITS_PER_WORD.
1307 We use a trick to adjust quickly. We logically shift op0_low right
1308 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1309 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1310 logical shift exists, we do an arithmetic right shift and subtract
1313 if (binoptab
== smul_optab
1314 && class == MODE_INT
1315 && GET_MODE_SIZE (mode
) == 2 * UNITS_PER_WORD
1316 && smul_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1317 && add_optab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
1318 && ((umul_widen_optab
->handlers
[(int) mode
].insn_code
1319 != CODE_FOR_nothing
)
1320 || (smul_widen_optab
->handlers
[(int) mode
].insn_code
1321 != CODE_FOR_nothing
)))
1323 int low
= (WORDS_BIG_ENDIAN
? 1 : 0);
1324 int high
= (WORDS_BIG_ENDIAN
? 0 : 1);
1325 rtx op0_high
= operand_subword_force (op0
, high
, mode
);
1326 rtx op0_low
= operand_subword_force (op0
, low
, mode
);
1327 rtx op1_high
= operand_subword_force (op1
, high
, mode
);
1328 rtx op1_low
= operand_subword_force (op1
, low
, mode
);
1330 rtx op0_xhigh
= NULL_RTX
;
1331 rtx op1_xhigh
= NULL_RTX
;
1333 /* If the target is the same as one of the inputs, don't use it. This
1334 prevents problems with the REG_EQUAL note. */
1335 if (target
== op0
|| target
== op1
1336 || (target
!= 0 && GET_CODE (target
) != REG
))
1339 /* Multiply the two lower words to get a double-word product.
1340 If unsigned widening multiplication is available, use that;
1341 otherwise use the signed form and compensate. */
1343 if (umul_widen_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1345 product
= expand_binop (mode
, umul_widen_optab
, op0_low
, op1_low
,
1346 target
, 1, OPTAB_DIRECT
);
1348 /* If we didn't succeed, delete everything we did so far. */
1350 delete_insns_since (last
);
1352 op0_xhigh
= op0_high
, op1_xhigh
= op1_high
;
1356 && smul_widen_optab
->handlers
[(int) mode
].insn_code
1357 != CODE_FOR_nothing
)
1359 rtx wordm1
= GEN_INT (BITS_PER_WORD
- 1);
1360 product
= expand_binop (mode
, smul_widen_optab
, op0_low
, op1_low
,
1361 target
, 1, OPTAB_DIRECT
);
1362 op0_xhigh
= expand_binop (word_mode
, lshr_optab
, op0_low
, wordm1
,
1363 NULL_RTX
, 1, next_methods
);
1365 op0_xhigh
= expand_binop (word_mode
, add_optab
, op0_high
,
1366 op0_xhigh
, op0_xhigh
, 0, next_methods
);
1369 op0_xhigh
= expand_binop (word_mode
, ashr_optab
, op0_low
, wordm1
,
1370 NULL_RTX
, 0, next_methods
);
1372 op0_xhigh
= expand_binop (word_mode
, sub_optab
, op0_high
,
1373 op0_xhigh
, op0_xhigh
, 0,
1377 op1_xhigh
= expand_binop (word_mode
, lshr_optab
, op1_low
, wordm1
,
1378 NULL_RTX
, 1, next_methods
);
1380 op1_xhigh
= expand_binop (word_mode
, add_optab
, op1_high
,
1381 op1_xhigh
, op1_xhigh
, 0, next_methods
);
1384 op1_xhigh
= expand_binop (word_mode
, ashr_optab
, op1_low
, wordm1
,
1385 NULL_RTX
, 0, next_methods
);
1387 op1_xhigh
= expand_binop (word_mode
, sub_optab
, op1_high
,
1388 op1_xhigh
, op1_xhigh
, 0,
1393 /* If we have been able to directly compute the product of the
1394 low-order words of the operands and perform any required adjustments
1395 of the operands, we proceed by trying two more multiplications
1396 and then computing the appropriate sum.
1398 We have checked above that the required addition is provided.
1399 Full-word addition will normally always succeed, especially if
1400 it is provided at all, so we don't worry about its failure. The
1401 multiplication may well fail, however, so we do handle that. */
1403 if (product
&& op0_xhigh
&& op1_xhigh
)
1405 rtx product_high
= operand_subword (product
, high
, 1, mode
);
1406 rtx temp
= expand_binop (word_mode
, binoptab
, op0_low
, op1_xhigh
,
1407 NULL_RTX
, 0, OPTAB_DIRECT
);
1410 temp
= expand_binop (word_mode
, add_optab
, temp
, product_high
,
1411 product_high
, 0, next_methods
);
1413 if (temp
!= 0 && temp
!= product_high
)
1414 emit_move_insn (product_high
, temp
);
1417 temp
= expand_binop (word_mode
, binoptab
, op1_low
, op0_xhigh
,
1418 NULL_RTX
, 0, OPTAB_DIRECT
);
1421 temp
= expand_binop (word_mode
, add_optab
, temp
,
1422 product_high
, product_high
,
1425 if (temp
!= 0 && temp
!= product_high
)
1426 emit_move_insn (product_high
, temp
);
1430 if (mov_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1432 temp
= emit_move_insn (product
, product
);
1433 set_unique_reg_note (temp
,
1435 gen_rtx_fmt_ee (MULT
, mode
,
1444 /* If we get here, we couldn't do it for some reason even though we
1445 originally thought we could. Delete anything we've emitted in
1448 delete_insns_since (last
);
1451 /* We need to open-code the complex type operations: '+, -, * and /' */
1453 /* At this point we allow operations between two similar complex
1454 numbers, and also if one of the operands is not a complex number
1455 but rather of MODE_FLOAT or MODE_INT. However, the caller
1456 must make sure that the MODE of the non-complex operand matches
1457 the SUBMODE of the complex operand. */
1459 if (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
)
1461 rtx real0
= 0, imag0
= 0;
1462 rtx real1
= 0, imag1
= 0;
1463 rtx realr
, imagr
, res
;
1468 /* Find the correct mode for the real and imaginary parts */
1469 enum machine_mode submode
1470 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
1471 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
1474 if (submode
== BLKmode
)
1478 target
= gen_reg_rtx (mode
);
1482 realr
= gen_realpart (submode
, target
);
1483 imagr
= gen_imagpart (submode
, target
);
1485 if (GET_MODE (op0
) == mode
)
1487 real0
= gen_realpart (submode
, op0
);
1488 imag0
= gen_imagpart (submode
, op0
);
1493 if (GET_MODE (op1
) == mode
)
1495 real1
= gen_realpart (submode
, op1
);
1496 imag1
= gen_imagpart (submode
, op1
);
1501 if (real0
== 0 || real1
== 0 || ! (imag0
!= 0|| imag1
!= 0))
1504 switch (binoptab
->code
)
1507 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1509 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1510 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1511 realr
, unsignedp
, methods
);
1515 else if (res
!= realr
)
1516 emit_move_insn (realr
, res
);
1519 res
= expand_binop (submode
, binoptab
, imag0
, imag1
,
1520 imagr
, unsignedp
, methods
);
1523 else if (binoptab
->code
== MINUS
)
1524 res
= expand_unop (submode
,
1525 binoptab
== subv_optab
? negv_optab
: neg_optab
,
1526 imag1
, imagr
, unsignedp
);
1532 else if (res
!= imagr
)
1533 emit_move_insn (imagr
, res
);
1539 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1545 /* Don't fetch these from memory more than once. */
1546 real0
= force_reg (submode
, real0
);
1547 real1
= force_reg (submode
, real1
);
1548 imag0
= force_reg (submode
, imag0
);
1549 imag1
= force_reg (submode
, imag1
);
1551 temp1
= expand_binop (submode
, binoptab
, real0
, real1
, NULL_RTX
,
1552 unsignedp
, methods
);
1554 temp2
= expand_binop (submode
, binoptab
, imag0
, imag1
, NULL_RTX
,
1555 unsignedp
, methods
);
1557 if (temp1
== 0 || temp2
== 0)
1562 binoptab
== smulv_optab
? subv_optab
: sub_optab
,
1563 temp1
, temp2
, realr
, unsignedp
, methods
));
1567 else if (res
!= realr
)
1568 emit_move_insn (realr
, res
);
1570 temp1
= expand_binop (submode
, binoptab
, real0
, imag1
,
1571 NULL_RTX
, unsignedp
, methods
);
1573 temp2
= expand_binop (submode
, binoptab
, real1
, imag0
,
1574 NULL_RTX
, unsignedp
, methods
);
1576 if (temp1
== 0 || temp2
== 0)
1581 binoptab
== smulv_optab
? addv_optab
: add_optab
,
1582 temp1
, temp2
, imagr
, unsignedp
, methods
));
1586 else if (res
!= imagr
)
1587 emit_move_insn (imagr
, res
);
1593 /* Don't fetch these from memory more than once. */
1594 real0
= force_reg (submode
, real0
);
1595 real1
= force_reg (submode
, real1
);
1597 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1598 realr
, unsignedp
, methods
);
1601 else if (res
!= realr
)
1602 emit_move_insn (realr
, res
);
1605 res
= expand_binop (submode
, binoptab
,
1606 real1
, imag0
, imagr
, unsignedp
, methods
);
1608 res
= expand_binop (submode
, binoptab
,
1609 real0
, imag1
, imagr
, unsignedp
, methods
);
1613 else if (res
!= imagr
)
1614 emit_move_insn (imagr
, res
);
1621 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1625 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1627 /* Don't fetch these from memory more than once. */
1628 real1
= force_reg (submode
, real1
);
1630 /* Simply divide the real and imaginary parts by `c' */
1631 if (class == MODE_COMPLEX_FLOAT
)
1632 res
= expand_binop (submode
, binoptab
, real0
, real1
,
1633 realr
, unsignedp
, methods
);
1635 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1636 real0
, real1
, realr
, unsignedp
);
1640 else if (res
!= realr
)
1641 emit_move_insn (realr
, res
);
1643 if (class == MODE_COMPLEX_FLOAT
)
1644 res
= expand_binop (submode
, binoptab
, imag0
, real1
,
1645 imagr
, unsignedp
, methods
);
1647 res
= expand_divmod (0, TRUNC_DIV_EXPR
, submode
,
1648 imag0
, real1
, imagr
, unsignedp
);
1652 else if (res
!= imagr
)
1653 emit_move_insn (imagr
, res
);
1659 switch (flag_complex_divide_method
)
1662 ok
= expand_cmplxdiv_straight (real0
, real1
, imag0
, imag1
,
1663 realr
, imagr
, submode
,
1669 ok
= expand_cmplxdiv_wide (real0
, real1
, imag0
, imag1
,
1670 realr
, imagr
, submode
,
1690 if (binoptab
->code
!= UNKNOWN
)
1692 = gen_rtx_fmt_ee (binoptab
->code
, mode
,
1693 copy_rtx (op0
), copy_rtx (op1
));
1697 emit_no_conflict_block (seq
, target
, op0
, op1
, equiv_value
);
1703 /* It can't be open-coded in this mode.
1704 Use a library call if one is available and caller says that's ok. */
1706 if (binoptab
->handlers
[(int) mode
].libfunc
1707 && (methods
== OPTAB_LIB
|| methods
== OPTAB_LIB_WIDEN
))
1711 enum machine_mode op1_mode
= mode
;
1718 op1_mode
= word_mode
;
1719 /* Specify unsigned here,
1720 since negative shift counts are meaningless. */
1721 op1x
= convert_to_mode (word_mode
, op1
, 1);
1724 if (GET_MODE (op0
) != VOIDmode
1725 && GET_MODE (op0
) != mode
)
1726 op0
= convert_to_mode (mode
, op0
, unsignedp
);
1728 /* Pass 1 for NO_QUEUE so we don't lose any increments
1729 if the libcall is cse'd or moved. */
1730 value
= emit_library_call_value (binoptab
->handlers
[(int) mode
].libfunc
,
1731 NULL_RTX
, LCT_CONST
, mode
, 2,
1732 op0
, mode
, op1x
, op1_mode
);
1734 insns
= get_insns ();
1737 target
= gen_reg_rtx (mode
);
1738 emit_libcall_block (insns
, target
, value
,
1739 gen_rtx_fmt_ee (binoptab
->code
, mode
, op0
, op1
));
1744 delete_insns_since (last
);
1746 /* It can't be done in this mode. Can we do it in a wider mode? */
1748 if (! (methods
== OPTAB_WIDEN
|| methods
== OPTAB_LIB_WIDEN
1749 || methods
== OPTAB_MUST_WIDEN
))
1751 /* Caller says, don't even try. */
1752 delete_insns_since (entry_last
);
1756 /* Compute the value of METHODS to pass to recursive calls.
1757 Don't allow widening to be tried recursively. */
1759 methods
= (methods
== OPTAB_LIB_WIDEN
? OPTAB_LIB
: OPTAB_DIRECT
);
1761 /* Look for a wider mode of the same class for which it appears we can do
1764 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1766 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1767 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1769 if ((binoptab
->handlers
[(int) wider_mode
].insn_code
1770 != CODE_FOR_nothing
)
1771 || (methods
== OPTAB_LIB
1772 && binoptab
->handlers
[(int) wider_mode
].libfunc
))
1774 rtx xop0
= op0
, xop1
= op1
;
1777 /* For certain integer operations, we need not actually extend
1778 the narrow operands, as long as we will truncate
1779 the results to the same narrowness. */
1781 if ((binoptab
== ior_optab
|| binoptab
== and_optab
1782 || binoptab
== xor_optab
1783 || binoptab
== add_optab
|| binoptab
== sub_optab
1784 || binoptab
== smul_optab
|| binoptab
== ashl_optab
)
1785 && class == MODE_INT
)
1788 xop0
= widen_operand (xop0
, wider_mode
, mode
,
1789 unsignedp
, no_extend
);
1791 /* The second operand of a shift must always be extended. */
1792 xop1
= widen_operand (xop1
, wider_mode
, mode
, unsignedp
,
1793 no_extend
&& binoptab
!= ashl_optab
);
1795 temp
= expand_binop (wider_mode
, binoptab
, xop0
, xop1
, NULL_RTX
,
1796 unsignedp
, methods
);
1799 if (class != MODE_INT
)
1802 target
= gen_reg_rtx (mode
);
1803 convert_move (target
, temp
, 0);
1807 return gen_lowpart (mode
, temp
);
1810 delete_insns_since (last
);
1815 delete_insns_since (entry_last
);
1819 /* Expand a binary operator which has both signed and unsigned forms.
1820 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1823 If we widen unsigned operands, we may use a signed wider operation instead
1824 of an unsigned wider operation, since the result would be the same. */
1827 sign_expand_binop (mode
, uoptab
, soptab
, op0
, op1
, target
, unsignedp
, methods
)
1828 enum machine_mode mode
;
1829 optab uoptab
, soptab
;
1830 rtx op0
, op1
, target
;
1832 enum optab_methods methods
;
1835 optab direct_optab
= unsignedp
? uoptab
: soptab
;
1836 struct optab wide_soptab
;
1838 /* Do it without widening, if possible. */
1839 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
,
1840 unsignedp
, OPTAB_DIRECT
);
1841 if (temp
|| methods
== OPTAB_DIRECT
)
1844 /* Try widening to a signed int. Make a fake signed optab that
1845 hides any signed insn for direct use. */
1846 wide_soptab
= *soptab
;
1847 wide_soptab
.handlers
[(int) mode
].insn_code
= CODE_FOR_nothing
;
1848 wide_soptab
.handlers
[(int) mode
].libfunc
= 0;
1850 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1851 unsignedp
, OPTAB_WIDEN
);
1853 /* For unsigned operands, try widening to an unsigned int. */
1854 if (temp
== 0 && unsignedp
)
1855 temp
= expand_binop (mode
, uoptab
, op0
, op1
, target
,
1856 unsignedp
, OPTAB_WIDEN
);
1857 if (temp
|| methods
== OPTAB_WIDEN
)
1860 /* Use the right width lib call if that exists. */
1861 temp
= expand_binop (mode
, direct_optab
, op0
, op1
, target
, unsignedp
, OPTAB_LIB
);
1862 if (temp
|| methods
== OPTAB_LIB
)
1865 /* Must widen and use a lib call, use either signed or unsigned. */
1866 temp
= expand_binop (mode
, &wide_soptab
, op0
, op1
, target
,
1867 unsignedp
, methods
);
1871 return expand_binop (mode
, uoptab
, op0
, op1
, target
,
1872 unsignedp
, methods
);
1876 /* Generate code to perform an operation specified by BINOPTAB
1877 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1878 We assume that the order of the operands for the instruction
1879 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1880 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1882 Either TARG0 or TARG1 may be zero, but what that means is that
1883 the result is not actually wanted. We will generate it into
1884 a dummy pseudo-reg and discard it. They may not both be zero.
1886 Returns 1 if this operation can be performed; 0 if not. */
1889 expand_twoval_binop (binoptab
, op0
, op1
, targ0
, targ1
, unsignedp
)
1895 enum machine_mode mode
= GET_MODE (targ0
? targ0
: targ1
);
1896 enum mode_class
class;
1897 enum machine_mode wider_mode
;
1898 rtx entry_last
= get_last_insn ();
1901 class = GET_MODE_CLASS (mode
);
1903 op0
= protect_from_queue (op0
, 0);
1904 op1
= protect_from_queue (op1
, 0);
1908 op0
= force_not_mem (op0
);
1909 op1
= force_not_mem (op1
);
1912 /* If we are inside an appropriately-short loop and one operand is an
1913 expensive constant, force it into a register. */
1914 if (CONSTANT_P (op0
) && preserve_subexpressions_p ()
1915 && rtx_cost (op0
, binoptab
->code
) > COSTS_N_INSNS (1))
1916 op0
= force_reg (mode
, op0
);
1918 if (CONSTANT_P (op1
) && preserve_subexpressions_p ()
1919 && rtx_cost (op1
, binoptab
->code
) > COSTS_N_INSNS (1))
1920 op1
= force_reg (mode
, op1
);
1923 targ0
= protect_from_queue (targ0
, 1);
1925 targ0
= gen_reg_rtx (mode
);
1927 targ1
= protect_from_queue (targ1
, 1);
1929 targ1
= gen_reg_rtx (mode
);
1931 /* Record where to go back to if we fail. */
1932 last
= get_last_insn ();
1934 if (binoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
1936 int icode
= (int) binoptab
->handlers
[(int) mode
].insn_code
;
1937 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
1938 enum machine_mode mode1
= insn_data
[icode
].operand
[2].mode
;
1940 rtx xop0
= op0
, xop1
= op1
;
1942 /* In case this insn wants input operands in modes different from the
1943 result, convert the operands. */
1944 if (GET_MODE (op0
) != VOIDmode
&& GET_MODE (op0
) != mode0
)
1945 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
1947 if (GET_MODE (op1
) != VOIDmode
&& GET_MODE (op1
) != mode1
)
1948 xop1
= convert_to_mode (mode1
, xop1
, unsignedp
);
1950 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1951 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
1952 xop0
= copy_to_mode_reg (mode0
, xop0
);
1954 if (! (*insn_data
[icode
].operand
[2].predicate
) (xop1
, mode1
))
1955 xop1
= copy_to_mode_reg (mode1
, xop1
);
1957 /* We could handle this, but we should always be called with a pseudo
1958 for our targets and all insns should take them as outputs. */
1959 if (! (*insn_data
[icode
].operand
[0].predicate
) (targ0
, mode
)
1960 || ! (*insn_data
[icode
].operand
[3].predicate
) (targ1
, mode
))
1963 pat
= GEN_FCN (icode
) (targ0
, xop0
, xop1
, targ1
);
1970 delete_insns_since (last
);
1973 /* It can't be done in this mode. Can we do it in a wider mode? */
1975 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
1977 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
1978 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
1980 if (binoptab
->handlers
[(int) wider_mode
].insn_code
1981 != CODE_FOR_nothing
)
1983 register rtx t0
= gen_reg_rtx (wider_mode
);
1984 register rtx t1
= gen_reg_rtx (wider_mode
);
1986 if (expand_twoval_binop (binoptab
,
1987 convert_modes (wider_mode
, mode
, op0
,
1989 convert_modes (wider_mode
, mode
, op1
,
1993 convert_move (targ0
, t0
, unsignedp
);
1994 convert_move (targ1
, t1
, unsignedp
);
1998 delete_insns_since (last
);
2003 delete_insns_since (entry_last
);
2007 /* Generate code to perform an operation specified by UNOPTAB
2008 on operand OP0, with result having machine-mode MODE.
2010 UNSIGNEDP is for the case where we have to widen the operands
2011 to perform the operation. It says to use zero-extension.
2013 If TARGET is nonzero, the value
2014 is generated there, if it is convenient to do so.
2015 In all cases an rtx is returned for the locus of the value;
2016 this may or may not be TARGET. */
2019 expand_unop (mode
, unoptab
, op0
, target
, unsignedp
)
2020 enum machine_mode mode
;
2026 enum mode_class
class;
2027 enum machine_mode wider_mode
;
2029 rtx last
= get_last_insn ();
2032 class = GET_MODE_CLASS (mode
);
2034 op0
= protect_from_queue (op0
, 0);
2038 op0
= force_not_mem (op0
);
2042 target
= protect_from_queue (target
, 1);
2044 if (unoptab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2046 int icode
= (int) unoptab
->handlers
[(int) mode
].insn_code
;
2047 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2053 temp
= gen_reg_rtx (mode
);
2055 if (GET_MODE (xop0
) != VOIDmode
2056 && GET_MODE (xop0
) != mode0
)
2057 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2059 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2061 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
2062 xop0
= copy_to_mode_reg (mode0
, xop0
);
2064 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, mode
))
2065 temp
= gen_reg_rtx (mode
);
2067 pat
= GEN_FCN (icode
) (temp
, xop0
);
2070 if (GET_CODE (pat
) == SEQUENCE
2071 && ! add_equal_note (pat
, temp
, unoptab
->code
, xop0
, NULL_RTX
))
2073 delete_insns_since (last
);
2074 return expand_unop (mode
, unoptab
, op0
, NULL_RTX
, unsignedp
);
2082 delete_insns_since (last
);
2085 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2087 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2088 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2089 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2091 if (unoptab
->handlers
[(int) wider_mode
].insn_code
!= CODE_FOR_nothing
)
2095 /* For certain operations, we need not actually extend
2096 the narrow operand, as long as we will truncate the
2097 results to the same narrowness. */
2099 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2100 (unoptab
== neg_optab
2101 || unoptab
== one_cmpl_optab
)
2102 && class == MODE_INT
);
2104 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2109 if (class != MODE_INT
)
2112 target
= gen_reg_rtx (mode
);
2113 convert_move (target
, temp
, 0);
2117 return gen_lowpart (mode
, temp
);
2120 delete_insns_since (last
);
2124 /* These can be done a word at a time. */
2125 if (unoptab
== one_cmpl_optab
2126 && class == MODE_INT
2127 && GET_MODE_SIZE (mode
) > UNITS_PER_WORD
2128 && unoptab
->handlers
[(int) word_mode
].insn_code
!= CODE_FOR_nothing
)
2133 if (target
== 0 || target
== op0
)
2134 target
= gen_reg_rtx (mode
);
2138 /* Do the actual arithmetic. */
2139 for (i
= 0; i
< GET_MODE_BITSIZE (mode
) / BITS_PER_WORD
; i
++)
2141 rtx target_piece
= operand_subword (target
, i
, 1, mode
);
2142 rtx x
= expand_unop (word_mode
, unoptab
,
2143 operand_subword_force (op0
, i
, mode
),
2144 target_piece
, unsignedp
);
2145 if (target_piece
!= x
)
2146 emit_move_insn (target_piece
, x
);
2149 insns
= get_insns ();
2152 emit_no_conflict_block (insns
, target
, op0
, NULL_RTX
,
2153 gen_rtx_fmt_e (unoptab
->code
, mode
,
2158 /* Open-code the complex negation operation. */
2159 else if (unoptab
->code
== NEG
2160 && (class == MODE_COMPLEX_FLOAT
|| class == MODE_COMPLEX_INT
))
2166 /* Find the correct mode for the real and imaginary parts */
2167 enum machine_mode submode
2168 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2169 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2172 if (submode
== BLKmode
)
2176 target
= gen_reg_rtx (mode
);
2180 target_piece
= gen_imagpart (submode
, target
);
2181 x
= expand_unop (submode
, unoptab
,
2182 gen_imagpart (submode
, op0
),
2183 target_piece
, unsignedp
);
2184 if (target_piece
!= x
)
2185 emit_move_insn (target_piece
, x
);
2187 target_piece
= gen_realpart (submode
, target
);
2188 x
= expand_unop (submode
, unoptab
,
2189 gen_realpart (submode
, op0
),
2190 target_piece
, unsignedp
);
2191 if (target_piece
!= x
)
2192 emit_move_insn (target_piece
, x
);
2197 emit_no_conflict_block (seq
, target
, op0
, 0,
2198 gen_rtx_fmt_e (unoptab
->code
, mode
,
2203 /* Now try a library call in this mode. */
2204 if (unoptab
->handlers
[(int) mode
].libfunc
)
2211 /* Pass 1 for NO_QUEUE so we don't lose any increments
2212 if the libcall is cse'd or moved. */
2213 value
= emit_library_call_value (unoptab
->handlers
[(int) mode
].libfunc
,
2214 NULL_RTX
, LCT_CONST
, mode
, 1, op0
, mode
);
2215 insns
= get_insns ();
2218 target
= gen_reg_rtx (mode
);
2219 emit_libcall_block (insns
, target
, value
,
2220 gen_rtx_fmt_e (unoptab
->code
, mode
, op0
));
2225 /* It can't be done in this mode. Can we do it in a wider mode? */
2227 if (class == MODE_INT
|| class == MODE_FLOAT
|| class == MODE_COMPLEX_FLOAT
)
2229 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2230 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2232 if ((unoptab
->handlers
[(int) wider_mode
].insn_code
2233 != CODE_FOR_nothing
)
2234 || unoptab
->handlers
[(int) wider_mode
].libfunc
)
2238 /* For certain operations, we need not actually extend
2239 the narrow operand, as long as we will truncate the
2240 results to the same narrowness. */
2242 xop0
= widen_operand (xop0
, wider_mode
, mode
, unsignedp
,
2243 (unoptab
== neg_optab
2244 || unoptab
== one_cmpl_optab
)
2245 && class == MODE_INT
);
2247 temp
= expand_unop (wider_mode
, unoptab
, xop0
, NULL_RTX
,
2252 if (class != MODE_INT
)
2255 target
= gen_reg_rtx (mode
);
2256 convert_move (target
, temp
, 0);
2260 return gen_lowpart (mode
, temp
);
2263 delete_insns_since (last
);
2268 /* If there is no negate operation, try doing a subtract from zero.
2269 The US Software GOFAST library needs this. */
2270 if (unoptab
->code
== NEG
)
2273 temp
= expand_binop (mode
,
2274 unoptab
== negv_optab
? subv_optab
: sub_optab
,
2275 CONST0_RTX (mode
), op0
,
2276 target
, unsignedp
, OPTAB_LIB_WIDEN
);
2284 /* Emit code to compute the absolute value of OP0, with result to
2285 TARGET if convenient. (TARGET may be 0.) The return value says
2286 where the result actually is to be found.
2288 MODE is the mode of the operand; the mode of the result is
2289 different but can be deduced from MODE.
2294 expand_abs (mode
, op0
, target
, result_unsignedp
, safe
)
2295 enum machine_mode mode
;
2298 int result_unsignedp
;
2304 result_unsignedp
= 1;
2306 /* First try to do it with a special abs instruction. */
2307 temp
= expand_unop (mode
, result_unsignedp
? abs_optab
: absv_optab
,
2312 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2313 if (smax_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2315 rtx last
= get_last_insn ();
2317 temp
= expand_unop (mode
, neg_optab
, op0
, NULL_RTX
, 0);
2319 temp
= expand_binop (mode
, smax_optab
, op0
, temp
, target
, 0,
2325 delete_insns_since (last
);
2328 /* If this machine has expensive jumps, we can do integer absolute
2329 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2330 where W is the width of MODE. */
2332 if (GET_MODE_CLASS (mode
) == MODE_INT
&& BRANCH_COST
>= 2)
2334 rtx extended
= expand_shift (RSHIFT_EXPR
, mode
, op0
,
2335 size_int (GET_MODE_BITSIZE (mode
) - 1),
2338 temp
= expand_binop (mode
, xor_optab
, extended
, op0
, target
, 0,
2341 temp
= expand_binop (mode
, result_unsignedp
? sub_optab
: subv_optab
,
2342 temp
, extended
, target
, 0, OPTAB_LIB_WIDEN
);
2348 /* If that does not win, use conditional jump and negate. */
2350 /* It is safe to use the target if it is the same
2351 as the source if this is also a pseudo register */
2352 if (op0
== target
&& GET_CODE (op0
) == REG
2353 && REGNO (op0
) >= FIRST_PSEUDO_REGISTER
)
2356 op1
= gen_label_rtx ();
2357 if (target
== 0 || ! safe
2358 || GET_MODE (target
) != mode
2359 || (GET_CODE (target
) == MEM
&& MEM_VOLATILE_P (target
))
2360 || (GET_CODE (target
) == REG
2361 && REGNO (target
) < FIRST_PSEUDO_REGISTER
))
2362 target
= gen_reg_rtx (mode
);
2364 emit_move_insn (target
, op0
);
2367 /* If this mode is an integer too wide to compare properly,
2368 compare word by word. Rely on CSE to optimize constant cases. */
2369 if (GET_MODE_CLASS (mode
) == MODE_INT
2370 && ! can_compare_p (GE
, mode
, ccp_jump
))
2371 do_jump_by_parts_greater_rtx (mode
, 0, target
, const0_rtx
,
2374 do_compare_rtx_and_jump (target
, CONST0_RTX (mode
), GE
, 0, mode
,
2375 NULL_RTX
, 0, NULL_RTX
, op1
);
2377 op0
= expand_unop (mode
, result_unsignedp
? neg_optab
: negv_optab
,
2380 emit_move_insn (target
, op0
);
2386 /* Emit code to compute the absolute value of OP0, with result to
2387 TARGET if convenient. (TARGET may be 0.) The return value says
2388 where the result actually is to be found.
2390 MODE is the mode of the operand; the mode of the result is
2391 different but can be deduced from MODE.
2393 UNSIGNEDP is relevant for complex integer modes. */
2396 expand_complex_abs (mode
, op0
, target
, unsignedp
)
2397 enum machine_mode mode
;
2402 enum mode_class
class = GET_MODE_CLASS (mode
);
2403 enum machine_mode wider_mode
;
2405 rtx entry_last
= get_last_insn ();
2408 optab this_abs_optab
;
2410 /* Find the correct mode for the real and imaginary parts. */
2411 enum machine_mode submode
2412 = mode_for_size (GET_MODE_UNIT_SIZE (mode
) * BITS_PER_UNIT
,
2413 class == MODE_COMPLEX_INT
? MODE_INT
: MODE_FLOAT
,
2416 if (submode
== BLKmode
)
2419 op0
= protect_from_queue (op0
, 0);
2423 op0
= force_not_mem (op0
);
2426 last
= get_last_insn ();
2429 target
= protect_from_queue (target
, 1);
2431 this_abs_optab
= ! unsignedp
&& flag_trapv
2432 && (GET_MODE_CLASS(mode
) == MODE_INT
)
2433 ? absv_optab
: abs_optab
;
2435 if (this_abs_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
2437 int icode
= (int) this_abs_optab
->handlers
[(int) mode
].insn_code
;
2438 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2444 temp
= gen_reg_rtx (submode
);
2446 if (GET_MODE (xop0
) != VOIDmode
2447 && GET_MODE (xop0
) != mode0
)
2448 xop0
= convert_to_mode (mode0
, xop0
, unsignedp
);
2450 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2452 if (! (*insn_data
[icode
].operand
[1].predicate
) (xop0
, mode0
))
2453 xop0
= copy_to_mode_reg (mode0
, xop0
);
2455 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, submode
))
2456 temp
= gen_reg_rtx (submode
);
2458 pat
= GEN_FCN (icode
) (temp
, xop0
);
2461 if (GET_CODE (pat
) == SEQUENCE
2462 && ! add_equal_note (pat
, temp
, this_abs_optab
->code
, xop0
,
2465 delete_insns_since (last
);
2466 return expand_unop (mode
, this_abs_optab
, op0
, NULL_RTX
,
2475 delete_insns_since (last
);
2478 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2480 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2481 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2483 if (this_abs_optab
->handlers
[(int) wider_mode
].insn_code
2484 != CODE_FOR_nothing
)
2488 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2489 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2493 if (class != MODE_COMPLEX_INT
)
2496 target
= gen_reg_rtx (submode
);
2497 convert_move (target
, temp
, 0);
2501 return gen_lowpart (submode
, temp
);
2504 delete_insns_since (last
);
2508 /* Open-code the complex absolute-value operation
2509 if we can open-code sqrt. Otherwise it's not worth while. */
2510 if (sqrt_optab
->handlers
[(int) submode
].insn_code
!= CODE_FOR_nothing
2513 rtx real
, imag
, total
;
2515 real
= gen_realpart (submode
, op0
);
2516 imag
= gen_imagpart (submode
, op0
);
2518 /* Square both parts. */
2519 real
= expand_mult (submode
, real
, real
, NULL_RTX
, 0);
2520 imag
= expand_mult (submode
, imag
, imag
, NULL_RTX
, 0);
2522 /* Sum the parts. */
2523 total
= expand_binop (submode
, add_optab
, real
, imag
, NULL_RTX
,
2524 0, OPTAB_LIB_WIDEN
);
2526 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2527 target
= expand_unop (submode
, sqrt_optab
, total
, target
, 0);
2529 delete_insns_since (last
);
2534 /* Now try a library call in this mode. */
2535 if (this_abs_optab
->handlers
[(int) mode
].libfunc
)
2542 /* Pass 1 for NO_QUEUE so we don't lose any increments
2543 if the libcall is cse'd or moved. */
2544 value
= emit_library_call_value (abs_optab
->handlers
[(int) mode
].libfunc
,
2545 NULL_RTX
, LCT_CONST
, submode
, 1, op0
, mode
);
2546 insns
= get_insns ();
2549 target
= gen_reg_rtx (submode
);
2550 emit_libcall_block (insns
, target
, value
,
2551 gen_rtx_fmt_e (this_abs_optab
->code
, mode
, op0
));
2556 /* It can't be done in this mode. Can we do it in a wider mode? */
2558 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
2559 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
2561 if ((this_abs_optab
->handlers
[(int) wider_mode
].insn_code
2562 != CODE_FOR_nothing
)
2563 || this_abs_optab
->handlers
[(int) wider_mode
].libfunc
)
2567 xop0
= convert_modes (wider_mode
, mode
, xop0
, unsignedp
);
2569 temp
= expand_complex_abs (wider_mode
, xop0
, NULL_RTX
, unsignedp
);
2573 if (class != MODE_COMPLEX_INT
)
2576 target
= gen_reg_rtx (submode
);
2577 convert_move (target
, temp
, 0);
2581 return gen_lowpart (submode
, temp
);
2584 delete_insns_since (last
);
2588 delete_insns_since (entry_last
);
2592 /* Generate an instruction whose insn-code is INSN_CODE,
2593 with two operands: an output TARGET and an input OP0.
2594 TARGET *must* be nonzero, and the output is always stored there.
2595 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2596 the value that is stored into TARGET. */
2599 emit_unop_insn (icode
, target
, op0
, code
)
2606 enum machine_mode mode0
= insn_data
[icode
].operand
[1].mode
;
2609 temp
= target
= protect_from_queue (target
, 1);
2611 op0
= protect_from_queue (op0
, 0);
2613 /* Sign and zero extension from memory is often done specially on
2614 RISC machines, so forcing into a register here can pessimize
2616 if (flag_force_mem
&& code
!= SIGN_EXTEND
&& code
!= ZERO_EXTEND
)
2617 op0
= force_not_mem (op0
);
2619 /* Now, if insn does not accept our operands, put them into pseudos. */
2621 if (! (*insn_data
[icode
].operand
[1].predicate
) (op0
, mode0
))
2622 op0
= copy_to_mode_reg (mode0
, op0
);
2624 if (! (*insn_data
[icode
].operand
[0].predicate
) (temp
, GET_MODE (temp
))
2625 || (flag_force_mem
&& GET_CODE (temp
) == MEM
))
2626 temp
= gen_reg_rtx (GET_MODE (temp
));
2628 pat
= GEN_FCN (icode
) (temp
, op0
);
2630 if (GET_CODE (pat
) == SEQUENCE
&& code
!= UNKNOWN
)
2631 add_equal_note (pat
, temp
, code
, op0
, NULL_RTX
);
2636 emit_move_insn (target
, temp
);
2639 /* Emit code to perform a series of operations on a multi-word quantity, one
2642 Such a block is preceded by a CLOBBER of the output, consists of multiple
2643 insns, each setting one word of the output, and followed by a SET copying
2644 the output to itself.
2646 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2647 note indicating that it doesn't conflict with the (also multi-word)
2648 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2651 INSNS is a block of code generated to perform the operation, not including
2652 the CLOBBER and final copy. All insns that compute intermediate values
2653 are first emitted, followed by the block as described above.
2655 TARGET, OP0, and OP1 are the output and inputs of the operations,
2656 respectively. OP1 may be zero for a unary operation.
2658 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2661 If TARGET is not a register, INSNS is simply emitted with no special
2662 processing. Likewise if anything in INSNS is not an INSN or if
2663 there is a libcall block inside INSNS.
2665 The final insn emitted is returned. */
2668 emit_no_conflict_block (insns
, target
, op0
, op1
, equiv
)
2674 rtx prev
, next
, first
, last
, insn
;
2676 if (GET_CODE (target
) != REG
|| reload_in_progress
)
2677 return emit_insns (insns
);
2679 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2680 if (GET_CODE (insn
) != INSN
2681 || find_reg_note (insn
, REG_LIBCALL
, NULL_RTX
))
2682 return emit_insns (insns
);
2684 /* First emit all insns that do not store into words of the output and remove
2685 these from the list. */
2686 for (insn
= insns
; insn
; insn
= next
)
2691 next
= NEXT_INSN (insn
);
2693 if (GET_CODE (PATTERN (insn
)) == SET
|| GET_CODE (PATTERN (insn
)) == USE
2694 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
2695 set
= PATTERN (insn
);
2696 else if (GET_CODE (PATTERN (insn
)) == PARALLEL
)
2698 for (i
= 0; i
< XVECLEN (PATTERN (insn
), 0); i
++)
2699 if (GET_CODE (XVECEXP (PATTERN (insn
), 0, i
)) == SET
)
2701 set
= XVECEXP (PATTERN (insn
), 0, i
);
2709 if (! reg_overlap_mentioned_p (target
, SET_DEST (set
)))
2711 if (PREV_INSN (insn
))
2712 NEXT_INSN (PREV_INSN (insn
)) = next
;
2717 PREV_INSN (next
) = PREV_INSN (insn
);
2723 prev
= get_last_insn ();
2725 /* Now write the CLOBBER of the output, followed by the setting of each
2726 of the words, followed by the final copy. */
2727 if (target
!= op0
&& target
!= op1
)
2728 emit_insn (gen_rtx_CLOBBER (VOIDmode
, target
));
2730 for (insn
= insns
; insn
; insn
= next
)
2732 next
= NEXT_INSN (insn
);
2735 if (op1
&& GET_CODE (op1
) == REG
)
2736 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op1
,
2739 if (op0
&& GET_CODE (op0
) == REG
)
2740 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT
, op0
,
2744 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2745 != CODE_FOR_nothing
)
2747 last
= emit_move_insn (target
, target
);
2749 set_unique_reg_note (last
, REG_EQUAL
, equiv
);
2753 last
= get_last_insn ();
2755 /* Remove any existing REG_EQUAL note from "last", or else it will
2756 be mistaken for a note referring to the full contents of the
2757 alleged libcall value when found together with the REG_RETVAL
2758 note added below. An existing note can come from an insn
2759 expansion at "last". */
2760 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
2764 first
= get_insns ();
2766 first
= NEXT_INSN (prev
);
2768 /* Encapsulate the block so it gets manipulated as a unit. */
2769 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2771 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2776 /* Emit code to make a call to a constant function or a library call.
2778 INSNS is a list containing all insns emitted in the call.
2779 These insns leave the result in RESULT. Our block is to copy RESULT
2780 to TARGET, which is logically equivalent to EQUIV.
2782 We first emit any insns that set a pseudo on the assumption that these are
2783 loading constants into registers; doing so allows them to be safely cse'ed
2784 between blocks. Then we emit all the other insns in the block, followed by
2785 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2786 note with an operand of EQUIV.
2788 Moving assignments to pseudos outside of the block is done to improve
2789 the generated code, but is not required to generate correct code,
2790 hence being unable to move an assignment is not grounds for not making
2791 a libcall block. There are two reasons why it is safe to leave these
2792 insns inside the block: First, we know that these pseudos cannot be
2793 used in generated RTL outside the block since they are created for
2794 temporary purposes within the block. Second, CSE will not record the
2795 values of anything set inside a libcall block, so we know they must
2796 be dead at the end of the block.
2798 Except for the first group of insns (the ones setting pseudos), the
2799 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2802 emit_libcall_block (insns
, target
, result
, equiv
)
2808 rtx final_dest
= target
;
2809 rtx prev
, next
, first
, last
, insn
;
2811 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2812 into a MEM later. Protect the libcall block from this change. */
2813 if (! REG_P (target
) || REG_USERVAR_P (target
))
2814 target
= gen_reg_rtx (GET_MODE (target
));
2816 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2817 reg note to indicate that this call cannot throw or execute a nonlocal
2818 goto (unless there is already a REG_EH_REGION note, in which case
2819 we update it). Also set the CONST_CALL_P flag. */
2821 for (insn
= insns
; insn
; insn
= NEXT_INSN (insn
))
2822 if (GET_CODE (insn
) == CALL_INSN
)
2824 rtx note
= find_reg_note (insn
, REG_EH_REGION
, NULL_RTX
);
2826 CONST_CALL_P (insn
) = 1;
2828 XEXP (note
, 0) = GEN_INT (-1);
2830 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_EH_REGION
, GEN_INT (-1),
2834 /* First emit all insns that set pseudos. Remove them from the list as
2835 we go. Avoid insns that set pseudos which were referenced in previous
2836 insns. These can be generated by move_by_pieces, for example,
2837 to update an address. Similarly, avoid insns that reference things
2838 set in previous insns. */
2840 for (insn
= insns
; insn
; insn
= next
)
2842 rtx set
= single_set (insn
);
2844 next
= NEXT_INSN (insn
);
2846 if (set
!= 0 && GET_CODE (SET_DEST (set
)) == REG
2847 && REGNO (SET_DEST (set
)) >= FIRST_PSEUDO_REGISTER
2849 || ((! INSN_P(insns
)
2850 || ! reg_mentioned_p (SET_DEST (set
), PATTERN (insns
)))
2851 && ! reg_used_between_p (SET_DEST (set
), insns
, insn
)
2852 && ! modified_in_p (SET_SRC (set
), insns
)
2853 && ! modified_between_p (SET_SRC (set
), insns
, insn
))))
2855 if (PREV_INSN (insn
))
2856 NEXT_INSN (PREV_INSN (insn
)) = next
;
2861 PREV_INSN (next
) = PREV_INSN (insn
);
2867 prev
= get_last_insn ();
2869 /* Write the remaining insns followed by the final copy. */
2871 for (insn
= insns
; insn
; insn
= next
)
2873 next
= NEXT_INSN (insn
);
2878 last
= emit_move_insn (target
, result
);
2879 if (mov_optab
->handlers
[(int) GET_MODE (target
)].insn_code
2880 != CODE_FOR_nothing
)
2881 set_unique_reg_note (last
, REG_EQUAL
, copy_rtx (equiv
));
2884 /* Remove any existing REG_EQUAL note from "last", or else it will
2885 be mistaken for a note referring to the full contents of the
2886 libcall value when found together with the REG_RETVAL note added
2887 below. An existing note can come from an insn expansion at
2889 remove_note (last
, find_reg_note (last
, REG_EQUAL
, NULL_RTX
));
2892 if (final_dest
!= target
)
2893 emit_move_insn (final_dest
, target
);
2896 first
= get_insns ();
2898 first
= NEXT_INSN (prev
);
2900 /* Encapsulate the block so it gets manipulated as a unit. */
2901 REG_NOTES (first
) = gen_rtx_INSN_LIST (REG_LIBCALL
, last
,
2903 REG_NOTES (last
) = gen_rtx_INSN_LIST (REG_RETVAL
, first
, REG_NOTES (last
));
2906 /* Generate code to store zero in X. */
2912 emit_move_insn (x
, const0_rtx
);
2915 /* Generate code to store 1 in X
2916 assuming it contains zero beforehand. */
2919 emit_0_to_1_insn (x
)
2922 emit_move_insn (x
, const1_rtx
);
2925 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2926 PURPOSE describes how this comparison will be used. CODE is the rtx
2927 comparison code we will be using.
2929 ??? Actually, CODE is slightly weaker than that. A target is still
2930 required to implement all of the normal bcc operations, but not
2931 required to implement all (or any) of the unordered bcc operations. */
2934 can_compare_p (code
, mode
, purpose
)
2936 enum machine_mode mode
;
2937 enum can_compare_purpose purpose
;
2941 if (cmp_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2943 if (purpose
== ccp_jump
)
2944 return bcc_gen_fctn
[(int)code
] != NULL
;
2945 else if (purpose
== ccp_store_flag
)
2946 return setcc_gen_code
[(int)code
] != CODE_FOR_nothing
;
2948 /* There's only one cmov entry point, and it's allowed to fail. */
2951 if (purpose
== ccp_jump
2952 && cbranch_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2954 if (purpose
== ccp_cmov
2955 && cmov_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2957 if (purpose
== ccp_store_flag
2958 && cstore_optab
->handlers
[(int)mode
].insn_code
!= CODE_FOR_nothing
)
2961 mode
= GET_MODE_WIDER_MODE (mode
);
2963 while (mode
!= VOIDmode
);
2968 /* This function is called when we are going to emit a compare instruction that
2969 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2971 *PMODE is the mode of the inputs (in case they are const_int).
2972 *PUNSIGNEDP nonzero says that the operands are unsigned;
2973 this matters if they need to be widened.
2975 If they have mode BLKmode, then SIZE specifies the size of both operands,
2976 and ALIGN specifies the known shared alignment of the operands.
2978 This function performs all the setup necessary so that the caller only has
2979 to emit a single comparison insn. This setup can involve doing a BLKmode
2980 comparison or emitting a library call to perform the comparison if no insn
2981 is available to handle it.
2982 The values which are passed in through pointers can be modified; the caller
2983 should perform the comparison on the modified values. */
2986 prepare_cmp_insn (px
, py
, pcomparison
, size
, pmode
, punsignedp
, align
,
2989 enum rtx_code
*pcomparison
;
2991 enum machine_mode
*pmode
;
2993 int align ATTRIBUTE_UNUSED
;
2994 enum can_compare_purpose purpose
;
2996 enum machine_mode mode
= *pmode
;
2997 rtx x
= *px
, y
= *py
;
2998 int unsignedp
= *punsignedp
;
2999 enum mode_class
class;
3000 rtx opalign ATTRIBUTE_UNUSED
= GEN_INT (align
/ BITS_PER_UNIT
);;
3002 class = GET_MODE_CLASS (mode
);
3004 /* They could both be VOIDmode if both args are immediate constants,
3005 but we should fold that at an earlier stage.
3006 With no special code here, this will call abort,
3007 reminding the programmer to implement such folding. */
3009 if (mode
!= BLKmode
&& flag_force_mem
)
3011 x
= force_not_mem (x
);
3012 y
= force_not_mem (y
);
3015 /* If we are inside an appropriately-short loop and one operand is an
3016 expensive constant, force it into a register. */
3017 if (CONSTANT_P (x
) && preserve_subexpressions_p ()
3018 && rtx_cost (x
, COMPARE
) > COSTS_N_INSNS (1))
3019 x
= force_reg (mode
, x
);
3021 if (CONSTANT_P (y
) && preserve_subexpressions_p ()
3022 && rtx_cost (y
, COMPARE
) > COSTS_N_INSNS (1))
3023 y
= force_reg (mode
, y
);
3026 /* Abort if we have a non-canonical comparison. The RTL documentation
3027 states that canonical comparisons are required only for targets which
3029 if (CONSTANT_P (x
) && ! CONSTANT_P (y
))
3033 /* Don't let both operands fail to indicate the mode. */
3034 if (GET_MODE (x
) == VOIDmode
&& GET_MODE (y
) == VOIDmode
)
3035 x
= force_reg (mode
, x
);
3037 /* Handle all BLKmode compares. */
3039 if (mode
== BLKmode
)
3042 enum machine_mode result_mode
;
3045 x
= protect_from_queue (x
, 0);
3046 y
= protect_from_queue (y
, 0);
3050 #ifdef HAVE_cmpstrqi
3052 && GET_CODE (size
) == CONST_INT
3053 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (QImode
)))
3055 result_mode
= insn_data
[(int) CODE_FOR_cmpstrqi
].operand
[0].mode
;
3056 result
= gen_reg_rtx (result_mode
);
3057 emit_insn (gen_cmpstrqi (result
, x
, y
, size
, opalign
));
3061 #ifdef HAVE_cmpstrhi
3063 && GET_CODE (size
) == CONST_INT
3064 && INTVAL (size
) < (1 << GET_MODE_BITSIZE (HImode
)))
3066 result_mode
= insn_data
[(int) CODE_FOR_cmpstrhi
].operand
[0].mode
;
3067 result
= gen_reg_rtx (result_mode
);
3068 emit_insn (gen_cmpstrhi (result
, x
, y
, size
, opalign
));
3072 #ifdef HAVE_cmpstrsi
3075 result_mode
= insn_data
[(int) CODE_FOR_cmpstrsi
].operand
[0].mode
;
3076 result
= gen_reg_rtx (result_mode
);
3077 size
= protect_from_queue (size
, 0);
3078 emit_insn (gen_cmpstrsi (result
, x
, y
,
3079 convert_to_mode (SImode
, size
, 1),
3085 #ifdef TARGET_MEM_FUNCTIONS
3086 emit_library_call (memcmp_libfunc
, LCT_PURE_MAKE_BLOCK
,
3087 TYPE_MODE (integer_type_node
), 3,
3088 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
3089 convert_to_mode (TYPE_MODE (sizetype
), size
,
3090 TREE_UNSIGNED (sizetype
)),
3091 TYPE_MODE (sizetype
));
3093 emit_library_call (bcmp_libfunc
, LCT_PURE_MAKE_BLOCK
,
3094 TYPE_MODE (integer_type_node
), 3,
3095 XEXP (x
, 0), Pmode
, XEXP (y
, 0), Pmode
,
3096 convert_to_mode (TYPE_MODE (integer_type_node
),
3098 TREE_UNSIGNED (integer_type_node
)),
3099 TYPE_MODE (integer_type_node
));
3102 /* Immediately move the result of the libcall into a pseudo
3103 register so reload doesn't clobber the value if it needs
3104 the return register for a spill reg. */
3105 result
= gen_reg_rtx (TYPE_MODE (integer_type_node
));
3106 result_mode
= TYPE_MODE (integer_type_node
);
3107 emit_move_insn (result
,
3108 hard_libcall_value (result_mode
));
3112 *pmode
= result_mode
;
3118 if (can_compare_p (*pcomparison
, mode
, purpose
))
3121 /* Handle a lib call just for the mode we are using. */
3123 if (cmp_optab
->handlers
[(int) mode
].libfunc
&& class != MODE_FLOAT
)
3125 rtx libfunc
= cmp_optab
->handlers
[(int) mode
].libfunc
;
3128 /* If we want unsigned, and this mode has a distinct unsigned
3129 comparison routine, use that. */
3130 if (unsignedp
&& ucmp_optab
->handlers
[(int) mode
].libfunc
)
3131 libfunc
= ucmp_optab
->handlers
[(int) mode
].libfunc
;
3133 emit_library_call (libfunc
, 1,
3134 word_mode
, 2, x
, mode
, y
, mode
);
3136 /* Immediately move the result of the libcall into a pseudo
3137 register so reload doesn't clobber the value if it needs
3138 the return register for a spill reg. */
3139 result
= gen_reg_rtx (word_mode
);
3140 emit_move_insn (result
, hard_libcall_value (word_mode
));
3142 /* Integer comparison returns a result that must be compared against 1,
3143 so that even if we do an unsigned compare afterward,
3144 there is still a value that can represent the result "less than". */
3151 if (class == MODE_FLOAT
)
3152 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
);
3158 /* Before emitting an insn with code ICODE, make sure that X, which is going
3159 to be used for operand OPNUM of the insn, is converted from mode MODE to
3160 WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3161 that it is accepted by the operand predicate. Return the new value. */
3164 prepare_operand (icode
, x
, opnum
, mode
, wider_mode
, unsignedp
)
3168 enum machine_mode mode
, wider_mode
;
3171 x
= protect_from_queue (x
, 0);
3173 if (mode
!= wider_mode
)
3174 x
= convert_modes (wider_mode
, mode
, x
, unsignedp
);
3176 if (! (*insn_data
[icode
].operand
[opnum
].predicate
)
3177 (x
, insn_data
[icode
].operand
[opnum
].mode
))
3178 x
= copy_to_mode_reg (insn_data
[icode
].operand
[opnum
].mode
, x
);
3182 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3183 we can do the comparison.
3184 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3185 be NULL_RTX which indicates that only a comparison is to be generated. */
3188 emit_cmp_and_jump_insn_1 (x
, y
, mode
, comparison
, unsignedp
, label
)
3190 enum machine_mode mode
;
3191 enum rtx_code comparison
;
3195 rtx test
= gen_rtx_fmt_ee (comparison
, mode
, x
, y
);
3196 enum mode_class
class = GET_MODE_CLASS (mode
);
3197 enum machine_mode wider_mode
= mode
;
3199 /* Try combined insns first. */
3202 enum insn_code icode
;
3203 PUT_MODE (test
, wider_mode
);
3207 icode
= cbranch_optab
->handlers
[(int)wider_mode
].insn_code
;
3209 if (icode
!= CODE_FOR_nothing
3210 && (*insn_data
[icode
].operand
[0].predicate
) (test
, wider_mode
))
3212 x
= prepare_operand (icode
, x
, 1, mode
, wider_mode
, unsignedp
);
3213 y
= prepare_operand (icode
, y
, 2, mode
, wider_mode
, unsignedp
);
3214 emit_jump_insn (GEN_FCN (icode
) (test
, x
, y
, label
));
3219 /* Handle some compares against zero. */
3220 icode
= (int) tst_optab
->handlers
[(int) wider_mode
].insn_code
;
3221 if (y
== CONST0_RTX (mode
) && icode
!= CODE_FOR_nothing
)
3223 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
3224 emit_insn (GEN_FCN (icode
) (x
));
3226 emit_jump_insn ((*bcc_gen_fctn
[(int) comparison
]) (label
));
3230 /* Handle compares for which there is a directly suitable insn. */
3232 icode
= (int) cmp_optab
->handlers
[(int) wider_mode
].insn_code
;
3233 if (icode
!= CODE_FOR_nothing
)
3235 x
= prepare_operand (icode
, x
, 0, mode
, wider_mode
, unsignedp
);
3236 y
= prepare_operand (icode
, y
, 1, mode
, wider_mode
, unsignedp
);
3237 emit_insn (GEN_FCN (icode
) (x
, y
));
3239 emit_jump_insn ((*bcc_gen_fctn
[(int) comparison
]) (label
));
3243 if (class != MODE_INT
&& class != MODE_FLOAT
3244 && class != MODE_COMPLEX_FLOAT
)
3247 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
);
3248 } while (wider_mode
!= VOIDmode
);
3253 /* Generate code to compare X with Y so that the condition codes are
3254 set and to jump to LABEL if the condition is true. If X is a
3255 constant and Y is not a constant, then the comparison is swapped to
3256 ensure that the comparison RTL has the canonical form.
3258 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3259 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3260 the proper branch condition code.
3262 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3263 and ALIGN specifies the known shared alignment of X and Y.
3265 MODE is the mode of the inputs (in case they are const_int).
3267 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3268 be passed unchanged to emit_cmp_insn, then potentially converted into an
3269 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3272 emit_cmp_and_jump_insns (x
, y
, comparison
, size
, mode
, unsignedp
, align
, label
)
3274 enum rtx_code comparison
;
3276 enum machine_mode mode
;
3284 if ((CONSTANT_P (x
) && ! CONSTANT_P (y
))
3285 || (GET_CODE (x
) == CONST_INT
&& GET_CODE (y
) != CONST_INT
))
3287 /* Swap operands and condition to ensure canonical RTL. */
3290 comparison
= swap_condition (comparison
);
3299 /* If OP0 is still a constant, then both X and Y must be constants. Force
3300 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3302 if (CONSTANT_P (op0
))
3303 op0
= force_reg (mode
, op0
);
3308 comparison
= unsigned_condition (comparison
);
3309 prepare_cmp_insn (&op0
, &op1
, &comparison
, size
, &mode
, &unsignedp
, align
,
3311 emit_cmp_and_jump_insn_1 (op0
, op1
, mode
, comparison
, unsignedp
, label
);
3314 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3317 emit_cmp_insn (x
, y
, comparison
, size
, mode
, unsignedp
, align
)
3319 enum rtx_code comparison
;
3321 enum machine_mode mode
;
3325 emit_cmp_and_jump_insns (x
, y
, comparison
, size
, mode
, unsignedp
, align
, 0);
3328 /* Emit a library call comparison between floating point X and Y.
3329 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3332 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
)
3334 enum rtx_code
*pcomparison
;
3335 enum machine_mode
*pmode
;
3338 enum rtx_code comparison
= *pcomparison
;
3339 rtx x
= *px
= protect_from_queue (*px
, 0);
3340 rtx y
= *py
= protect_from_queue (*py
, 0);
3341 enum machine_mode mode
= GET_MODE (x
);
3349 libfunc
= eqhf2_libfunc
;
3353 libfunc
= nehf2_libfunc
;
3357 libfunc
= gthf2_libfunc
;
3361 libfunc
= gehf2_libfunc
;
3365 libfunc
= lthf2_libfunc
;
3369 libfunc
= lehf2_libfunc
;
3373 libfunc
= unordhf2_libfunc
;
3379 else if (mode
== SFmode
)
3383 libfunc
= eqsf2_libfunc
;
3387 libfunc
= nesf2_libfunc
;
3391 libfunc
= gtsf2_libfunc
;
3395 libfunc
= gesf2_libfunc
;
3399 libfunc
= ltsf2_libfunc
;
3403 libfunc
= lesf2_libfunc
;
3407 libfunc
= unordsf2_libfunc
;
3413 else if (mode
== DFmode
)
3417 libfunc
= eqdf2_libfunc
;
3421 libfunc
= nedf2_libfunc
;
3425 libfunc
= gtdf2_libfunc
;
3429 libfunc
= gedf2_libfunc
;
3433 libfunc
= ltdf2_libfunc
;
3437 libfunc
= ledf2_libfunc
;
3441 libfunc
= unorddf2_libfunc
;
3447 else if (mode
== XFmode
)
3451 libfunc
= eqxf2_libfunc
;
3455 libfunc
= nexf2_libfunc
;
3459 libfunc
= gtxf2_libfunc
;
3463 libfunc
= gexf2_libfunc
;
3467 libfunc
= ltxf2_libfunc
;
3471 libfunc
= lexf2_libfunc
;
3475 libfunc
= unordxf2_libfunc
;
3481 else if (mode
== TFmode
)
3485 libfunc
= eqtf2_libfunc
;
3489 libfunc
= netf2_libfunc
;
3493 libfunc
= gttf2_libfunc
;
3497 libfunc
= getf2_libfunc
;
3501 libfunc
= lttf2_libfunc
;
3505 libfunc
= letf2_libfunc
;
3509 libfunc
= unordtf2_libfunc
;
3517 enum machine_mode wider_mode
;
3519 for (wider_mode
= GET_MODE_WIDER_MODE (mode
); wider_mode
!= VOIDmode
;
3520 wider_mode
= GET_MODE_WIDER_MODE (wider_mode
))
3522 if ((cmp_optab
->handlers
[(int) wider_mode
].insn_code
3523 != CODE_FOR_nothing
)
3524 || (cmp_optab
->handlers
[(int) wider_mode
].libfunc
!= 0))
3526 x
= protect_from_queue (x
, 0);
3527 y
= protect_from_queue (y
, 0);
3528 *px
= convert_to_mode (wider_mode
, x
, 0);
3529 *py
= convert_to_mode (wider_mode
, y
, 0);
3530 prepare_float_lib_cmp (px
, py
, pcomparison
, pmode
, punsignedp
);
3540 emit_library_call (libfunc
, LCT_CONST_MAKE_BLOCK
, word_mode
, 2, x
, mode
, y
,
3543 /* Immediately move the result of the libcall into a pseudo
3544 register so reload doesn't clobber the value if it needs
3545 the return register for a spill reg. */
3546 result
= gen_reg_rtx (word_mode
);
3547 emit_move_insn (result
, hard_libcall_value (word_mode
));
3551 if (comparison
== UNORDERED
)
3553 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3554 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode
, comparison
))
3560 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3563 emit_indirect_jump (loc
)
3566 if (! ((*insn_data
[(int)CODE_FOR_indirect_jump
].operand
[0].predicate
)
3568 loc
= copy_to_mode_reg (Pmode
, loc
);
3570 emit_jump_insn (gen_indirect_jump (loc
));
3574 #ifdef HAVE_conditional_move
3576 /* Emit a conditional move instruction if the machine supports one for that
3577 condition and machine mode.
3579 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3580 the mode to use should they be constants. If it is VOIDmode, they cannot
3583 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3584 should be stored there. MODE is the mode to use should they be constants.
3585 If it is VOIDmode, they cannot both be constants.
3587 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3588 is not supported. */
3591 emit_conditional_move (target
, code
, op0
, op1
, cmode
, op2
, op3
, mode
,
3596 enum machine_mode cmode
;
3598 enum machine_mode mode
;
3601 rtx tem
, subtarget
, comparison
, insn
;
3602 enum insn_code icode
;
3604 /* If one operand is constant, make it the second one. Only do this
3605 if the other operand is not constant as well. */
3607 if ((CONSTANT_P (op0
) && ! CONSTANT_P (op1
))
3608 || (GET_CODE (op0
) == CONST_INT
&& GET_CODE (op1
) != CONST_INT
))
3613 code
= swap_condition (code
);
3616 /* get_condition will prefer to generate LT and GT even if the old
3617 comparison was against zero, so undo that canonicalization here since
3618 comparisons against zero are cheaper. */
3619 if (code
== LT
&& GET_CODE (op1
) == CONST_INT
&& INTVAL (op1
) == 1)
3620 code
= LE
, op1
= const0_rtx
;
3621 else if (code
== GT
&& GET_CODE (op1
) == CONST_INT
&& INTVAL (op1
) == -1)
3622 code
= GE
, op1
= const0_rtx
;
3624 if (cmode
== VOIDmode
)
3625 cmode
= GET_MODE (op0
);
3627 if (((CONSTANT_P (op2
) && ! CONSTANT_P (op3
))
3628 || (GET_CODE (op2
) == CONST_INT
&& GET_CODE (op3
) != CONST_INT
))
3629 && (GET_MODE_CLASS (GET_MODE (op1
)) != MODE_FLOAT
3630 || TARGET_FLOAT_FORMAT
!= IEEE_FLOAT_FORMAT
3631 || flag_unsafe_math_optimizations
))
3636 code
= reverse_condition (code
);
3639 if (mode
== VOIDmode
)
3640 mode
= GET_MODE (op2
);
3642 icode
= movcc_gen_code
[mode
];
3644 if (icode
== CODE_FOR_nothing
)
3649 op2
= force_not_mem (op2
);
3650 op3
= force_not_mem (op3
);
3654 target
= protect_from_queue (target
, 1);
3656 target
= gen_reg_rtx (mode
);
3662 op2
= protect_from_queue (op2
, 0);
3663 op3
= protect_from_queue (op3
, 0);
3665 /* If the insn doesn't accept these operands, put them in pseudos. */
3667 if (! (*insn_data
[icode
].operand
[0].predicate
)
3668 (subtarget
, insn_data
[icode
].operand
[0].mode
))
3669 subtarget
= gen_reg_rtx (insn_data
[icode
].operand
[0].mode
);
3671 if (! (*insn_data
[icode
].operand
[2].predicate
)
3672 (op2
, insn_data
[icode
].operand
[2].mode
))
3673 op2
= copy_to_mode_reg (insn_data
[icode
].operand
[2].mode
, op2
);
3675 if (! (*insn_data
[icode
].operand
[3].predicate
)
3676 (op3
, insn_data
[icode
].operand
[3].mode
))
3677 op3
= copy_to_mode_reg (insn_data
[icode
].operand
[3].mode
, op3
);
3679 /* Everything should now be in the suitable form, so emit the compare insn
3680 and then the conditional move. */
3683 = compare_from_rtx (op0
, op1
, code
, unsignedp
, cmode
, NULL_RTX
, 0);
3685 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3686 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3687 return NULL and let the caller figure out how best to deal with this
3689 if (GET_CODE (comparison
) != code
)
3692 insn
= GEN_FCN (icode
) (subtarget
, comparison
, op2
, op3
);
3694 /* If that failed, then give up. */
3700 if (subtarget
!= target
)
3701 convert_move (target
, subtarget
, 0);
3706 /* Return non-zero if a conditional move of mode MODE is supported.
3708 This function is for combine so it can tell whether an insn that looks
3709 like a conditional move is actually supported by the hardware. If we
3710 guess wrong we lose a bit on optimization, but that's it. */
3711 /* ??? sparc64 supports conditionally moving integers values based on fp
3712 comparisons, and vice versa. How do we handle them? */
3715 can_conditionally_move_p (mode
)
3716 enum machine_mode mode
;
3718 if (movcc_gen_code
[mode
] != CODE_FOR_nothing
)
3724 #endif /* HAVE_conditional_move */
3726 /* These three functions generate an insn body and return it
3727 rather than emitting the insn.
3729 They do not protect from queued increments,
3730 because they may be used 1) in protect_from_queue itself
3731 and 2) in other passes where there is no queue. */
3733 /* Generate and return an insn body to add Y to X. */
3736 gen_add2_insn (x
, y
)
3739 int icode
= (int) add_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3741 if (! ((*insn_data
[icode
].operand
[0].predicate
)
3742 (x
, insn_data
[icode
].operand
[0].mode
))
3743 || ! ((*insn_data
[icode
].operand
[1].predicate
)
3744 (x
, insn_data
[icode
].operand
[1].mode
))
3745 || ! ((*insn_data
[icode
].operand
[2].predicate
)
3746 (y
, insn_data
[icode
].operand
[2].mode
)))
3749 return (GEN_FCN (icode
) (x
, x
, y
));
3753 have_add2_insn (mode
)
3754 enum machine_mode mode
;
3756 return add_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3759 /* Generate and return an insn body to subtract Y from X. */
3762 gen_sub2_insn (x
, y
)
3765 int icode
= (int) sub_optab
->handlers
[(int) GET_MODE (x
)].insn_code
;
3767 if (! ((*insn_data
[icode
].operand
[0].predicate
)
3768 (x
, insn_data
[icode
].operand
[0].mode
))
3769 || ! ((*insn_data
[icode
].operand
[1].predicate
)
3770 (x
, insn_data
[icode
].operand
[1].mode
))
3771 || ! ((*insn_data
[icode
].operand
[2].predicate
)
3772 (y
, insn_data
[icode
].operand
[2].mode
)))
3775 return (GEN_FCN (icode
) (x
, x
, y
));
3779 have_sub2_insn (mode
)
3780 enum machine_mode mode
;
3782 return sub_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
;
3785 /* Generate the body of an instruction to copy Y into X.
3786 It may be a SEQUENCE, if one insn isn't enough. */
3789 gen_move_insn (x
, y
)
3792 register enum machine_mode mode
= GET_MODE (x
);
3793 enum insn_code insn_code
;
3796 if (mode
== VOIDmode
)
3797 mode
= GET_MODE (y
);
3799 insn_code
= mov_optab
->handlers
[(int) mode
].insn_code
;
3801 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3802 find a mode to do it in. If we have a movcc, use it. Otherwise,
3803 find the MODE_INT mode of the same width. */
3805 if (GET_MODE_CLASS (mode
) == MODE_CC
&& insn_code
== CODE_FOR_nothing
)
3807 enum machine_mode tmode
= VOIDmode
;
3811 && mov_optab
->handlers
[(int) CCmode
].insn_code
!= CODE_FOR_nothing
)
3814 for (tmode
= QImode
; tmode
!= VOIDmode
;
3815 tmode
= GET_MODE_WIDER_MODE (tmode
))
3816 if (GET_MODE_SIZE (tmode
) == GET_MODE_SIZE (mode
))
3819 if (tmode
== VOIDmode
)
3822 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3823 may call change_address which is not appropriate if we were
3824 called when a reload was in progress. We don't have to worry
3825 about changing the address since the size in bytes is supposed to
3826 be the same. Copy the MEM to change the mode and move any
3827 substitutions from the old MEM to the new one. */
3829 if (reload_in_progress
)
3831 x
= gen_lowpart_common (tmode
, x1
);
3832 if (x
== 0 && GET_CODE (x1
) == MEM
)
3834 x
= gen_rtx_MEM (tmode
, XEXP (x1
, 0));
3835 MEM_COPY_ATTRIBUTES (x
, x1
);
3836 copy_replacements (x1
, x
);
3839 y
= gen_lowpart_common (tmode
, y1
);
3840 if (y
== 0 && GET_CODE (y1
) == MEM
)
3842 y
= gen_rtx_MEM (tmode
, XEXP (y1
, 0));
3843 MEM_COPY_ATTRIBUTES (y
, y1
);
3844 copy_replacements (y1
, y
);
3849 x
= gen_lowpart (tmode
, x
);
3850 y
= gen_lowpart (tmode
, y
);
3853 insn_code
= mov_optab
->handlers
[(int) tmode
].insn_code
;
3854 return (GEN_FCN (insn_code
) (x
, y
));
3858 emit_move_insn_1 (x
, y
);
3859 seq
= gen_sequence ();
3864 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3865 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3866 no such operation exists, CODE_FOR_nothing will be returned. */
3869 can_extend_p (to_mode
, from_mode
, unsignedp
)
3870 enum machine_mode to_mode
, from_mode
;
3873 return extendtab
[(int) to_mode
][(int) from_mode
][unsignedp
!= 0];
3876 /* Generate the body of an insn to extend Y (with mode MFROM)
3877 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3880 gen_extend_insn (x
, y
, mto
, mfrom
, unsignedp
)
3882 enum machine_mode mto
, mfrom
;
3885 return (GEN_FCN (extendtab
[(int) mto
][(int) mfrom
][unsignedp
!= 0]) (x
, y
));
3888 /* can_fix_p and can_float_p say whether the target machine
3889 can directly convert a given fixed point type to
3890 a given floating point type, or vice versa.
3891 The returned value is the CODE_FOR_... value to use,
3892 or CODE_FOR_nothing if these modes cannot be directly converted.
3894 *TRUNCP_PTR is set to 1 if it is necessary to output
3895 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3897 static enum insn_code
3898 can_fix_p (fixmode
, fltmode
, unsignedp
, truncp_ptr
)
3899 enum machine_mode fltmode
, fixmode
;
3904 if (fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0]
3905 != CODE_FOR_nothing
)
3906 return fixtrunctab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3908 if (ftrunc_optab
->handlers
[(int) fltmode
].insn_code
!= CODE_FOR_nothing
)
3911 return fixtab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3913 return CODE_FOR_nothing
;
3916 static enum insn_code
3917 can_float_p (fltmode
, fixmode
, unsignedp
)
3918 enum machine_mode fixmode
, fltmode
;
3921 return floattab
[(int) fltmode
][(int) fixmode
][unsignedp
!= 0];
3924 /* Generate code to convert FROM to floating point
3925 and store in TO. FROM must be fixed point and not VOIDmode.
3926 UNSIGNEDP nonzero means regard FROM as unsigned.
3927 Normally this is done by correcting the final value
3928 if it is negative. */
3931 expand_float (to
, from
, unsignedp
)
3935 enum insn_code icode
;
3936 register rtx target
= to
;
3937 enum machine_mode fmode
, imode
;
3939 /* Crash now, because we won't be able to decide which mode to use. */
3940 if (GET_MODE (from
) == VOIDmode
)
3943 /* Look for an insn to do the conversion. Do it in the specified
3944 modes if possible; otherwise convert either input, output or both to
3945 wider mode. If the integer mode is wider than the mode of FROM,
3946 we can do the conversion signed even if the input is unsigned. */
3948 for (imode
= GET_MODE (from
); imode
!= VOIDmode
;
3949 imode
= GET_MODE_WIDER_MODE (imode
))
3950 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
3951 fmode
= GET_MODE_WIDER_MODE (fmode
))
3953 int doing_unsigned
= unsignedp
;
3955 if (fmode
!= GET_MODE (to
)
3956 && significand_size (fmode
) < GET_MODE_BITSIZE (GET_MODE (from
)))
3959 icode
= can_float_p (fmode
, imode
, unsignedp
);
3960 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (from
) && unsignedp
)
3961 icode
= can_float_p (fmode
, imode
, 0), doing_unsigned
= 0;
3963 if (icode
!= CODE_FOR_nothing
)
3965 to
= protect_from_queue (to
, 1);
3966 from
= protect_from_queue (from
, 0);
3968 if (imode
!= GET_MODE (from
))
3969 from
= convert_to_mode (imode
, from
, unsignedp
);
3971 if (fmode
!= GET_MODE (to
))
3972 target
= gen_reg_rtx (fmode
);
3974 emit_unop_insn (icode
, target
, from
,
3975 doing_unsigned
? UNSIGNED_FLOAT
: FLOAT
);
3978 convert_move (to
, target
, 0);
3983 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3985 /* Unsigned integer, and no way to convert directly.
3986 Convert as signed, then conditionally adjust the result. */
3989 rtx label
= gen_label_rtx ();
3991 REAL_VALUE_TYPE offset
;
3995 to
= protect_from_queue (to
, 1);
3996 from
= protect_from_queue (from
, 0);
3999 from
= force_not_mem (from
);
4001 /* Look for a usable floating mode FMODE wider than the source and at
4002 least as wide as the target. Using FMODE will avoid rounding woes
4003 with unsigned values greater than the signed maximum value. */
4005 for (fmode
= GET_MODE (to
); fmode
!= VOIDmode
;
4006 fmode
= GET_MODE_WIDER_MODE (fmode
))
4007 if (GET_MODE_BITSIZE (GET_MODE (from
)) < GET_MODE_BITSIZE (fmode
)
4008 && can_float_p (fmode
, GET_MODE (from
), 0) != CODE_FOR_nothing
)
4011 if (fmode
== VOIDmode
)
4013 /* There is no such mode. Pretend the target is wide enough. */
4014 fmode
= GET_MODE (to
);
4016 /* Avoid double-rounding when TO is narrower than FROM. */
4017 if ((significand_size (fmode
) + 1)
4018 < GET_MODE_BITSIZE (GET_MODE (from
)))
4021 rtx neglabel
= gen_label_rtx ();
4023 /* Don't use TARGET if it isn't a register, is a hard register,
4024 or is the wrong mode. */
4025 if (GET_CODE (target
) != REG
4026 || REGNO (target
) < FIRST_PSEUDO_REGISTER
4027 || GET_MODE (target
) != fmode
)
4028 target
= gen_reg_rtx (fmode
);
4030 imode
= GET_MODE (from
);
4031 do_pending_stack_adjust ();
4033 /* Test whether the sign bit is set. */
4034 emit_cmp_and_jump_insns (from
, const0_rtx
, LT
, NULL_RTX
, imode
,
4037 /* The sign bit is not set. Convert as signed. */
4038 expand_float (target
, from
, 0);
4039 emit_jump_insn (gen_jump (label
));
4042 /* The sign bit is set.
4043 Convert to a usable (positive signed) value by shifting right
4044 one bit, while remembering if a nonzero bit was shifted
4045 out; i.e., compute (from & 1) | (from >> 1). */
4047 emit_label (neglabel
);
4048 temp
= expand_binop (imode
, and_optab
, from
, const1_rtx
,
4049 NULL_RTX
, 1, OPTAB_LIB_WIDEN
);
4050 temp1
= expand_shift (RSHIFT_EXPR
, imode
, from
, integer_one_node
,
4052 temp
= expand_binop (imode
, ior_optab
, temp
, temp1
, temp
, 1,
4054 expand_float (target
, temp
, 0);
4056 /* Multiply by 2 to undo the shift above. */
4057 temp
= expand_binop (fmode
, add_optab
, target
, target
,
4058 target
, 0, OPTAB_LIB_WIDEN
);
4060 emit_move_insn (target
, temp
);
4062 do_pending_stack_adjust ();
4068 /* If we are about to do some arithmetic to correct for an
4069 unsigned operand, do it in a pseudo-register. */
4071 if (GET_MODE (to
) != fmode
4072 || GET_CODE (to
) != REG
|| REGNO (to
) < FIRST_PSEUDO_REGISTER
)
4073 target
= gen_reg_rtx (fmode
);
4075 /* Convert as signed integer to floating. */
4076 expand_float (target
, from
, 0);
4078 /* If FROM is negative (and therefore TO is negative),
4079 correct its value by 2**bitwidth. */
4081 do_pending_stack_adjust ();
4082 emit_cmp_and_jump_insns (from
, const0_rtx
, GE
, NULL_RTX
, GET_MODE (from
),
4085 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4086 Rather than setting up a dconst_dot_5, let's hope SCO
4088 offset
= REAL_VALUE_LDEXP (dconst1
, GET_MODE_BITSIZE (GET_MODE (from
)));
4089 temp
= expand_binop (fmode
, add_optab
, target
,
4090 CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
),
4091 target
, 0, OPTAB_LIB_WIDEN
);
4093 emit_move_insn (target
, temp
);
4095 do_pending_stack_adjust ();
4101 /* No hardware instruction available; call a library routine to convert from
4102 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4108 to
= protect_from_queue (to
, 1);
4109 from
= protect_from_queue (from
, 0);
4111 if (GET_MODE_SIZE (GET_MODE (from
)) < GET_MODE_SIZE (SImode
))
4112 from
= convert_to_mode (SImode
, from
, unsignedp
);
4115 from
= force_not_mem (from
);
4117 if (GET_MODE (to
) == SFmode
)
4119 if (GET_MODE (from
) == SImode
)
4120 libfcn
= floatsisf_libfunc
;
4121 else if (GET_MODE (from
) == DImode
)
4122 libfcn
= floatdisf_libfunc
;
4123 else if (GET_MODE (from
) == TImode
)
4124 libfcn
= floattisf_libfunc
;
4128 else if (GET_MODE (to
) == DFmode
)
4130 if (GET_MODE (from
) == SImode
)
4131 libfcn
= floatsidf_libfunc
;
4132 else if (GET_MODE (from
) == DImode
)
4133 libfcn
= floatdidf_libfunc
;
4134 else if (GET_MODE (from
) == TImode
)
4135 libfcn
= floattidf_libfunc
;
4139 else if (GET_MODE (to
) == XFmode
)
4141 if (GET_MODE (from
) == SImode
)
4142 libfcn
= floatsixf_libfunc
;
4143 else if (GET_MODE (from
) == DImode
)
4144 libfcn
= floatdixf_libfunc
;
4145 else if (GET_MODE (from
) == TImode
)
4146 libfcn
= floattixf_libfunc
;
4150 else if (GET_MODE (to
) == TFmode
)
4152 if (GET_MODE (from
) == SImode
)
4153 libfcn
= floatsitf_libfunc
;
4154 else if (GET_MODE (from
) == DImode
)
4155 libfcn
= floatditf_libfunc
;
4156 else if (GET_MODE (from
) == TImode
)
4157 libfcn
= floattitf_libfunc
;
4166 value
= emit_library_call_value (libfcn
, NULL_RTX
, LCT_CONST
,
4167 GET_MODE (to
), 1, from
,
4169 insns
= get_insns ();
4172 emit_libcall_block (insns
, target
, value
,
4173 gen_rtx_FLOAT (GET_MODE (to
), from
));
4178 /* Copy result to requested destination
4179 if we have been computing in a temp location. */
4183 if (GET_MODE (target
) == GET_MODE (to
))
4184 emit_move_insn (to
, target
);
4186 convert_move (to
, target
, 0);
4190 /* expand_fix: generate code to convert FROM to fixed point
4191 and store in TO. FROM must be floating point. */
4197 rtx temp
= gen_reg_rtx (GET_MODE (x
));
4198 return expand_unop (GET_MODE (x
), ftrunc_optab
, x
, temp
, 0);
4202 expand_fix (to
, from
, unsignedp
)
4203 register rtx to
, from
;
4206 enum insn_code icode
;
4207 register rtx target
= to
;
4208 enum machine_mode fmode
, imode
;
4212 /* We first try to find a pair of modes, one real and one integer, at
4213 least as wide as FROM and TO, respectively, in which we can open-code
4214 this conversion. If the integer mode is wider than the mode of TO,
4215 we can do the conversion either signed or unsigned. */
4217 for (imode
= GET_MODE (to
); imode
!= VOIDmode
;
4218 imode
= GET_MODE_WIDER_MODE (imode
))
4219 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4220 fmode
= GET_MODE_WIDER_MODE (fmode
))
4222 int doing_unsigned
= unsignedp
;
4224 icode
= can_fix_p (imode
, fmode
, unsignedp
, &must_trunc
);
4225 if (icode
== CODE_FOR_nothing
&& imode
!= GET_MODE (to
) && unsignedp
)
4226 icode
= can_fix_p (imode
, fmode
, 0, &must_trunc
), doing_unsigned
= 0;
4228 if (icode
!= CODE_FOR_nothing
)
4230 to
= protect_from_queue (to
, 1);
4231 from
= protect_from_queue (from
, 0);
4233 if (fmode
!= GET_MODE (from
))
4234 from
= convert_to_mode (fmode
, from
, 0);
4237 from
= ftruncify (from
);
4239 if (imode
!= GET_MODE (to
))
4240 target
= gen_reg_rtx (imode
);
4242 emit_unop_insn (icode
, target
, from
,
4243 doing_unsigned
? UNSIGNED_FIX
: FIX
);
4245 convert_move (to
, target
, unsignedp
);
4250 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4251 /* For an unsigned conversion, there is one more way to do it.
4252 If we have a signed conversion, we generate code that compares
4253 the real value to the largest representable positive number. If if
4254 is smaller, the conversion is done normally. Otherwise, subtract
4255 one plus the highest signed number, convert, and add it back.
4257 We only need to check all real modes, since we know we didn't find
4258 anything with a wider integer mode. */
4260 if (unsignedp
&& GET_MODE_BITSIZE (GET_MODE (to
)) <= HOST_BITS_PER_WIDE_INT
)
4261 for (fmode
= GET_MODE (from
); fmode
!= VOIDmode
;
4262 fmode
= GET_MODE_WIDER_MODE (fmode
))
4263 /* Make sure we won't lose significant bits doing this. */
4264 if (GET_MODE_BITSIZE (fmode
) > GET_MODE_BITSIZE (GET_MODE (to
))
4265 && CODE_FOR_nothing
!= can_fix_p (GET_MODE (to
), fmode
, 0,
4269 REAL_VALUE_TYPE offset
;
4270 rtx limit
, lab1
, lab2
, insn
;
4272 bitsize
= GET_MODE_BITSIZE (GET_MODE (to
));
4273 offset
= REAL_VALUE_LDEXP (dconst1
, bitsize
- 1);
4274 limit
= CONST_DOUBLE_FROM_REAL_VALUE (offset
, fmode
);
4275 lab1
= gen_label_rtx ();
4276 lab2
= gen_label_rtx ();
4279 to
= protect_from_queue (to
, 1);
4280 from
= protect_from_queue (from
, 0);
4283 from
= force_not_mem (from
);
4285 if (fmode
!= GET_MODE (from
))
4286 from
= convert_to_mode (fmode
, from
, 0);
4288 /* See if we need to do the subtraction. */
4289 do_pending_stack_adjust ();
4290 emit_cmp_and_jump_insns (from
, limit
, GE
, NULL_RTX
, GET_MODE (from
),
4293 /* If not, do the signed "fix" and branch around fixup code. */
4294 expand_fix (to
, from
, 0);
4295 emit_jump_insn (gen_jump (lab2
));
4298 /* Otherwise, subtract 2**(N-1), convert to signed number,
4299 then add 2**(N-1). Do the addition using XOR since this
4300 will often generate better code. */
4302 target
= expand_binop (GET_MODE (from
), sub_optab
, from
, limit
,
4303 NULL_RTX
, 0, OPTAB_LIB_WIDEN
);
4304 expand_fix (to
, target
, 0);
4305 target
= expand_binop (GET_MODE (to
), xor_optab
, to
,
4306 GEN_INT (trunc_int_for_mode
4307 ((HOST_WIDE_INT
) 1 << (bitsize
- 1),
4309 to
, 1, OPTAB_LIB_WIDEN
);
4312 emit_move_insn (to
, target
);
4316 if (mov_optab
->handlers
[(int) GET_MODE (to
)].insn_code
4317 != CODE_FOR_nothing
)
4319 /* Make a place for a REG_NOTE and add it. */
4320 insn
= emit_move_insn (to
, to
);
4321 set_unique_reg_note (insn
,
4323 gen_rtx_fmt_e (UNSIGNED_FIX
,
4332 /* We can't do it with an insn, so use a library call. But first ensure
4333 that the mode of TO is at least as wide as SImode, since those are the
4334 only library calls we know about. */
4336 if (GET_MODE_SIZE (GET_MODE (to
)) < GET_MODE_SIZE (SImode
))
4338 target
= gen_reg_rtx (SImode
);
4340 expand_fix (target
, from
, unsignedp
);
4342 else if (GET_MODE (from
) == SFmode
)
4344 if (GET_MODE (to
) == SImode
)
4345 libfcn
= unsignedp
? fixunssfsi_libfunc
: fixsfsi_libfunc
;
4346 else if (GET_MODE (to
) == DImode
)
4347 libfcn
= unsignedp
? fixunssfdi_libfunc
: fixsfdi_libfunc
;
4348 else if (GET_MODE (to
) == TImode
)
4349 libfcn
= unsignedp
? fixunssfti_libfunc
: fixsfti_libfunc
;
4353 else if (GET_MODE (from
) == DFmode
)
4355 if (GET_MODE (to
) == SImode
)
4356 libfcn
= unsignedp
? fixunsdfsi_libfunc
: fixdfsi_libfunc
;
4357 else if (GET_MODE (to
) == DImode
)
4358 libfcn
= unsignedp
? fixunsdfdi_libfunc
: fixdfdi_libfunc
;
4359 else if (GET_MODE (to
) == TImode
)
4360 libfcn
= unsignedp
? fixunsdfti_libfunc
: fixdfti_libfunc
;
4364 else if (GET_MODE (from
) == XFmode
)
4366 if (GET_MODE (to
) == SImode
)
4367 libfcn
= unsignedp
? fixunsxfsi_libfunc
: fixxfsi_libfunc
;
4368 else if (GET_MODE (to
) == DImode
)
4369 libfcn
= unsignedp
? fixunsxfdi_libfunc
: fixxfdi_libfunc
;
4370 else if (GET_MODE (to
) == TImode
)
4371 libfcn
= unsignedp
? fixunsxfti_libfunc
: fixxfti_libfunc
;
4375 else if (GET_MODE (from
) == TFmode
)
4377 if (GET_MODE (to
) == SImode
)
4378 libfcn
= unsignedp
? fixunstfsi_libfunc
: fixtfsi_libfunc
;
4379 else if (GET_MODE (to
) == DImode
)
4380 libfcn
= unsignedp
? fixunstfdi_libfunc
: fixtfdi_libfunc
;
4381 else if (GET_MODE (to
) == TImode
)
4382 libfcn
= unsignedp
? fixunstfti_libfunc
: fixtfti_libfunc
;
4394 to
= protect_from_queue (to
, 1);
4395 from
= protect_from_queue (from
, 0);
4398 from
= force_not_mem (from
);
4402 value
= emit_library_call_value (libfcn
, NULL_RTX
, LCT_CONST
,
4403 GET_MODE (to
), 1, from
,
4405 insns
= get_insns ();
4408 emit_libcall_block (insns
, target
, value
,
4409 gen_rtx_fmt_e (unsignedp
? UNSIGNED_FIX
: FIX
,
4410 GET_MODE (to
), from
));
4415 if (GET_MODE (to
) == GET_MODE (target
))
4416 emit_move_insn (to
, target
);
4418 convert_move (to
, target
, 0);
4427 optab op
= (optab
) xmalloc (sizeof (struct optab
));
4429 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4431 op
->handlers
[i
].insn_code
= CODE_FOR_nothing
;
4432 op
->handlers
[i
].libfunc
= 0;
4435 if (code
!= UNKNOWN
)
4436 code_to_optab
[(int) code
] = op
;
4441 /* Initialize the libfunc fields of an entire group of entries in some
4442 optab. Each entry is set equal to a string consisting of a leading
4443 pair of underscores followed by a generic operation name followed by
4444 a mode name (downshifted to lower case) followed by a single character
4445 representing the number of operands for the given operation (which is
4446 usually one of the characters '2', '3', or '4').
4448 OPTABLE is the table in which libfunc fields are to be initialized.
4449 FIRST_MODE is the first machine mode index in the given optab to
4451 LAST_MODE is the last machine mode index in the given optab to
4453 OPNAME is the generic (string) name of the operation.
4454 SUFFIX is the character which specifies the number of operands for
4455 the given generic operation.
4459 init_libfuncs (optable
, first_mode
, last_mode
, opname
, suffix
)
4460 register optab optable
;
4461 register int first_mode
;
4462 register int last_mode
;
4463 register const char *opname
;
4464 register int suffix
;
4467 register unsigned opname_len
= strlen (opname
);
4469 for (mode
= first_mode
; (int) mode
<= (int) last_mode
;
4470 mode
= (enum machine_mode
) ((int) mode
+ 1))
4472 register const char *mname
= GET_MODE_NAME(mode
);
4473 register unsigned mname_len
= strlen (mname
);
4474 register char *libfunc_name
= alloca (2 + opname_len
+ mname_len
+ 1 + 1);
4476 register const char *q
;
4481 for (q
= opname
; *q
; )
4483 for (q
= mname
; *q
; q
++)
4484 *p
++ = TOLOWER (*q
);
4488 optable
->handlers
[(int) mode
].libfunc
4489 = gen_rtx_SYMBOL_REF (Pmode
, ggc_alloc_string (libfunc_name
,
4494 /* Initialize the libfunc fields of an entire group of entries in some
4495 optab which correspond to all integer mode operations. The parameters
4496 have the same meaning as similarly named ones for the `init_libfuncs'
4497 routine. (See above). */
4500 init_integral_libfuncs (optable
, opname
, suffix
)
4501 register optab optable
;
4502 register const char *opname
;
4503 register int suffix
;
4505 init_libfuncs (optable
, SImode
, TImode
, opname
, suffix
);
4508 /* Initialize the libfunc fields of an entire group of entries in some
4509 optab which correspond to all real mode operations. The parameters
4510 have the same meaning as similarly named ones for the `init_libfuncs'
4511 routine. (See above). */
4514 init_floating_libfuncs (optable
, opname
, suffix
)
4515 register optab optable
;
4516 register const char *opname
;
4517 register int suffix
;
4519 init_libfuncs (optable
, SFmode
, TFmode
, opname
, suffix
);
4523 init_one_libfunc (name
)
4524 register const char *name
;
4526 name
= ggc_strdup (name
);
4528 return gen_rtx_SYMBOL_REF (Pmode
, name
);
4531 /* Mark ARG (which is really an OPTAB *) for GC. */
4537 optab o
= *(optab
*) arg
;
4540 for (i
= 0; i
< NUM_MACHINE_MODES
; ++i
)
4541 ggc_mark_rtx (o
->handlers
[i
].libfunc
);
4544 /* Call this once to initialize the contents of the optabs
4545 appropriately for the current target machine. */
4550 unsigned int i
, j
, k
;
4552 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4554 for (i
= 0; i
< ARRAY_SIZE (fixtab
); i
++)
4555 for (j
= 0; j
< ARRAY_SIZE (fixtab
[0]); j
++)
4556 for (k
= 0; k
< ARRAY_SIZE (fixtab
[0][0]); k
++)
4557 fixtab
[i
][j
][k
] = CODE_FOR_nothing
;
4559 for (i
= 0; i
< ARRAY_SIZE (fixtrunctab
); i
++)
4560 for (j
= 0; j
< ARRAY_SIZE (fixtrunctab
[0]); j
++)
4561 for (k
= 0; k
< ARRAY_SIZE (fixtrunctab
[0][0]); k
++)
4562 fixtrunctab
[i
][j
][k
] = CODE_FOR_nothing
;
4564 for (i
= 0; i
< ARRAY_SIZE (floattab
); i
++)
4565 for (j
= 0; j
< ARRAY_SIZE (floattab
[0]); j
++)
4566 for (k
= 0; k
< ARRAY_SIZE (floattab
[0][0]); k
++)
4567 floattab
[i
][j
][k
] = CODE_FOR_nothing
;
4569 for (i
= 0; i
< ARRAY_SIZE (extendtab
); i
++)
4570 for (j
= 0; j
< ARRAY_SIZE (extendtab
[0]); j
++)
4571 for (k
= 0; k
< ARRAY_SIZE (extendtab
[0][0]); k
++)
4572 extendtab
[i
][j
][k
] = CODE_FOR_nothing
;
4574 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
4575 setcc_gen_code
[i
] = CODE_FOR_nothing
;
4577 #ifdef HAVE_conditional_move
4578 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4579 movcc_gen_code
[i
] = CODE_FOR_nothing
;
4582 add_optab
= init_optab (PLUS
);
4583 addv_optab
= init_optab (PLUS
);
4584 sub_optab
= init_optab (MINUS
);
4585 subv_optab
= init_optab (MINUS
);
4586 smul_optab
= init_optab (MULT
);
4587 smulv_optab
= init_optab (MULT
);
4588 smul_highpart_optab
= init_optab (UNKNOWN
);
4589 umul_highpart_optab
= init_optab (UNKNOWN
);
4590 smul_widen_optab
= init_optab (UNKNOWN
);
4591 umul_widen_optab
= init_optab (UNKNOWN
);
4592 sdiv_optab
= init_optab (DIV
);
4593 sdivv_optab
= init_optab (DIV
);
4594 sdivmod_optab
= init_optab (UNKNOWN
);
4595 udiv_optab
= init_optab (UDIV
);
4596 udivmod_optab
= init_optab (UNKNOWN
);
4597 smod_optab
= init_optab (MOD
);
4598 umod_optab
= init_optab (UMOD
);
4599 flodiv_optab
= init_optab (DIV
);
4600 ftrunc_optab
= init_optab (UNKNOWN
);
4601 and_optab
= init_optab (AND
);
4602 ior_optab
= init_optab (IOR
);
4603 xor_optab
= init_optab (XOR
);
4604 ashl_optab
= init_optab (ASHIFT
);
4605 ashr_optab
= init_optab (ASHIFTRT
);
4606 lshr_optab
= init_optab (LSHIFTRT
);
4607 rotl_optab
= init_optab (ROTATE
);
4608 rotr_optab
= init_optab (ROTATERT
);
4609 smin_optab
= init_optab (SMIN
);
4610 smax_optab
= init_optab (SMAX
);
4611 umin_optab
= init_optab (UMIN
);
4612 umax_optab
= init_optab (UMAX
);
4613 mov_optab
= init_optab (UNKNOWN
);
4614 movstrict_optab
= init_optab (UNKNOWN
);
4615 cmp_optab
= init_optab (UNKNOWN
);
4616 ucmp_optab
= init_optab (UNKNOWN
);
4617 tst_optab
= init_optab (UNKNOWN
);
4618 neg_optab
= init_optab (NEG
);
4619 negv_optab
= init_optab (NEG
);
4620 abs_optab
= init_optab (ABS
);
4621 absv_optab
= init_optab (ABS
);
4622 one_cmpl_optab
= init_optab (NOT
);
4623 ffs_optab
= init_optab (FFS
);
4624 sqrt_optab
= init_optab (SQRT
);
4625 sin_optab
= init_optab (UNKNOWN
);
4626 cos_optab
= init_optab (UNKNOWN
);
4627 strlen_optab
= init_optab (UNKNOWN
);
4628 cbranch_optab
= init_optab (UNKNOWN
);
4629 cmov_optab
= init_optab (UNKNOWN
);
4630 cstore_optab
= init_optab (UNKNOWN
);
4632 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4634 movstr_optab
[i
] = CODE_FOR_nothing
;
4635 clrstr_optab
[i
] = CODE_FOR_nothing
;
4637 #ifdef HAVE_SECONDARY_RELOADS
4638 reload_in_optab
[i
] = reload_out_optab
[i
] = CODE_FOR_nothing
;
4642 /* Fill in the optabs with the insns we support. */
4645 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4646 /* This flag says the same insns that convert to a signed fixnum
4647 also convert validly to an unsigned one. */
4648 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
4649 for (j
= 0; j
< NUM_MACHINE_MODES
; j
++)
4650 fixtrunctab
[i
][j
][1] = fixtrunctab
[i
][j
][0];
4653 /* Initialize the optabs with the names of the library functions. */
4654 init_integral_libfuncs (add_optab
, "add", '3');
4655 init_floating_libfuncs (add_optab
, "add", '3');
4656 init_integral_libfuncs (addv_optab
, "addv", '3');
4657 init_floating_libfuncs (addv_optab
, "add", '3');
4658 init_integral_libfuncs (sub_optab
, "sub", '3');
4659 init_floating_libfuncs (sub_optab
, "sub", '3');
4660 init_integral_libfuncs (subv_optab
, "subv", '3');
4661 init_floating_libfuncs (subv_optab
, "sub", '3');
4662 init_integral_libfuncs (smul_optab
, "mul", '3');
4663 init_floating_libfuncs (smul_optab
, "mul", '3');
4664 init_integral_libfuncs (smulv_optab
, "mulv", '3');
4665 init_floating_libfuncs (smulv_optab
, "mul", '3');
4666 init_integral_libfuncs (sdiv_optab
, "div", '3');
4667 init_integral_libfuncs (sdivv_optab
, "divv", '3');
4668 init_integral_libfuncs (udiv_optab
, "udiv", '3');
4669 init_integral_libfuncs (sdivmod_optab
, "divmod", '4');
4670 init_integral_libfuncs (udivmod_optab
, "udivmod", '4');
4671 init_integral_libfuncs (smod_optab
, "mod", '3');
4672 init_integral_libfuncs (umod_optab
, "umod", '3');
4673 init_floating_libfuncs (flodiv_optab
, "div", '3');
4674 init_floating_libfuncs (ftrunc_optab
, "ftrunc", '2');
4675 init_integral_libfuncs (and_optab
, "and", '3');
4676 init_integral_libfuncs (ior_optab
, "ior", '3');
4677 init_integral_libfuncs (xor_optab
, "xor", '3');
4678 init_integral_libfuncs (ashl_optab
, "ashl", '3');
4679 init_integral_libfuncs (ashr_optab
, "ashr", '3');
4680 init_integral_libfuncs (lshr_optab
, "lshr", '3');
4681 init_integral_libfuncs (smin_optab
, "min", '3');
4682 init_floating_libfuncs (smin_optab
, "min", '3');
4683 init_integral_libfuncs (smax_optab
, "max", '3');
4684 init_floating_libfuncs (smax_optab
, "max", '3');
4685 init_integral_libfuncs (umin_optab
, "umin", '3');
4686 init_integral_libfuncs (umax_optab
, "umax", '3');
4687 init_integral_libfuncs (neg_optab
, "neg", '2');
4688 init_floating_libfuncs (neg_optab
, "neg", '2');
4689 init_integral_libfuncs (negv_optab
, "negv", '2');
4690 init_floating_libfuncs (negv_optab
, "neg", '2');
4691 init_integral_libfuncs (one_cmpl_optab
, "one_cmpl", '2');
4692 init_integral_libfuncs (ffs_optab
, "ffs", '2');
4694 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4695 init_integral_libfuncs (cmp_optab
, "cmp", '2');
4696 init_integral_libfuncs (ucmp_optab
, "ucmp", '2');
4697 init_floating_libfuncs (cmp_optab
, "cmp", '2');
4699 #ifdef MULSI3_LIBCALL
4700 smul_optab
->handlers
[(int) SImode
].libfunc
4701 = init_one_libfunc (MULSI3_LIBCALL
);
4703 #ifdef MULDI3_LIBCALL
4704 smul_optab
->handlers
[(int) DImode
].libfunc
4705 = init_one_libfunc (MULDI3_LIBCALL
);
4708 #ifdef DIVSI3_LIBCALL
4709 sdiv_optab
->handlers
[(int) SImode
].libfunc
4710 = init_one_libfunc (DIVSI3_LIBCALL
);
4712 #ifdef DIVDI3_LIBCALL
4713 sdiv_optab
->handlers
[(int) DImode
].libfunc
4714 = init_one_libfunc (DIVDI3_LIBCALL
);
4717 #ifdef UDIVSI3_LIBCALL
4718 udiv_optab
->handlers
[(int) SImode
].libfunc
4719 = init_one_libfunc (UDIVSI3_LIBCALL
);
4721 #ifdef UDIVDI3_LIBCALL
4722 udiv_optab
->handlers
[(int) DImode
].libfunc
4723 = init_one_libfunc (UDIVDI3_LIBCALL
);
4726 #ifdef MODSI3_LIBCALL
4727 smod_optab
->handlers
[(int) SImode
].libfunc
4728 = init_one_libfunc (MODSI3_LIBCALL
);
4730 #ifdef MODDI3_LIBCALL
4731 smod_optab
->handlers
[(int) DImode
].libfunc
4732 = init_one_libfunc (MODDI3_LIBCALL
);
4735 #ifdef UMODSI3_LIBCALL
4736 umod_optab
->handlers
[(int) SImode
].libfunc
4737 = init_one_libfunc (UMODSI3_LIBCALL
);
4739 #ifdef UMODDI3_LIBCALL
4740 umod_optab
->handlers
[(int) DImode
].libfunc
4741 = init_one_libfunc (UMODDI3_LIBCALL
);
4744 /* Use cabs for DC complex abs, since systems generally have cabs.
4745 Don't define any libcall for SCmode, so that cabs will be used. */
4746 abs_optab
->handlers
[(int) DCmode
].libfunc
4747 = init_one_libfunc ("cabs");
4749 /* The ffs function operates on `int'. */
4750 ffs_optab
->handlers
[(int) mode_for_size (INT_TYPE_SIZE
, MODE_INT
, 0)].libfunc
4751 = init_one_libfunc ("ffs");
4753 extendsfdf2_libfunc
= init_one_libfunc ("__extendsfdf2");
4754 extendsfxf2_libfunc
= init_one_libfunc ("__extendsfxf2");
4755 extendsftf2_libfunc
= init_one_libfunc ("__extendsftf2");
4756 extenddfxf2_libfunc
= init_one_libfunc ("__extenddfxf2");
4757 extenddftf2_libfunc
= init_one_libfunc ("__extenddftf2");
4759 truncdfsf2_libfunc
= init_one_libfunc ("__truncdfsf2");
4760 truncxfsf2_libfunc
= init_one_libfunc ("__truncxfsf2");
4761 trunctfsf2_libfunc
= init_one_libfunc ("__trunctfsf2");
4762 truncxfdf2_libfunc
= init_one_libfunc ("__truncxfdf2");
4763 trunctfdf2_libfunc
= init_one_libfunc ("__trunctfdf2");
4765 memcpy_libfunc
= init_one_libfunc ("memcpy");
4766 memmove_libfunc
= init_one_libfunc ("memmove");
4767 bcopy_libfunc
= init_one_libfunc ("bcopy");
4768 memcmp_libfunc
= init_one_libfunc ("memcmp");
4769 bcmp_libfunc
= init_one_libfunc ("__gcc_bcmp");
4770 memset_libfunc
= init_one_libfunc ("memset");
4771 bzero_libfunc
= init_one_libfunc ("bzero");
4773 unwind_resume_libfunc
= init_one_libfunc (USING_SJLJ_EXCEPTIONS
4774 ? "_Unwind_SjLj_Resume"
4775 : "_Unwind_Resume");
4776 #ifndef DONT_USE_BUILTIN_SETJMP
4777 setjmp_libfunc
= init_one_libfunc ("__builtin_setjmp");
4778 longjmp_libfunc
= init_one_libfunc ("__builtin_longjmp");
4780 setjmp_libfunc
= init_one_libfunc ("setjmp");
4781 longjmp_libfunc
= init_one_libfunc ("longjmp");
4783 unwind_sjlj_register_libfunc
= init_one_libfunc ("_Unwind_SjLj_Register");
4784 unwind_sjlj_unregister_libfunc
4785 = init_one_libfunc ("_Unwind_SjLj_Unregister");
4787 eqhf2_libfunc
= init_one_libfunc ("__eqhf2");
4788 nehf2_libfunc
= init_one_libfunc ("__nehf2");
4789 gthf2_libfunc
= init_one_libfunc ("__gthf2");
4790 gehf2_libfunc
= init_one_libfunc ("__gehf2");
4791 lthf2_libfunc
= init_one_libfunc ("__lthf2");
4792 lehf2_libfunc
= init_one_libfunc ("__lehf2");
4793 unordhf2_libfunc
= init_one_libfunc ("__unordhf2");
4795 eqsf2_libfunc
= init_one_libfunc ("__eqsf2");
4796 nesf2_libfunc
= init_one_libfunc ("__nesf2");
4797 gtsf2_libfunc
= init_one_libfunc ("__gtsf2");
4798 gesf2_libfunc
= init_one_libfunc ("__gesf2");
4799 ltsf2_libfunc
= init_one_libfunc ("__ltsf2");
4800 lesf2_libfunc
= init_one_libfunc ("__lesf2");
4801 unordsf2_libfunc
= init_one_libfunc ("__unordsf2");
4803 eqdf2_libfunc
= init_one_libfunc ("__eqdf2");
4804 nedf2_libfunc
= init_one_libfunc ("__nedf2");
4805 gtdf2_libfunc
= init_one_libfunc ("__gtdf2");
4806 gedf2_libfunc
= init_one_libfunc ("__gedf2");
4807 ltdf2_libfunc
= init_one_libfunc ("__ltdf2");
4808 ledf2_libfunc
= init_one_libfunc ("__ledf2");
4809 unorddf2_libfunc
= init_one_libfunc ("__unorddf2");
4811 eqxf2_libfunc
= init_one_libfunc ("__eqxf2");
4812 nexf2_libfunc
= init_one_libfunc ("__nexf2");
4813 gtxf2_libfunc
= init_one_libfunc ("__gtxf2");
4814 gexf2_libfunc
= init_one_libfunc ("__gexf2");
4815 ltxf2_libfunc
= init_one_libfunc ("__ltxf2");
4816 lexf2_libfunc
= init_one_libfunc ("__lexf2");
4817 unordxf2_libfunc
= init_one_libfunc ("__unordxf2");
4819 eqtf2_libfunc
= init_one_libfunc ("__eqtf2");
4820 netf2_libfunc
= init_one_libfunc ("__netf2");
4821 gttf2_libfunc
= init_one_libfunc ("__gttf2");
4822 getf2_libfunc
= init_one_libfunc ("__getf2");
4823 lttf2_libfunc
= init_one_libfunc ("__lttf2");
4824 letf2_libfunc
= init_one_libfunc ("__letf2");
4825 unordtf2_libfunc
= init_one_libfunc ("__unordtf2");
4827 floatsisf_libfunc
= init_one_libfunc ("__floatsisf");
4828 floatdisf_libfunc
= init_one_libfunc ("__floatdisf");
4829 floattisf_libfunc
= init_one_libfunc ("__floattisf");
4831 floatsidf_libfunc
= init_one_libfunc ("__floatsidf");
4832 floatdidf_libfunc
= init_one_libfunc ("__floatdidf");
4833 floattidf_libfunc
= init_one_libfunc ("__floattidf");
4835 floatsixf_libfunc
= init_one_libfunc ("__floatsixf");
4836 floatdixf_libfunc
= init_one_libfunc ("__floatdixf");
4837 floattixf_libfunc
= init_one_libfunc ("__floattixf");
4839 floatsitf_libfunc
= init_one_libfunc ("__floatsitf");
4840 floatditf_libfunc
= init_one_libfunc ("__floatditf");
4841 floattitf_libfunc
= init_one_libfunc ("__floattitf");
4843 fixsfsi_libfunc
= init_one_libfunc ("__fixsfsi");
4844 fixsfdi_libfunc
= init_one_libfunc ("__fixsfdi");
4845 fixsfti_libfunc
= init_one_libfunc ("__fixsfti");
4847 fixdfsi_libfunc
= init_one_libfunc ("__fixdfsi");
4848 fixdfdi_libfunc
= init_one_libfunc ("__fixdfdi");
4849 fixdfti_libfunc
= init_one_libfunc ("__fixdfti");
4851 fixxfsi_libfunc
= init_one_libfunc ("__fixxfsi");
4852 fixxfdi_libfunc
= init_one_libfunc ("__fixxfdi");
4853 fixxfti_libfunc
= init_one_libfunc ("__fixxfti");
4855 fixtfsi_libfunc
= init_one_libfunc ("__fixtfsi");
4856 fixtfdi_libfunc
= init_one_libfunc ("__fixtfdi");
4857 fixtfti_libfunc
= init_one_libfunc ("__fixtfti");
4859 fixunssfsi_libfunc
= init_one_libfunc ("__fixunssfsi");
4860 fixunssfdi_libfunc
= init_one_libfunc ("__fixunssfdi");
4861 fixunssfti_libfunc
= init_one_libfunc ("__fixunssfti");
4863 fixunsdfsi_libfunc
= init_one_libfunc ("__fixunsdfsi");
4864 fixunsdfdi_libfunc
= init_one_libfunc ("__fixunsdfdi");
4865 fixunsdfti_libfunc
= init_one_libfunc ("__fixunsdfti");
4867 fixunsxfsi_libfunc
= init_one_libfunc ("__fixunsxfsi");
4868 fixunsxfdi_libfunc
= init_one_libfunc ("__fixunsxfdi");
4869 fixunsxfti_libfunc
= init_one_libfunc ("__fixunsxfti");
4871 fixunstfsi_libfunc
= init_one_libfunc ("__fixunstfsi");
4872 fixunstfdi_libfunc
= init_one_libfunc ("__fixunstfdi");
4873 fixunstfti_libfunc
= init_one_libfunc ("__fixunstfti");
4875 /* For check-memory-usage. */
4876 chkr_check_addr_libfunc
= init_one_libfunc ("chkr_check_addr");
4877 chkr_set_right_libfunc
= init_one_libfunc ("chkr_set_right");
4878 chkr_copy_bitmap_libfunc
= init_one_libfunc ("chkr_copy_bitmap");
4879 chkr_check_exec_libfunc
= init_one_libfunc ("chkr_check_exec");
4880 chkr_check_str_libfunc
= init_one_libfunc ("chkr_check_str");
4882 /* For function entry/exit instrumentation. */
4883 profile_function_entry_libfunc
4884 = init_one_libfunc ("__cyg_profile_func_enter");
4885 profile_function_exit_libfunc
4886 = init_one_libfunc ("__cyg_profile_func_exit");
4888 #ifdef HAVE_conditional_trap
4892 #ifdef INIT_TARGET_OPTABS
4893 /* Allow the target to add more libcalls or rename some, etc. */
4897 /* Add these GC roots. */
4898 ggc_add_root (optab_table
, OTI_MAX
, sizeof(optab
), mark_optab
);
4899 ggc_add_rtx_root (libfunc_table
, LTI_MAX
);
4904 /* SCO 3.2 apparently has a broken ldexp. */
4917 #endif /* BROKEN_LDEXP */
4919 #ifdef HAVE_conditional_trap
4920 /* The insn generating function can not take an rtx_code argument.
4921 TRAP_RTX is used as an rtx argument. Its code is replaced with
4922 the code to be used in the trap insn and all other fields are
4924 static rtx trap_rtx
;
4929 if (HAVE_conditional_trap
)
4931 trap_rtx
= gen_rtx_fmt_ee (EQ
, VOIDmode
, NULL_RTX
, NULL_RTX
);
4932 ggc_add_rtx_root (&trap_rtx
, 1);
4937 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4938 CODE. Return 0 on failure. */
4941 gen_cond_trap (code
, op1
, op2
, tcode
)
4942 enum rtx_code code ATTRIBUTE_UNUSED
;
4943 rtx op1
, op2 ATTRIBUTE_UNUSED
, tcode ATTRIBUTE_UNUSED
;
4945 enum machine_mode mode
= GET_MODE (op1
);
4947 if (mode
== VOIDmode
)
4950 #ifdef HAVE_conditional_trap
4951 if (HAVE_conditional_trap
4952 && cmp_optab
->handlers
[(int) mode
].insn_code
!= CODE_FOR_nothing
)
4956 emit_insn (GEN_FCN (cmp_optab
->handlers
[(int) mode
].insn_code
) (op1
, op2
));
4957 PUT_CODE (trap_rtx
, code
);
4958 insn
= gen_conditional_trap (trap_rtx
, tcode
);
4962 insn
= gen_sequence ();