Avoid unnecessary dependencies on COND_EXEC insns.
[official-gcc.git] / gcc / optabs.c
blob5ee436d7bf7d4e3c7657c21a8005cbda3fbd2add
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
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. */
23 #include "config.h"
24 #include "system.h"
25 #include "toplev.h"
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "tm_p.h"
33 #include "flags.h"
34 #include "insn-flags.h"
35 #include "insn-codes.h"
36 #include "function.h"
37 #include "expr.h"
38 #include "recog.h"
39 #include "reload.h"
40 #include "ggc.h"
41 #include "real.h"
42 #include "defaults.h"
44 /* Each optab contains info on how this target machine
45 can perform a particular operation
46 for all sizes and kinds of operands.
48 The operation to be performed is often specified
49 by passing one of these optabs as an argument.
51 See expr.h for documentation of these optabs. */
53 optab optab_table[OTI_MAX];
55 rtx libfunc_table[LTI_MAX];
57 /* Tables of patterns for extending one integer mode to another. */
58 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
60 /* Tables of patterns for converting between fixed and floating point. */
61 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
62 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
63 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
65 /* Contains the optab used for each rtx code. */
66 optab code_to_optab[NUM_RTX_CODE + 1];
68 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
69 gives the gen_function to make a branch to test that condition. */
71 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
73 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
74 gives the insn code to make a store-condition insn
75 to test that condition. */
77 enum insn_code setcc_gen_code[NUM_RTX_CODE];
79 #ifdef HAVE_conditional_move
80 /* Indexed by the machine mode, gives the insn code to make a conditional
81 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
82 setcc_gen_code to cut down on the number of named patterns. Consider a day
83 when a lot more rtx codes are conditional (eg: for the ARM). */
85 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
86 #endif
88 static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
89 static rtx widen_operand PARAMS ((rtx, enum machine_mode,
90 enum machine_mode, int, int));
91 static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
92 rtx, rtx, enum machine_mode,
93 int, enum optab_methods,
94 enum mode_class, optab));
95 static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
96 rtx, rtx, enum machine_mode,
97 int, enum optab_methods,
98 enum mode_class, optab));
99 static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode,
100 int, int *));
101 static enum insn_code can_float_p PARAMS ((enum machine_mode, enum machine_mode,
102 int));
103 static rtx ftruncify PARAMS ((rtx));
104 static optab init_optab PARAMS ((enum rtx_code));
105 static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
106 static void init_integral_libfuncs PARAMS ((optab, const char *, int));
107 static void init_floating_libfuncs PARAMS ((optab, const char *, int));
108 #ifdef HAVE_conditional_trap
109 static void init_traps PARAMS ((void));
110 #endif
111 static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
112 enum rtx_code, int, rtx));
113 static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
114 enum machine_mode *, int *));
116 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
117 the result of operation CODE applied to OP0 (and OP1 if it is a binary
118 operation).
120 If the last insn does not set TARGET, don't do anything, but return 1.
122 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
123 don't add the REG_EQUAL note but return 0. Our caller can then try
124 again, ensuring that TARGET is not one of the operands. */
126 static int
127 add_equal_note (seq, target, code, op0, op1)
128 rtx seq;
129 rtx target;
130 enum rtx_code code;
131 rtx op0, op1;
133 rtx set;
134 int i;
135 rtx note;
137 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
138 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
139 || GET_CODE (seq) != SEQUENCE
140 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
141 || GET_CODE (target) == ZERO_EXTRACT
142 || (! rtx_equal_p (SET_DEST (set), target)
143 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
144 SUBREG. */
145 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
146 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
147 target))))
148 return 1;
150 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
151 besides the last insn. */
152 if (reg_overlap_mentioned_p (target, op0)
153 || (op1 && reg_overlap_mentioned_p (target, op1)))
154 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
155 if (reg_set_p (target, XVECEXP (seq, 0, i)))
156 return 0;
158 if (GET_RTX_CLASS (code) == '1')
159 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
160 else
161 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
163 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
165 return 1;
168 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
169 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
170 not actually do a sign-extend or zero-extend, but can leave the
171 higher-order bits of the result rtx undefined, for example, in the case
172 of logical operations, but not right shifts. */
174 static rtx
175 widen_operand (op, mode, oldmode, unsignedp, no_extend)
176 rtx op;
177 enum machine_mode mode, oldmode;
178 int unsignedp;
179 int no_extend;
181 rtx result;
183 /* If we must extend do so. If OP is either a constant or a SUBREG
184 for a promoted object, also extend since it will be more efficient to
185 do so. */
186 if (! no_extend
187 || GET_MODE (op) == VOIDmode
188 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
189 return convert_modes (mode, oldmode, op, unsignedp);
191 /* If MODE is no wider than a single word, we return a paradoxical
192 SUBREG. */
193 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
194 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
196 /* Otherwise, get an object of MODE, clobber it, and set the low-order
197 part to OP. */
199 result = gen_reg_rtx (mode);
200 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
201 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
202 return result;
205 /* Generate code to perform a straightforward complex divide. */
207 static int
208 expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
209 unsignedp, methods, class, binoptab)
210 rtx real0, real1, imag0, imag1, realr, imagr;
211 enum machine_mode submode;
212 int unsignedp;
213 enum optab_methods methods;
214 enum mode_class class;
215 optab binoptab;
217 rtx divisor;
218 rtx real_t, imag_t;
219 rtx temp1, temp2;
220 rtx res;
221 optab this_add_optab = add_optab;
222 optab this_sub_optab = sub_optab;
223 optab this_neg_optab = neg_optab;
224 optab this_mul_optab = smul_optab;
226 if (binoptab == sdivv_optab)
228 this_add_optab = addv_optab;
229 this_sub_optab = subv_optab;
230 this_neg_optab = negv_optab;
231 this_mul_optab = smulv_optab;
234 /* Don't fetch these from memory more than once. */
235 real0 = force_reg (submode, real0);
236 real1 = force_reg (submode, real1);
238 if (imag0 != 0)
239 imag0 = force_reg (submode, imag0);
241 imag1 = force_reg (submode, imag1);
243 /* Divisor: c*c + d*d. */
244 temp1 = expand_binop (submode, this_mul_optab, real1, real1,
245 NULL_RTX, unsignedp, methods);
247 temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
248 NULL_RTX, unsignedp, methods);
250 if (temp1 == 0 || temp2 == 0)
251 return 0;
253 divisor = expand_binop (submode, this_add_optab, temp1, temp2,
254 NULL_RTX, unsignedp, methods);
255 if (divisor == 0)
256 return 0;
258 if (imag0 == 0)
260 /* Mathematically, ((a)(c-id))/divisor. */
261 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
263 /* Calculate the dividend. */
264 real_t = expand_binop (submode, this_mul_optab, real0, real1,
265 NULL_RTX, unsignedp, methods);
267 imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
268 NULL_RTX, unsignedp, methods);
270 if (real_t == 0 || imag_t == 0)
271 return 0;
273 imag_t = expand_unop (submode, this_neg_optab, imag_t,
274 NULL_RTX, unsignedp);
276 else
278 /* Mathematically, ((a+ib)(c-id))/divider. */
279 /* Calculate the dividend. */
280 temp1 = expand_binop (submode, this_mul_optab, real0, real1,
281 NULL_RTX, unsignedp, methods);
283 temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
284 NULL_RTX, unsignedp, methods);
286 if (temp1 == 0 || temp2 == 0)
287 return 0;
289 real_t = expand_binop (submode, this_add_optab, temp1, temp2,
290 NULL_RTX, unsignedp, methods);
292 temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
293 NULL_RTX, unsignedp, methods);
295 temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
296 NULL_RTX, unsignedp, methods);
298 if (temp1 == 0 || temp2 == 0)
299 return 0;
301 imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
302 NULL_RTX, unsignedp, methods);
304 if (real_t == 0 || imag_t == 0)
305 return 0;
308 if (class == MODE_COMPLEX_FLOAT)
309 res = expand_binop (submode, binoptab, real_t, divisor,
310 realr, unsignedp, methods);
311 else
312 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
313 real_t, divisor, realr, unsignedp);
315 if (res == 0)
316 return 0;
318 if (res != realr)
319 emit_move_insn (realr, res);
321 if (class == MODE_COMPLEX_FLOAT)
322 res = expand_binop (submode, binoptab, imag_t, divisor,
323 imagr, unsignedp, methods);
324 else
325 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
326 imag_t, divisor, imagr, unsignedp);
328 if (res == 0)
329 return 0;
331 if (res != imagr)
332 emit_move_insn (imagr, res);
334 return 1;
337 /* Generate code to perform a wide-input-range-acceptable complex divide. */
339 static int
340 expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
341 unsignedp, methods, class, binoptab)
342 rtx real0, real1, imag0, imag1, realr, imagr;
343 enum machine_mode submode;
344 int unsignedp;
345 enum optab_methods methods;
346 enum mode_class class;
347 optab binoptab;
349 rtx ratio, divisor;
350 rtx real_t, imag_t;
351 rtx temp1, temp2, lab1, lab2;
352 enum machine_mode mode;
353 int align;
354 rtx res;
355 optab this_add_optab = add_optab;
356 optab this_sub_optab = sub_optab;
357 optab this_neg_optab = neg_optab;
358 optab this_mul_optab = smul_optab;
360 if (binoptab == sdivv_optab)
362 this_add_optab = addv_optab;
363 this_sub_optab = subv_optab;
364 this_neg_optab = negv_optab;
365 this_mul_optab = smulv_optab;
368 /* Don't fetch these from memory more than once. */
369 real0 = force_reg (submode, real0);
370 real1 = force_reg (submode, real1);
372 if (imag0 != 0)
373 imag0 = force_reg (submode, imag0);
375 imag1 = force_reg (submode, imag1);
377 /* XXX What's an "unsigned" complex number? */
378 if (unsignedp)
380 temp1 = real1;
381 temp2 = imag1;
383 else
385 temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
386 temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
389 if (temp1 == 0 || temp2 == 0)
390 return 0;
392 mode = GET_MODE (temp1);
393 align = GET_MODE_ALIGNMENT (mode);
394 lab1 = gen_label_rtx ();
395 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
396 mode, unsignedp, align, lab1);
398 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
400 if (class == MODE_COMPLEX_FLOAT)
401 ratio = expand_binop (submode, binoptab, imag1, real1,
402 NULL_RTX, unsignedp, methods);
403 else
404 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
405 imag1, real1, NULL_RTX, unsignedp);
407 if (ratio == 0)
408 return 0;
410 /* Calculate divisor. */
412 temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
413 NULL_RTX, unsignedp, methods);
415 if (temp1 == 0)
416 return 0;
418 divisor = expand_binop (submode, this_add_optab, temp1, real1,
419 NULL_RTX, unsignedp, methods);
421 if (divisor == 0)
422 return 0;
424 /* Calculate dividend. */
426 if (imag0 == 0)
428 real_t = real0;
430 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
432 imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
433 NULL_RTX, unsignedp, methods);
435 if (imag_t == 0)
436 return 0;
438 imag_t = expand_unop (submode, this_neg_optab, imag_t,
439 NULL_RTX, unsignedp);
441 if (real_t == 0 || imag_t == 0)
442 return 0;
444 else
446 /* Compute (a+ib)/(c+id) as
447 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
449 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
450 NULL_RTX, unsignedp, methods);
452 if (temp1 == 0)
453 return 0;
455 real_t = expand_binop (submode, this_add_optab, temp1, real0,
456 NULL_RTX, unsignedp, methods);
458 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
459 NULL_RTX, unsignedp, methods);
461 if (temp1 == 0)
462 return 0;
464 imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
465 NULL_RTX, unsignedp, methods);
467 if (real_t == 0 || imag_t == 0)
468 return 0;
471 if (class == MODE_COMPLEX_FLOAT)
472 res = expand_binop (submode, binoptab, real_t, divisor,
473 realr, unsignedp, methods);
474 else
475 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
476 real_t, divisor, realr, unsignedp);
478 if (res == 0)
479 return 0;
481 if (res != realr)
482 emit_move_insn (realr, res);
484 if (class == MODE_COMPLEX_FLOAT)
485 res = expand_binop (submode, binoptab, imag_t, divisor,
486 imagr, unsignedp, methods);
487 else
488 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
489 imag_t, divisor, imagr, unsignedp);
491 if (res == 0)
492 return 0;
494 if (res != imagr)
495 emit_move_insn (imagr, res);
497 lab2 = gen_label_rtx ();
498 emit_jump_insn (gen_jump (lab2));
499 emit_barrier ();
501 emit_label (lab1);
503 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
505 if (class == MODE_COMPLEX_FLOAT)
506 ratio = expand_binop (submode, binoptab, real1, imag1,
507 NULL_RTX, unsignedp, methods);
508 else
509 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
510 real1, imag1, NULL_RTX, unsignedp);
512 if (ratio == 0)
513 return 0;
515 /* Calculate divisor. */
517 temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
518 NULL_RTX, unsignedp, methods);
520 if (temp1 == 0)
521 return 0;
523 divisor = expand_binop (submode, this_add_optab, temp1, imag1,
524 NULL_RTX, unsignedp, methods);
526 if (divisor == 0)
527 return 0;
529 /* Calculate dividend. */
531 if (imag0 == 0)
533 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
535 real_t = expand_binop (submode, this_mul_optab, real0, ratio,
536 NULL_RTX, unsignedp, methods);
538 imag_t = expand_unop (submode, this_neg_optab, real0,
539 NULL_RTX, unsignedp);
541 if (real_t == 0 || imag_t == 0)
542 return 0;
544 else
546 /* Compute (a+ib)/(c+id) as
547 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
549 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
550 NULL_RTX, unsignedp, methods);
552 if (temp1 == 0)
553 return 0;
555 real_t = expand_binop (submode, this_add_optab, temp1, imag0,
556 NULL_RTX, unsignedp, methods);
558 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
559 NULL_RTX, unsignedp, methods);
561 if (temp1 == 0)
562 return 0;
564 imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
565 NULL_RTX, unsignedp, methods);
567 if (real_t == 0 || imag_t == 0)
568 return 0;
571 if (class == MODE_COMPLEX_FLOAT)
572 res = expand_binop (submode, binoptab, real_t, divisor,
573 realr, unsignedp, methods);
574 else
575 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
576 real_t, divisor, realr, unsignedp);
578 if (res == 0)
579 return 0;
581 if (res != realr)
582 emit_move_insn (realr, res);
584 if (class == MODE_COMPLEX_FLOAT)
585 res = expand_binop (submode, binoptab, imag_t, divisor,
586 imagr, unsignedp, methods);
587 else
588 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
589 imag_t, divisor, imagr, unsignedp);
591 if (res == 0)
592 return 0;
594 if (res != imagr)
595 emit_move_insn (imagr, res);
597 emit_label (lab2);
599 return 1;
602 /* Generate code to perform an operation specified by BINOPTAB
603 on operands OP0 and OP1, with result having machine-mode MODE.
605 UNSIGNEDP is for the case where we have to widen the operands
606 to perform the operation. It says to use zero-extension.
608 If TARGET is nonzero, the value
609 is generated there, if it is convenient to do so.
610 In all cases an rtx is returned for the locus of the value;
611 this may or may not be TARGET. */
614 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
615 enum machine_mode mode;
616 optab binoptab;
617 rtx op0, op1;
618 rtx target;
619 int unsignedp;
620 enum optab_methods methods;
622 enum optab_methods next_methods
623 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
624 ? OPTAB_WIDEN : methods);
625 enum mode_class class;
626 enum machine_mode wider_mode;
627 register rtx temp;
628 int commutative_op = 0;
629 int shift_op = (binoptab->code == ASHIFT
630 || binoptab->code == ASHIFTRT
631 || binoptab->code == LSHIFTRT
632 || binoptab->code == ROTATE
633 || binoptab->code == ROTATERT);
634 rtx entry_last = get_last_insn ();
635 rtx last;
637 class = GET_MODE_CLASS (mode);
639 op0 = protect_from_queue (op0, 0);
640 op1 = protect_from_queue (op1, 0);
641 if (target)
642 target = protect_from_queue (target, 1);
644 if (flag_force_mem)
646 op0 = force_not_mem (op0);
647 op1 = force_not_mem (op1);
650 /* If subtracting an integer constant, convert this into an addition of
651 the negated constant. */
653 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
655 op1 = negate_rtx (mode, op1);
656 binoptab = add_optab;
659 /* If we are inside an appropriately-short loop and one operand is an
660 expensive constant, force it into a register. */
661 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
662 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
663 op0 = force_reg (mode, op0);
665 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
666 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
667 op1 = force_reg (mode, op1);
669 /* Record where to delete back to if we backtrack. */
670 last = get_last_insn ();
672 /* If operation is commutative,
673 try to make the first operand a register.
674 Even better, try to make it the same as the target.
675 Also try to make the last operand a constant. */
676 if (GET_RTX_CLASS (binoptab->code) == 'c'
677 || binoptab == smul_widen_optab
678 || binoptab == umul_widen_optab
679 || binoptab == smul_highpart_optab
680 || binoptab == umul_highpart_optab)
682 commutative_op = 1;
684 if (((target == 0 || GET_CODE (target) == REG)
685 ? ((GET_CODE (op1) == REG
686 && GET_CODE (op0) != REG)
687 || target == op1)
688 : rtx_equal_p (op1, target))
689 || GET_CODE (op0) == CONST_INT)
691 temp = op1;
692 op1 = op0;
693 op0 = temp;
697 /* If we can do it with a three-operand insn, do so. */
699 if (methods != OPTAB_MUST_WIDEN
700 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
702 int icode = (int) binoptab->handlers[(int) mode].insn_code;
703 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
704 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
705 rtx pat;
706 rtx xop0 = op0, xop1 = op1;
708 if (target)
709 temp = target;
710 else
711 temp = gen_reg_rtx (mode);
713 /* If it is a commutative operator and the modes would match
714 if we would swap the operands, we can save the conversions. */
715 if (commutative_op)
717 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
718 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
720 register rtx tmp;
722 tmp = op0; op0 = op1; op1 = tmp;
723 tmp = xop0; xop0 = xop1; xop1 = tmp;
727 /* In case the insn wants input operands in modes different from
728 the result, convert the operands. */
730 if (GET_MODE (op0) != VOIDmode
731 && GET_MODE (op0) != mode0
732 && mode0 != VOIDmode)
733 xop0 = convert_to_mode (mode0, xop0, unsignedp);
735 if (GET_MODE (xop1) != VOIDmode
736 && GET_MODE (xop1) != mode1
737 && mode1 != VOIDmode)
738 xop1 = convert_to_mode (mode1, xop1, unsignedp);
740 /* Now, if insn's predicates don't allow our operands, put them into
741 pseudo regs. */
743 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
744 && mode0 != VOIDmode)
745 xop0 = copy_to_mode_reg (mode0, xop0);
747 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
748 && mode1 != VOIDmode)
749 xop1 = copy_to_mode_reg (mode1, xop1);
751 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
752 temp = gen_reg_rtx (mode);
754 pat = GEN_FCN (icode) (temp, xop0, xop1);
755 if (pat)
757 /* If PAT is a multi-insn sequence, try to add an appropriate
758 REG_EQUAL note to it. If we can't because TEMP conflicts with an
759 operand, call ourselves again, this time without a target. */
760 if (GET_CODE (pat) == SEQUENCE
761 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
763 delete_insns_since (last);
764 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
765 unsignedp, methods);
768 emit_insn (pat);
769 return temp;
771 else
772 delete_insns_since (last);
775 /* If this is a multiply, see if we can do a widening operation that
776 takes operands of this mode and makes a wider mode. */
778 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
779 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
780 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
781 != CODE_FOR_nothing))
783 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
784 unsignedp ? umul_widen_optab : smul_widen_optab,
785 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
787 if (temp != 0)
789 if (GET_MODE_CLASS (mode) == MODE_INT)
790 return gen_lowpart (mode, temp);
791 else
792 return convert_to_mode (mode, temp, unsignedp);
796 /* Look for a wider mode of the same class for which we think we
797 can open-code the operation. Check for a widening multiply at the
798 wider mode as well. */
800 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
801 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
802 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
803 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
805 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
806 || (binoptab == smul_optab
807 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
808 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
809 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
810 != CODE_FOR_nothing)))
812 rtx xop0 = op0, xop1 = op1;
813 int no_extend = 0;
815 /* For certain integer operations, we need not actually extend
816 the narrow operands, as long as we will truncate
817 the results to the same narrowness. */
819 if ((binoptab == ior_optab || binoptab == and_optab
820 || binoptab == xor_optab
821 || binoptab == add_optab || binoptab == sub_optab
822 || binoptab == smul_optab || binoptab == ashl_optab)
823 && class == MODE_INT)
824 no_extend = 1;
826 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
828 /* The second operand of a shift must always be extended. */
829 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
830 no_extend && binoptab != ashl_optab);
832 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
833 unsignedp, OPTAB_DIRECT);
834 if (temp)
836 if (class != MODE_INT)
838 if (target == 0)
839 target = gen_reg_rtx (mode);
840 convert_move (target, temp, 0);
841 return target;
843 else
844 return gen_lowpart (mode, temp);
846 else
847 delete_insns_since (last);
851 /* These can be done a word at a time. */
852 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
853 && class == MODE_INT
854 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
855 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
857 unsigned int i;
858 rtx insns;
859 rtx equiv_value;
861 /* If TARGET is the same as one of the operands, the REG_EQUAL note
862 won't be accurate, so use a new target. */
863 if (target == 0 || target == op0 || target == op1)
864 target = gen_reg_rtx (mode);
866 start_sequence ();
868 /* Do the actual arithmetic. */
869 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
871 rtx target_piece = operand_subword (target, i, 1, mode);
872 rtx x = expand_binop (word_mode, binoptab,
873 operand_subword_force (op0, i, mode),
874 operand_subword_force (op1, i, mode),
875 target_piece, unsignedp, next_methods);
877 if (x == 0)
878 break;
880 if (target_piece != x)
881 emit_move_insn (target_piece, x);
884 insns = get_insns ();
885 end_sequence ();
887 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
889 if (binoptab->code != UNKNOWN)
890 equiv_value
891 = gen_rtx_fmt_ee (binoptab->code, mode,
892 copy_rtx (op0), copy_rtx (op1));
893 else
894 equiv_value = 0;
896 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
897 return target;
901 /* Synthesize double word shifts from single word shifts. */
902 if ((binoptab == lshr_optab || binoptab == ashl_optab
903 || binoptab == ashr_optab)
904 && class == MODE_INT
905 && GET_CODE (op1) == CONST_INT
906 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
907 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
908 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
909 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
911 rtx insns, inter, equiv_value;
912 rtx into_target, outof_target;
913 rtx into_input, outof_input;
914 int shift_count, left_shift, outof_word;
916 /* If TARGET is the same as one of the operands, the REG_EQUAL note
917 won't be accurate, so use a new target. */
918 if (target == 0 || target == op0 || target == op1)
919 target = gen_reg_rtx (mode);
921 start_sequence ();
923 shift_count = INTVAL (op1);
925 /* OUTOF_* is the word we are shifting bits away from, and
926 INTO_* is the word that we are shifting bits towards, thus
927 they differ depending on the direction of the shift and
928 WORDS_BIG_ENDIAN. */
930 left_shift = binoptab == ashl_optab;
931 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
933 outof_target = operand_subword (target, outof_word, 1, mode);
934 into_target = operand_subword (target, 1 - outof_word, 1, mode);
936 outof_input = operand_subword_force (op0, outof_word, mode);
937 into_input = operand_subword_force (op0, 1 - outof_word, mode);
939 if (shift_count >= BITS_PER_WORD)
941 inter = expand_binop (word_mode, binoptab,
942 outof_input,
943 GEN_INT (shift_count - BITS_PER_WORD),
944 into_target, unsignedp, next_methods);
946 if (inter != 0 && inter != into_target)
947 emit_move_insn (into_target, inter);
949 /* For a signed right shift, we must fill the word we are shifting
950 out of with copies of the sign bit. Otherwise it is zeroed. */
951 if (inter != 0 && binoptab != ashr_optab)
952 inter = CONST0_RTX (word_mode);
953 else if (inter != 0)
954 inter = expand_binop (word_mode, binoptab,
955 outof_input,
956 GEN_INT (BITS_PER_WORD - 1),
957 outof_target, unsignedp, next_methods);
959 if (inter != 0 && inter != outof_target)
960 emit_move_insn (outof_target, inter);
962 else
964 rtx carries;
965 optab reverse_unsigned_shift, unsigned_shift;
967 /* For a shift of less then BITS_PER_WORD, to compute the carry,
968 we must do a logical shift in the opposite direction of the
969 desired shift. */
971 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
973 /* For a shift of less than BITS_PER_WORD, to compute the word
974 shifted towards, we need to unsigned shift the orig value of
975 that word. */
977 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
979 carries = expand_binop (word_mode, reverse_unsigned_shift,
980 outof_input,
981 GEN_INT (BITS_PER_WORD - shift_count),
982 0, unsignedp, next_methods);
984 if (carries == 0)
985 inter = 0;
986 else
987 inter = expand_binop (word_mode, unsigned_shift, into_input,
988 op1, 0, unsignedp, next_methods);
990 if (inter != 0)
991 inter = expand_binop (word_mode, ior_optab, carries, inter,
992 into_target, unsignedp, next_methods);
994 if (inter != 0 && inter != into_target)
995 emit_move_insn (into_target, inter);
997 if (inter != 0)
998 inter = expand_binop (word_mode, binoptab, outof_input,
999 op1, outof_target, unsignedp, next_methods);
1001 if (inter != 0 && inter != outof_target)
1002 emit_move_insn (outof_target, inter);
1005 insns = get_insns ();
1006 end_sequence ();
1008 if (inter != 0)
1010 if (binoptab->code != UNKNOWN)
1011 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1012 else
1013 equiv_value = 0;
1015 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1016 return target;
1020 /* Synthesize double word rotates from single word shifts. */
1021 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1022 && class == MODE_INT
1023 && GET_CODE (op1) == CONST_INT
1024 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1025 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1026 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1028 rtx insns, equiv_value;
1029 rtx into_target, outof_target;
1030 rtx into_input, outof_input;
1031 rtx inter;
1032 int shift_count, left_shift, outof_word;
1034 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1035 won't be accurate, so use a new target. */
1036 if (target == 0 || target == op0 || target == op1)
1037 target = gen_reg_rtx (mode);
1039 start_sequence ();
1041 shift_count = INTVAL (op1);
1043 /* OUTOF_* is the word we are shifting bits away from, and
1044 INTO_* is the word that we are shifting bits towards, thus
1045 they differ depending on the direction of the shift and
1046 WORDS_BIG_ENDIAN. */
1048 left_shift = (binoptab == rotl_optab);
1049 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1051 outof_target = operand_subword (target, outof_word, 1, mode);
1052 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1054 outof_input = operand_subword_force (op0, outof_word, mode);
1055 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1057 if (shift_count == BITS_PER_WORD)
1059 /* This is just a word swap. */
1060 emit_move_insn (outof_target, into_input);
1061 emit_move_insn (into_target, outof_input);
1062 inter = const0_rtx;
1064 else
1066 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1067 rtx first_shift_count, second_shift_count;
1068 optab reverse_unsigned_shift, unsigned_shift;
1070 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1071 ? lshr_optab : ashl_optab);
1073 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1074 ? ashl_optab : lshr_optab);
1076 if (shift_count > BITS_PER_WORD)
1078 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1079 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1081 else
1083 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1084 second_shift_count = GEN_INT (shift_count);
1087 into_temp1 = expand_binop (word_mode, unsigned_shift,
1088 outof_input, first_shift_count,
1089 NULL_RTX, unsignedp, next_methods);
1090 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1091 into_input, second_shift_count,
1092 into_target, unsignedp, next_methods);
1094 if (into_temp1 != 0 && into_temp2 != 0)
1095 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1096 into_target, unsignedp, next_methods);
1097 else
1098 inter = 0;
1100 if (inter != 0 && inter != into_target)
1101 emit_move_insn (into_target, inter);
1103 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1104 into_input, first_shift_count,
1105 NULL_RTX, unsignedp, next_methods);
1106 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1107 outof_input, second_shift_count,
1108 outof_target, unsignedp, next_methods);
1110 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1111 inter = expand_binop (word_mode, ior_optab,
1112 outof_temp1, outof_temp2,
1113 outof_target, unsignedp, next_methods);
1115 if (inter != 0 && inter != outof_target)
1116 emit_move_insn (outof_target, inter);
1119 insns = get_insns ();
1120 end_sequence ();
1122 if (inter != 0)
1124 if (binoptab->code != UNKNOWN)
1125 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1126 else
1127 equiv_value = 0;
1129 /* We can't make this a no conflict block if this is a word swap,
1130 because the word swap case fails if the input and output values
1131 are in the same register. */
1132 if (shift_count != BITS_PER_WORD)
1133 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1134 else
1135 emit_insns (insns);
1138 return target;
1142 /* These can be done a word at a time by propagating carries. */
1143 if ((binoptab == add_optab || binoptab == sub_optab)
1144 && class == MODE_INT
1145 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1146 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1148 unsigned int i;
1149 rtx carry_tmp = gen_reg_rtx (word_mode);
1150 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1151 unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1152 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1153 rtx xop0, xop1;
1155 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1156 value is one of those, use it. Otherwise, use 1 since it is the
1157 one easiest to get. */
1158 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1159 int normalizep = STORE_FLAG_VALUE;
1160 #else
1161 int normalizep = 1;
1162 #endif
1164 /* Prepare the operands. */
1165 xop0 = force_reg (mode, op0);
1166 xop1 = force_reg (mode, op1);
1168 if (target == 0 || GET_CODE (target) != REG
1169 || target == xop0 || target == xop1)
1170 target = gen_reg_rtx (mode);
1172 /* Indicate for flow that the entire target reg is being set. */
1173 if (GET_CODE (target) == REG)
1174 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1176 /* Do the actual arithmetic. */
1177 for (i = 0; i < nwords; i++)
1179 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1180 rtx target_piece = operand_subword (target, index, 1, mode);
1181 rtx op0_piece = operand_subword_force (xop0, index, mode);
1182 rtx op1_piece = operand_subword_force (xop1, index, mode);
1183 rtx x;
1185 /* Main add/subtract of the input operands. */
1186 x = expand_binop (word_mode, binoptab,
1187 op0_piece, op1_piece,
1188 target_piece, unsignedp, next_methods);
1189 if (x == 0)
1190 break;
1192 if (i + 1 < nwords)
1194 /* Store carry from main add/subtract. */
1195 carry_out = gen_reg_rtx (word_mode);
1196 carry_out = emit_store_flag_force (carry_out,
1197 (binoptab == add_optab
1198 ? LT : GT),
1199 x, op0_piece,
1200 word_mode, 1, normalizep);
1203 if (i > 0)
1205 /* Add/subtract previous carry to main result. */
1206 x = expand_binop (word_mode,
1207 normalizep == 1 ? binoptab : otheroptab,
1208 x, carry_in,
1209 target_piece, 1, next_methods);
1210 if (x == 0)
1211 break;
1212 else if (target_piece != x)
1213 emit_move_insn (target_piece, x);
1215 if (i + 1 < nwords)
1217 /* THIS CODE HAS NOT BEEN TESTED. */
1218 /* Get out carry from adding/subtracting carry in. */
1219 carry_tmp = emit_store_flag_force (carry_tmp,
1220 binoptab == add_optab
1221 ? LT : GT,
1222 x, carry_in,
1223 word_mode, 1, normalizep);
1225 /* Logical-ior the two poss. carry together. */
1226 carry_out = expand_binop (word_mode, ior_optab,
1227 carry_out, carry_tmp,
1228 carry_out, 0, next_methods);
1229 if (carry_out == 0)
1230 break;
1234 carry_in = carry_out;
1237 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1239 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1241 rtx temp = emit_move_insn (target, target);
1243 set_unique_reg_note (temp,
1244 REG_EQUAL,
1245 gen_rtx_fmt_ee (binoptab->code, mode,
1246 copy_rtx (xop0),
1247 copy_rtx (xop1)));
1250 return target;
1253 else
1254 delete_insns_since (last);
1257 /* If we want to multiply two two-word values and have normal and widening
1258 multiplies of single-word values, we can do this with three smaller
1259 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1260 because we are not operating on one word at a time.
1262 The multiplication proceeds as follows:
1263 _______________________
1264 [__op0_high_|__op0_low__]
1265 _______________________
1266 * [__op1_high_|__op1_low__]
1267 _______________________________________________
1268 _______________________
1269 (1) [__op0_low__*__op1_low__]
1270 _______________________
1271 (2a) [__op0_low__*__op1_high_]
1272 _______________________
1273 (2b) [__op0_high_*__op1_low__]
1274 _______________________
1275 (3) [__op0_high_*__op1_high_]
1278 This gives a 4-word result. Since we are only interested in the
1279 lower 2 words, partial result (3) and the upper words of (2a) and
1280 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1281 calculated using non-widening multiplication.
1283 (1), however, needs to be calculated with an unsigned widening
1284 multiplication. If this operation is not directly supported we
1285 try using a signed widening multiplication and adjust the result.
1286 This adjustment works as follows:
1288 If both operands are positive then no adjustment is needed.
1290 If the operands have different signs, for example op0_low < 0 and
1291 op1_low >= 0, the instruction treats the most significant bit of
1292 op0_low as a sign bit instead of a bit with significance
1293 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1294 with 2**BITS_PER_WORD - op0_low, and two's complements the
1295 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1296 the result.
1298 Similarly, if both operands are negative, we need to add
1299 (op0_low + op1_low) * 2**BITS_PER_WORD.
1301 We use a trick to adjust quickly. We logically shift op0_low right
1302 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1303 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1304 logical shift exists, we do an arithmetic right shift and subtract
1305 the 0 or -1. */
1307 if (binoptab == smul_optab
1308 && class == MODE_INT
1309 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1310 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1311 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1312 && ((umul_widen_optab->handlers[(int) mode].insn_code
1313 != CODE_FOR_nothing)
1314 || (smul_widen_optab->handlers[(int) mode].insn_code
1315 != CODE_FOR_nothing)))
1317 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1318 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1319 rtx op0_high = operand_subword_force (op0, high, mode);
1320 rtx op0_low = operand_subword_force (op0, low, mode);
1321 rtx op1_high = operand_subword_force (op1, high, mode);
1322 rtx op1_low = operand_subword_force (op1, low, mode);
1323 rtx product = 0;
1324 rtx op0_xhigh = NULL_RTX;
1325 rtx op1_xhigh = NULL_RTX;
1327 /* If the target is the same as one of the inputs, don't use it. This
1328 prevents problems with the REG_EQUAL note. */
1329 if (target == op0 || target == op1
1330 || (target != 0 && GET_CODE (target) != REG))
1331 target = 0;
1333 /* Multiply the two lower words to get a double-word product.
1334 If unsigned widening multiplication is available, use that;
1335 otherwise use the signed form and compensate. */
1337 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1339 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1340 target, 1, OPTAB_DIRECT);
1342 /* If we didn't succeed, delete everything we did so far. */
1343 if (product == 0)
1344 delete_insns_since (last);
1345 else
1346 op0_xhigh = op0_high, op1_xhigh = op1_high;
1349 if (product == 0
1350 && smul_widen_optab->handlers[(int) mode].insn_code
1351 != CODE_FOR_nothing)
1353 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1354 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1355 target, 1, OPTAB_DIRECT);
1356 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1357 NULL_RTX, 1, next_methods);
1358 if (op0_xhigh)
1359 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1360 op0_xhigh, op0_xhigh, 0, next_methods);
1361 else
1363 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1364 NULL_RTX, 0, next_methods);
1365 if (op0_xhigh)
1366 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1367 op0_xhigh, op0_xhigh, 0,
1368 next_methods);
1371 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1372 NULL_RTX, 1, next_methods);
1373 if (op1_xhigh)
1374 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1375 op1_xhigh, op1_xhigh, 0, next_methods);
1376 else
1378 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1379 NULL_RTX, 0, next_methods);
1380 if (op1_xhigh)
1381 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1382 op1_xhigh, op1_xhigh, 0,
1383 next_methods);
1387 /* If we have been able to directly compute the product of the
1388 low-order words of the operands and perform any required adjustments
1389 of the operands, we proceed by trying two more multiplications
1390 and then computing the appropriate sum.
1392 We have checked above that the required addition is provided.
1393 Full-word addition will normally always succeed, especially if
1394 it is provided at all, so we don't worry about its failure. The
1395 multiplication may well fail, however, so we do handle that. */
1397 if (product && op0_xhigh && op1_xhigh)
1399 rtx product_high = operand_subword (product, high, 1, mode);
1400 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1401 NULL_RTX, 0, OPTAB_DIRECT);
1403 if (temp != 0)
1404 temp = expand_binop (word_mode, add_optab, temp, product_high,
1405 product_high, 0, next_methods);
1407 if (temp != 0 && temp != product_high)
1408 emit_move_insn (product_high, temp);
1410 if (temp != 0)
1411 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1412 NULL_RTX, 0, OPTAB_DIRECT);
1414 if (temp != 0)
1415 temp = expand_binop (word_mode, add_optab, temp,
1416 product_high, product_high,
1417 0, next_methods);
1419 if (temp != 0 && temp != product_high)
1420 emit_move_insn (product_high, temp);
1422 if (temp != 0)
1424 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1426 temp = emit_move_insn (product, product);
1427 set_unique_reg_note (temp,
1428 REG_EQUAL,
1429 gen_rtx_fmt_ee (MULT, mode,
1430 copy_rtx (op0),
1431 copy_rtx (op1)));
1434 return product;
1438 /* If we get here, we couldn't do it for some reason even though we
1439 originally thought we could. Delete anything we've emitted in
1440 trying to do it. */
1442 delete_insns_since (last);
1445 /* We need to open-code the complex type operations: '+, -, * and /' */
1447 /* At this point we allow operations between two similar complex
1448 numbers, and also if one of the operands is not a complex number
1449 but rather of MODE_FLOAT or MODE_INT. However, the caller
1450 must make sure that the MODE of the non-complex operand matches
1451 the SUBMODE of the complex operand. */
1453 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1455 rtx real0 = 0, imag0 = 0;
1456 rtx real1 = 0, imag1 = 0;
1457 rtx realr, imagr, res;
1458 rtx seq;
1459 rtx equiv_value;
1460 int ok = 0;
1462 /* Find the correct mode for the real and imaginary parts */
1463 enum machine_mode submode
1464 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1465 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1468 if (submode == BLKmode)
1469 abort ();
1471 if (! target)
1472 target = gen_reg_rtx (mode);
1474 start_sequence ();
1476 realr = gen_realpart (submode, target);
1477 imagr = gen_imagpart (submode, target);
1479 if (GET_MODE (op0) == mode)
1481 real0 = gen_realpart (submode, op0);
1482 imag0 = gen_imagpart (submode, op0);
1484 else
1485 real0 = op0;
1487 if (GET_MODE (op1) == mode)
1489 real1 = gen_realpart (submode, op1);
1490 imag1 = gen_imagpart (submode, op1);
1492 else
1493 real1 = op1;
1495 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1496 abort ();
1498 switch (binoptab->code)
1500 case PLUS:
1501 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1502 case MINUS:
1503 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1504 res = expand_binop (submode, binoptab, real0, real1,
1505 realr, unsignedp, methods);
1507 if (res == 0)
1508 break;
1509 else if (res != realr)
1510 emit_move_insn (realr, res);
1512 if (imag0 && imag1)
1513 res = expand_binop (submode, binoptab, imag0, imag1,
1514 imagr, unsignedp, methods);
1515 else if (imag0)
1516 res = imag0;
1517 else if (binoptab->code == MINUS)
1518 res = expand_unop (submode,
1519 binoptab == subv_optab ? negv_optab : neg_optab,
1520 imag1, imagr, unsignedp);
1521 else
1522 res = imag1;
1524 if (res == 0)
1525 break;
1526 else if (res != imagr)
1527 emit_move_insn (imagr, res);
1529 ok = 1;
1530 break;
1532 case MULT:
1533 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1535 if (imag0 && imag1)
1537 rtx temp1, temp2;
1539 /* Don't fetch these from memory more than once. */
1540 real0 = force_reg (submode, real0);
1541 real1 = force_reg (submode, real1);
1542 imag0 = force_reg (submode, imag0);
1543 imag1 = force_reg (submode, imag1);
1545 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1546 unsignedp, methods);
1548 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1549 unsignedp, methods);
1551 if (temp1 == 0 || temp2 == 0)
1552 break;
1554 res = (expand_binop
1555 (submode,
1556 binoptab == smulv_optab ? subv_optab : sub_optab,
1557 temp1, temp2, realr, unsignedp, methods));
1559 if (res == 0)
1560 break;
1561 else if (res != realr)
1562 emit_move_insn (realr, res);
1564 temp1 = expand_binop (submode, binoptab, real0, imag1,
1565 NULL_RTX, unsignedp, methods);
1567 temp2 = expand_binop (submode, binoptab, real1, imag0,
1568 NULL_RTX, unsignedp, methods);
1570 if (temp1 == 0 || temp2 == 0)
1571 break;
1573 res = (expand_binop
1574 (submode,
1575 binoptab == smulv_optab ? addv_optab : add_optab,
1576 temp1, temp2, imagr, unsignedp, methods));
1578 if (res == 0)
1579 break;
1580 else if (res != imagr)
1581 emit_move_insn (imagr, res);
1583 ok = 1;
1585 else
1587 /* Don't fetch these from memory more than once. */
1588 real0 = force_reg (submode, real0);
1589 real1 = force_reg (submode, real1);
1591 res = expand_binop (submode, binoptab, real0, real1,
1592 realr, unsignedp, methods);
1593 if (res == 0)
1594 break;
1595 else if (res != realr)
1596 emit_move_insn (realr, res);
1598 if (imag0 != 0)
1599 res = expand_binop (submode, binoptab,
1600 real1, imag0, imagr, unsignedp, methods);
1601 else
1602 res = expand_binop (submode, binoptab,
1603 real0, imag1, imagr, unsignedp, methods);
1605 if (res == 0)
1606 break;
1607 else if (res != imagr)
1608 emit_move_insn (imagr, res);
1610 ok = 1;
1612 break;
1614 case DIV:
1615 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1617 if (imag1 == 0)
1619 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1621 /* Don't fetch these from memory more than once. */
1622 real1 = force_reg (submode, real1);
1624 /* Simply divide the real and imaginary parts by `c' */
1625 if (class == MODE_COMPLEX_FLOAT)
1626 res = expand_binop (submode, binoptab, real0, real1,
1627 realr, unsignedp, methods);
1628 else
1629 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1630 real0, real1, realr, unsignedp);
1632 if (res == 0)
1633 break;
1634 else if (res != realr)
1635 emit_move_insn (realr, res);
1637 if (class == MODE_COMPLEX_FLOAT)
1638 res = expand_binop (submode, binoptab, imag0, real1,
1639 imagr, unsignedp, methods);
1640 else
1641 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1642 imag0, real1, imagr, unsignedp);
1644 if (res == 0)
1645 break;
1646 else if (res != imagr)
1647 emit_move_insn (imagr, res);
1649 ok = 1;
1651 else
1653 switch (flag_complex_divide_method)
1655 case 0:
1656 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1657 realr, imagr, submode,
1658 unsignedp, methods,
1659 class, binoptab);
1660 break;
1662 case 1:
1663 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1664 realr, imagr, submode,
1665 unsignedp, methods,
1666 class, binoptab);
1667 break;
1669 default:
1670 abort ();
1673 break;
1675 default:
1676 abort ();
1679 seq = get_insns ();
1680 end_sequence ();
1682 if (ok)
1684 if (binoptab->code != UNKNOWN)
1685 equiv_value
1686 = gen_rtx_fmt_ee (binoptab->code, mode,
1687 copy_rtx (op0), copy_rtx (op1));
1688 else
1689 equiv_value = 0;
1691 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1693 return target;
1697 /* It can't be open-coded in this mode.
1698 Use a library call if one is available and caller says that's ok. */
1700 if (binoptab->handlers[(int) mode].libfunc
1701 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1703 rtx insns;
1704 rtx op1x = op1;
1705 enum machine_mode op1_mode = mode;
1706 rtx value;
1708 start_sequence ();
1710 if (shift_op)
1712 op1_mode = word_mode;
1713 /* Specify unsigned here,
1714 since negative shift counts are meaningless. */
1715 op1x = convert_to_mode (word_mode, op1, 1);
1718 if (GET_MODE (op0) != VOIDmode
1719 && GET_MODE (op0) != mode)
1720 op0 = convert_to_mode (mode, op0, unsignedp);
1722 /* Pass 1 for NO_QUEUE so we don't lose any increments
1723 if the libcall is cse'd or moved. */
1724 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1725 NULL_RTX, LCT_CONST, mode, 2,
1726 op0, mode, op1x, op1_mode);
1728 insns = get_insns ();
1729 end_sequence ();
1731 target = gen_reg_rtx (mode);
1732 emit_libcall_block (insns, target, value,
1733 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1735 return target;
1738 delete_insns_since (last);
1740 /* It can't be done in this mode. Can we do it in a wider mode? */
1742 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1743 || methods == OPTAB_MUST_WIDEN))
1745 /* Caller says, don't even try. */
1746 delete_insns_since (entry_last);
1747 return 0;
1750 /* Compute the value of METHODS to pass to recursive calls.
1751 Don't allow widening to be tried recursively. */
1753 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1755 /* Look for a wider mode of the same class for which it appears we can do
1756 the operation. */
1758 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1760 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1761 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1763 if ((binoptab->handlers[(int) wider_mode].insn_code
1764 != CODE_FOR_nothing)
1765 || (methods == OPTAB_LIB
1766 && binoptab->handlers[(int) wider_mode].libfunc))
1768 rtx xop0 = op0, xop1 = op1;
1769 int no_extend = 0;
1771 /* For certain integer operations, we need not actually extend
1772 the narrow operands, as long as we will truncate
1773 the results to the same narrowness. */
1775 if ((binoptab == ior_optab || binoptab == and_optab
1776 || binoptab == xor_optab
1777 || binoptab == add_optab || binoptab == sub_optab
1778 || binoptab == smul_optab || binoptab == ashl_optab)
1779 && class == MODE_INT)
1780 no_extend = 1;
1782 xop0 = widen_operand (xop0, wider_mode, mode,
1783 unsignedp, no_extend);
1785 /* The second operand of a shift must always be extended. */
1786 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1787 no_extend && binoptab != ashl_optab);
1789 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1790 unsignedp, methods);
1791 if (temp)
1793 if (class != MODE_INT)
1795 if (target == 0)
1796 target = gen_reg_rtx (mode);
1797 convert_move (target, temp, 0);
1798 return target;
1800 else
1801 return gen_lowpart (mode, temp);
1803 else
1804 delete_insns_since (last);
1809 delete_insns_since (entry_last);
1810 return 0;
1813 /* Expand a binary operator which has both signed and unsigned forms.
1814 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1815 signed operations.
1817 If we widen unsigned operands, we may use a signed wider operation instead
1818 of an unsigned wider operation, since the result would be the same. */
1821 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1822 enum machine_mode mode;
1823 optab uoptab, soptab;
1824 rtx op0, op1, target;
1825 int unsignedp;
1826 enum optab_methods methods;
1828 register rtx temp;
1829 optab direct_optab = unsignedp ? uoptab : soptab;
1830 struct optab wide_soptab;
1832 /* Do it without widening, if possible. */
1833 temp = expand_binop (mode, direct_optab, op0, op1, target,
1834 unsignedp, OPTAB_DIRECT);
1835 if (temp || methods == OPTAB_DIRECT)
1836 return temp;
1838 /* Try widening to a signed int. Make a fake signed optab that
1839 hides any signed insn for direct use. */
1840 wide_soptab = *soptab;
1841 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1842 wide_soptab.handlers[(int) mode].libfunc = 0;
1844 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1845 unsignedp, OPTAB_WIDEN);
1847 /* For unsigned operands, try widening to an unsigned int. */
1848 if (temp == 0 && unsignedp)
1849 temp = expand_binop (mode, uoptab, op0, op1, target,
1850 unsignedp, OPTAB_WIDEN);
1851 if (temp || methods == OPTAB_WIDEN)
1852 return temp;
1854 /* Use the right width lib call if that exists. */
1855 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1856 if (temp || methods == OPTAB_LIB)
1857 return temp;
1859 /* Must widen and use a lib call, use either signed or unsigned. */
1860 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1861 unsignedp, methods);
1862 if (temp != 0)
1863 return temp;
1864 if (unsignedp)
1865 return expand_binop (mode, uoptab, op0, op1, target,
1866 unsignedp, methods);
1867 return 0;
1870 /* Generate code to perform an operation specified by BINOPTAB
1871 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1872 We assume that the order of the operands for the instruction
1873 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1874 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1876 Either TARG0 or TARG1 may be zero, but what that means is that
1877 the result is not actually wanted. We will generate it into
1878 a dummy pseudo-reg and discard it. They may not both be zero.
1880 Returns 1 if this operation can be performed; 0 if not. */
1883 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1884 optab binoptab;
1885 rtx op0, op1;
1886 rtx targ0, targ1;
1887 int unsignedp;
1889 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1890 enum mode_class class;
1891 enum machine_mode wider_mode;
1892 rtx entry_last = get_last_insn ();
1893 rtx last;
1895 class = GET_MODE_CLASS (mode);
1897 op0 = protect_from_queue (op0, 0);
1898 op1 = protect_from_queue (op1, 0);
1900 if (flag_force_mem)
1902 op0 = force_not_mem (op0);
1903 op1 = force_not_mem (op1);
1906 /* If we are inside an appropriately-short loop and one operand is an
1907 expensive constant, force it into a register. */
1908 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1909 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1910 op0 = force_reg (mode, op0);
1912 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1913 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1914 op1 = force_reg (mode, op1);
1916 if (targ0)
1917 targ0 = protect_from_queue (targ0, 1);
1918 else
1919 targ0 = gen_reg_rtx (mode);
1920 if (targ1)
1921 targ1 = protect_from_queue (targ1, 1);
1922 else
1923 targ1 = gen_reg_rtx (mode);
1925 /* Record where to go back to if we fail. */
1926 last = get_last_insn ();
1928 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1930 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1931 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1932 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1933 rtx pat;
1934 rtx xop0 = op0, xop1 = op1;
1936 /* In case this insn wants input operands in modes different from the
1937 result, convert the operands. */
1938 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1939 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1941 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1942 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1944 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1945 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
1946 xop0 = copy_to_mode_reg (mode0, xop0);
1948 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
1949 xop1 = copy_to_mode_reg (mode1, xop1);
1951 /* We could handle this, but we should always be called with a pseudo
1952 for our targets and all insns should take them as outputs. */
1953 if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
1954 || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
1955 abort ();
1957 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1958 if (pat)
1960 emit_insn (pat);
1961 return 1;
1963 else
1964 delete_insns_since (last);
1967 /* It can't be done in this mode. Can we do it in a wider mode? */
1969 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1971 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1972 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1974 if (binoptab->handlers[(int) wider_mode].insn_code
1975 != CODE_FOR_nothing)
1977 register rtx t0 = gen_reg_rtx (wider_mode);
1978 register rtx t1 = gen_reg_rtx (wider_mode);
1980 if (expand_twoval_binop (binoptab,
1981 convert_modes (wider_mode, mode, op0,
1982 unsignedp),
1983 convert_modes (wider_mode, mode, op1,
1984 unsignedp),
1985 t0, t1, unsignedp))
1987 convert_move (targ0, t0, unsignedp);
1988 convert_move (targ1, t1, unsignedp);
1989 return 1;
1991 else
1992 delete_insns_since (last);
1997 delete_insns_since (entry_last);
1998 return 0;
2001 /* Generate code to perform an operation specified by UNOPTAB
2002 on operand OP0, with result having machine-mode MODE.
2004 UNSIGNEDP is for the case where we have to widen the operands
2005 to perform the operation. It says to use zero-extension.
2007 If TARGET is nonzero, the value
2008 is generated there, if it is convenient to do so.
2009 In all cases an rtx is returned for the locus of the value;
2010 this may or may not be TARGET. */
2013 expand_unop (mode, unoptab, op0, target, unsignedp)
2014 enum machine_mode mode;
2015 optab unoptab;
2016 rtx op0;
2017 rtx target;
2018 int unsignedp;
2020 enum mode_class class;
2021 enum machine_mode wider_mode;
2022 register rtx temp;
2023 rtx last = get_last_insn ();
2024 rtx pat;
2026 class = GET_MODE_CLASS (mode);
2028 op0 = protect_from_queue (op0, 0);
2030 if (flag_force_mem)
2032 op0 = force_not_mem (op0);
2035 if (target)
2036 target = protect_from_queue (target, 1);
2038 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2040 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2041 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2042 rtx xop0 = op0;
2044 if (target)
2045 temp = target;
2046 else
2047 temp = gen_reg_rtx (mode);
2049 if (GET_MODE (xop0) != VOIDmode
2050 && GET_MODE (xop0) != mode0)
2051 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2053 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2055 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2056 xop0 = copy_to_mode_reg (mode0, xop0);
2058 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2059 temp = gen_reg_rtx (mode);
2061 pat = GEN_FCN (icode) (temp, xop0);
2062 if (pat)
2064 if (GET_CODE (pat) == SEQUENCE
2065 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2067 delete_insns_since (last);
2068 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2071 emit_insn (pat);
2073 return temp;
2075 else
2076 delete_insns_since (last);
2079 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2081 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2082 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2083 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2085 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2087 rtx xop0 = op0;
2089 /* For certain operations, we need not actually extend
2090 the narrow operand, as long as we will truncate the
2091 results to the same narrowness. */
2093 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2094 (unoptab == neg_optab
2095 || unoptab == one_cmpl_optab)
2096 && class == MODE_INT);
2098 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2099 unsignedp);
2101 if (temp)
2103 if (class != MODE_INT)
2105 if (target == 0)
2106 target = gen_reg_rtx (mode);
2107 convert_move (target, temp, 0);
2108 return target;
2110 else
2111 return gen_lowpart (mode, temp);
2113 else
2114 delete_insns_since (last);
2118 /* These can be done a word at a time. */
2119 if (unoptab == one_cmpl_optab
2120 && class == MODE_INT
2121 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2122 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2124 unsigned int i;
2125 rtx insns;
2127 if (target == 0 || target == op0)
2128 target = gen_reg_rtx (mode);
2130 start_sequence ();
2132 /* Do the actual arithmetic. */
2133 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2135 rtx target_piece = operand_subword (target, i, 1, mode);
2136 rtx x = expand_unop (word_mode, unoptab,
2137 operand_subword_force (op0, i, mode),
2138 target_piece, unsignedp);
2139 if (target_piece != x)
2140 emit_move_insn (target_piece, x);
2143 insns = get_insns ();
2144 end_sequence ();
2146 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2147 gen_rtx_fmt_e (unoptab->code, mode,
2148 copy_rtx (op0)));
2149 return target;
2152 /* Open-code the complex negation operation. */
2153 else if (unoptab->code == NEG
2154 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2156 rtx target_piece;
2157 rtx x;
2158 rtx seq;
2160 /* Find the correct mode for the real and imaginary parts */
2161 enum machine_mode submode
2162 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2163 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2166 if (submode == BLKmode)
2167 abort ();
2169 if (target == 0)
2170 target = gen_reg_rtx (mode);
2172 start_sequence ();
2174 target_piece = gen_imagpart (submode, target);
2175 x = expand_unop (submode, unoptab,
2176 gen_imagpart (submode, op0),
2177 target_piece, unsignedp);
2178 if (target_piece != x)
2179 emit_move_insn (target_piece, x);
2181 target_piece = gen_realpart (submode, target);
2182 x = expand_unop (submode, unoptab,
2183 gen_realpart (submode, op0),
2184 target_piece, unsignedp);
2185 if (target_piece != x)
2186 emit_move_insn (target_piece, x);
2188 seq = get_insns ();
2189 end_sequence ();
2191 emit_no_conflict_block (seq, target, op0, 0,
2192 gen_rtx_fmt_e (unoptab->code, mode,
2193 copy_rtx (op0)));
2194 return target;
2197 /* Now try a library call in this mode. */
2198 if (unoptab->handlers[(int) mode].libfunc)
2200 rtx insns;
2201 rtx value;
2203 start_sequence ();
2205 /* Pass 1 for NO_QUEUE so we don't lose any increments
2206 if the libcall is cse'd or moved. */
2207 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2208 NULL_RTX, LCT_CONST, mode, 1, op0, mode);
2209 insns = get_insns ();
2210 end_sequence ();
2212 target = gen_reg_rtx (mode);
2213 emit_libcall_block (insns, target, value,
2214 gen_rtx_fmt_e (unoptab->code, mode, op0));
2216 return target;
2219 /* It can't be done in this mode. Can we do it in a wider mode? */
2221 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2223 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2224 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2226 if ((unoptab->handlers[(int) wider_mode].insn_code
2227 != CODE_FOR_nothing)
2228 || unoptab->handlers[(int) wider_mode].libfunc)
2230 rtx xop0 = op0;
2232 /* For certain operations, we need not actually extend
2233 the narrow operand, as long as we will truncate the
2234 results to the same narrowness. */
2236 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2237 (unoptab == neg_optab
2238 || unoptab == one_cmpl_optab)
2239 && class == MODE_INT);
2241 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2242 unsignedp);
2244 if (temp)
2246 if (class != MODE_INT)
2248 if (target == 0)
2249 target = gen_reg_rtx (mode);
2250 convert_move (target, temp, 0);
2251 return target;
2253 else
2254 return gen_lowpart (mode, temp);
2256 else
2257 delete_insns_since (last);
2262 /* If there is no negate operation, try doing a subtract from zero.
2263 The US Software GOFAST library needs this. */
2264 if (unoptab->code == NEG)
2266 rtx temp;
2267 temp = expand_binop (mode,
2268 unoptab == negv_optab ? subv_optab : sub_optab,
2269 CONST0_RTX (mode), op0,
2270 target, unsignedp, OPTAB_LIB_WIDEN);
2271 if (temp)
2272 return temp;
2275 return 0;
2278 /* Emit code to compute the absolute value of OP0, with result to
2279 TARGET if convenient. (TARGET may be 0.) The return value says
2280 where the result actually is to be found.
2282 MODE is the mode of the operand; the mode of the result is
2283 different but can be deduced from MODE.
2288 expand_abs (mode, op0, target, result_unsignedp, safe)
2289 enum machine_mode mode;
2290 rtx op0;
2291 rtx target;
2292 int result_unsignedp;
2293 int safe;
2295 rtx temp, op1;
2297 if (! flag_trapv)
2298 result_unsignedp = 1;
2300 /* First try to do it with a special abs instruction. */
2301 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2302 op0, target, 0);
2303 if (temp != 0)
2304 return temp;
2306 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2307 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2309 rtx last = get_last_insn ();
2311 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2312 if (temp != 0)
2313 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2314 OPTAB_WIDEN);
2316 if (temp != 0)
2317 return temp;
2319 delete_insns_since (last);
2322 /* If this machine has expensive jumps, we can do integer absolute
2323 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2324 where W is the width of MODE. But don't do this if the machine has
2325 conditional arithmetic since the branches will be converted into
2326 a conditional negation insn. */
2328 #ifndef HAVE_conditional_arithmetic
2329 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2331 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2332 size_int (GET_MODE_BITSIZE (mode) - 1),
2333 NULL_RTX, 0);
2335 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2336 OPTAB_LIB_WIDEN);
2337 if (temp != 0)
2338 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2339 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2341 if (temp != 0)
2342 return temp;
2344 #endif
2346 /* If that does not win, use conditional jump and negate. */
2348 /* It is safe to use the target if it is the same
2349 as the source if this is also a pseudo register */
2350 if (op0 == target && GET_CODE (op0) == REG
2351 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2352 safe = 1;
2354 op1 = gen_label_rtx ();
2355 if (target == 0 || ! safe
2356 || GET_MODE (target) != mode
2357 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2358 || (GET_CODE (target) == REG
2359 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2360 target = gen_reg_rtx (mode);
2362 emit_move_insn (target, op0);
2363 NO_DEFER_POP;
2365 /* If this mode is an integer too wide to compare properly,
2366 compare word by word. Rely on CSE to optimize constant cases. */
2367 if (GET_MODE_CLASS (mode) == MODE_INT
2368 && ! can_compare_p (GE, mode, ccp_jump))
2369 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2370 NULL_RTX, op1);
2371 else
2372 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2373 NULL_RTX, 0, NULL_RTX, op1);
2375 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2376 target, target, 0);
2377 if (op0 != target)
2378 emit_move_insn (target, op0);
2379 emit_label (op1);
2380 OK_DEFER_POP;
2381 return target;
2384 /* Emit code to compute the absolute value of OP0, with result to
2385 TARGET if convenient. (TARGET may be 0.) The return value says
2386 where the result actually is to be found.
2388 MODE is the mode of the operand; the mode of the result is
2389 different but can be deduced from MODE.
2391 UNSIGNEDP is relevant for complex integer modes. */
2394 expand_complex_abs (mode, op0, target, unsignedp)
2395 enum machine_mode mode;
2396 rtx op0;
2397 rtx target;
2398 int unsignedp;
2400 enum mode_class class = GET_MODE_CLASS (mode);
2401 enum machine_mode wider_mode;
2402 register rtx temp;
2403 rtx entry_last = get_last_insn ();
2404 rtx last;
2405 rtx pat;
2406 optab this_abs_optab;
2408 /* Find the correct mode for the real and imaginary parts. */
2409 enum machine_mode submode
2410 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2411 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2414 if (submode == BLKmode)
2415 abort ();
2417 op0 = protect_from_queue (op0, 0);
2419 if (flag_force_mem)
2421 op0 = force_not_mem (op0);
2424 last = get_last_insn ();
2426 if (target)
2427 target = protect_from_queue (target, 1);
2429 this_abs_optab = ! unsignedp && flag_trapv
2430 && (GET_MODE_CLASS(mode) == MODE_INT)
2431 ? absv_optab : abs_optab;
2433 if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2435 int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2436 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2437 rtx xop0 = op0;
2439 if (target)
2440 temp = target;
2441 else
2442 temp = gen_reg_rtx (submode);
2444 if (GET_MODE (xop0) != VOIDmode
2445 && GET_MODE (xop0) != mode0)
2446 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2448 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2450 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2451 xop0 = copy_to_mode_reg (mode0, xop0);
2453 if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2454 temp = gen_reg_rtx (submode);
2456 pat = GEN_FCN (icode) (temp, xop0);
2457 if (pat)
2459 if (GET_CODE (pat) == SEQUENCE
2460 && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
2461 NULL_RTX))
2463 delete_insns_since (last);
2464 return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
2465 unsignedp);
2468 emit_insn (pat);
2470 return temp;
2472 else
2473 delete_insns_since (last);
2476 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2478 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2479 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2481 if (this_abs_optab->handlers[(int) wider_mode].insn_code
2482 != CODE_FOR_nothing)
2484 rtx xop0 = op0;
2486 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2487 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2489 if (temp)
2491 if (class != MODE_COMPLEX_INT)
2493 if (target == 0)
2494 target = gen_reg_rtx (submode);
2495 convert_move (target, temp, 0);
2496 return target;
2498 else
2499 return gen_lowpart (submode, temp);
2501 else
2502 delete_insns_since (last);
2506 /* Open-code the complex absolute-value operation
2507 if we can open-code sqrt. Otherwise it's not worth while. */
2508 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2509 && ! flag_trapv)
2511 rtx real, imag, total;
2513 real = gen_realpart (submode, op0);
2514 imag = gen_imagpart (submode, op0);
2516 /* Square both parts. */
2517 real = expand_mult (submode, real, real, NULL_RTX, 0);
2518 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2520 /* Sum the parts. */
2521 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2522 0, OPTAB_LIB_WIDEN);
2524 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2525 target = expand_unop (submode, sqrt_optab, total, target, 0);
2526 if (target == 0)
2527 delete_insns_since (last);
2528 else
2529 return target;
2532 /* Now try a library call in this mode. */
2533 if (this_abs_optab->handlers[(int) mode].libfunc)
2535 rtx insns;
2536 rtx value;
2538 start_sequence ();
2540 /* Pass 1 for NO_QUEUE so we don't lose any increments
2541 if the libcall is cse'd or moved. */
2542 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2543 NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2544 insns = get_insns ();
2545 end_sequence ();
2547 target = gen_reg_rtx (submode);
2548 emit_libcall_block (insns, target, value,
2549 gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2551 return target;
2554 /* It can't be done in this mode. Can we do it in a wider mode? */
2556 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2557 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2559 if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2560 != CODE_FOR_nothing)
2561 || this_abs_optab->handlers[(int) wider_mode].libfunc)
2563 rtx xop0 = op0;
2565 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2567 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2569 if (temp)
2571 if (class != MODE_COMPLEX_INT)
2573 if (target == 0)
2574 target = gen_reg_rtx (submode);
2575 convert_move (target, temp, 0);
2576 return target;
2578 else
2579 return gen_lowpart (submode, temp);
2581 else
2582 delete_insns_since (last);
2586 delete_insns_since (entry_last);
2587 return 0;
2590 /* Generate an instruction whose insn-code is INSN_CODE,
2591 with two operands: an output TARGET and an input OP0.
2592 TARGET *must* be nonzero, and the output is always stored there.
2593 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2594 the value that is stored into TARGET. */
2596 void
2597 emit_unop_insn (icode, target, op0, code)
2598 int icode;
2599 rtx target;
2600 rtx op0;
2601 enum rtx_code code;
2603 register rtx temp;
2604 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2605 rtx pat;
2607 temp = target = protect_from_queue (target, 1);
2609 op0 = protect_from_queue (op0, 0);
2611 /* Sign and zero extension from memory is often done specially on
2612 RISC machines, so forcing into a register here can pessimize
2613 code. */
2614 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2615 op0 = force_not_mem (op0);
2617 /* Now, if insn does not accept our operands, put them into pseudos. */
2619 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2620 op0 = copy_to_mode_reg (mode0, op0);
2622 if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2623 || (flag_force_mem && GET_CODE (temp) == MEM))
2624 temp = gen_reg_rtx (GET_MODE (temp));
2626 pat = GEN_FCN (icode) (temp, op0);
2628 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2629 add_equal_note (pat, temp, code, op0, NULL_RTX);
2631 emit_insn (pat);
2633 if (temp != target)
2634 emit_move_insn (target, temp);
2637 /* Emit code to perform a series of operations on a multi-word quantity, one
2638 word at a time.
2640 Such a block is preceded by a CLOBBER of the output, consists of multiple
2641 insns, each setting one word of the output, and followed by a SET copying
2642 the output to itself.
2644 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2645 note indicating that it doesn't conflict with the (also multi-word)
2646 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2647 notes.
2649 INSNS is a block of code generated to perform the operation, not including
2650 the CLOBBER and final copy. All insns that compute intermediate values
2651 are first emitted, followed by the block as described above.
2653 TARGET, OP0, and OP1 are the output and inputs of the operations,
2654 respectively. OP1 may be zero for a unary operation.
2656 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2657 on the last insn.
2659 If TARGET is not a register, INSNS is simply emitted with no special
2660 processing. Likewise if anything in INSNS is not an INSN or if
2661 there is a libcall block inside INSNS.
2663 The final insn emitted is returned. */
2666 emit_no_conflict_block (insns, target, op0, op1, equiv)
2667 rtx insns;
2668 rtx target;
2669 rtx op0, op1;
2670 rtx equiv;
2672 rtx prev, next, first, last, insn;
2674 if (GET_CODE (target) != REG || reload_in_progress)
2675 return emit_insns (insns);
2676 else
2677 for (insn = insns; insn; insn = NEXT_INSN (insn))
2678 if (GET_CODE (insn) != INSN
2679 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2680 return emit_insns (insns);
2682 /* First emit all insns that do not store into words of the output and remove
2683 these from the list. */
2684 for (insn = insns; insn; insn = next)
2686 rtx set = 0;
2687 int i;
2689 next = NEXT_INSN (insn);
2691 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
2692 || GET_CODE (PATTERN (insn)) == CLOBBER)
2693 set = PATTERN (insn);
2694 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2696 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2697 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2699 set = XVECEXP (PATTERN (insn), 0, i);
2700 break;
2704 if (set == 0)
2705 abort ();
2707 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2709 if (PREV_INSN (insn))
2710 NEXT_INSN (PREV_INSN (insn)) = next;
2711 else
2712 insns = next;
2714 if (next)
2715 PREV_INSN (next) = PREV_INSN (insn);
2717 add_insn (insn);
2721 prev = get_last_insn ();
2723 /* Now write the CLOBBER of the output, followed by the setting of each
2724 of the words, followed by the final copy. */
2725 if (target != op0 && target != op1)
2726 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2728 for (insn = insns; insn; insn = next)
2730 next = NEXT_INSN (insn);
2731 add_insn (insn);
2733 if (op1 && GET_CODE (op1) == REG)
2734 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2735 REG_NOTES (insn));
2737 if (op0 && GET_CODE (op0) == REG)
2738 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2739 REG_NOTES (insn));
2742 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2743 != CODE_FOR_nothing)
2745 last = emit_move_insn (target, target);
2746 if (equiv)
2747 set_unique_reg_note (last, REG_EQUAL, equiv);
2749 else
2751 last = get_last_insn ();
2753 /* Remove any existing REG_EQUAL note from "last", or else it will
2754 be mistaken for a note referring to the full contents of the
2755 alleged libcall value when found together with the REG_RETVAL
2756 note added below. An existing note can come from an insn
2757 expansion at "last". */
2758 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2761 if (prev == 0)
2762 first = get_insns ();
2763 else
2764 first = NEXT_INSN (prev);
2766 /* Encapsulate the block so it gets manipulated as a unit. */
2767 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2768 REG_NOTES (first));
2769 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2771 return last;
2774 /* Emit code to make a call to a constant function or a library call.
2776 INSNS is a list containing all insns emitted in the call.
2777 These insns leave the result in RESULT. Our block is to copy RESULT
2778 to TARGET, which is logically equivalent to EQUIV.
2780 We first emit any insns that set a pseudo on the assumption that these are
2781 loading constants into registers; doing so allows them to be safely cse'ed
2782 between blocks. Then we emit all the other insns in the block, followed by
2783 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2784 note with an operand of EQUIV.
2786 Moving assignments to pseudos outside of the block is done to improve
2787 the generated code, but is not required to generate correct code,
2788 hence being unable to move an assignment is not grounds for not making
2789 a libcall block. There are two reasons why it is safe to leave these
2790 insns inside the block: First, we know that these pseudos cannot be
2791 used in generated RTL outside the block since they are created for
2792 temporary purposes within the block. Second, CSE will not record the
2793 values of anything set inside a libcall block, so we know they must
2794 be dead at the end of the block.
2796 Except for the first group of insns (the ones setting pseudos), the
2797 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2799 void
2800 emit_libcall_block (insns, target, result, equiv)
2801 rtx insns;
2802 rtx target;
2803 rtx result;
2804 rtx equiv;
2806 rtx final_dest = target;
2807 rtx prev, next, first, last, insn;
2809 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2810 into a MEM later. Protect the libcall block from this change. */
2811 if (! REG_P (target) || REG_USERVAR_P (target))
2812 target = gen_reg_rtx (GET_MODE (target));
2814 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2815 reg note to indicate that this call cannot throw or execute a nonlocal
2816 goto (unless there is already a REG_EH_REGION note, in which case
2817 we update it). Also set the CONST_CALL_P flag. */
2819 for (insn = insns; insn; insn = NEXT_INSN (insn))
2820 if (GET_CODE (insn) == CALL_INSN)
2822 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2824 CONST_CALL_P (insn) = 1;
2825 if (note != 0)
2826 XEXP (note, 0) = GEN_INT (-1);
2827 else
2828 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2829 REG_NOTES (insn));
2832 /* First emit all insns that set pseudos. Remove them from the list as
2833 we go. Avoid insns that set pseudos which were referenced in previous
2834 insns. These can be generated by move_by_pieces, for example,
2835 to update an address. Similarly, avoid insns that reference things
2836 set in previous insns. */
2838 for (insn = insns; insn; insn = next)
2840 rtx set = single_set (insn);
2842 next = NEXT_INSN (insn);
2844 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2845 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2846 && (insn == insns
2847 || ((! INSN_P(insns)
2848 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
2849 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2850 && ! modified_in_p (SET_SRC (set), insns)
2851 && ! modified_between_p (SET_SRC (set), insns, insn))))
2853 if (PREV_INSN (insn))
2854 NEXT_INSN (PREV_INSN (insn)) = next;
2855 else
2856 insns = next;
2858 if (next)
2859 PREV_INSN (next) = PREV_INSN (insn);
2861 add_insn (insn);
2865 prev = get_last_insn ();
2867 /* Write the remaining insns followed by the final copy. */
2869 for (insn = insns; insn; insn = next)
2871 next = NEXT_INSN (insn);
2873 add_insn (insn);
2876 last = emit_move_insn (target, result);
2877 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2878 != CODE_FOR_nothing)
2879 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2880 else
2882 /* Remove any existing REG_EQUAL note from "last", or else it will
2883 be mistaken for a note referring to the full contents of the
2884 libcall value when found together with the REG_RETVAL note added
2885 below. An existing note can come from an insn expansion at
2886 "last". */
2887 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2890 if (final_dest != target)
2891 emit_move_insn (final_dest, target);
2893 if (prev == 0)
2894 first = get_insns ();
2895 else
2896 first = NEXT_INSN (prev);
2898 /* Encapsulate the block so it gets manipulated as a unit. */
2899 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2900 REG_NOTES (first));
2901 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2904 /* Generate code to store zero in X. */
2906 void
2907 emit_clr_insn (x)
2908 rtx x;
2910 emit_move_insn (x, const0_rtx);
2913 /* Generate code to store 1 in X
2914 assuming it contains zero beforehand. */
2916 void
2917 emit_0_to_1_insn (x)
2918 rtx x;
2920 emit_move_insn (x, const1_rtx);
2923 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2924 PURPOSE describes how this comparison will be used. CODE is the rtx
2925 comparison code we will be using.
2927 ??? Actually, CODE is slightly weaker than that. A target is still
2928 required to implement all of the normal bcc operations, but not
2929 required to implement all (or any) of the unordered bcc operations. */
2932 can_compare_p (code, mode, purpose)
2933 enum rtx_code code;
2934 enum machine_mode mode;
2935 enum can_compare_purpose purpose;
2939 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2941 if (purpose == ccp_jump)
2942 return bcc_gen_fctn[(int)code] != NULL;
2943 else if (purpose == ccp_store_flag)
2944 return setcc_gen_code[(int)code] != CODE_FOR_nothing;
2945 else
2946 /* There's only one cmov entry point, and it's allowed to fail. */
2947 return 1;
2949 if (purpose == ccp_jump
2950 && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2951 return 1;
2952 if (purpose == ccp_cmov
2953 && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2954 return 1;
2955 if (purpose == ccp_store_flag
2956 && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2957 return 1;
2959 mode = GET_MODE_WIDER_MODE (mode);
2961 while (mode != VOIDmode);
2963 return 0;
2966 /* This function is called when we are going to emit a compare instruction that
2967 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2969 *PMODE is the mode of the inputs (in case they are const_int).
2970 *PUNSIGNEDP nonzero says that the operands are unsigned;
2971 this matters if they need to be widened.
2973 If they have mode BLKmode, then SIZE specifies the size of both operands,
2974 and ALIGN specifies the known shared alignment of the operands.
2976 This function performs all the setup necessary so that the caller only has
2977 to emit a single comparison insn. This setup can involve doing a BLKmode
2978 comparison or emitting a library call to perform the comparison if no insn
2979 is available to handle it.
2980 The values which are passed in through pointers can be modified; the caller
2981 should perform the comparison on the modified values. */
2983 void
2984 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
2985 purpose)
2986 rtx *px, *py;
2987 enum rtx_code *pcomparison;
2988 rtx size;
2989 enum machine_mode *pmode;
2990 int *punsignedp;
2991 int align ATTRIBUTE_UNUSED;
2992 enum can_compare_purpose purpose;
2994 enum machine_mode mode = *pmode;
2995 rtx x = *px, y = *py;
2996 int unsignedp = *punsignedp;
2997 enum mode_class class;
2998 rtx opalign ATTRIBUTE_UNUSED = GEN_INT (align / BITS_PER_UNIT);;
3000 class = GET_MODE_CLASS (mode);
3002 /* They could both be VOIDmode if both args are immediate constants,
3003 but we should fold that at an earlier stage.
3004 With no special code here, this will call abort,
3005 reminding the programmer to implement such folding. */
3007 if (mode != BLKmode && flag_force_mem)
3009 x = force_not_mem (x);
3010 y = force_not_mem (y);
3013 /* If we are inside an appropriately-short loop and one operand is an
3014 expensive constant, force it into a register. */
3015 if (CONSTANT_P (x) && preserve_subexpressions_p ()
3016 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3017 x = force_reg (mode, x);
3019 if (CONSTANT_P (y) && preserve_subexpressions_p ()
3020 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3021 y = force_reg (mode, y);
3023 #ifdef HAVE_cc0
3024 /* Abort if we have a non-canonical comparison. The RTL documentation
3025 states that canonical comparisons are required only for targets which
3026 have cc0. */
3027 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3028 abort();
3029 #endif
3031 /* Don't let both operands fail to indicate the mode. */
3032 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3033 x = force_reg (mode, x);
3035 /* Handle all BLKmode compares. */
3037 if (mode == BLKmode)
3039 rtx result;
3040 enum machine_mode result_mode;
3042 emit_queue ();
3043 x = protect_from_queue (x, 0);
3044 y = protect_from_queue (y, 0);
3046 if (size == 0)
3047 abort ();
3048 #ifdef HAVE_cmpstrqi
3049 if (HAVE_cmpstrqi
3050 && GET_CODE (size) == CONST_INT
3051 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3053 result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3054 result = gen_reg_rtx (result_mode);
3055 emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3057 else
3058 #endif
3059 #ifdef HAVE_cmpstrhi
3060 if (HAVE_cmpstrhi
3061 && GET_CODE (size) == CONST_INT
3062 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3064 result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3065 result = gen_reg_rtx (result_mode);
3066 emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3068 else
3069 #endif
3070 #ifdef HAVE_cmpstrsi
3071 if (HAVE_cmpstrsi)
3073 result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3074 result = gen_reg_rtx (result_mode);
3075 size = protect_from_queue (size, 0);
3076 emit_insn (gen_cmpstrsi (result, x, y,
3077 convert_to_mode (SImode, size, 1),
3078 opalign));
3080 else
3081 #endif
3083 #ifdef TARGET_MEM_FUNCTIONS
3084 emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3085 TYPE_MODE (integer_type_node), 3,
3086 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3087 convert_to_mode (TYPE_MODE (sizetype), size,
3088 TREE_UNSIGNED (sizetype)),
3089 TYPE_MODE (sizetype));
3090 #else
3091 emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3092 TYPE_MODE (integer_type_node), 3,
3093 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3094 convert_to_mode (TYPE_MODE (integer_type_node),
3095 size,
3096 TREE_UNSIGNED (integer_type_node)),
3097 TYPE_MODE (integer_type_node));
3098 #endif
3100 /* Immediately move the result of the libcall into a pseudo
3101 register so reload doesn't clobber the value if it needs
3102 the return register for a spill reg. */
3103 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3104 result_mode = TYPE_MODE (integer_type_node);
3105 emit_move_insn (result,
3106 hard_libcall_value (result_mode));
3108 *px = result;
3109 *py = const0_rtx;
3110 *pmode = result_mode;
3111 return;
3114 *px = x;
3115 *py = y;
3116 if (can_compare_p (*pcomparison, mode, purpose))
3117 return;
3119 /* Handle a lib call just for the mode we are using. */
3121 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3123 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3124 rtx result;
3126 /* If we want unsigned, and this mode has a distinct unsigned
3127 comparison routine, use that. */
3128 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3129 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3131 emit_library_call (libfunc, 1,
3132 word_mode, 2, x, mode, y, mode);
3134 /* Immediately move the result of the libcall into a pseudo
3135 register so reload doesn't clobber the value if it needs
3136 the return register for a spill reg. */
3137 result = gen_reg_rtx (word_mode);
3138 emit_move_insn (result, hard_libcall_value (word_mode));
3140 /* Integer comparison returns a result that must be compared against 1,
3141 so that even if we do an unsigned compare afterward,
3142 there is still a value that can represent the result "less than". */
3143 *px = result;
3144 *py = const1_rtx;
3145 *pmode = word_mode;
3146 return;
3149 if (class == MODE_FLOAT)
3150 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3152 else
3153 abort ();
3156 /* Before emitting an insn with code ICODE, make sure that X, which is going
3157 to be used for operand OPNUM of the insn, is converted from mode MODE to
3158 WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3159 that it is accepted by the operand predicate. Return the new value. */
3162 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3163 int icode;
3164 rtx x;
3165 int opnum;
3166 enum machine_mode mode, wider_mode;
3167 int unsignedp;
3169 x = protect_from_queue (x, 0);
3171 if (mode != wider_mode)
3172 x = convert_modes (wider_mode, mode, x, unsignedp);
3174 if (! (*insn_data[icode].operand[opnum].predicate)
3175 (x, insn_data[icode].operand[opnum].mode))
3176 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3177 return x;
3180 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3181 we can do the comparison.
3182 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3183 be NULL_RTX which indicates that only a comparison is to be generated. */
3185 static void
3186 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3187 rtx x, y;
3188 enum machine_mode mode;
3189 enum rtx_code comparison;
3190 int unsignedp;
3191 rtx label;
3193 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3194 enum mode_class class = GET_MODE_CLASS (mode);
3195 enum machine_mode wider_mode = mode;
3197 /* Try combined insns first. */
3200 enum insn_code icode;
3201 PUT_MODE (test, wider_mode);
3203 if (label)
3205 icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3207 if (icode != CODE_FOR_nothing
3208 && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3210 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3211 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3212 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3213 return;
3217 /* Handle some compares against zero. */
3218 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3219 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3221 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3222 emit_insn (GEN_FCN (icode) (x));
3223 if (label)
3224 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3225 return;
3228 /* Handle compares for which there is a directly suitable insn. */
3230 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3231 if (icode != CODE_FOR_nothing)
3233 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3234 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3235 emit_insn (GEN_FCN (icode) (x, y));
3236 if (label)
3237 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3238 return;
3241 if (class != MODE_INT && class != MODE_FLOAT
3242 && class != MODE_COMPLEX_FLOAT)
3243 break;
3245 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3246 } while (wider_mode != VOIDmode);
3248 abort ();
3251 /* Generate code to compare X with Y so that the condition codes are
3252 set and to jump to LABEL if the condition is true. If X is a
3253 constant and Y is not a constant, then the comparison is swapped to
3254 ensure that the comparison RTL has the canonical form.
3256 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3257 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3258 the proper branch condition code.
3260 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3261 and ALIGN specifies the known shared alignment of X and Y.
3263 MODE is the mode of the inputs (in case they are const_int).
3265 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3266 be passed unchanged to emit_cmp_insn, then potentially converted into an
3267 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3269 void
3270 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3271 rtx x, y;
3272 enum rtx_code comparison;
3273 rtx size;
3274 enum machine_mode mode;
3275 int unsignedp;
3276 unsigned int align;
3277 rtx label;
3279 rtx op0;
3280 rtx op1;
3282 if ((CONSTANT_P (x) && ! CONSTANT_P (y))
3283 || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
3285 /* Swap operands and condition to ensure canonical RTL. */
3286 op0 = y;
3287 op1 = x;
3288 comparison = swap_condition (comparison);
3290 else
3292 op0 = x;
3293 op1 = y;
3296 #ifdef HAVE_cc0
3297 /* If OP0 is still a constant, then both X and Y must be constants. Force
3298 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3299 RTL. */
3300 if (CONSTANT_P (op0))
3301 op0 = force_reg (mode, op0);
3302 #endif
3304 emit_queue ();
3305 if (unsignedp)
3306 comparison = unsigned_condition (comparison);
3307 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, align,
3308 ccp_jump);
3309 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3312 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3314 void
3315 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3316 rtx x, y;
3317 enum rtx_code comparison;
3318 rtx size;
3319 enum machine_mode mode;
3320 int unsignedp;
3321 unsigned int align;
3323 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
3326 /* Emit a library call comparison between floating point X and Y.
3327 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3329 static void
3330 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3331 rtx *px, *py;
3332 enum rtx_code *pcomparison;
3333 enum machine_mode *pmode;
3334 int *punsignedp;
3336 enum rtx_code comparison = *pcomparison;
3337 rtx x = *px = protect_from_queue (*px, 0);
3338 rtx y = *py = protect_from_queue (*py, 0);
3339 enum machine_mode mode = GET_MODE (x);
3340 rtx libfunc = 0;
3341 rtx result;
3343 if (mode == HFmode)
3344 switch (comparison)
3346 case EQ:
3347 libfunc = eqhf2_libfunc;
3348 break;
3350 case NE:
3351 libfunc = nehf2_libfunc;
3352 break;
3354 case GT:
3355 libfunc = gthf2_libfunc;
3356 break;
3358 case GE:
3359 libfunc = gehf2_libfunc;
3360 break;
3362 case LT:
3363 libfunc = lthf2_libfunc;
3364 break;
3366 case LE:
3367 libfunc = lehf2_libfunc;
3368 break;
3370 case UNORDERED:
3371 libfunc = unordhf2_libfunc;
3372 break;
3374 default:
3375 break;
3377 else if (mode == SFmode)
3378 switch (comparison)
3380 case EQ:
3381 libfunc = eqsf2_libfunc;
3382 break;
3384 case NE:
3385 libfunc = nesf2_libfunc;
3386 break;
3388 case GT:
3389 libfunc = gtsf2_libfunc;
3390 break;
3392 case GE:
3393 libfunc = gesf2_libfunc;
3394 break;
3396 case LT:
3397 libfunc = ltsf2_libfunc;
3398 break;
3400 case LE:
3401 libfunc = lesf2_libfunc;
3402 break;
3404 case UNORDERED:
3405 libfunc = unordsf2_libfunc;
3406 break;
3408 default:
3409 break;
3411 else if (mode == DFmode)
3412 switch (comparison)
3414 case EQ:
3415 libfunc = eqdf2_libfunc;
3416 break;
3418 case NE:
3419 libfunc = nedf2_libfunc;
3420 break;
3422 case GT:
3423 libfunc = gtdf2_libfunc;
3424 break;
3426 case GE:
3427 libfunc = gedf2_libfunc;
3428 break;
3430 case LT:
3431 libfunc = ltdf2_libfunc;
3432 break;
3434 case LE:
3435 libfunc = ledf2_libfunc;
3436 break;
3438 case UNORDERED:
3439 libfunc = unorddf2_libfunc;
3440 break;
3442 default:
3443 break;
3445 else if (mode == XFmode)
3446 switch (comparison)
3448 case EQ:
3449 libfunc = eqxf2_libfunc;
3450 break;
3452 case NE:
3453 libfunc = nexf2_libfunc;
3454 break;
3456 case GT:
3457 libfunc = gtxf2_libfunc;
3458 break;
3460 case GE:
3461 libfunc = gexf2_libfunc;
3462 break;
3464 case LT:
3465 libfunc = ltxf2_libfunc;
3466 break;
3468 case LE:
3469 libfunc = lexf2_libfunc;
3470 break;
3472 case UNORDERED:
3473 libfunc = unordxf2_libfunc;
3474 break;
3476 default:
3477 break;
3479 else if (mode == TFmode)
3480 switch (comparison)
3482 case EQ:
3483 libfunc = eqtf2_libfunc;
3484 break;
3486 case NE:
3487 libfunc = netf2_libfunc;
3488 break;
3490 case GT:
3491 libfunc = gttf2_libfunc;
3492 break;
3494 case GE:
3495 libfunc = getf2_libfunc;
3496 break;
3498 case LT:
3499 libfunc = lttf2_libfunc;
3500 break;
3502 case LE:
3503 libfunc = letf2_libfunc;
3504 break;
3506 case UNORDERED:
3507 libfunc = unordtf2_libfunc;
3508 break;
3510 default:
3511 break;
3513 else
3515 enum machine_mode wider_mode;
3517 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3518 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3520 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3521 != CODE_FOR_nothing)
3522 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3524 x = protect_from_queue (x, 0);
3525 y = protect_from_queue (y, 0);
3526 *px = convert_to_mode (wider_mode, x, 0);
3527 *py = convert_to_mode (wider_mode, y, 0);
3528 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3529 return;
3532 abort ();
3535 if (libfunc == 0)
3536 abort ();
3538 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
3539 mode);
3541 /* Immediately move the result of the libcall into a pseudo
3542 register so reload doesn't clobber the value if it needs
3543 the return register for a spill reg. */
3544 result = gen_reg_rtx (word_mode);
3545 emit_move_insn (result, hard_libcall_value (word_mode));
3546 *px = result;
3547 *py = const0_rtx;
3548 *pmode = word_mode;
3549 if (comparison == UNORDERED)
3550 *pcomparison = NE;
3551 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3552 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3553 *pcomparison = NE;
3554 #endif
3555 *punsignedp = 0;
3558 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3560 void
3561 emit_indirect_jump (loc)
3562 rtx loc;
3564 if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
3565 (loc, Pmode)))
3566 loc = copy_to_mode_reg (Pmode, loc);
3568 emit_jump_insn (gen_indirect_jump (loc));
3569 emit_barrier ();
3572 #ifdef HAVE_conditional_move
3574 /* Emit a conditional move instruction if the machine supports one for that
3575 condition and machine mode.
3577 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3578 the mode to use should they be constants. If it is VOIDmode, they cannot
3579 both be constants.
3581 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3582 should be stored there. MODE is the mode to use should they be constants.
3583 If it is VOIDmode, they cannot both be constants.
3585 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3586 is not supported. */
3589 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3590 unsignedp)
3591 rtx target;
3592 enum rtx_code code;
3593 rtx op0, op1;
3594 enum machine_mode cmode;
3595 rtx op2, op3;
3596 enum machine_mode mode;
3597 int unsignedp;
3599 rtx tem, subtarget, comparison, insn;
3600 enum insn_code icode;
3602 /* If one operand is constant, make it the second one. Only do this
3603 if the other operand is not constant as well. */
3605 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3606 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3608 tem = op0;
3609 op0 = op1;
3610 op1 = tem;
3611 code = swap_condition (code);
3614 /* get_condition will prefer to generate LT and GT even if the old
3615 comparison was against zero, so undo that canonicalization here since
3616 comparisons against zero are cheaper. */
3617 if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
3618 code = LE, op1 = const0_rtx;
3619 else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
3620 code = GE, op1 = const0_rtx;
3622 if (cmode == VOIDmode)
3623 cmode = GET_MODE (op0);
3625 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3626 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3627 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3628 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3630 tem = op2;
3631 op2 = op3;
3632 op3 = tem;
3633 code = reverse_condition (code);
3636 if (mode == VOIDmode)
3637 mode = GET_MODE (op2);
3639 icode = movcc_gen_code[mode];
3641 if (icode == CODE_FOR_nothing)
3642 return 0;
3644 if (flag_force_mem)
3646 op2 = force_not_mem (op2);
3647 op3 = force_not_mem (op3);
3650 if (target)
3651 target = protect_from_queue (target, 1);
3652 else
3653 target = gen_reg_rtx (mode);
3655 subtarget = target;
3657 emit_queue ();
3659 op2 = protect_from_queue (op2, 0);
3660 op3 = protect_from_queue (op3, 0);
3662 /* If the insn doesn't accept these operands, put them in pseudos. */
3664 if (! (*insn_data[icode].operand[0].predicate)
3665 (subtarget, insn_data[icode].operand[0].mode))
3666 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3668 if (! (*insn_data[icode].operand[2].predicate)
3669 (op2, insn_data[icode].operand[2].mode))
3670 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3672 if (! (*insn_data[icode].operand[3].predicate)
3673 (op3, insn_data[icode].operand[3].mode))
3674 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3676 /* Everything should now be in the suitable form, so emit the compare insn
3677 and then the conditional move. */
3679 comparison
3680 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3682 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3683 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3684 return NULL and let the caller figure out how best to deal with this
3685 situation. */
3686 if (GET_CODE (comparison) != code)
3687 return NULL_RTX;
3689 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3691 /* If that failed, then give up. */
3692 if (insn == 0)
3693 return 0;
3695 emit_insn (insn);
3697 if (subtarget != target)
3698 convert_move (target, subtarget, 0);
3700 return target;
3703 /* Return non-zero if a conditional move of mode MODE is supported.
3705 This function is for combine so it can tell whether an insn that looks
3706 like a conditional move is actually supported by the hardware. If we
3707 guess wrong we lose a bit on optimization, but that's it. */
3708 /* ??? sparc64 supports conditionally moving integers values based on fp
3709 comparisons, and vice versa. How do we handle them? */
3712 can_conditionally_move_p (mode)
3713 enum machine_mode mode;
3715 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3716 return 1;
3718 return 0;
3721 #endif /* HAVE_conditional_move */
3723 /* These three functions generate an insn body and return it
3724 rather than emitting the insn.
3726 They do not protect from queued increments,
3727 because they may be used 1) in protect_from_queue itself
3728 and 2) in other passes where there is no queue. */
3730 /* Generate and return an insn body to add Y to X. */
3733 gen_add2_insn (x, y)
3734 rtx x, y;
3736 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3738 if (! ((*insn_data[icode].operand[0].predicate)
3739 (x, insn_data[icode].operand[0].mode))
3740 || ! ((*insn_data[icode].operand[1].predicate)
3741 (x, insn_data[icode].operand[1].mode))
3742 || ! ((*insn_data[icode].operand[2].predicate)
3743 (y, insn_data[icode].operand[2].mode)))
3744 abort ();
3746 return (GEN_FCN (icode) (x, x, y));
3750 have_add2_insn (mode)
3751 enum machine_mode mode;
3753 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3756 /* Generate and return an insn body to subtract Y from X. */
3759 gen_sub2_insn (x, y)
3760 rtx x, y;
3762 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3764 if (! ((*insn_data[icode].operand[0].predicate)
3765 (x, insn_data[icode].operand[0].mode))
3766 || ! ((*insn_data[icode].operand[1].predicate)
3767 (x, insn_data[icode].operand[1].mode))
3768 || ! ((*insn_data[icode].operand[2].predicate)
3769 (y, insn_data[icode].operand[2].mode)))
3770 abort ();
3772 return (GEN_FCN (icode) (x, x, y));
3776 have_sub2_insn (mode)
3777 enum machine_mode mode;
3779 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3782 /* Generate the body of an instruction to copy Y into X.
3783 It may be a SEQUENCE, if one insn isn't enough. */
3786 gen_move_insn (x, y)
3787 rtx x, y;
3789 register enum machine_mode mode = GET_MODE (x);
3790 enum insn_code insn_code;
3791 rtx seq;
3793 if (mode == VOIDmode)
3794 mode = GET_MODE (y);
3796 insn_code = mov_optab->handlers[(int) mode].insn_code;
3798 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3799 find a mode to do it in. If we have a movcc, use it. Otherwise,
3800 find the MODE_INT mode of the same width. */
3802 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3804 enum machine_mode tmode = VOIDmode;
3805 rtx x1 = x, y1 = y;
3807 if (mode != CCmode
3808 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3809 tmode = CCmode;
3810 else
3811 for (tmode = QImode; tmode != VOIDmode;
3812 tmode = GET_MODE_WIDER_MODE (tmode))
3813 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3814 break;
3816 if (tmode == VOIDmode)
3817 abort ();
3819 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3820 may call change_address which is not appropriate if we were
3821 called when a reload was in progress. We don't have to worry
3822 about changing the address since the size in bytes is supposed to
3823 be the same. Copy the MEM to change the mode and move any
3824 substitutions from the old MEM to the new one. */
3826 if (reload_in_progress)
3828 x = gen_lowpart_common (tmode, x1);
3829 if (x == 0 && GET_CODE (x1) == MEM)
3831 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3832 MEM_COPY_ATTRIBUTES (x, x1);
3833 copy_replacements (x1, x);
3836 y = gen_lowpart_common (tmode, y1);
3837 if (y == 0 && GET_CODE (y1) == MEM)
3839 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3840 MEM_COPY_ATTRIBUTES (y, y1);
3841 copy_replacements (y1, y);
3844 else
3846 x = gen_lowpart (tmode, x);
3847 y = gen_lowpart (tmode, y);
3850 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3851 return (GEN_FCN (insn_code) (x, y));
3854 start_sequence ();
3855 emit_move_insn_1 (x, y);
3856 seq = gen_sequence ();
3857 end_sequence ();
3858 return seq;
3861 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3862 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3863 no such operation exists, CODE_FOR_nothing will be returned. */
3865 enum insn_code
3866 can_extend_p (to_mode, from_mode, unsignedp)
3867 enum machine_mode to_mode, from_mode;
3868 int unsignedp;
3870 return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
3873 /* Generate the body of an insn to extend Y (with mode MFROM)
3874 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3877 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3878 rtx x, y;
3879 enum machine_mode mto, mfrom;
3880 int unsignedp;
3882 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
3885 /* can_fix_p and can_float_p say whether the target machine
3886 can directly convert a given fixed point type to
3887 a given floating point type, or vice versa.
3888 The returned value is the CODE_FOR_... value to use,
3889 or CODE_FOR_nothing if these modes cannot be directly converted.
3891 *TRUNCP_PTR is set to 1 if it is necessary to output
3892 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3894 static enum insn_code
3895 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3896 enum machine_mode fltmode, fixmode;
3897 int unsignedp;
3898 int *truncp_ptr;
3900 *truncp_ptr = 0;
3901 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
3902 != CODE_FOR_nothing)
3903 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
3905 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3907 *truncp_ptr = 1;
3908 return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
3910 return CODE_FOR_nothing;
3913 static enum insn_code
3914 can_float_p (fltmode, fixmode, unsignedp)
3915 enum machine_mode fixmode, fltmode;
3916 int unsignedp;
3918 return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
3921 /* Generate code to convert FROM to floating point
3922 and store in TO. FROM must be fixed point and not VOIDmode.
3923 UNSIGNEDP nonzero means regard FROM as unsigned.
3924 Normally this is done by correcting the final value
3925 if it is negative. */
3927 void
3928 expand_float (to, from, unsignedp)
3929 rtx to, from;
3930 int unsignedp;
3932 enum insn_code icode;
3933 register rtx target = to;
3934 enum machine_mode fmode, imode;
3936 /* Crash now, because we won't be able to decide which mode to use. */
3937 if (GET_MODE (from) == VOIDmode)
3938 abort ();
3940 /* Look for an insn to do the conversion. Do it in the specified
3941 modes if possible; otherwise convert either input, output or both to
3942 wider mode. If the integer mode is wider than the mode of FROM,
3943 we can do the conversion signed even if the input is unsigned. */
3945 for (imode = GET_MODE (from); imode != VOIDmode;
3946 imode = GET_MODE_WIDER_MODE (imode))
3947 for (fmode = GET_MODE (to); fmode != VOIDmode;
3948 fmode = GET_MODE_WIDER_MODE (fmode))
3950 int doing_unsigned = unsignedp;
3952 if (fmode != GET_MODE (to)
3953 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
3954 continue;
3956 icode = can_float_p (fmode, imode, unsignedp);
3957 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3958 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3960 if (icode != CODE_FOR_nothing)
3962 to = protect_from_queue (to, 1);
3963 from = protect_from_queue (from, 0);
3965 if (imode != GET_MODE (from))
3966 from = convert_to_mode (imode, from, unsignedp);
3968 if (fmode != GET_MODE (to))
3969 target = gen_reg_rtx (fmode);
3971 emit_unop_insn (icode, target, from,
3972 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3974 if (target != to)
3975 convert_move (to, target, 0);
3976 return;
3980 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3982 /* Unsigned integer, and no way to convert directly.
3983 Convert as signed, then conditionally adjust the result. */
3984 if (unsignedp)
3986 rtx label = gen_label_rtx ();
3987 rtx temp;
3988 REAL_VALUE_TYPE offset;
3990 emit_queue ();
3992 to = protect_from_queue (to, 1);
3993 from = protect_from_queue (from, 0);
3995 if (flag_force_mem)
3996 from = force_not_mem (from);
3998 /* Look for a usable floating mode FMODE wider than the source and at
3999 least as wide as the target. Using FMODE will avoid rounding woes
4000 with unsigned values greater than the signed maximum value. */
4002 for (fmode = GET_MODE (to); fmode != VOIDmode;
4003 fmode = GET_MODE_WIDER_MODE (fmode))
4004 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4005 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4006 break;
4008 if (fmode == VOIDmode)
4010 /* There is no such mode. Pretend the target is wide enough. */
4011 fmode = GET_MODE (to);
4013 /* Avoid double-rounding when TO is narrower than FROM. */
4014 if ((significand_size (fmode) + 1)
4015 < GET_MODE_BITSIZE (GET_MODE (from)))
4017 rtx temp1;
4018 rtx neglabel = gen_label_rtx ();
4020 /* Don't use TARGET if it isn't a register, is a hard register,
4021 or is the wrong mode. */
4022 if (GET_CODE (target) != REG
4023 || REGNO (target) < FIRST_PSEUDO_REGISTER
4024 || GET_MODE (target) != fmode)
4025 target = gen_reg_rtx (fmode);
4027 imode = GET_MODE (from);
4028 do_pending_stack_adjust ();
4030 /* Test whether the sign bit is set. */
4031 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4032 0, 0, neglabel);
4034 /* The sign bit is not set. Convert as signed. */
4035 expand_float (target, from, 0);
4036 emit_jump_insn (gen_jump (label));
4037 emit_barrier ();
4039 /* The sign bit is set.
4040 Convert to a usable (positive signed) value by shifting right
4041 one bit, while remembering if a nonzero bit was shifted
4042 out; i.e., compute (from & 1) | (from >> 1). */
4044 emit_label (neglabel);
4045 temp = expand_binop (imode, and_optab, from, const1_rtx,
4046 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4047 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4048 NULL_RTX, 1);
4049 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4050 OPTAB_LIB_WIDEN);
4051 expand_float (target, temp, 0);
4053 /* Multiply by 2 to undo the shift above. */
4054 temp = expand_binop (fmode, add_optab, target, target,
4055 target, 0, OPTAB_LIB_WIDEN);
4056 if (temp != target)
4057 emit_move_insn (target, temp);
4059 do_pending_stack_adjust ();
4060 emit_label (label);
4061 goto done;
4065 /* If we are about to do some arithmetic to correct for an
4066 unsigned operand, do it in a pseudo-register. */
4068 if (GET_MODE (to) != fmode
4069 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4070 target = gen_reg_rtx (fmode);
4072 /* Convert as signed integer to floating. */
4073 expand_float (target, from, 0);
4075 /* If FROM is negative (and therefore TO is negative),
4076 correct its value by 2**bitwidth. */
4078 do_pending_stack_adjust ();
4079 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4080 0, 0, label);
4082 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4083 Rather than setting up a dconst_dot_5, let's hope SCO
4084 fixes the bug. */
4085 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4086 temp = expand_binop (fmode, add_optab, target,
4087 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4088 target, 0, OPTAB_LIB_WIDEN);
4089 if (temp != target)
4090 emit_move_insn (target, temp);
4092 do_pending_stack_adjust ();
4093 emit_label (label);
4094 goto done;
4096 #endif
4098 /* No hardware instruction available; call a library routine to convert from
4099 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4101 rtx libfcn;
4102 rtx insns;
4103 rtx value;
4105 to = protect_from_queue (to, 1);
4106 from = protect_from_queue (from, 0);
4108 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4109 from = convert_to_mode (SImode, from, unsignedp);
4111 if (flag_force_mem)
4112 from = force_not_mem (from);
4114 if (GET_MODE (to) == SFmode)
4116 if (GET_MODE (from) == SImode)
4117 libfcn = floatsisf_libfunc;
4118 else if (GET_MODE (from) == DImode)
4119 libfcn = floatdisf_libfunc;
4120 else if (GET_MODE (from) == TImode)
4121 libfcn = floattisf_libfunc;
4122 else
4123 abort ();
4125 else if (GET_MODE (to) == DFmode)
4127 if (GET_MODE (from) == SImode)
4128 libfcn = floatsidf_libfunc;
4129 else if (GET_MODE (from) == DImode)
4130 libfcn = floatdidf_libfunc;
4131 else if (GET_MODE (from) == TImode)
4132 libfcn = floattidf_libfunc;
4133 else
4134 abort ();
4136 else if (GET_MODE (to) == XFmode)
4138 if (GET_MODE (from) == SImode)
4139 libfcn = floatsixf_libfunc;
4140 else if (GET_MODE (from) == DImode)
4141 libfcn = floatdixf_libfunc;
4142 else if (GET_MODE (from) == TImode)
4143 libfcn = floattixf_libfunc;
4144 else
4145 abort ();
4147 else if (GET_MODE (to) == TFmode)
4149 if (GET_MODE (from) == SImode)
4150 libfcn = floatsitf_libfunc;
4151 else if (GET_MODE (from) == DImode)
4152 libfcn = floatditf_libfunc;
4153 else if (GET_MODE (from) == TImode)
4154 libfcn = floattitf_libfunc;
4155 else
4156 abort ();
4158 else
4159 abort ();
4161 start_sequence ();
4163 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4164 GET_MODE (to), 1, from,
4165 GET_MODE (from));
4166 insns = get_insns ();
4167 end_sequence ();
4169 emit_libcall_block (insns, target, value,
4170 gen_rtx_FLOAT (GET_MODE (to), from));
4173 done:
4175 /* Copy result to requested destination
4176 if we have been computing in a temp location. */
4178 if (target != to)
4180 if (GET_MODE (target) == GET_MODE (to))
4181 emit_move_insn (to, target);
4182 else
4183 convert_move (to, target, 0);
4187 /* expand_fix: generate code to convert FROM to fixed point
4188 and store in TO. FROM must be floating point. */
4190 static rtx
4191 ftruncify (x)
4192 rtx x;
4194 rtx temp = gen_reg_rtx (GET_MODE (x));
4195 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4198 void
4199 expand_fix (to, from, unsignedp)
4200 register rtx to, from;
4201 int unsignedp;
4203 enum insn_code icode;
4204 register rtx target = to;
4205 enum machine_mode fmode, imode;
4206 int must_trunc = 0;
4207 rtx libfcn = 0;
4209 /* We first try to find a pair of modes, one real and one integer, at
4210 least as wide as FROM and TO, respectively, in which we can open-code
4211 this conversion. If the integer mode is wider than the mode of TO,
4212 we can do the conversion either signed or unsigned. */
4214 for (imode = GET_MODE (to); imode != VOIDmode;
4215 imode = GET_MODE_WIDER_MODE (imode))
4216 for (fmode = GET_MODE (from); fmode != VOIDmode;
4217 fmode = GET_MODE_WIDER_MODE (fmode))
4219 int doing_unsigned = unsignedp;
4221 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4222 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4223 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4225 if (icode != CODE_FOR_nothing)
4227 to = protect_from_queue (to, 1);
4228 from = protect_from_queue (from, 0);
4230 if (fmode != GET_MODE (from))
4231 from = convert_to_mode (fmode, from, 0);
4233 if (must_trunc)
4234 from = ftruncify (from);
4236 if (imode != GET_MODE (to))
4237 target = gen_reg_rtx (imode);
4239 emit_unop_insn (icode, target, from,
4240 doing_unsigned ? UNSIGNED_FIX : FIX);
4241 if (target != to)
4242 convert_move (to, target, unsignedp);
4243 return;
4247 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4248 /* For an unsigned conversion, there is one more way to do it.
4249 If we have a signed conversion, we generate code that compares
4250 the real value to the largest representable positive number. If if
4251 is smaller, the conversion is done normally. Otherwise, subtract
4252 one plus the highest signed number, convert, and add it back.
4254 We only need to check all real modes, since we know we didn't find
4255 anything with a wider integer mode. */
4257 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4258 for (fmode = GET_MODE (from); fmode != VOIDmode;
4259 fmode = GET_MODE_WIDER_MODE (fmode))
4260 /* Make sure we won't lose significant bits doing this. */
4261 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4262 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4263 &must_trunc))
4265 int bitsize;
4266 REAL_VALUE_TYPE offset;
4267 rtx limit, lab1, lab2, insn;
4269 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4270 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4271 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4272 lab1 = gen_label_rtx ();
4273 lab2 = gen_label_rtx ();
4275 emit_queue ();
4276 to = protect_from_queue (to, 1);
4277 from = protect_from_queue (from, 0);
4279 if (flag_force_mem)
4280 from = force_not_mem (from);
4282 if (fmode != GET_MODE (from))
4283 from = convert_to_mode (fmode, from, 0);
4285 /* See if we need to do the subtraction. */
4286 do_pending_stack_adjust ();
4287 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4288 0, 0, lab1);
4290 /* If not, do the signed "fix" and branch around fixup code. */
4291 expand_fix (to, from, 0);
4292 emit_jump_insn (gen_jump (lab2));
4293 emit_barrier ();
4295 /* Otherwise, subtract 2**(N-1), convert to signed number,
4296 then add 2**(N-1). Do the addition using XOR since this
4297 will often generate better code. */
4298 emit_label (lab1);
4299 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4300 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4301 expand_fix (to, target, 0);
4302 target = expand_binop (GET_MODE (to), xor_optab, to,
4303 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4304 to, 1, OPTAB_LIB_WIDEN);
4306 if (target != to)
4307 emit_move_insn (to, target);
4309 emit_label (lab2);
4311 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4312 != CODE_FOR_nothing)
4314 /* Make a place for a REG_NOTE and add it. */
4315 insn = emit_move_insn (to, to);
4316 set_unique_reg_note (insn,
4317 REG_EQUAL,
4318 gen_rtx_fmt_e (UNSIGNED_FIX,
4319 GET_MODE (to),
4320 copy_rtx (from)));
4323 return;
4325 #endif
4327 /* We can't do it with an insn, so use a library call. But first ensure
4328 that the mode of TO is at least as wide as SImode, since those are the
4329 only library calls we know about. */
4331 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4333 target = gen_reg_rtx (SImode);
4335 expand_fix (target, from, unsignedp);
4337 else if (GET_MODE (from) == SFmode)
4339 if (GET_MODE (to) == SImode)
4340 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4341 else if (GET_MODE (to) == DImode)
4342 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4343 else if (GET_MODE (to) == TImode)
4344 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4345 else
4346 abort ();
4348 else if (GET_MODE (from) == DFmode)
4350 if (GET_MODE (to) == SImode)
4351 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4352 else if (GET_MODE (to) == DImode)
4353 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4354 else if (GET_MODE (to) == TImode)
4355 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4356 else
4357 abort ();
4359 else if (GET_MODE (from) == XFmode)
4361 if (GET_MODE (to) == SImode)
4362 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4363 else if (GET_MODE (to) == DImode)
4364 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4365 else if (GET_MODE (to) == TImode)
4366 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4367 else
4368 abort ();
4370 else if (GET_MODE (from) == TFmode)
4372 if (GET_MODE (to) == SImode)
4373 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4374 else if (GET_MODE (to) == DImode)
4375 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4376 else if (GET_MODE (to) == TImode)
4377 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4378 else
4379 abort ();
4381 else
4382 abort ();
4384 if (libfcn)
4386 rtx insns;
4387 rtx value;
4389 to = protect_from_queue (to, 1);
4390 from = protect_from_queue (from, 0);
4392 if (flag_force_mem)
4393 from = force_not_mem (from);
4395 start_sequence ();
4397 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4398 GET_MODE (to), 1, from,
4399 GET_MODE (from));
4400 insns = get_insns ();
4401 end_sequence ();
4403 emit_libcall_block (insns, target, value,
4404 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4405 GET_MODE (to), from));
4408 if (target != to)
4410 if (GET_MODE (to) == GET_MODE (target))
4411 emit_move_insn (to, target);
4412 else
4413 convert_move (to, target, 0);
4417 static optab
4418 init_optab (code)
4419 enum rtx_code code;
4421 int i;
4422 optab op = (optab) xmalloc (sizeof (struct optab));
4423 op->code = code;
4424 for (i = 0; i < NUM_MACHINE_MODES; i++)
4426 op->handlers[i].insn_code = CODE_FOR_nothing;
4427 op->handlers[i].libfunc = 0;
4430 if (code != UNKNOWN)
4431 code_to_optab[(int) code] = op;
4433 return op;
4436 /* Initialize the libfunc fields of an entire group of entries in some
4437 optab. Each entry is set equal to a string consisting of a leading
4438 pair of underscores followed by a generic operation name followed by
4439 a mode name (downshifted to lower case) followed by a single character
4440 representing the number of operands for the given operation (which is
4441 usually one of the characters '2', '3', or '4').
4443 OPTABLE is the table in which libfunc fields are to be initialized.
4444 FIRST_MODE is the first machine mode index in the given optab to
4445 initialize.
4446 LAST_MODE is the last machine mode index in the given optab to
4447 initialize.
4448 OPNAME is the generic (string) name of the operation.
4449 SUFFIX is the character which specifies the number of operands for
4450 the given generic operation.
4453 static void
4454 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4455 register optab optable;
4456 register int first_mode;
4457 register int last_mode;
4458 register const char *opname;
4459 register int suffix;
4461 register int mode;
4462 register unsigned opname_len = strlen (opname);
4464 for (mode = first_mode; (int) mode <= (int) last_mode;
4465 mode = (enum machine_mode) ((int) mode + 1))
4467 register const char *mname = GET_MODE_NAME(mode);
4468 register unsigned mname_len = strlen (mname);
4469 register char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4470 register char *p;
4471 register const char *q;
4473 p = libfunc_name;
4474 *p++ = '_';
4475 *p++ = '_';
4476 for (q = opname; *q; )
4477 *p++ = *q++;
4478 for (q = mname; *q; q++)
4479 *p++ = TOLOWER (*q);
4480 *p++ = suffix;
4481 *p = '\0';
4483 optable->handlers[(int) mode].libfunc
4484 = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
4485 p - libfunc_name));
4489 /* Initialize the libfunc fields of an entire group of entries in some
4490 optab which correspond to all integer mode operations. The parameters
4491 have the same meaning as similarly named ones for the `init_libfuncs'
4492 routine. (See above). */
4494 static void
4495 init_integral_libfuncs (optable, opname, suffix)
4496 register optab optable;
4497 register const char *opname;
4498 register int suffix;
4500 init_libfuncs (optable, SImode, TImode, opname, suffix);
4503 /* Initialize the libfunc fields of an entire group of entries in some
4504 optab which correspond to all real mode operations. The parameters
4505 have the same meaning as similarly named ones for the `init_libfuncs'
4506 routine. (See above). */
4508 static void
4509 init_floating_libfuncs (optable, opname, suffix)
4510 register optab optable;
4511 register const char *opname;
4512 register int suffix;
4514 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4518 init_one_libfunc (name)
4519 register const char *name;
4521 name = ggc_strdup (name);
4523 return gen_rtx_SYMBOL_REF (Pmode, name);
4526 /* Mark ARG (which is really an OPTAB *) for GC. */
4528 void
4529 mark_optab (arg)
4530 void *arg;
4532 optab o = *(optab *) arg;
4533 int i;
4535 for (i = 0; i < NUM_MACHINE_MODES; ++i)
4536 ggc_mark_rtx (o->handlers[i].libfunc);
4539 /* Call this once to initialize the contents of the optabs
4540 appropriately for the current target machine. */
4542 void
4543 init_optabs ()
4545 unsigned int i, j, k;
4547 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4549 for (i = 0; i < ARRAY_SIZE (fixtab); i++)
4550 for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
4551 for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
4552 fixtab[i][j][k] = CODE_FOR_nothing;
4554 for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
4555 for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
4556 for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
4557 fixtrunctab[i][j][k] = CODE_FOR_nothing;
4559 for (i = 0; i < ARRAY_SIZE (floattab); i++)
4560 for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
4561 for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
4562 floattab[i][j][k] = CODE_FOR_nothing;
4564 for (i = 0; i < ARRAY_SIZE (extendtab); i++)
4565 for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
4566 for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
4567 extendtab[i][j][k] = CODE_FOR_nothing;
4569 for (i = 0; i < NUM_RTX_CODE; i++)
4570 setcc_gen_code[i] = CODE_FOR_nothing;
4572 #ifdef HAVE_conditional_move
4573 for (i = 0; i < NUM_MACHINE_MODES; i++)
4574 movcc_gen_code[i] = CODE_FOR_nothing;
4575 #endif
4577 add_optab = init_optab (PLUS);
4578 addv_optab = init_optab (PLUS);
4579 sub_optab = init_optab (MINUS);
4580 subv_optab = init_optab (MINUS);
4581 smul_optab = init_optab (MULT);
4582 smulv_optab = init_optab (MULT);
4583 smul_highpart_optab = init_optab (UNKNOWN);
4584 umul_highpart_optab = init_optab (UNKNOWN);
4585 smul_widen_optab = init_optab (UNKNOWN);
4586 umul_widen_optab = init_optab (UNKNOWN);
4587 sdiv_optab = init_optab (DIV);
4588 sdivv_optab = init_optab (DIV);
4589 sdivmod_optab = init_optab (UNKNOWN);
4590 udiv_optab = init_optab (UDIV);
4591 udivmod_optab = init_optab (UNKNOWN);
4592 smod_optab = init_optab (MOD);
4593 umod_optab = init_optab (UMOD);
4594 flodiv_optab = init_optab (DIV);
4595 ftrunc_optab = init_optab (UNKNOWN);
4596 and_optab = init_optab (AND);
4597 ior_optab = init_optab (IOR);
4598 xor_optab = init_optab (XOR);
4599 ashl_optab = init_optab (ASHIFT);
4600 ashr_optab = init_optab (ASHIFTRT);
4601 lshr_optab = init_optab (LSHIFTRT);
4602 rotl_optab = init_optab (ROTATE);
4603 rotr_optab = init_optab (ROTATERT);
4604 smin_optab = init_optab (SMIN);
4605 smax_optab = init_optab (SMAX);
4606 umin_optab = init_optab (UMIN);
4607 umax_optab = init_optab (UMAX);
4608 mov_optab = init_optab (UNKNOWN);
4609 movstrict_optab = init_optab (UNKNOWN);
4610 cmp_optab = init_optab (UNKNOWN);
4611 ucmp_optab = init_optab (UNKNOWN);
4612 tst_optab = init_optab (UNKNOWN);
4613 neg_optab = init_optab (NEG);
4614 negv_optab = init_optab (NEG);
4615 abs_optab = init_optab (ABS);
4616 absv_optab = init_optab (ABS);
4617 one_cmpl_optab = init_optab (NOT);
4618 ffs_optab = init_optab (FFS);
4619 sqrt_optab = init_optab (SQRT);
4620 sin_optab = init_optab (UNKNOWN);
4621 cos_optab = init_optab (UNKNOWN);
4622 strlen_optab = init_optab (UNKNOWN);
4623 cbranch_optab = init_optab (UNKNOWN);
4624 cmov_optab = init_optab (UNKNOWN);
4625 cstore_optab = init_optab (UNKNOWN);
4627 for (i = 0; i < NUM_MACHINE_MODES; i++)
4629 movstr_optab[i] = CODE_FOR_nothing;
4630 clrstr_optab[i] = CODE_FOR_nothing;
4632 #ifdef HAVE_SECONDARY_RELOADS
4633 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4634 #endif
4637 /* Fill in the optabs with the insns we support. */
4638 init_all_optabs ();
4640 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4641 /* This flag says the same insns that convert to a signed fixnum
4642 also convert validly to an unsigned one. */
4643 for (i = 0; i < NUM_MACHINE_MODES; i++)
4644 for (j = 0; j < NUM_MACHINE_MODES; j++)
4645 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4646 #endif
4648 /* Initialize the optabs with the names of the library functions. */
4649 init_integral_libfuncs (add_optab, "add", '3');
4650 init_floating_libfuncs (add_optab, "add", '3');
4651 init_integral_libfuncs (addv_optab, "addv", '3');
4652 init_floating_libfuncs (addv_optab, "add", '3');
4653 init_integral_libfuncs (sub_optab, "sub", '3');
4654 init_floating_libfuncs (sub_optab, "sub", '3');
4655 init_integral_libfuncs (subv_optab, "subv", '3');
4656 init_floating_libfuncs (subv_optab, "sub", '3');
4657 init_integral_libfuncs (smul_optab, "mul", '3');
4658 init_floating_libfuncs (smul_optab, "mul", '3');
4659 init_integral_libfuncs (smulv_optab, "mulv", '3');
4660 init_floating_libfuncs (smulv_optab, "mul", '3');
4661 init_integral_libfuncs (sdiv_optab, "div", '3');
4662 init_integral_libfuncs (sdivv_optab, "divv", '3');
4663 init_integral_libfuncs (udiv_optab, "udiv", '3');
4664 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4665 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4666 init_integral_libfuncs (smod_optab, "mod", '3');
4667 init_integral_libfuncs (umod_optab, "umod", '3');
4668 init_floating_libfuncs (flodiv_optab, "div", '3');
4669 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4670 init_integral_libfuncs (and_optab, "and", '3');
4671 init_integral_libfuncs (ior_optab, "ior", '3');
4672 init_integral_libfuncs (xor_optab, "xor", '3');
4673 init_integral_libfuncs (ashl_optab, "ashl", '3');
4674 init_integral_libfuncs (ashr_optab, "ashr", '3');
4675 init_integral_libfuncs (lshr_optab, "lshr", '3');
4676 init_integral_libfuncs (smin_optab, "min", '3');
4677 init_floating_libfuncs (smin_optab, "min", '3');
4678 init_integral_libfuncs (smax_optab, "max", '3');
4679 init_floating_libfuncs (smax_optab, "max", '3');
4680 init_integral_libfuncs (umin_optab, "umin", '3');
4681 init_integral_libfuncs (umax_optab, "umax", '3');
4682 init_integral_libfuncs (neg_optab, "neg", '2');
4683 init_floating_libfuncs (neg_optab, "neg", '2');
4684 init_integral_libfuncs (negv_optab, "negv", '2');
4685 init_floating_libfuncs (negv_optab, "neg", '2');
4686 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4687 init_integral_libfuncs (ffs_optab, "ffs", '2');
4689 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4690 init_integral_libfuncs (cmp_optab, "cmp", '2');
4691 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4692 init_floating_libfuncs (cmp_optab, "cmp", '2');
4694 #ifdef MULSI3_LIBCALL
4695 smul_optab->handlers[(int) SImode].libfunc
4696 = init_one_libfunc (MULSI3_LIBCALL);
4697 #endif
4698 #ifdef MULDI3_LIBCALL
4699 smul_optab->handlers[(int) DImode].libfunc
4700 = init_one_libfunc (MULDI3_LIBCALL);
4701 #endif
4703 #ifdef DIVSI3_LIBCALL
4704 sdiv_optab->handlers[(int) SImode].libfunc
4705 = init_one_libfunc (DIVSI3_LIBCALL);
4706 #endif
4707 #ifdef DIVDI3_LIBCALL
4708 sdiv_optab->handlers[(int) DImode].libfunc
4709 = init_one_libfunc (DIVDI3_LIBCALL);
4710 #endif
4712 #ifdef UDIVSI3_LIBCALL
4713 udiv_optab->handlers[(int) SImode].libfunc
4714 = init_one_libfunc (UDIVSI3_LIBCALL);
4715 #endif
4716 #ifdef UDIVDI3_LIBCALL
4717 udiv_optab->handlers[(int) DImode].libfunc
4718 = init_one_libfunc (UDIVDI3_LIBCALL);
4719 #endif
4721 #ifdef MODSI3_LIBCALL
4722 smod_optab->handlers[(int) SImode].libfunc
4723 = init_one_libfunc (MODSI3_LIBCALL);
4724 #endif
4725 #ifdef MODDI3_LIBCALL
4726 smod_optab->handlers[(int) DImode].libfunc
4727 = init_one_libfunc (MODDI3_LIBCALL);
4728 #endif
4730 #ifdef UMODSI3_LIBCALL
4731 umod_optab->handlers[(int) SImode].libfunc
4732 = init_one_libfunc (UMODSI3_LIBCALL);
4733 #endif
4734 #ifdef UMODDI3_LIBCALL
4735 umod_optab->handlers[(int) DImode].libfunc
4736 = init_one_libfunc (UMODDI3_LIBCALL);
4737 #endif
4739 /* Use cabs for DC complex abs, since systems generally have cabs.
4740 Don't define any libcall for SCmode, so that cabs will be used. */
4741 abs_optab->handlers[(int) DCmode].libfunc
4742 = init_one_libfunc ("cabs");
4744 /* The ffs function operates on `int'. */
4745 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
4746 = init_one_libfunc ("ffs");
4748 extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
4749 extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
4750 extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
4751 extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
4752 extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
4754 truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
4755 truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
4756 trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
4757 truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
4758 trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
4760 memcpy_libfunc = init_one_libfunc ("memcpy");
4761 bcopy_libfunc = init_one_libfunc ("bcopy");
4762 memcmp_libfunc = init_one_libfunc ("memcmp");
4763 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
4764 memset_libfunc = init_one_libfunc ("memset");
4765 bzero_libfunc = init_one_libfunc ("bzero");
4767 throw_libfunc = init_one_libfunc ("__throw");
4768 rethrow_libfunc = init_one_libfunc ("__rethrow");
4769 sjthrow_libfunc = init_one_libfunc ("__sjthrow");
4770 sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
4771 terminate_libfunc = init_one_libfunc ("__terminate");
4772 eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
4773 #ifndef DONT_USE_BUILTIN_SETJMP
4774 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
4775 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
4776 #else
4777 setjmp_libfunc = init_one_libfunc ("setjmp");
4778 longjmp_libfunc = init_one_libfunc ("longjmp");
4779 #endif
4781 eqhf2_libfunc = init_one_libfunc ("__eqhf2");
4782 nehf2_libfunc = init_one_libfunc ("__nehf2");
4783 gthf2_libfunc = init_one_libfunc ("__gthf2");
4784 gehf2_libfunc = init_one_libfunc ("__gehf2");
4785 lthf2_libfunc = init_one_libfunc ("__lthf2");
4786 lehf2_libfunc = init_one_libfunc ("__lehf2");
4787 unordhf2_libfunc = init_one_libfunc ("__unordhf2");
4789 eqsf2_libfunc = init_one_libfunc ("__eqsf2");
4790 nesf2_libfunc = init_one_libfunc ("__nesf2");
4791 gtsf2_libfunc = init_one_libfunc ("__gtsf2");
4792 gesf2_libfunc = init_one_libfunc ("__gesf2");
4793 ltsf2_libfunc = init_one_libfunc ("__ltsf2");
4794 lesf2_libfunc = init_one_libfunc ("__lesf2");
4795 unordsf2_libfunc = init_one_libfunc ("__unordsf2");
4797 eqdf2_libfunc = init_one_libfunc ("__eqdf2");
4798 nedf2_libfunc = init_one_libfunc ("__nedf2");
4799 gtdf2_libfunc = init_one_libfunc ("__gtdf2");
4800 gedf2_libfunc = init_one_libfunc ("__gedf2");
4801 ltdf2_libfunc = init_one_libfunc ("__ltdf2");
4802 ledf2_libfunc = init_one_libfunc ("__ledf2");
4803 unorddf2_libfunc = init_one_libfunc ("__unorddf2");
4805 eqxf2_libfunc = init_one_libfunc ("__eqxf2");
4806 nexf2_libfunc = init_one_libfunc ("__nexf2");
4807 gtxf2_libfunc = init_one_libfunc ("__gtxf2");
4808 gexf2_libfunc = init_one_libfunc ("__gexf2");
4809 ltxf2_libfunc = init_one_libfunc ("__ltxf2");
4810 lexf2_libfunc = init_one_libfunc ("__lexf2");
4811 unordxf2_libfunc = init_one_libfunc ("__unordxf2");
4813 eqtf2_libfunc = init_one_libfunc ("__eqtf2");
4814 netf2_libfunc = init_one_libfunc ("__netf2");
4815 gttf2_libfunc = init_one_libfunc ("__gttf2");
4816 getf2_libfunc = init_one_libfunc ("__getf2");
4817 lttf2_libfunc = init_one_libfunc ("__lttf2");
4818 letf2_libfunc = init_one_libfunc ("__letf2");
4819 unordtf2_libfunc = init_one_libfunc ("__unordtf2");
4821 floatsisf_libfunc = init_one_libfunc ("__floatsisf");
4822 floatdisf_libfunc = init_one_libfunc ("__floatdisf");
4823 floattisf_libfunc = init_one_libfunc ("__floattisf");
4825 floatsidf_libfunc = init_one_libfunc ("__floatsidf");
4826 floatdidf_libfunc = init_one_libfunc ("__floatdidf");
4827 floattidf_libfunc = init_one_libfunc ("__floattidf");
4829 floatsixf_libfunc = init_one_libfunc ("__floatsixf");
4830 floatdixf_libfunc = init_one_libfunc ("__floatdixf");
4831 floattixf_libfunc = init_one_libfunc ("__floattixf");
4833 floatsitf_libfunc = init_one_libfunc ("__floatsitf");
4834 floatditf_libfunc = init_one_libfunc ("__floatditf");
4835 floattitf_libfunc = init_one_libfunc ("__floattitf");
4837 fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
4838 fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
4839 fixsfti_libfunc = init_one_libfunc ("__fixsfti");
4841 fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
4842 fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
4843 fixdfti_libfunc = init_one_libfunc ("__fixdfti");
4845 fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
4846 fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
4847 fixxfti_libfunc = init_one_libfunc ("__fixxfti");
4849 fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
4850 fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
4851 fixtfti_libfunc = init_one_libfunc ("__fixtfti");
4853 fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
4854 fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
4855 fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
4857 fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
4858 fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
4859 fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
4861 fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
4862 fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
4863 fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
4865 fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
4866 fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
4867 fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
4869 /* For check-memory-usage. */
4870 chkr_check_addr_libfunc = init_one_libfunc ("chkr_check_addr");
4871 chkr_set_right_libfunc = init_one_libfunc ("chkr_set_right");
4872 chkr_copy_bitmap_libfunc = init_one_libfunc ("chkr_copy_bitmap");
4873 chkr_check_exec_libfunc = init_one_libfunc ("chkr_check_exec");
4874 chkr_check_str_libfunc = init_one_libfunc ("chkr_check_str");
4876 /* For function entry/exit instrumentation. */
4877 profile_function_entry_libfunc
4878 = init_one_libfunc ("__cyg_profile_func_enter");
4879 profile_function_exit_libfunc
4880 = init_one_libfunc ("__cyg_profile_func_exit");
4882 #ifdef HAVE_conditional_trap
4883 init_traps ();
4884 #endif
4886 #ifdef INIT_TARGET_OPTABS
4887 /* Allow the target to add more libcalls or rename some, etc. */
4888 INIT_TARGET_OPTABS;
4889 #endif
4891 /* Add these GC roots. */
4892 ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
4893 ggc_add_rtx_root (libfunc_table, LTI_MAX);
4896 #ifdef BROKEN_LDEXP
4898 /* SCO 3.2 apparently has a broken ldexp. */
4900 double
4901 ldexp(x,n)
4902 double x;
4903 int n;
4905 if (n > 0)
4906 while (n--)
4907 x *= 2;
4909 return x;
4911 #endif /* BROKEN_LDEXP */
4913 #ifdef HAVE_conditional_trap
4914 /* The insn generating function can not take an rtx_code argument.
4915 TRAP_RTX is used as an rtx argument. Its code is replaced with
4916 the code to be used in the trap insn and all other fields are
4917 ignored. */
4918 static rtx trap_rtx;
4920 static void
4921 init_traps ()
4923 if (HAVE_conditional_trap)
4925 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4926 ggc_add_rtx_root (&trap_rtx, 1);
4929 #endif
4931 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4932 CODE. Return 0 on failure. */
4935 gen_cond_trap (code, op1, op2, tcode)
4936 enum rtx_code code ATTRIBUTE_UNUSED;
4937 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4939 enum machine_mode mode = GET_MODE (op1);
4941 if (mode == VOIDmode)
4942 return 0;
4944 #ifdef HAVE_conditional_trap
4945 if (HAVE_conditional_trap
4946 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4948 rtx insn;
4949 start_sequence();
4950 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4951 PUT_CODE (trap_rtx, code);
4952 insn = gen_conditional_trap (trap_rtx, tcode);
4953 if (insn)
4955 emit_insn (insn);
4956 insn = gen_sequence ();
4958 end_sequence();
4959 return insn;
4961 #endif
4963 return 0;