* cfgcleanup.c (cleanup_cfg): Fix updating of liveness.
[official-gcc.git] / gcc / optabs.c
blob94927b9b2fe66982a88c47bf3cdb350aea4eb846
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 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 "function.h"
35 #include "except.h"
36 #include "expr.h"
37 #include "optabs.h"
38 #include "libfuncs.h"
39 #include "recog.h"
40 #include "reload.h"
41 #include "ggc.h"
42 #include "real.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 void prepare_cmp_insn PARAMS ((rtx *, rtx *, enum rtx_code *, rtx,
100 enum machine_mode *, int *,
101 enum can_compare_purpose));
102 static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode,
103 int, int *));
104 static enum insn_code can_float_p PARAMS ((enum machine_mode,
105 enum machine_mode,
106 int));
107 static rtx ftruncify PARAMS ((rtx));
108 static optab new_optab PARAMS ((void));
109 static inline optab init_optab PARAMS ((enum rtx_code));
110 static inline optab init_optabv PARAMS ((enum rtx_code));
111 static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
112 static void init_integral_libfuncs PARAMS ((optab, const char *, int));
113 static void init_floating_libfuncs PARAMS ((optab, const char *, int));
114 #ifdef HAVE_conditional_trap
115 static void init_traps PARAMS ((void));
116 #endif
117 static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
118 enum rtx_code, int, rtx));
119 static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
120 enum machine_mode *, int *));
122 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
123 the result of operation CODE applied to OP0 (and OP1 if it is a binary
124 operation).
126 If the last insn does not set TARGET, don't do anything, but return 1.
128 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
129 don't add the REG_EQUAL note but return 0. Our caller can then try
130 again, ensuring that TARGET is not one of the operands. */
132 static int
133 add_equal_note (seq, target, code, op0, op1)
134 rtx seq;
135 rtx target;
136 enum rtx_code code;
137 rtx op0, op1;
139 rtx set;
140 int i;
141 rtx note;
143 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
144 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
145 || GET_CODE (seq) != SEQUENCE
146 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
147 || GET_CODE (target) == ZERO_EXTRACT
148 || (! rtx_equal_p (SET_DEST (set), target)
149 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
150 SUBREG. */
151 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
152 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
153 target))))
154 return 1;
156 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
157 besides the last insn. */
158 if (reg_overlap_mentioned_p (target, op0)
159 || (op1 && reg_overlap_mentioned_p (target, op1)))
160 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
161 if (reg_set_p (target, XVECEXP (seq, 0, i)))
162 return 0;
164 if (GET_RTX_CLASS (code) == '1')
165 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
166 else
167 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
169 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
171 return 1;
174 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
175 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
176 not actually do a sign-extend or zero-extend, but can leave the
177 higher-order bits of the result rtx undefined, for example, in the case
178 of logical operations, but not right shifts. */
180 static rtx
181 widen_operand (op, mode, oldmode, unsignedp, no_extend)
182 rtx op;
183 enum machine_mode mode, oldmode;
184 int unsignedp;
185 int no_extend;
187 rtx result;
189 /* If we don't have to extend and this is a constant, return it. */
190 if (no_extend && GET_MODE (op) == VOIDmode)
191 return op;
193 /* If we must extend do so. If OP is a SUBREG for a promoted object, also
194 extend since it will be more efficient to do so unless the signedness of
195 a promoted object differs from our extension. */
196 if (! no_extend
197 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)
198 && SUBREG_PROMOTED_UNSIGNED_P (op) == unsignedp))
199 return convert_modes (mode, oldmode, op, unsignedp);
201 /* If MODE is no wider than a single word, we return a paradoxical
202 SUBREG. */
203 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
204 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
206 /* Otherwise, get an object of MODE, clobber it, and set the low-order
207 part to OP. */
209 result = gen_reg_rtx (mode);
210 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
211 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
212 return result;
215 /* Generate code to perform a straightforward complex divide. */
217 static int
218 expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
219 unsignedp, methods, class, binoptab)
220 rtx real0, real1, imag0, imag1, realr, imagr;
221 enum machine_mode submode;
222 int unsignedp;
223 enum optab_methods methods;
224 enum mode_class class;
225 optab binoptab;
227 rtx divisor;
228 rtx real_t, imag_t;
229 rtx temp1, temp2;
230 rtx res;
231 optab this_add_optab = add_optab;
232 optab this_sub_optab = sub_optab;
233 optab this_neg_optab = neg_optab;
234 optab this_mul_optab = smul_optab;
236 if (binoptab == sdivv_optab)
238 this_add_optab = addv_optab;
239 this_sub_optab = subv_optab;
240 this_neg_optab = negv_optab;
241 this_mul_optab = smulv_optab;
244 /* Don't fetch these from memory more than once. */
245 real0 = force_reg (submode, real0);
246 real1 = force_reg (submode, real1);
248 if (imag0 != 0)
249 imag0 = force_reg (submode, imag0);
251 imag1 = force_reg (submode, imag1);
253 /* Divisor: c*c + d*d. */
254 temp1 = expand_binop (submode, this_mul_optab, real1, real1,
255 NULL_RTX, unsignedp, methods);
257 temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
258 NULL_RTX, unsignedp, methods);
260 if (temp1 == 0 || temp2 == 0)
261 return 0;
263 divisor = expand_binop (submode, this_add_optab, temp1, temp2,
264 NULL_RTX, unsignedp, methods);
265 if (divisor == 0)
266 return 0;
268 if (imag0 == 0)
270 /* Mathematically, ((a)(c-id))/divisor. */
271 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
273 /* Calculate the dividend. */
274 real_t = expand_binop (submode, this_mul_optab, real0, real1,
275 NULL_RTX, unsignedp, methods);
277 imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
278 NULL_RTX, unsignedp, methods);
280 if (real_t == 0 || imag_t == 0)
281 return 0;
283 imag_t = expand_unop (submode, this_neg_optab, imag_t,
284 NULL_RTX, unsignedp);
286 else
288 /* Mathematically, ((a+ib)(c-id))/divider. */
289 /* Calculate the dividend. */
290 temp1 = expand_binop (submode, this_mul_optab, real0, real1,
291 NULL_RTX, unsignedp, methods);
293 temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
294 NULL_RTX, unsignedp, methods);
296 if (temp1 == 0 || temp2 == 0)
297 return 0;
299 real_t = expand_binop (submode, this_add_optab, temp1, temp2,
300 NULL_RTX, unsignedp, methods);
302 temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
303 NULL_RTX, unsignedp, methods);
305 temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
306 NULL_RTX, unsignedp, methods);
308 if (temp1 == 0 || temp2 == 0)
309 return 0;
311 imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
312 NULL_RTX, unsignedp, methods);
314 if (real_t == 0 || imag_t == 0)
315 return 0;
318 if (class == MODE_COMPLEX_FLOAT)
319 res = expand_binop (submode, binoptab, real_t, divisor,
320 realr, unsignedp, methods);
321 else
322 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
323 real_t, divisor, realr, unsignedp);
325 if (res == 0)
326 return 0;
328 if (res != realr)
329 emit_move_insn (realr, res);
331 if (class == MODE_COMPLEX_FLOAT)
332 res = expand_binop (submode, binoptab, imag_t, divisor,
333 imagr, unsignedp, methods);
334 else
335 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
336 imag_t, divisor, imagr, unsignedp);
338 if (res == 0)
339 return 0;
341 if (res != imagr)
342 emit_move_insn (imagr, res);
344 return 1;
347 /* Generate code to perform a wide-input-range-acceptable complex divide. */
349 static int
350 expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
351 unsignedp, methods, class, binoptab)
352 rtx real0, real1, imag0, imag1, realr, imagr;
353 enum machine_mode submode;
354 int unsignedp;
355 enum optab_methods methods;
356 enum mode_class class;
357 optab binoptab;
359 rtx ratio, divisor;
360 rtx real_t, imag_t;
361 rtx temp1, temp2, lab1, lab2;
362 enum machine_mode mode;
363 rtx res;
364 optab this_add_optab = add_optab;
365 optab this_sub_optab = sub_optab;
366 optab this_neg_optab = neg_optab;
367 optab this_mul_optab = smul_optab;
369 if (binoptab == sdivv_optab)
371 this_add_optab = addv_optab;
372 this_sub_optab = subv_optab;
373 this_neg_optab = negv_optab;
374 this_mul_optab = smulv_optab;
377 /* Don't fetch these from memory more than once. */
378 real0 = force_reg (submode, real0);
379 real1 = force_reg (submode, real1);
381 if (imag0 != 0)
382 imag0 = force_reg (submode, imag0);
384 imag1 = force_reg (submode, imag1);
386 /* XXX What's an "unsigned" complex number? */
387 if (unsignedp)
389 temp1 = real1;
390 temp2 = imag1;
392 else
394 temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
395 temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
398 if (temp1 == 0 || temp2 == 0)
399 return 0;
401 mode = GET_MODE (temp1);
402 lab1 = gen_label_rtx ();
403 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
404 mode, unsignedp, lab1);
406 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
408 if (class == MODE_COMPLEX_FLOAT)
409 ratio = expand_binop (submode, binoptab, imag1, real1,
410 NULL_RTX, unsignedp, methods);
411 else
412 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
413 imag1, real1, NULL_RTX, unsignedp);
415 if (ratio == 0)
416 return 0;
418 /* Calculate divisor. */
420 temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
421 NULL_RTX, unsignedp, methods);
423 if (temp1 == 0)
424 return 0;
426 divisor = expand_binop (submode, this_add_optab, temp1, real1,
427 NULL_RTX, unsignedp, methods);
429 if (divisor == 0)
430 return 0;
432 /* Calculate dividend. */
434 if (imag0 == 0)
436 real_t = real0;
438 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
440 imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
441 NULL_RTX, unsignedp, methods);
443 if (imag_t == 0)
444 return 0;
446 imag_t = expand_unop (submode, this_neg_optab, imag_t,
447 NULL_RTX, unsignedp);
449 if (real_t == 0 || imag_t == 0)
450 return 0;
452 else
454 /* Compute (a+ib)/(c+id) as
455 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
457 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
458 NULL_RTX, unsignedp, methods);
460 if (temp1 == 0)
461 return 0;
463 real_t = expand_binop (submode, this_add_optab, temp1, real0,
464 NULL_RTX, unsignedp, methods);
466 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
467 NULL_RTX, unsignedp, methods);
469 if (temp1 == 0)
470 return 0;
472 imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
473 NULL_RTX, unsignedp, methods);
475 if (real_t == 0 || imag_t == 0)
476 return 0;
479 if (class == MODE_COMPLEX_FLOAT)
480 res = expand_binop (submode, binoptab, real_t, divisor,
481 realr, unsignedp, methods);
482 else
483 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
484 real_t, divisor, realr, unsignedp);
486 if (res == 0)
487 return 0;
489 if (res != realr)
490 emit_move_insn (realr, res);
492 if (class == MODE_COMPLEX_FLOAT)
493 res = expand_binop (submode, binoptab, imag_t, divisor,
494 imagr, unsignedp, methods);
495 else
496 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
497 imag_t, divisor, imagr, unsignedp);
499 if (res == 0)
500 return 0;
502 if (res != imagr)
503 emit_move_insn (imagr, res);
505 lab2 = gen_label_rtx ();
506 emit_jump_insn (gen_jump (lab2));
507 emit_barrier ();
509 emit_label (lab1);
511 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
513 if (class == MODE_COMPLEX_FLOAT)
514 ratio = expand_binop (submode, binoptab, real1, imag1,
515 NULL_RTX, unsignedp, methods);
516 else
517 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
518 real1, imag1, NULL_RTX, unsignedp);
520 if (ratio == 0)
521 return 0;
523 /* Calculate divisor. */
525 temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
526 NULL_RTX, unsignedp, methods);
528 if (temp1 == 0)
529 return 0;
531 divisor = expand_binop (submode, this_add_optab, temp1, imag1,
532 NULL_RTX, unsignedp, methods);
534 if (divisor == 0)
535 return 0;
537 /* Calculate dividend. */
539 if (imag0 == 0)
541 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
543 real_t = expand_binop (submode, this_mul_optab, real0, ratio,
544 NULL_RTX, unsignedp, methods);
546 imag_t = expand_unop (submode, this_neg_optab, real0,
547 NULL_RTX, unsignedp);
549 if (real_t == 0 || imag_t == 0)
550 return 0;
552 else
554 /* Compute (a+ib)/(c+id) as
555 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
557 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
558 NULL_RTX, unsignedp, methods);
560 if (temp1 == 0)
561 return 0;
563 real_t = expand_binop (submode, this_add_optab, temp1, imag0,
564 NULL_RTX, unsignedp, methods);
566 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
567 NULL_RTX, unsignedp, methods);
569 if (temp1 == 0)
570 return 0;
572 imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
573 NULL_RTX, unsignedp, methods);
575 if (real_t == 0 || imag_t == 0)
576 return 0;
579 if (class == MODE_COMPLEX_FLOAT)
580 res = expand_binop (submode, binoptab, real_t, divisor,
581 realr, unsignedp, methods);
582 else
583 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
584 real_t, divisor, realr, unsignedp);
586 if (res == 0)
587 return 0;
589 if (res != realr)
590 emit_move_insn (realr, res);
592 if (class == MODE_COMPLEX_FLOAT)
593 res = expand_binop (submode, binoptab, imag_t, divisor,
594 imagr, unsignedp, methods);
595 else
596 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
597 imag_t, divisor, imagr, unsignedp);
599 if (res == 0)
600 return 0;
602 if (res != imagr)
603 emit_move_insn (imagr, res);
605 emit_label (lab2);
607 return 1;
610 /* Wrapper around expand_binop which takes an rtx code to specify
611 the operation to perform, not an optab pointer. All other
612 arguments are the same. */
614 expand_simple_binop (mode, code, op0, op1, target, unsignedp, methods)
615 enum machine_mode mode;
616 enum rtx_code code;
617 rtx op0, op1;
618 rtx target;
619 int unsignedp;
620 enum optab_methods methods;
622 optab binop = code_to_optab [(int) code];
623 if (binop == 0)
624 abort ();
626 return expand_binop (mode, binop, op0, op1, target, unsignedp, methods);
629 /* Generate code to perform an operation specified by BINOPTAB
630 on operands OP0 and OP1, with result having machine-mode MODE.
632 UNSIGNEDP is for the case where we have to widen the operands
633 to perform the operation. It says to use zero-extension.
635 If TARGET is nonzero, the value
636 is generated there, if it is convenient to do so.
637 In all cases an rtx is returned for the locus of the value;
638 this may or may not be TARGET. */
641 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
642 enum machine_mode mode;
643 optab binoptab;
644 rtx op0, op1;
645 rtx target;
646 int unsignedp;
647 enum optab_methods methods;
649 enum optab_methods next_methods
650 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
651 ? OPTAB_WIDEN : methods);
652 enum mode_class class;
653 enum machine_mode wider_mode;
654 rtx temp;
655 int commutative_op = 0;
656 int shift_op = (binoptab->code == ASHIFT
657 || binoptab->code == ASHIFTRT
658 || binoptab->code == LSHIFTRT
659 || binoptab->code == ROTATE
660 || binoptab->code == ROTATERT);
661 rtx entry_last = get_last_insn ();
662 rtx last;
664 class = GET_MODE_CLASS (mode);
666 op0 = protect_from_queue (op0, 0);
667 op1 = protect_from_queue (op1, 0);
668 if (target)
669 target = protect_from_queue (target, 1);
671 if (flag_force_mem)
673 op0 = force_not_mem (op0);
674 op1 = force_not_mem (op1);
677 /* If subtracting an integer constant, convert this into an addition of
678 the negated constant. */
680 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
682 op1 = negate_rtx (mode, op1);
683 binoptab = add_optab;
686 /* If we are inside an appropriately-short loop and one operand is an
687 expensive constant, force it into a register. */
688 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
689 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
690 op0 = force_reg (mode, op0);
692 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
693 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
694 op1 = force_reg (mode, op1);
696 /* Record where to delete back to if we backtrack. */
697 last = get_last_insn ();
699 /* If operation is commutative,
700 try to make the first operand a register.
701 Even better, try to make it the same as the target.
702 Also try to make the last operand a constant. */
703 if (GET_RTX_CLASS (binoptab->code) == 'c'
704 || binoptab == smul_widen_optab
705 || binoptab == umul_widen_optab
706 || binoptab == smul_highpart_optab
707 || binoptab == umul_highpart_optab)
709 commutative_op = 1;
711 if (((target == 0 || GET_CODE (target) == REG)
712 ? ((GET_CODE (op1) == REG
713 && GET_CODE (op0) != REG)
714 || target == op1)
715 : rtx_equal_p (op1, target))
716 || GET_CODE (op0) == CONST_INT)
718 temp = op1;
719 op1 = op0;
720 op0 = temp;
724 /* If we can do it with a three-operand insn, do so. */
726 if (methods != OPTAB_MUST_WIDEN
727 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
729 int icode = (int) binoptab->handlers[(int) mode].insn_code;
730 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
731 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
732 rtx pat;
733 rtx xop0 = op0, xop1 = op1;
735 if (target)
736 temp = target;
737 else
738 temp = gen_reg_rtx (mode);
740 /* If it is a commutative operator and the modes would match
741 if we would swap the operands, we can save the conversions. */
742 if (commutative_op)
744 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
745 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
747 rtx tmp;
749 tmp = op0; op0 = op1; op1 = tmp;
750 tmp = xop0; xop0 = xop1; xop1 = tmp;
754 /* In case the insn wants input operands in modes different from
755 the result, convert the operands. It would seem that we
756 don't need to convert CONST_INTs, but we do, so that they're
757 a properly sign-extended for their modes; we choose the
758 widest mode between mode and mode[01], so that, in a widening
759 operation, we call convert_modes with different FROM and TO
760 modes, which ensures the value is sign-extended. Shift
761 operations are an exception, because the second operand needs
762 not be extended to the mode of the result. */
764 if (GET_MODE (op0) != mode0
765 && mode0 != VOIDmode)
766 xop0 = convert_modes (mode0,
767 GET_MODE (op0) != VOIDmode
768 ? GET_MODE (op0)
769 : GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode0)
770 ? mode
771 : mode0,
772 xop0, unsignedp);
774 if (GET_MODE (xop1) != mode1
775 && mode1 != VOIDmode)
776 xop1 = convert_modes (mode1,
777 GET_MODE (op1) != VOIDmode
778 ? GET_MODE (op1)
779 : (GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode1)
780 && ! shift_op)
781 ? mode
782 : mode1,
783 xop1, unsignedp);
785 /* Now, if insn's predicates don't allow our operands, put them into
786 pseudo regs. */
788 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
789 && mode0 != VOIDmode)
790 xop0 = copy_to_mode_reg (mode0, xop0);
792 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
793 && mode1 != VOIDmode)
794 xop1 = copy_to_mode_reg (mode1, xop1);
796 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
797 temp = gen_reg_rtx (mode);
799 pat = GEN_FCN (icode) (temp, xop0, xop1);
800 if (pat)
802 /* If PAT is a multi-insn sequence, try to add an appropriate
803 REG_EQUAL note to it. If we can't because TEMP conflicts with an
804 operand, call ourselves again, this time without a target. */
805 if (GET_CODE (pat) == SEQUENCE
806 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
808 delete_insns_since (last);
809 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
810 unsignedp, methods);
813 emit_insn (pat);
814 return temp;
816 else
817 delete_insns_since (last);
820 /* If this is a multiply, see if we can do a widening operation that
821 takes operands of this mode and makes a wider mode. */
823 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
824 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
825 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
826 != CODE_FOR_nothing))
828 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
829 unsignedp ? umul_widen_optab : smul_widen_optab,
830 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
832 if (temp != 0)
834 if (GET_MODE_CLASS (mode) == MODE_INT)
835 return gen_lowpart (mode, temp);
836 else
837 return convert_to_mode (mode, temp, unsignedp);
841 /* Look for a wider mode of the same class for which we think we
842 can open-code the operation. Check for a widening multiply at the
843 wider mode as well. */
845 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
846 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
847 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
848 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
850 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
851 || (binoptab == smul_optab
852 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
853 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
854 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
855 != CODE_FOR_nothing)))
857 rtx xop0 = op0, xop1 = op1;
858 int no_extend = 0;
860 /* For certain integer operations, we need not actually extend
861 the narrow operands, as long as we will truncate
862 the results to the same narrowness. */
864 if ((binoptab == ior_optab || binoptab == and_optab
865 || binoptab == xor_optab
866 || binoptab == add_optab || binoptab == sub_optab
867 || binoptab == smul_optab || binoptab == ashl_optab)
868 && class == MODE_INT)
869 no_extend = 1;
871 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
873 /* The second operand of a shift must always be extended. */
874 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
875 no_extend && binoptab != ashl_optab);
877 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
878 unsignedp, OPTAB_DIRECT);
879 if (temp)
881 if (class != MODE_INT)
883 if (target == 0)
884 target = gen_reg_rtx (mode);
885 convert_move (target, temp, 0);
886 return target;
888 else
889 return gen_lowpart (mode, temp);
891 else
892 delete_insns_since (last);
896 /* These can be done a word at a time. */
897 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
898 && class == MODE_INT
899 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
900 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
902 int i;
903 rtx insns;
904 rtx equiv_value;
906 /* If TARGET is the same as one of the operands, the REG_EQUAL note
907 won't be accurate, so use a new target. */
908 if (target == 0 || target == op0 || target == op1)
909 target = gen_reg_rtx (mode);
911 start_sequence ();
913 /* Do the actual arithmetic. */
914 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
916 rtx target_piece = operand_subword (target, i, 1, mode);
917 rtx x = expand_binop (word_mode, binoptab,
918 operand_subword_force (op0, i, mode),
919 operand_subword_force (op1, i, mode),
920 target_piece, unsignedp, next_methods);
922 if (x == 0)
923 break;
925 if (target_piece != x)
926 emit_move_insn (target_piece, x);
929 insns = get_insns ();
930 end_sequence ();
932 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
934 if (binoptab->code != UNKNOWN)
935 equiv_value
936 = gen_rtx_fmt_ee (binoptab->code, mode,
937 copy_rtx (op0), copy_rtx (op1));
938 else
939 equiv_value = 0;
941 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
942 return target;
946 /* Synthesize double word shifts from single word shifts. */
947 if ((binoptab == lshr_optab || binoptab == ashl_optab
948 || binoptab == ashr_optab)
949 && class == MODE_INT
950 && GET_CODE (op1) == CONST_INT
951 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
952 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
953 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
954 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
956 rtx insns, inter, equiv_value;
957 rtx into_target, outof_target;
958 rtx into_input, outof_input;
959 int shift_count, left_shift, outof_word;
961 /* If TARGET is the same as one of the operands, the REG_EQUAL note
962 won't be accurate, so use a new target. */
963 if (target == 0 || target == op0 || target == op1)
964 target = gen_reg_rtx (mode);
966 start_sequence ();
968 shift_count = INTVAL (op1);
970 /* OUTOF_* is the word we are shifting bits away from, and
971 INTO_* is the word that we are shifting bits towards, thus
972 they differ depending on the direction of the shift and
973 WORDS_BIG_ENDIAN. */
975 left_shift = binoptab == ashl_optab;
976 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
978 outof_target = operand_subword (target, outof_word, 1, mode);
979 into_target = operand_subword (target, 1 - outof_word, 1, mode);
981 outof_input = operand_subword_force (op0, outof_word, mode);
982 into_input = operand_subword_force (op0, 1 - outof_word, mode);
984 if (shift_count >= BITS_PER_WORD)
986 inter = expand_binop (word_mode, binoptab,
987 outof_input,
988 GEN_INT (shift_count - BITS_PER_WORD),
989 into_target, unsignedp, next_methods);
991 if (inter != 0 && inter != into_target)
992 emit_move_insn (into_target, inter);
994 /* For a signed right shift, we must fill the word we are shifting
995 out of with copies of the sign bit. Otherwise it is zeroed. */
996 if (inter != 0 && binoptab != ashr_optab)
997 inter = CONST0_RTX (word_mode);
998 else if (inter != 0)
999 inter = expand_binop (word_mode, binoptab,
1000 outof_input,
1001 GEN_INT (BITS_PER_WORD - 1),
1002 outof_target, unsignedp, next_methods);
1004 if (inter != 0 && inter != outof_target)
1005 emit_move_insn (outof_target, inter);
1007 else
1009 rtx carries;
1010 optab reverse_unsigned_shift, unsigned_shift;
1012 /* For a shift of less then BITS_PER_WORD, to compute the carry,
1013 we must do a logical shift in the opposite direction of the
1014 desired shift. */
1016 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
1018 /* For a shift of less than BITS_PER_WORD, to compute the word
1019 shifted towards, we need to unsigned shift the orig value of
1020 that word. */
1022 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
1024 carries = expand_binop (word_mode, reverse_unsigned_shift,
1025 outof_input,
1026 GEN_INT (BITS_PER_WORD - shift_count),
1027 0, unsignedp, next_methods);
1029 if (carries == 0)
1030 inter = 0;
1031 else
1032 inter = expand_binop (word_mode, unsigned_shift, into_input,
1033 op1, 0, unsignedp, next_methods);
1035 if (inter != 0)
1036 inter = expand_binop (word_mode, ior_optab, carries, inter,
1037 into_target, unsignedp, next_methods);
1039 if (inter != 0 && inter != into_target)
1040 emit_move_insn (into_target, inter);
1042 if (inter != 0)
1043 inter = expand_binop (word_mode, binoptab, outof_input,
1044 op1, outof_target, unsignedp, next_methods);
1046 if (inter != 0 && inter != outof_target)
1047 emit_move_insn (outof_target, inter);
1050 insns = get_insns ();
1051 end_sequence ();
1053 if (inter != 0)
1055 if (binoptab->code != UNKNOWN)
1056 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1057 else
1058 equiv_value = 0;
1060 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1061 return target;
1065 /* Synthesize double word rotates from single word shifts. */
1066 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1067 && class == MODE_INT
1068 && GET_CODE (op1) == CONST_INT
1069 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1070 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1071 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1073 rtx insns, equiv_value;
1074 rtx into_target, outof_target;
1075 rtx into_input, outof_input;
1076 rtx inter;
1077 int shift_count, left_shift, outof_word;
1079 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1080 won't be accurate, so use a new target. */
1081 if (target == 0 || target == op0 || target == op1)
1082 target = gen_reg_rtx (mode);
1084 start_sequence ();
1086 shift_count = INTVAL (op1);
1088 /* OUTOF_* is the word we are shifting bits away from, and
1089 INTO_* is the word that we are shifting bits towards, thus
1090 they differ depending on the direction of the shift and
1091 WORDS_BIG_ENDIAN. */
1093 left_shift = (binoptab == rotl_optab);
1094 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1096 outof_target = operand_subword (target, outof_word, 1, mode);
1097 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1099 outof_input = operand_subword_force (op0, outof_word, mode);
1100 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1102 if (shift_count == BITS_PER_WORD)
1104 /* This is just a word swap. */
1105 emit_move_insn (outof_target, into_input);
1106 emit_move_insn (into_target, outof_input);
1107 inter = const0_rtx;
1109 else
1111 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1112 rtx first_shift_count, second_shift_count;
1113 optab reverse_unsigned_shift, unsigned_shift;
1115 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1116 ? lshr_optab : ashl_optab);
1118 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1119 ? ashl_optab : lshr_optab);
1121 if (shift_count > BITS_PER_WORD)
1123 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1124 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1126 else
1128 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1129 second_shift_count = GEN_INT (shift_count);
1132 into_temp1 = expand_binop (word_mode, unsigned_shift,
1133 outof_input, first_shift_count,
1134 NULL_RTX, unsignedp, next_methods);
1135 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1136 into_input, second_shift_count,
1137 into_target, unsignedp, next_methods);
1139 if (into_temp1 != 0 && into_temp2 != 0)
1140 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1141 into_target, unsignedp, next_methods);
1142 else
1143 inter = 0;
1145 if (inter != 0 && inter != into_target)
1146 emit_move_insn (into_target, inter);
1148 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1149 into_input, first_shift_count,
1150 NULL_RTX, unsignedp, next_methods);
1151 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1152 outof_input, second_shift_count,
1153 outof_target, unsignedp, next_methods);
1155 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1156 inter = expand_binop (word_mode, ior_optab,
1157 outof_temp1, outof_temp2,
1158 outof_target, unsignedp, next_methods);
1160 if (inter != 0 && inter != outof_target)
1161 emit_move_insn (outof_target, inter);
1164 insns = get_insns ();
1165 end_sequence ();
1167 if (inter != 0)
1169 if (binoptab->code != UNKNOWN)
1170 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1171 else
1172 equiv_value = 0;
1174 /* We can't make this a no conflict block if this is a word swap,
1175 because the word swap case fails if the input and output values
1176 are in the same register. */
1177 if (shift_count != BITS_PER_WORD)
1178 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1179 else
1180 emit_insns (insns);
1183 return target;
1187 /* These can be done a word at a time by propagating carries. */
1188 if ((binoptab == add_optab || binoptab == sub_optab)
1189 && class == MODE_INT
1190 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1191 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1193 int i;
1194 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1195 unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1196 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1197 rtx xop0, xop1;
1199 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1200 value is one of those, use it. Otherwise, use 1 since it is the
1201 one easiest to get. */
1202 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1203 int normalizep = STORE_FLAG_VALUE;
1204 #else
1205 int normalizep = 1;
1206 #endif
1208 /* Prepare the operands. */
1209 xop0 = force_reg (mode, op0);
1210 xop1 = force_reg (mode, op1);
1212 if (target == 0 || GET_CODE (target) != REG
1213 || target == xop0 || target == xop1)
1214 target = gen_reg_rtx (mode);
1216 /* Indicate for flow that the entire target reg is being set. */
1217 if (GET_CODE (target) == REG)
1218 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1220 /* Do the actual arithmetic. */
1221 for (i = 0; i < nwords; i++)
1223 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1224 rtx target_piece = operand_subword (target, index, 1, mode);
1225 rtx op0_piece = operand_subword_force (xop0, index, mode);
1226 rtx op1_piece = operand_subword_force (xop1, index, mode);
1227 rtx x;
1229 /* Main add/subtract of the input operands. */
1230 x = expand_binop (word_mode, binoptab,
1231 op0_piece, op1_piece,
1232 target_piece, unsignedp, next_methods);
1233 if (x == 0)
1234 break;
1236 if (i + 1 < nwords)
1238 /* Store carry from main add/subtract. */
1239 carry_out = gen_reg_rtx (word_mode);
1240 carry_out = emit_store_flag_force (carry_out,
1241 (binoptab == add_optab
1242 ? LT : GT),
1243 x, op0_piece,
1244 word_mode, 1, normalizep);
1247 if (i > 0)
1249 rtx newx;
1251 /* Add/subtract previous carry to main result. */
1252 newx = expand_binop (word_mode,
1253 normalizep == 1 ? binoptab : otheroptab,
1254 x, carry_in,
1255 NULL_RTX, 1, next_methods);
1257 if (i + 1 < nwords)
1259 /* Get out carry from adding/subtracting carry in. */
1260 rtx carry_tmp = gen_reg_rtx (word_mode);
1261 carry_tmp = emit_store_flag_force (carry_tmp,
1262 (binoptab == add_optab
1263 ? LT : GT),
1264 newx, x,
1265 word_mode, 1, normalizep);
1267 /* Logical-ior the two poss. carry together. */
1268 carry_out = expand_binop (word_mode, ior_optab,
1269 carry_out, carry_tmp,
1270 carry_out, 0, next_methods);
1271 if (carry_out == 0)
1272 break;
1274 emit_move_insn (target_piece, newx);
1277 carry_in = carry_out;
1280 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1282 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1284 rtx temp = emit_move_insn (target, target);
1286 set_unique_reg_note (temp,
1287 REG_EQUAL,
1288 gen_rtx_fmt_ee (binoptab->code, mode,
1289 copy_rtx (xop0),
1290 copy_rtx (xop1)));
1293 return target;
1296 else
1297 delete_insns_since (last);
1300 /* If we want to multiply two two-word values and have normal and widening
1301 multiplies of single-word values, we can do this with three smaller
1302 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1303 because we are not operating on one word at a time.
1305 The multiplication proceeds as follows:
1306 _______________________
1307 [__op0_high_|__op0_low__]
1308 _______________________
1309 * [__op1_high_|__op1_low__]
1310 _______________________________________________
1311 _______________________
1312 (1) [__op0_low__*__op1_low__]
1313 _______________________
1314 (2a) [__op0_low__*__op1_high_]
1315 _______________________
1316 (2b) [__op0_high_*__op1_low__]
1317 _______________________
1318 (3) [__op0_high_*__op1_high_]
1321 This gives a 4-word result. Since we are only interested in the
1322 lower 2 words, partial result (3) and the upper words of (2a) and
1323 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1324 calculated using non-widening multiplication.
1326 (1), however, needs to be calculated with an unsigned widening
1327 multiplication. If this operation is not directly supported we
1328 try using a signed widening multiplication and adjust the result.
1329 This adjustment works as follows:
1331 If both operands are positive then no adjustment is needed.
1333 If the operands have different signs, for example op0_low < 0 and
1334 op1_low >= 0, the instruction treats the most significant bit of
1335 op0_low as a sign bit instead of a bit with significance
1336 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1337 with 2**BITS_PER_WORD - op0_low, and two's complements the
1338 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1339 the result.
1341 Similarly, if both operands are negative, we need to add
1342 (op0_low + op1_low) * 2**BITS_PER_WORD.
1344 We use a trick to adjust quickly. We logically shift op0_low right
1345 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1346 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1347 logical shift exists, we do an arithmetic right shift and subtract
1348 the 0 or -1. */
1350 if (binoptab == smul_optab
1351 && class == MODE_INT
1352 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1353 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1354 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1355 && ((umul_widen_optab->handlers[(int) mode].insn_code
1356 != CODE_FOR_nothing)
1357 || (smul_widen_optab->handlers[(int) mode].insn_code
1358 != CODE_FOR_nothing)))
1360 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1361 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1362 rtx op0_high = operand_subword_force (op0, high, mode);
1363 rtx op0_low = operand_subword_force (op0, low, mode);
1364 rtx op1_high = operand_subword_force (op1, high, mode);
1365 rtx op1_low = operand_subword_force (op1, low, mode);
1366 rtx product = 0;
1367 rtx op0_xhigh = NULL_RTX;
1368 rtx op1_xhigh = NULL_RTX;
1370 /* If the target is the same as one of the inputs, don't use it. This
1371 prevents problems with the REG_EQUAL note. */
1372 if (target == op0 || target == op1
1373 || (target != 0 && GET_CODE (target) != REG))
1374 target = 0;
1376 /* Multiply the two lower words to get a double-word product.
1377 If unsigned widening multiplication is available, use that;
1378 otherwise use the signed form and compensate. */
1380 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1382 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1383 target, 1, OPTAB_DIRECT);
1385 /* If we didn't succeed, delete everything we did so far. */
1386 if (product == 0)
1387 delete_insns_since (last);
1388 else
1389 op0_xhigh = op0_high, op1_xhigh = op1_high;
1392 if (product == 0
1393 && smul_widen_optab->handlers[(int) mode].insn_code
1394 != CODE_FOR_nothing)
1396 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1397 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1398 target, 1, OPTAB_DIRECT);
1399 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1400 NULL_RTX, 1, next_methods);
1401 if (op0_xhigh)
1402 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1403 op0_xhigh, op0_xhigh, 0, next_methods);
1404 else
1406 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1407 NULL_RTX, 0, next_methods);
1408 if (op0_xhigh)
1409 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1410 op0_xhigh, op0_xhigh, 0,
1411 next_methods);
1414 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1415 NULL_RTX, 1, next_methods);
1416 if (op1_xhigh)
1417 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1418 op1_xhigh, op1_xhigh, 0, next_methods);
1419 else
1421 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1422 NULL_RTX, 0, next_methods);
1423 if (op1_xhigh)
1424 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1425 op1_xhigh, op1_xhigh, 0,
1426 next_methods);
1430 /* If we have been able to directly compute the product of the
1431 low-order words of the operands and perform any required adjustments
1432 of the operands, we proceed by trying two more multiplications
1433 and then computing the appropriate sum.
1435 We have checked above that the required addition is provided.
1436 Full-word addition will normally always succeed, especially if
1437 it is provided at all, so we don't worry about its failure. The
1438 multiplication may well fail, however, so we do handle that. */
1440 if (product && op0_xhigh && op1_xhigh)
1442 rtx product_high = operand_subword (product, high, 1, mode);
1443 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1444 NULL_RTX, 0, OPTAB_DIRECT);
1446 if (temp != 0)
1447 temp = expand_binop (word_mode, add_optab, temp, product_high,
1448 product_high, 0, next_methods);
1450 if (temp != 0 && temp != product_high)
1451 emit_move_insn (product_high, temp);
1453 if (temp != 0)
1454 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1455 NULL_RTX, 0, OPTAB_DIRECT);
1457 if (temp != 0)
1458 temp = expand_binop (word_mode, add_optab, temp,
1459 product_high, product_high,
1460 0, next_methods);
1462 if (temp != 0 && temp != product_high)
1463 emit_move_insn (product_high, temp);
1465 if (temp != 0)
1467 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1469 temp = emit_move_insn (product, product);
1470 set_unique_reg_note (temp,
1471 REG_EQUAL,
1472 gen_rtx_fmt_ee (MULT, mode,
1473 copy_rtx (op0),
1474 copy_rtx (op1)));
1477 return product;
1481 /* If we get here, we couldn't do it for some reason even though we
1482 originally thought we could. Delete anything we've emitted in
1483 trying to do it. */
1485 delete_insns_since (last);
1488 /* We need to open-code the complex type operations: '+, -, * and /' */
1490 /* At this point we allow operations between two similar complex
1491 numbers, and also if one of the operands is not a complex number
1492 but rather of MODE_FLOAT or MODE_INT. However, the caller
1493 must make sure that the MODE of the non-complex operand matches
1494 the SUBMODE of the complex operand. */
1496 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1498 rtx real0 = 0, imag0 = 0;
1499 rtx real1 = 0, imag1 = 0;
1500 rtx realr, imagr, res;
1501 rtx seq;
1502 rtx equiv_value;
1503 int ok = 0;
1505 /* Find the correct mode for the real and imaginary parts */
1506 enum machine_mode submode
1507 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1508 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1511 if (submode == BLKmode)
1512 abort ();
1514 if (! target)
1515 target = gen_reg_rtx (mode);
1517 start_sequence ();
1519 realr = gen_realpart (submode, target);
1520 imagr = gen_imagpart (submode, target);
1522 if (GET_MODE (op0) == mode)
1524 real0 = gen_realpart (submode, op0);
1525 imag0 = gen_imagpart (submode, op0);
1527 else
1528 real0 = op0;
1530 if (GET_MODE (op1) == mode)
1532 real1 = gen_realpart (submode, op1);
1533 imag1 = gen_imagpart (submode, op1);
1535 else
1536 real1 = op1;
1538 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1539 abort ();
1541 switch (binoptab->code)
1543 case PLUS:
1544 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1545 case MINUS:
1546 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1547 res = expand_binop (submode, binoptab, real0, real1,
1548 realr, unsignedp, methods);
1550 if (res == 0)
1551 break;
1552 else if (res != realr)
1553 emit_move_insn (realr, res);
1555 if (imag0 && imag1)
1556 res = expand_binop (submode, binoptab, imag0, imag1,
1557 imagr, unsignedp, methods);
1558 else if (imag0)
1559 res = imag0;
1560 else if (binoptab->code == MINUS)
1561 res = expand_unop (submode,
1562 binoptab == subv_optab ? negv_optab : neg_optab,
1563 imag1, imagr, unsignedp);
1564 else
1565 res = imag1;
1567 if (res == 0)
1568 break;
1569 else if (res != imagr)
1570 emit_move_insn (imagr, res);
1572 ok = 1;
1573 break;
1575 case MULT:
1576 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1578 if (imag0 && imag1)
1580 rtx temp1, temp2;
1582 /* Don't fetch these from memory more than once. */
1583 real0 = force_reg (submode, real0);
1584 real1 = force_reg (submode, real1);
1585 imag0 = force_reg (submode, imag0);
1586 imag1 = force_reg (submode, imag1);
1588 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1589 unsignedp, methods);
1591 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1592 unsignedp, methods);
1594 if (temp1 == 0 || temp2 == 0)
1595 break;
1597 res = (expand_binop
1598 (submode,
1599 binoptab == smulv_optab ? subv_optab : sub_optab,
1600 temp1, temp2, realr, unsignedp, methods));
1602 if (res == 0)
1603 break;
1604 else if (res != realr)
1605 emit_move_insn (realr, res);
1607 temp1 = expand_binop (submode, binoptab, real0, imag1,
1608 NULL_RTX, unsignedp, methods);
1610 temp2 = expand_binop (submode, binoptab, real1, imag0,
1611 NULL_RTX, unsignedp, methods);
1613 if (temp1 == 0 || temp2 == 0)
1614 break;
1616 res = (expand_binop
1617 (submode,
1618 binoptab == smulv_optab ? addv_optab : add_optab,
1619 temp1, temp2, imagr, unsignedp, methods));
1621 if (res == 0)
1622 break;
1623 else if (res != imagr)
1624 emit_move_insn (imagr, res);
1626 ok = 1;
1628 else
1630 /* Don't fetch these from memory more than once. */
1631 real0 = force_reg (submode, real0);
1632 real1 = force_reg (submode, real1);
1634 res = expand_binop (submode, binoptab, real0, real1,
1635 realr, unsignedp, methods);
1636 if (res == 0)
1637 break;
1638 else if (res != realr)
1639 emit_move_insn (realr, res);
1641 if (imag0 != 0)
1642 res = expand_binop (submode, binoptab,
1643 real1, imag0, imagr, unsignedp, methods);
1644 else
1645 res = expand_binop (submode, binoptab,
1646 real0, imag1, imagr, unsignedp, methods);
1648 if (res == 0)
1649 break;
1650 else if (res != imagr)
1651 emit_move_insn (imagr, res);
1653 ok = 1;
1655 break;
1657 case DIV:
1658 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1660 if (imag1 == 0)
1662 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1664 /* Don't fetch these from memory more than once. */
1665 real1 = force_reg (submode, real1);
1667 /* Simply divide the real and imaginary parts by `c' */
1668 if (class == MODE_COMPLEX_FLOAT)
1669 res = expand_binop (submode, binoptab, real0, real1,
1670 realr, unsignedp, methods);
1671 else
1672 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1673 real0, real1, realr, unsignedp);
1675 if (res == 0)
1676 break;
1677 else if (res != realr)
1678 emit_move_insn (realr, res);
1680 if (class == MODE_COMPLEX_FLOAT)
1681 res = expand_binop (submode, binoptab, imag0, real1,
1682 imagr, unsignedp, methods);
1683 else
1684 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1685 imag0, real1, imagr, unsignedp);
1687 if (res == 0)
1688 break;
1689 else if (res != imagr)
1690 emit_move_insn (imagr, res);
1692 ok = 1;
1694 else
1696 switch (flag_complex_divide_method)
1698 case 0:
1699 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1700 realr, imagr, submode,
1701 unsignedp, methods,
1702 class, binoptab);
1703 break;
1705 case 1:
1706 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1707 realr, imagr, submode,
1708 unsignedp, methods,
1709 class, binoptab);
1710 break;
1712 default:
1713 abort ();
1716 break;
1718 default:
1719 abort ();
1722 seq = get_insns ();
1723 end_sequence ();
1725 if (ok)
1727 if (binoptab->code != UNKNOWN)
1728 equiv_value
1729 = gen_rtx_fmt_ee (binoptab->code, mode,
1730 copy_rtx (op0), copy_rtx (op1));
1731 else
1732 equiv_value = 0;
1734 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1736 return target;
1740 /* It can't be open-coded in this mode.
1741 Use a library call if one is available and caller says that's ok. */
1743 if (binoptab->handlers[(int) mode].libfunc
1744 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1746 rtx insns;
1747 rtx op1x = op1;
1748 enum machine_mode op1_mode = mode;
1749 rtx value;
1751 start_sequence ();
1753 if (shift_op)
1755 op1_mode = word_mode;
1756 /* Specify unsigned here,
1757 since negative shift counts are meaningless. */
1758 op1x = convert_to_mode (word_mode, op1, 1);
1761 if (GET_MODE (op0) != VOIDmode
1762 && GET_MODE (op0) != mode)
1763 op0 = convert_to_mode (mode, op0, unsignedp);
1765 /* Pass 1 for NO_QUEUE so we don't lose any increments
1766 if the libcall is cse'd or moved. */
1767 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1768 NULL_RTX, LCT_CONST, mode, 2,
1769 op0, mode, op1x, op1_mode);
1771 insns = get_insns ();
1772 end_sequence ();
1774 target = gen_reg_rtx (mode);
1775 emit_libcall_block (insns, target, value,
1776 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1778 return target;
1781 delete_insns_since (last);
1783 /* It can't be done in this mode. Can we do it in a wider mode? */
1785 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1786 || methods == OPTAB_MUST_WIDEN))
1788 /* Caller says, don't even try. */
1789 delete_insns_since (entry_last);
1790 return 0;
1793 /* Compute the value of METHODS to pass to recursive calls.
1794 Don't allow widening to be tried recursively. */
1796 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1798 /* Look for a wider mode of the same class for which it appears we can do
1799 the operation. */
1801 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1803 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1804 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1806 if ((binoptab->handlers[(int) wider_mode].insn_code
1807 != CODE_FOR_nothing)
1808 || (methods == OPTAB_LIB
1809 && binoptab->handlers[(int) wider_mode].libfunc))
1811 rtx xop0 = op0, xop1 = op1;
1812 int no_extend = 0;
1814 /* For certain integer operations, we need not actually extend
1815 the narrow operands, as long as we will truncate
1816 the results to the same narrowness. */
1818 if ((binoptab == ior_optab || binoptab == and_optab
1819 || binoptab == xor_optab
1820 || binoptab == add_optab || binoptab == sub_optab
1821 || binoptab == smul_optab || binoptab == ashl_optab)
1822 && class == MODE_INT)
1823 no_extend = 1;
1825 xop0 = widen_operand (xop0, wider_mode, mode,
1826 unsignedp, no_extend);
1828 /* The second operand of a shift must always be extended. */
1829 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1830 no_extend && binoptab != ashl_optab);
1832 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1833 unsignedp, methods);
1834 if (temp)
1836 if (class != MODE_INT)
1838 if (target == 0)
1839 target = gen_reg_rtx (mode);
1840 convert_move (target, temp, 0);
1841 return target;
1843 else
1844 return gen_lowpart (mode, temp);
1846 else
1847 delete_insns_since (last);
1852 delete_insns_since (entry_last);
1853 return 0;
1856 /* Expand a binary operator which has both signed and unsigned forms.
1857 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1858 signed operations.
1860 If we widen unsigned operands, we may use a signed wider operation instead
1861 of an unsigned wider operation, since the result would be the same. */
1864 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1865 enum machine_mode mode;
1866 optab uoptab, soptab;
1867 rtx op0, op1, target;
1868 int unsignedp;
1869 enum optab_methods methods;
1871 rtx temp;
1872 optab direct_optab = unsignedp ? uoptab : soptab;
1873 struct optab wide_soptab;
1875 /* Do it without widening, if possible. */
1876 temp = expand_binop (mode, direct_optab, op0, op1, target,
1877 unsignedp, OPTAB_DIRECT);
1878 if (temp || methods == OPTAB_DIRECT)
1879 return temp;
1881 /* Try widening to a signed int. Make a fake signed optab that
1882 hides any signed insn for direct use. */
1883 wide_soptab = *soptab;
1884 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1885 wide_soptab.handlers[(int) mode].libfunc = 0;
1887 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1888 unsignedp, OPTAB_WIDEN);
1890 /* For unsigned operands, try widening to an unsigned int. */
1891 if (temp == 0 && unsignedp)
1892 temp = expand_binop (mode, uoptab, op0, op1, target,
1893 unsignedp, OPTAB_WIDEN);
1894 if (temp || methods == OPTAB_WIDEN)
1895 return temp;
1897 /* Use the right width lib call if that exists. */
1898 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1899 if (temp || methods == OPTAB_LIB)
1900 return temp;
1902 /* Must widen and use a lib call, use either signed or unsigned. */
1903 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1904 unsignedp, methods);
1905 if (temp != 0)
1906 return temp;
1907 if (unsignedp)
1908 return expand_binop (mode, uoptab, op0, op1, target,
1909 unsignedp, methods);
1910 return 0;
1913 /* Generate code to perform an operation specified by BINOPTAB
1914 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1915 We assume that the order of the operands for the instruction
1916 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1917 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1919 Either TARG0 or TARG1 may be zero, but what that means is that
1920 the result is not actually wanted. We will generate it into
1921 a dummy pseudo-reg and discard it. They may not both be zero.
1923 Returns 1 if this operation can be performed; 0 if not. */
1926 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1927 optab binoptab;
1928 rtx op0, op1;
1929 rtx targ0, targ1;
1930 int unsignedp;
1932 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1933 enum mode_class class;
1934 enum machine_mode wider_mode;
1935 rtx entry_last = get_last_insn ();
1936 rtx last;
1938 class = GET_MODE_CLASS (mode);
1940 op0 = protect_from_queue (op0, 0);
1941 op1 = protect_from_queue (op1, 0);
1943 if (flag_force_mem)
1945 op0 = force_not_mem (op0);
1946 op1 = force_not_mem (op1);
1949 /* If we are inside an appropriately-short loop and one operand is an
1950 expensive constant, force it into a register. */
1951 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1952 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1953 op0 = force_reg (mode, op0);
1955 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1956 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1957 op1 = force_reg (mode, op1);
1959 if (targ0)
1960 targ0 = protect_from_queue (targ0, 1);
1961 else
1962 targ0 = gen_reg_rtx (mode);
1963 if (targ1)
1964 targ1 = protect_from_queue (targ1, 1);
1965 else
1966 targ1 = gen_reg_rtx (mode);
1968 /* Record where to go back to if we fail. */
1969 last = get_last_insn ();
1971 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1973 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1974 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1975 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1976 rtx pat;
1977 rtx xop0 = op0, xop1 = op1;
1979 /* In case this insn wants input operands in modes different from the
1980 result, convert the operands. */
1981 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1982 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1984 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1985 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1987 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1988 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
1989 xop0 = copy_to_mode_reg (mode0, xop0);
1991 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
1992 xop1 = copy_to_mode_reg (mode1, xop1);
1994 /* We could handle this, but we should always be called with a pseudo
1995 for our targets and all insns should take them as outputs. */
1996 if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
1997 || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
1998 abort ();
2000 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
2001 if (pat)
2003 emit_insn (pat);
2004 return 1;
2006 else
2007 delete_insns_since (last);
2010 /* It can't be done in this mode. Can we do it in a wider mode? */
2012 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2014 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2015 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2017 if (binoptab->handlers[(int) wider_mode].insn_code
2018 != CODE_FOR_nothing)
2020 rtx t0 = gen_reg_rtx (wider_mode);
2021 rtx t1 = gen_reg_rtx (wider_mode);
2022 rtx cop0 = convert_modes (wider_mode, mode, op0, unsignedp);
2023 rtx cop1 = convert_modes (wider_mode, mode, op1, unsignedp);
2025 if (expand_twoval_binop (binoptab, cop0, cop1,
2026 t0, t1, unsignedp))
2028 convert_move (targ0, t0, unsignedp);
2029 convert_move (targ1, t1, unsignedp);
2030 return 1;
2032 else
2033 delete_insns_since (last);
2038 delete_insns_since (entry_last);
2039 return 0;
2042 /* Wrapper around expand_unop which takes an rtx code to specify
2043 the operation to perform, not an optab pointer. All other
2044 arguments are the same. */
2046 expand_simple_unop (mode, code, op0, target, unsignedp)
2047 enum machine_mode mode;
2048 enum rtx_code code;
2049 rtx op0;
2050 rtx target;
2051 int unsignedp;
2053 optab unop = code_to_optab [(int) code];
2054 if (unop == 0)
2055 abort ();
2057 return expand_unop (mode, unop, op0, target, unsignedp);
2060 /* Generate code to perform an operation specified by UNOPTAB
2061 on operand OP0, with result having machine-mode MODE.
2063 UNSIGNEDP is for the case where we have to widen the operands
2064 to perform the operation. It says to use zero-extension.
2066 If TARGET is nonzero, the value
2067 is generated there, if it is convenient to do so.
2068 In all cases an rtx is returned for the locus of the value;
2069 this may or may not be TARGET. */
2072 expand_unop (mode, unoptab, op0, target, unsignedp)
2073 enum machine_mode mode;
2074 optab unoptab;
2075 rtx op0;
2076 rtx target;
2077 int unsignedp;
2079 enum mode_class class;
2080 enum machine_mode wider_mode;
2081 rtx temp;
2082 rtx last = get_last_insn ();
2083 rtx pat;
2085 class = GET_MODE_CLASS (mode);
2087 op0 = protect_from_queue (op0, 0);
2089 if (flag_force_mem)
2091 op0 = force_not_mem (op0);
2094 if (target)
2095 target = protect_from_queue (target, 1);
2097 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2099 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2100 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2101 rtx xop0 = op0;
2103 if (target)
2104 temp = target;
2105 else
2106 temp = gen_reg_rtx (mode);
2108 if (GET_MODE (xop0) != VOIDmode
2109 && GET_MODE (xop0) != mode0)
2110 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2112 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2114 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2115 xop0 = copy_to_mode_reg (mode0, xop0);
2117 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2118 temp = gen_reg_rtx (mode);
2120 pat = GEN_FCN (icode) (temp, xop0);
2121 if (pat)
2123 if (GET_CODE (pat) == SEQUENCE
2124 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2126 delete_insns_since (last);
2127 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2130 emit_insn (pat);
2132 return temp;
2134 else
2135 delete_insns_since (last);
2138 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2140 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2141 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2142 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2144 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2146 rtx xop0 = op0;
2148 /* For certain operations, we need not actually extend
2149 the narrow operand, as long as we will truncate the
2150 results to the same narrowness. */
2152 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2153 (unoptab == neg_optab
2154 || unoptab == one_cmpl_optab)
2155 && class == MODE_INT);
2157 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2158 unsignedp);
2160 if (temp)
2162 if (class != MODE_INT)
2164 if (target == 0)
2165 target = gen_reg_rtx (mode);
2166 convert_move (target, temp, 0);
2167 return target;
2169 else
2170 return gen_lowpart (mode, temp);
2172 else
2173 delete_insns_since (last);
2177 /* These can be done a word at a time. */
2178 if (unoptab == one_cmpl_optab
2179 && class == MODE_INT
2180 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2181 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2183 int i;
2184 rtx insns;
2186 if (target == 0 || target == op0)
2187 target = gen_reg_rtx (mode);
2189 start_sequence ();
2191 /* Do the actual arithmetic. */
2192 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2194 rtx target_piece = operand_subword (target, i, 1, mode);
2195 rtx x = expand_unop (word_mode, unoptab,
2196 operand_subword_force (op0, i, mode),
2197 target_piece, unsignedp);
2199 if (target_piece != x)
2200 emit_move_insn (target_piece, x);
2203 insns = get_insns ();
2204 end_sequence ();
2206 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2207 gen_rtx_fmt_e (unoptab->code, mode,
2208 copy_rtx (op0)));
2209 return target;
2212 /* Open-code the complex negation operation. */
2213 else if (unoptab->code == NEG
2214 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2216 rtx target_piece;
2217 rtx x;
2218 rtx seq;
2220 /* Find the correct mode for the real and imaginary parts */
2221 enum machine_mode submode
2222 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2223 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2226 if (submode == BLKmode)
2227 abort ();
2229 if (target == 0)
2230 target = gen_reg_rtx (mode);
2232 start_sequence ();
2234 target_piece = gen_imagpart (submode, target);
2235 x = expand_unop (submode, unoptab,
2236 gen_imagpart (submode, op0),
2237 target_piece, unsignedp);
2238 if (target_piece != x)
2239 emit_move_insn (target_piece, x);
2241 target_piece = gen_realpart (submode, target);
2242 x = expand_unop (submode, unoptab,
2243 gen_realpart (submode, op0),
2244 target_piece, unsignedp);
2245 if (target_piece != x)
2246 emit_move_insn (target_piece, x);
2248 seq = get_insns ();
2249 end_sequence ();
2251 emit_no_conflict_block (seq, target, op0, 0,
2252 gen_rtx_fmt_e (unoptab->code, mode,
2253 copy_rtx (op0)));
2254 return target;
2257 /* Now try a library call in this mode. */
2258 if (unoptab->handlers[(int) mode].libfunc)
2260 rtx insns;
2261 rtx value;
2263 start_sequence ();
2265 /* Pass 1 for NO_QUEUE so we don't lose any increments
2266 if the libcall is cse'd or moved. */
2267 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2268 NULL_RTX, LCT_CONST, mode, 1, op0, mode);
2269 insns = get_insns ();
2270 end_sequence ();
2272 target = gen_reg_rtx (mode);
2273 emit_libcall_block (insns, target, value,
2274 gen_rtx_fmt_e (unoptab->code, mode, op0));
2276 return target;
2279 /* It can't be done in this mode. Can we do it in a wider mode? */
2281 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2283 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2284 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2286 if ((unoptab->handlers[(int) wider_mode].insn_code
2287 != CODE_FOR_nothing)
2288 || unoptab->handlers[(int) wider_mode].libfunc)
2290 rtx xop0 = op0;
2292 /* For certain operations, we need not actually extend
2293 the narrow operand, as long as we will truncate the
2294 results to the same narrowness. */
2296 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2297 (unoptab == neg_optab
2298 || unoptab == one_cmpl_optab)
2299 && class == MODE_INT);
2301 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2302 unsignedp);
2304 if (temp)
2306 if (class != MODE_INT)
2308 if (target == 0)
2309 target = gen_reg_rtx (mode);
2310 convert_move (target, temp, 0);
2311 return target;
2313 else
2314 return gen_lowpart (mode, temp);
2316 else
2317 delete_insns_since (last);
2322 /* If there is no negate operation, try doing a subtract from zero.
2323 The US Software GOFAST library needs this. */
2324 if (unoptab->code == NEG)
2326 rtx temp;
2327 temp = expand_binop (mode,
2328 unoptab == negv_optab ? subv_optab : sub_optab,
2329 CONST0_RTX (mode), op0,
2330 target, unsignedp, OPTAB_LIB_WIDEN);
2331 if (temp)
2332 return temp;
2335 return 0;
2338 /* Emit code to compute the absolute value of OP0, with result to
2339 TARGET if convenient. (TARGET may be 0.) The return value says
2340 where the result actually is to be found.
2342 MODE is the mode of the operand; the mode of the result is
2343 different but can be deduced from MODE.
2348 expand_abs (mode, op0, target, result_unsignedp, safe)
2349 enum machine_mode mode;
2350 rtx op0;
2351 rtx target;
2352 int result_unsignedp;
2353 int safe;
2355 rtx temp, op1;
2357 if (! flag_trapv)
2358 result_unsignedp = 1;
2360 /* First try to do it with a special abs instruction. */
2361 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2362 op0, target, 0);
2363 if (temp != 0)
2364 return temp;
2366 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2367 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2369 rtx last = get_last_insn ();
2371 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2372 if (temp != 0)
2373 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2374 OPTAB_WIDEN);
2376 if (temp != 0)
2377 return temp;
2379 delete_insns_since (last);
2382 /* If this machine has expensive jumps, we can do integer absolute
2383 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2384 where W is the width of MODE. */
2386 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2388 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2389 size_int (GET_MODE_BITSIZE (mode) - 1),
2390 NULL_RTX, 0);
2392 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2393 OPTAB_LIB_WIDEN);
2394 if (temp != 0)
2395 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2396 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2398 if (temp != 0)
2399 return temp;
2402 /* If that does not win, use conditional jump and negate. */
2404 /* It is safe to use the target if it is the same
2405 as the source if this is also a pseudo register */
2406 if (op0 == target && GET_CODE (op0) == REG
2407 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2408 safe = 1;
2410 op1 = gen_label_rtx ();
2411 if (target == 0 || ! safe
2412 || GET_MODE (target) != mode
2413 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2414 || (GET_CODE (target) == REG
2415 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2416 target = gen_reg_rtx (mode);
2418 emit_move_insn (target, op0);
2419 NO_DEFER_POP;
2421 /* If this mode is an integer too wide to compare properly,
2422 compare word by word. Rely on CSE to optimize constant cases. */
2423 if (GET_MODE_CLASS (mode) == MODE_INT
2424 && ! can_compare_p (GE, mode, ccp_jump))
2425 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2426 NULL_RTX, op1);
2427 else
2428 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2429 NULL_RTX, NULL_RTX, op1);
2431 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2432 target, target, 0);
2433 if (op0 != target)
2434 emit_move_insn (target, op0);
2435 emit_label (op1);
2436 OK_DEFER_POP;
2437 return target;
2440 /* Emit code to compute the absolute value of OP0, with result to
2441 TARGET if convenient. (TARGET may be 0.) The return value says
2442 where the result actually is to be found.
2444 MODE is the mode of the operand; the mode of the result is
2445 different but can be deduced from MODE.
2447 UNSIGNEDP is relevant for complex integer modes. */
2450 expand_complex_abs (mode, op0, target, unsignedp)
2451 enum machine_mode mode;
2452 rtx op0;
2453 rtx target;
2454 int unsignedp;
2456 enum mode_class class = GET_MODE_CLASS (mode);
2457 enum machine_mode wider_mode;
2458 rtx temp;
2459 rtx entry_last = get_last_insn ();
2460 rtx last;
2461 rtx pat;
2462 optab this_abs_optab;
2464 /* Find the correct mode for the real and imaginary parts. */
2465 enum machine_mode submode
2466 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2467 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2470 if (submode == BLKmode)
2471 abort ();
2473 op0 = protect_from_queue (op0, 0);
2475 if (flag_force_mem)
2477 op0 = force_not_mem (op0);
2480 last = get_last_insn ();
2482 if (target)
2483 target = protect_from_queue (target, 1);
2485 this_abs_optab = ! unsignedp && flag_trapv
2486 && (GET_MODE_CLASS(mode) == MODE_INT)
2487 ? absv_optab : abs_optab;
2489 if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2491 int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2492 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2493 rtx xop0 = op0;
2495 if (target)
2496 temp = target;
2497 else
2498 temp = gen_reg_rtx (submode);
2500 if (GET_MODE (xop0) != VOIDmode
2501 && GET_MODE (xop0) != mode0)
2502 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2504 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2506 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2507 xop0 = copy_to_mode_reg (mode0, xop0);
2509 if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2510 temp = gen_reg_rtx (submode);
2512 pat = GEN_FCN (icode) (temp, xop0);
2513 if (pat)
2515 if (GET_CODE (pat) == SEQUENCE
2516 && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
2517 NULL_RTX))
2519 delete_insns_since (last);
2520 return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
2521 unsignedp);
2524 emit_insn (pat);
2526 return temp;
2528 else
2529 delete_insns_since (last);
2532 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2534 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2535 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2537 if (this_abs_optab->handlers[(int) wider_mode].insn_code
2538 != CODE_FOR_nothing)
2540 rtx xop0 = op0;
2542 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2543 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2545 if (temp)
2547 if (class != MODE_COMPLEX_INT)
2549 if (target == 0)
2550 target = gen_reg_rtx (submode);
2551 convert_move (target, temp, 0);
2552 return target;
2554 else
2555 return gen_lowpart (submode, temp);
2557 else
2558 delete_insns_since (last);
2562 /* Open-code the complex absolute-value operation
2563 if we can open-code sqrt. Otherwise it's not worth while. */
2564 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2565 && ! flag_trapv)
2567 rtx real, imag, total;
2569 real = gen_realpart (submode, op0);
2570 imag = gen_imagpart (submode, op0);
2572 /* Square both parts. */
2573 real = expand_mult (submode, real, real, NULL_RTX, 0);
2574 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2576 /* Sum the parts. */
2577 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2578 0, OPTAB_LIB_WIDEN);
2580 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2581 target = expand_unop (submode, sqrt_optab, total, target, 0);
2582 if (target == 0)
2583 delete_insns_since (last);
2584 else
2585 return target;
2588 /* Now try a library call in this mode. */
2589 if (this_abs_optab->handlers[(int) mode].libfunc)
2591 rtx insns;
2592 rtx value;
2594 start_sequence ();
2596 /* Pass 1 for NO_QUEUE so we don't lose any increments
2597 if the libcall is cse'd or moved. */
2598 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2599 NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2600 insns = get_insns ();
2601 end_sequence ();
2603 target = gen_reg_rtx (submode);
2604 emit_libcall_block (insns, target, value,
2605 gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2607 return target;
2610 /* It can't be done in this mode. Can we do it in a wider mode? */
2612 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2613 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2615 if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2616 != CODE_FOR_nothing)
2617 || this_abs_optab->handlers[(int) wider_mode].libfunc)
2619 rtx xop0 = op0;
2621 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2623 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2625 if (temp)
2627 if (class != MODE_COMPLEX_INT)
2629 if (target == 0)
2630 target = gen_reg_rtx (submode);
2631 convert_move (target, temp, 0);
2632 return target;
2634 else
2635 return gen_lowpart (submode, temp);
2637 else
2638 delete_insns_since (last);
2642 delete_insns_since (entry_last);
2643 return 0;
2646 /* Generate an instruction whose insn-code is INSN_CODE,
2647 with two operands: an output TARGET and an input OP0.
2648 TARGET *must* be nonzero, and the output is always stored there.
2649 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2650 the value that is stored into TARGET. */
2652 void
2653 emit_unop_insn (icode, target, op0, code)
2654 int icode;
2655 rtx target;
2656 rtx op0;
2657 enum rtx_code code;
2659 rtx temp;
2660 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2661 rtx pat;
2663 temp = target = protect_from_queue (target, 1);
2665 op0 = protect_from_queue (op0, 0);
2667 /* Sign and zero extension from memory is often done specially on
2668 RISC machines, so forcing into a register here can pessimize
2669 code. */
2670 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2671 op0 = force_not_mem (op0);
2673 /* Now, if insn does not accept our operands, put them into pseudos. */
2675 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2676 op0 = copy_to_mode_reg (mode0, op0);
2678 if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2679 || (flag_force_mem && GET_CODE (temp) == MEM))
2680 temp = gen_reg_rtx (GET_MODE (temp));
2682 pat = GEN_FCN (icode) (temp, op0);
2684 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2685 add_equal_note (pat, temp, code, op0, NULL_RTX);
2687 emit_insn (pat);
2689 if (temp != target)
2690 emit_move_insn (target, temp);
2693 /* Emit code to perform a series of operations on a multi-word quantity, one
2694 word at a time.
2696 Such a block is preceded by a CLOBBER of the output, consists of multiple
2697 insns, each setting one word of the output, and followed by a SET copying
2698 the output to itself.
2700 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2701 note indicating that it doesn't conflict with the (also multi-word)
2702 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2703 notes.
2705 INSNS is a block of code generated to perform the operation, not including
2706 the CLOBBER and final copy. All insns that compute intermediate values
2707 are first emitted, followed by the block as described above.
2709 TARGET, OP0, and OP1 are the output and inputs of the operations,
2710 respectively. OP1 may be zero for a unary operation.
2712 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2713 on the last insn.
2715 If TARGET is not a register, INSNS is simply emitted with no special
2716 processing. Likewise if anything in INSNS is not an INSN or if
2717 there is a libcall block inside INSNS.
2719 The final insn emitted is returned. */
2722 emit_no_conflict_block (insns, target, op0, op1, equiv)
2723 rtx insns;
2724 rtx target;
2725 rtx op0, op1;
2726 rtx equiv;
2728 rtx prev, next, first, last, insn;
2730 if (GET_CODE (target) != REG || reload_in_progress)
2731 return emit_insns (insns);
2732 else
2733 for (insn = insns; insn; insn = NEXT_INSN (insn))
2734 if (GET_CODE (insn) != INSN
2735 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2736 return emit_insns (insns);
2738 /* First emit all insns that do not store into words of the output and remove
2739 these from the list. */
2740 for (insn = insns; insn; insn = next)
2742 rtx set = 0;
2743 int i;
2745 next = NEXT_INSN (insn);
2747 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
2748 || GET_CODE (PATTERN (insn)) == CLOBBER)
2749 set = PATTERN (insn);
2750 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2752 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2753 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2755 set = XVECEXP (PATTERN (insn), 0, i);
2756 break;
2760 if (set == 0)
2761 abort ();
2763 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2765 if (PREV_INSN (insn))
2766 NEXT_INSN (PREV_INSN (insn)) = next;
2767 else
2768 insns = next;
2770 if (next)
2771 PREV_INSN (next) = PREV_INSN (insn);
2773 add_insn (insn);
2777 prev = get_last_insn ();
2779 /* Now write the CLOBBER of the output, followed by the setting of each
2780 of the words, followed by the final copy. */
2781 if (target != op0 && target != op1)
2782 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2784 for (insn = insns; insn; insn = next)
2786 next = NEXT_INSN (insn);
2787 add_insn (insn);
2789 if (op1 && GET_CODE (op1) == REG)
2790 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2791 REG_NOTES (insn));
2793 if (op0 && GET_CODE (op0) == REG)
2794 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2795 REG_NOTES (insn));
2798 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2799 != CODE_FOR_nothing)
2801 last = emit_move_insn (target, target);
2802 if (equiv)
2803 set_unique_reg_note (last, REG_EQUAL, equiv);
2805 else
2807 last = get_last_insn ();
2809 /* Remove any existing REG_EQUAL note from "last", or else it will
2810 be mistaken for a note referring to the full contents of the
2811 alleged libcall value when found together with the REG_RETVAL
2812 note added below. An existing note can come from an insn
2813 expansion at "last". */
2814 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2817 if (prev == 0)
2818 first = get_insns ();
2819 else
2820 first = NEXT_INSN (prev);
2822 /* Encapsulate the block so it gets manipulated as a unit. */
2823 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2824 REG_NOTES (first));
2825 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2827 return last;
2830 /* Emit code to make a call to a constant function or a library call.
2832 INSNS is a list containing all insns emitted in the call.
2833 These insns leave the result in RESULT. Our block is to copy RESULT
2834 to TARGET, which is logically equivalent to EQUIV.
2836 We first emit any insns that set a pseudo on the assumption that these are
2837 loading constants into registers; doing so allows them to be safely cse'ed
2838 between blocks. Then we emit all the other insns in the block, followed by
2839 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2840 note with an operand of EQUIV.
2842 Moving assignments to pseudos outside of the block is done to improve
2843 the generated code, but is not required to generate correct code,
2844 hence being unable to move an assignment is not grounds for not making
2845 a libcall block. There are two reasons why it is safe to leave these
2846 insns inside the block: First, we know that these pseudos cannot be
2847 used in generated RTL outside the block since they are created for
2848 temporary purposes within the block. Second, CSE will not record the
2849 values of anything set inside a libcall block, so we know they must
2850 be dead at the end of the block.
2852 Except for the first group of insns (the ones setting pseudos), the
2853 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2855 void
2856 emit_libcall_block (insns, target, result, equiv)
2857 rtx insns;
2858 rtx target;
2859 rtx result;
2860 rtx equiv;
2862 rtx final_dest = target;
2863 rtx prev, next, first, last, insn;
2865 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2866 into a MEM later. Protect the libcall block from this change. */
2867 if (! REG_P (target) || REG_USERVAR_P (target))
2868 target = gen_reg_rtx (GET_MODE (target));
2870 /* If we're using non-call exceptions, a libcall corresponding to an
2871 operation that may trap may also trap. */
2872 if (flag_non_call_exceptions && may_trap_p (equiv))
2874 for (insn = insns; insn; insn = NEXT_INSN (insn))
2875 if (GET_CODE (insn) == CALL_INSN)
2877 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2879 if (note != 0 && INTVAL (XEXP (note, 0)) <= 0)
2880 remove_note (insn, note);
2883 else
2884 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2885 reg note to indicate that this call cannot throw or execute a nonlocal
2886 goto (unless there is already a REG_EH_REGION note, in which case
2887 we update it). */
2888 for (insn = insns; insn; insn = NEXT_INSN (insn))
2889 if (GET_CODE (insn) == CALL_INSN)
2891 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2893 if (note != 0)
2894 XEXP (note, 0) = GEN_INT (-1);
2895 else
2896 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2897 REG_NOTES (insn));
2900 /* First emit all insns that set pseudos. Remove them from the list as
2901 we go. Avoid insns that set pseudos which were referenced in previous
2902 insns. These can be generated by move_by_pieces, for example,
2903 to update an address. Similarly, avoid insns that reference things
2904 set in previous insns. */
2906 for (insn = insns; insn; insn = next)
2908 rtx set = single_set (insn);
2910 next = NEXT_INSN (insn);
2912 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2913 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2914 && (insn == insns
2915 || ((! INSN_P(insns)
2916 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
2917 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2918 && ! modified_in_p (SET_SRC (set), insns)
2919 && ! modified_between_p (SET_SRC (set), insns, insn))))
2921 if (PREV_INSN (insn))
2922 NEXT_INSN (PREV_INSN (insn)) = next;
2923 else
2924 insns = next;
2926 if (next)
2927 PREV_INSN (next) = PREV_INSN (insn);
2929 add_insn (insn);
2933 prev = get_last_insn ();
2935 /* Write the remaining insns followed by the final copy. */
2937 for (insn = insns; insn; insn = next)
2939 next = NEXT_INSN (insn);
2941 add_insn (insn);
2944 last = emit_move_insn (target, result);
2945 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2946 != CODE_FOR_nothing)
2947 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2948 else
2950 /* Remove any existing REG_EQUAL note from "last", or else it will
2951 be mistaken for a note referring to the full contents of the
2952 libcall value when found together with the REG_RETVAL note added
2953 below. An existing note can come from an insn expansion at
2954 "last". */
2955 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2958 if (final_dest != target)
2959 emit_move_insn (final_dest, target);
2961 if (prev == 0)
2962 first = get_insns ();
2963 else
2964 first = NEXT_INSN (prev);
2966 /* Encapsulate the block so it gets manipulated as a unit. */
2967 if (!flag_non_call_exceptions || !may_trap_p (equiv))
2969 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2970 REG_NOTES (first));
2971 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first,
2972 REG_NOTES (last));
2976 /* Generate code to store zero in X. */
2978 void
2979 emit_clr_insn (x)
2980 rtx x;
2982 emit_move_insn (x, const0_rtx);
2985 /* Generate code to store 1 in X
2986 assuming it contains zero beforehand. */
2988 void
2989 emit_0_to_1_insn (x)
2990 rtx x;
2992 emit_move_insn (x, const1_rtx);
2995 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2996 PURPOSE describes how this comparison will be used. CODE is the rtx
2997 comparison code we will be using.
2999 ??? Actually, CODE is slightly weaker than that. A target is still
3000 required to implement all of the normal bcc operations, but not
3001 required to implement all (or any) of the unordered bcc operations. */
3004 can_compare_p (code, mode, purpose)
3005 enum rtx_code code;
3006 enum machine_mode mode;
3007 enum can_compare_purpose purpose;
3011 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3013 if (purpose == ccp_jump)
3014 return bcc_gen_fctn[(int)code] != NULL;
3015 else if (purpose == ccp_store_flag)
3016 return setcc_gen_code[(int)code] != CODE_FOR_nothing;
3017 else
3018 /* There's only one cmov entry point, and it's allowed to fail. */
3019 return 1;
3021 if (purpose == ccp_jump
3022 && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3023 return 1;
3024 if (purpose == ccp_cmov
3025 && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3026 return 1;
3027 if (purpose == ccp_store_flag
3028 && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
3029 return 1;
3031 mode = GET_MODE_WIDER_MODE (mode);
3033 while (mode != VOIDmode);
3035 return 0;
3038 /* This function is called when we are going to emit a compare instruction that
3039 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
3041 *PMODE is the mode of the inputs (in case they are const_int).
3042 *PUNSIGNEDP nonzero says that the operands are unsigned;
3043 this matters if they need to be widened.
3045 If they have mode BLKmode, then SIZE specifies the size of both operands.
3047 This function performs all the setup necessary so that the caller only has
3048 to emit a single comparison insn. This setup can involve doing a BLKmode
3049 comparison or emitting a library call to perform the comparison if no insn
3050 is available to handle it.
3051 The values which are passed in through pointers can be modified; the caller
3052 should perform the comparison on the modified values. */
3054 static void
3055 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, purpose)
3056 rtx *px, *py;
3057 enum rtx_code *pcomparison;
3058 rtx size;
3059 enum machine_mode *pmode;
3060 int *punsignedp;
3061 enum can_compare_purpose purpose;
3063 enum machine_mode mode = *pmode;
3064 rtx x = *px, y = *py;
3065 int unsignedp = *punsignedp;
3066 enum mode_class class;
3068 class = GET_MODE_CLASS (mode);
3070 /* They could both be VOIDmode if both args are immediate constants,
3071 but we should fold that at an earlier stage.
3072 With no special code here, this will call abort,
3073 reminding the programmer to implement such folding. */
3075 if (mode != BLKmode && flag_force_mem)
3077 x = force_not_mem (x);
3078 y = force_not_mem (y);
3081 /* If we are inside an appropriately-short loop and one operand is an
3082 expensive constant, force it into a register. */
3083 if (CONSTANT_P (x) && preserve_subexpressions_p ()
3084 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3085 x = force_reg (mode, x);
3087 if (CONSTANT_P (y) && preserve_subexpressions_p ()
3088 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3089 y = force_reg (mode, y);
3091 #ifdef HAVE_cc0
3092 /* Abort if we have a non-canonical comparison. The RTL documentation
3093 states that canonical comparisons are required only for targets which
3094 have cc0. */
3095 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3096 abort();
3097 #endif
3099 /* Don't let both operands fail to indicate the mode. */
3100 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3101 x = force_reg (mode, x);
3103 /* Handle all BLKmode compares. */
3105 if (mode == BLKmode)
3107 rtx result;
3108 enum machine_mode result_mode;
3109 rtx opalign ATTRIBUTE_UNUSED
3110 = GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
3112 emit_queue ();
3113 x = protect_from_queue (x, 0);
3114 y = protect_from_queue (y, 0);
3116 if (size == 0)
3117 abort ();
3118 #ifdef HAVE_cmpstrqi
3119 if (HAVE_cmpstrqi
3120 && GET_CODE (size) == CONST_INT
3121 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3123 result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3124 result = gen_reg_rtx (result_mode);
3125 emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3127 else
3128 #endif
3129 #ifdef HAVE_cmpstrhi
3130 if (HAVE_cmpstrhi
3131 && GET_CODE (size) == CONST_INT
3132 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3134 result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3135 result = gen_reg_rtx (result_mode);
3136 emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3138 else
3139 #endif
3140 #ifdef HAVE_cmpstrsi
3141 if (HAVE_cmpstrsi)
3143 result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3144 result = gen_reg_rtx (result_mode);
3145 size = protect_from_queue (size, 0);
3146 emit_insn (gen_cmpstrsi (result, x, y,
3147 convert_to_mode (SImode, size, 1),
3148 opalign));
3150 else
3151 #endif
3153 #ifdef TARGET_MEM_FUNCTIONS
3154 emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3155 TYPE_MODE (integer_type_node), 3,
3156 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3157 convert_to_mode (TYPE_MODE (sizetype), size,
3158 TREE_UNSIGNED (sizetype)),
3159 TYPE_MODE (sizetype));
3160 #else
3161 emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3162 TYPE_MODE (integer_type_node), 3,
3163 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3164 convert_to_mode (TYPE_MODE (integer_type_node),
3165 size,
3166 TREE_UNSIGNED (integer_type_node)),
3167 TYPE_MODE (integer_type_node));
3168 #endif
3170 /* Immediately move the result of the libcall into a pseudo
3171 register so reload doesn't clobber the value if it needs
3172 the return register for a spill reg. */
3173 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3174 result_mode = TYPE_MODE (integer_type_node);
3175 emit_move_insn (result,
3176 hard_libcall_value (result_mode));
3178 *px = result;
3179 *py = const0_rtx;
3180 *pmode = result_mode;
3181 return;
3184 *px = x;
3185 *py = y;
3186 if (can_compare_p (*pcomparison, mode, purpose))
3187 return;
3189 /* Handle a lib call just for the mode we are using. */
3191 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3193 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3194 rtx result;
3196 /* If we want unsigned, and this mode has a distinct unsigned
3197 comparison routine, use that. */
3198 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3199 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3201 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode,
3202 y, mode);
3204 /* Immediately move the result of the libcall into a pseudo
3205 register so reload doesn't clobber the value if it needs
3206 the return register for a spill reg. */
3207 result = gen_reg_rtx (word_mode);
3208 emit_move_insn (result, hard_libcall_value (word_mode));
3210 /* Integer comparison returns a result that must be compared against 1,
3211 so that even if we do an unsigned compare afterward,
3212 there is still a value that can represent the result "less than". */
3213 *px = result;
3214 *py = const1_rtx;
3215 *pmode = word_mode;
3216 return;
3219 if (class == MODE_FLOAT)
3220 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3222 else
3223 abort ();
3226 /* Before emitting an insn with code ICODE, make sure that X, which is going
3227 to be used for operand OPNUM of the insn, is converted from mode MODE to
3228 WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
3229 that it is accepted by the operand predicate. Return the new value. */
3232 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3233 int icode;
3234 rtx x;
3235 int opnum;
3236 enum machine_mode mode, wider_mode;
3237 int unsignedp;
3239 x = protect_from_queue (x, 0);
3241 if (mode != wider_mode)
3242 x = convert_modes (wider_mode, mode, x, unsignedp);
3244 if (! (*insn_data[icode].operand[opnum].predicate)
3245 (x, insn_data[icode].operand[opnum].mode))
3246 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3247 return x;
3250 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3251 we can do the comparison.
3252 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3253 be NULL_RTX which indicates that only a comparison is to be generated. */
3255 static void
3256 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3257 rtx x, y;
3258 enum machine_mode mode;
3259 enum rtx_code comparison;
3260 int unsignedp;
3261 rtx label;
3263 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3264 enum mode_class class = GET_MODE_CLASS (mode);
3265 enum machine_mode wider_mode = mode;
3267 /* Try combined insns first. */
3270 enum insn_code icode;
3271 PUT_MODE (test, wider_mode);
3273 if (label)
3275 icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3277 if (icode != CODE_FOR_nothing
3278 && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3280 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3281 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3282 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3283 return;
3287 /* Handle some compares against zero. */
3288 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3289 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3291 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3292 emit_insn (GEN_FCN (icode) (x));
3293 if (label)
3294 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3295 return;
3298 /* Handle compares for which there is a directly suitable insn. */
3300 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3301 if (icode != CODE_FOR_nothing)
3303 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3304 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3305 emit_insn (GEN_FCN (icode) (x, y));
3306 if (label)
3307 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3308 return;
3311 if (class != MODE_INT && class != MODE_FLOAT
3312 && class != MODE_COMPLEX_FLOAT)
3313 break;
3315 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3316 } while (wider_mode != VOIDmode);
3318 abort ();
3321 /* Generate code to compare X with Y so that the condition codes are
3322 set and to jump to LABEL if the condition is true. If X is a
3323 constant and Y is not a constant, then the comparison is swapped to
3324 ensure that the comparison RTL has the canonical form.
3326 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3327 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3328 the proper branch condition code.
3330 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y.
3332 MODE is the mode of the inputs (in case they are const_int).
3334 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3335 be passed unchanged to emit_cmp_insn, then potentially converted into an
3336 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3338 void
3339 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, label)
3340 rtx x, y;
3341 enum rtx_code comparison;
3342 rtx size;
3343 enum machine_mode mode;
3344 int unsignedp;
3345 rtx label;
3347 rtx op0 = x, op1 = y;
3349 /* Swap operands and condition to ensure canonical RTL. */
3350 if (swap_commutative_operands_p (x, y))
3352 /* If we're not emitting a branch, this means some caller
3353 is out of sync. */
3354 if (! label)
3355 abort ();
3357 op0 = y, op1 = x;
3358 comparison = swap_condition (comparison);
3361 #ifdef HAVE_cc0
3362 /* If OP0 is still a constant, then both X and Y must be constants. Force
3363 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3364 RTL. */
3365 if (CONSTANT_P (op0))
3366 op0 = force_reg (mode, op0);
3367 #endif
3369 emit_queue ();
3370 if (unsignedp)
3371 comparison = unsigned_condition (comparison);
3373 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp,
3374 ccp_jump);
3375 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3378 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3380 void
3381 emit_cmp_insn (x, y, comparison, size, mode, unsignedp)
3382 rtx x, y;
3383 enum rtx_code comparison;
3384 rtx size;
3385 enum machine_mode mode;
3386 int unsignedp;
3388 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, 0);
3391 /* Emit a library call comparison between floating point X and Y.
3392 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3394 static void
3395 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3396 rtx *px, *py;
3397 enum rtx_code *pcomparison;
3398 enum machine_mode *pmode;
3399 int *punsignedp;
3401 enum rtx_code comparison = *pcomparison;
3402 rtx tmp;
3403 rtx x = *px = protect_from_queue (*px, 0);
3404 rtx y = *py = protect_from_queue (*py, 0);
3405 enum machine_mode mode = GET_MODE (x);
3406 rtx libfunc = 0;
3407 rtx result;
3409 if (mode == HFmode)
3410 switch (comparison)
3412 case EQ:
3413 libfunc = eqhf2_libfunc;
3414 break;
3416 case NE:
3417 libfunc = nehf2_libfunc;
3418 break;
3420 case GT:
3421 libfunc = gthf2_libfunc;
3422 if (libfunc == NULL_RTX)
3424 tmp = x; x = y; y = tmp;
3425 *pcomparison = LT;
3426 libfunc = lthf2_libfunc;
3428 break;
3430 case GE:
3431 libfunc = gehf2_libfunc;
3432 if (libfunc == NULL_RTX)
3434 tmp = x; x = y; y = tmp;
3435 *pcomparison = LE;
3436 libfunc = lehf2_libfunc;
3438 break;
3440 case LT:
3441 libfunc = lthf2_libfunc;
3442 if (libfunc == NULL_RTX)
3444 tmp = x; x = y; y = tmp;
3445 *pcomparison = GT;
3446 libfunc = gthf2_libfunc;
3448 break;
3450 case LE:
3451 libfunc = lehf2_libfunc;
3452 if (libfunc == NULL_RTX)
3454 tmp = x; x = y; y = tmp;
3455 *pcomparison = GE;
3456 libfunc = gehf2_libfunc;
3458 break;
3460 case UNORDERED:
3461 libfunc = unordhf2_libfunc;
3462 break;
3464 default:
3465 break;
3467 else if (mode == SFmode)
3468 switch (comparison)
3470 case EQ:
3471 libfunc = eqsf2_libfunc;
3472 break;
3474 case NE:
3475 libfunc = nesf2_libfunc;
3476 break;
3478 case GT:
3479 libfunc = gtsf2_libfunc;
3480 if (libfunc == NULL_RTX)
3482 tmp = x; x = y; y = tmp;
3483 *pcomparison = LT;
3484 libfunc = ltsf2_libfunc;
3486 break;
3488 case GE:
3489 libfunc = gesf2_libfunc;
3490 if (libfunc == NULL_RTX)
3492 tmp = x; x = y; y = tmp;
3493 *pcomparison = LE;
3494 libfunc = lesf2_libfunc;
3496 break;
3498 case LT:
3499 libfunc = ltsf2_libfunc;
3500 if (libfunc == NULL_RTX)
3502 tmp = x; x = y; y = tmp;
3503 *pcomparison = GT;
3504 libfunc = gtsf2_libfunc;
3506 break;
3508 case LE:
3509 libfunc = lesf2_libfunc;
3510 if (libfunc == NULL_RTX)
3512 tmp = x; x = y; y = tmp;
3513 *pcomparison = GE;
3514 libfunc = gesf2_libfunc;
3516 break;
3518 case UNORDERED:
3519 libfunc = unordsf2_libfunc;
3520 break;
3522 default:
3523 break;
3525 else if (mode == DFmode)
3526 switch (comparison)
3528 case EQ:
3529 libfunc = eqdf2_libfunc;
3530 break;
3532 case NE:
3533 libfunc = nedf2_libfunc;
3534 break;
3536 case GT:
3537 libfunc = gtdf2_libfunc;
3538 if (libfunc == NULL_RTX)
3540 tmp = x; x = y; y = tmp;
3541 *pcomparison = LT;
3542 libfunc = ltdf2_libfunc;
3544 break;
3546 case GE:
3547 libfunc = gedf2_libfunc;
3548 if (libfunc == NULL_RTX)
3550 tmp = x; x = y; y = tmp;
3551 *pcomparison = LE;
3552 libfunc = ledf2_libfunc;
3554 break;
3556 case LT:
3557 libfunc = ltdf2_libfunc;
3558 if (libfunc == NULL_RTX)
3560 tmp = x; x = y; y = tmp;
3561 *pcomparison = GT;
3562 libfunc = gtdf2_libfunc;
3564 break;
3566 case LE:
3567 libfunc = ledf2_libfunc;
3568 if (libfunc == NULL_RTX)
3570 tmp = x; x = y; y = tmp;
3571 *pcomparison = GE;
3572 libfunc = gedf2_libfunc;
3574 break;
3576 case UNORDERED:
3577 libfunc = unorddf2_libfunc;
3578 break;
3580 default:
3581 break;
3583 else if (mode == XFmode)
3584 switch (comparison)
3586 case EQ:
3587 libfunc = eqxf2_libfunc;
3588 break;
3590 case NE:
3591 libfunc = nexf2_libfunc;
3592 break;
3594 case GT:
3595 libfunc = gtxf2_libfunc;
3596 if (libfunc == NULL_RTX)
3598 tmp = x; x = y; y = tmp;
3599 *pcomparison = LT;
3600 libfunc = ltxf2_libfunc;
3602 break;
3604 case GE:
3605 libfunc = gexf2_libfunc;
3606 if (libfunc == NULL_RTX)
3608 tmp = x; x = y; y = tmp;
3609 *pcomparison = LE;
3610 libfunc = lexf2_libfunc;
3612 break;
3614 case LT:
3615 libfunc = ltxf2_libfunc;
3616 if (libfunc == NULL_RTX)
3618 tmp = x; x = y; y = tmp;
3619 *pcomparison = GT;
3620 libfunc = gtxf2_libfunc;
3622 break;
3624 case LE:
3625 libfunc = lexf2_libfunc;
3626 if (libfunc == NULL_RTX)
3628 tmp = x; x = y; y = tmp;
3629 *pcomparison = GE;
3630 libfunc = gexf2_libfunc;
3632 break;
3634 case UNORDERED:
3635 libfunc = unordxf2_libfunc;
3636 break;
3638 default:
3639 break;
3641 else if (mode == TFmode)
3642 switch (comparison)
3644 case EQ:
3645 libfunc = eqtf2_libfunc;
3646 break;
3648 case NE:
3649 libfunc = netf2_libfunc;
3650 break;
3652 case GT:
3653 libfunc = gttf2_libfunc;
3654 if (libfunc == NULL_RTX)
3656 tmp = x; x = y; y = tmp;
3657 *pcomparison = LT;
3658 libfunc = lttf2_libfunc;
3660 break;
3662 case GE:
3663 libfunc = getf2_libfunc;
3664 if (libfunc == NULL_RTX)
3666 tmp = x; x = y; y = tmp;
3667 *pcomparison = LE;
3668 libfunc = letf2_libfunc;
3670 break;
3672 case LT:
3673 libfunc = lttf2_libfunc;
3674 if (libfunc == NULL_RTX)
3676 tmp = x; x = y; y = tmp;
3677 *pcomparison = GT;
3678 libfunc = gttf2_libfunc;
3680 break;
3682 case LE:
3683 libfunc = letf2_libfunc;
3684 if (libfunc == NULL_RTX)
3686 tmp = x; x = y; y = tmp;
3687 *pcomparison = GE;
3688 libfunc = getf2_libfunc;
3690 break;
3692 case UNORDERED:
3693 libfunc = unordtf2_libfunc;
3694 break;
3696 default:
3697 break;
3699 else
3701 enum machine_mode wider_mode;
3703 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3704 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3706 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3707 != CODE_FOR_nothing)
3708 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3710 x = protect_from_queue (x, 0);
3711 y = protect_from_queue (y, 0);
3712 *px = convert_to_mode (wider_mode, x, 0);
3713 *py = convert_to_mode (wider_mode, y, 0);
3714 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3715 return;
3718 abort ();
3721 if (libfunc == 0)
3722 abort ();
3724 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
3725 mode);
3727 /* Immediately move the result of the libcall into a pseudo
3728 register so reload doesn't clobber the value if it needs
3729 the return register for a spill reg. */
3730 result = gen_reg_rtx (word_mode);
3731 emit_move_insn (result, hard_libcall_value (word_mode));
3732 *px = result;
3733 *py = const0_rtx;
3734 *pmode = word_mode;
3735 if (comparison == UNORDERED)
3736 *pcomparison = NE;
3737 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3738 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3739 *pcomparison = NE;
3740 #endif
3741 *punsignedp = 0;
3744 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3746 void
3747 emit_indirect_jump (loc)
3748 rtx loc;
3750 if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
3751 (loc, Pmode)))
3752 loc = copy_to_mode_reg (Pmode, loc);
3754 emit_jump_insn (gen_indirect_jump (loc));
3755 emit_barrier ();
3758 #ifdef HAVE_conditional_move
3760 /* Emit a conditional move instruction if the machine supports one for that
3761 condition and machine mode.
3763 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3764 the mode to use should they be constants. If it is VOIDmode, they cannot
3765 both be constants.
3767 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3768 should be stored there. MODE is the mode to use should they be constants.
3769 If it is VOIDmode, they cannot both be constants.
3771 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3772 is not supported. */
3775 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3776 unsignedp)
3777 rtx target;
3778 enum rtx_code code;
3779 rtx op0, op1;
3780 enum machine_mode cmode;
3781 rtx op2, op3;
3782 enum machine_mode mode;
3783 int unsignedp;
3785 rtx tem, subtarget, comparison, insn;
3786 enum insn_code icode;
3787 enum rtx_code reversed;
3789 /* If one operand is constant, make it the second one. Only do this
3790 if the other operand is not constant as well. */
3792 if (swap_commutative_operands_p (op0, op1))
3794 tem = op0;
3795 op0 = op1;
3796 op1 = tem;
3797 code = swap_condition (code);
3800 /* get_condition will prefer to generate LT and GT even if the old
3801 comparison was against zero, so undo that canonicalization here since
3802 comparisons against zero are cheaper. */
3803 if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
3804 code = LE, op1 = const0_rtx;
3805 else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
3806 code = GE, op1 = const0_rtx;
3808 if (cmode == VOIDmode)
3809 cmode = GET_MODE (op0);
3811 if (swap_commutative_operands_p (op2, op3)
3812 && ((reversed = reversed_comparison_code_parts (code, op0, op1, NULL))
3813 != UNKNOWN))
3815 tem = op2;
3816 op2 = op3;
3817 op3 = tem;
3818 code = reversed;
3821 if (mode == VOIDmode)
3822 mode = GET_MODE (op2);
3824 icode = movcc_gen_code[mode];
3826 if (icode == CODE_FOR_nothing)
3827 return 0;
3829 if (flag_force_mem)
3831 op2 = force_not_mem (op2);
3832 op3 = force_not_mem (op3);
3835 if (target)
3836 target = protect_from_queue (target, 1);
3837 else
3838 target = gen_reg_rtx (mode);
3840 subtarget = target;
3842 emit_queue ();
3844 op2 = protect_from_queue (op2, 0);
3845 op3 = protect_from_queue (op3, 0);
3847 /* If the insn doesn't accept these operands, put them in pseudos. */
3849 if (! (*insn_data[icode].operand[0].predicate)
3850 (subtarget, insn_data[icode].operand[0].mode))
3851 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3853 if (! (*insn_data[icode].operand[2].predicate)
3854 (op2, insn_data[icode].operand[2].mode))
3855 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3857 if (! (*insn_data[icode].operand[3].predicate)
3858 (op3, insn_data[icode].operand[3].mode))
3859 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3861 /* Everything should now be in the suitable form, so emit the compare insn
3862 and then the conditional move. */
3864 comparison
3865 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX);
3867 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3868 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3869 return NULL and let the caller figure out how best to deal with this
3870 situation. */
3871 if (GET_CODE (comparison) != code)
3872 return NULL_RTX;
3874 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3876 /* If that failed, then give up. */
3877 if (insn == 0)
3878 return 0;
3880 emit_insn (insn);
3882 if (subtarget != target)
3883 convert_move (target, subtarget, 0);
3885 return target;
3888 /* Return non-zero if a conditional move of mode MODE is supported.
3890 This function is for combine so it can tell whether an insn that looks
3891 like a conditional move is actually supported by the hardware. If we
3892 guess wrong we lose a bit on optimization, but that's it. */
3893 /* ??? sparc64 supports conditionally moving integers values based on fp
3894 comparisons, and vice versa. How do we handle them? */
3897 can_conditionally_move_p (mode)
3898 enum machine_mode mode;
3900 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3901 return 1;
3903 return 0;
3906 #endif /* HAVE_conditional_move */
3908 /* These functions generate an insn body and return it
3909 rather than emitting the insn.
3911 They do not protect from queued increments,
3912 because they may be used 1) in protect_from_queue itself
3913 and 2) in other passes where there is no queue. */
3915 /* Generate and return an insn body to add Y to X. */
3918 gen_add2_insn (x, y)
3919 rtx x, y;
3921 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3923 if (! ((*insn_data[icode].operand[0].predicate)
3924 (x, insn_data[icode].operand[0].mode))
3925 || ! ((*insn_data[icode].operand[1].predicate)
3926 (x, insn_data[icode].operand[1].mode))
3927 || ! ((*insn_data[icode].operand[2].predicate)
3928 (y, insn_data[icode].operand[2].mode)))
3929 abort ();
3931 return (GEN_FCN (icode) (x, x, y));
3934 /* Generate and return an insn body to add r1 and c,
3935 storing the result in r0. */
3937 gen_add3_insn (r0, r1, c)
3938 rtx r0, r1, c;
3940 int icode = (int) add_optab->handlers[(int) GET_MODE (r0)].insn_code;
3942 if (icode == CODE_FOR_nothing
3943 || ! ((*insn_data[icode].operand[0].predicate)
3944 (r0, insn_data[icode].operand[0].mode))
3945 || ! ((*insn_data[icode].operand[1].predicate)
3946 (r1, insn_data[icode].operand[1].mode))
3947 || ! ((*insn_data[icode].operand[2].predicate)
3948 (c, insn_data[icode].operand[2].mode)))
3949 return NULL_RTX;
3951 return (GEN_FCN (icode) (r0, r1, c));
3955 have_add2_insn (x, y)
3956 rtx x, y;
3958 int icode;
3960 if (GET_MODE (x) == VOIDmode)
3961 abort ();
3963 icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3965 if (icode == CODE_FOR_nothing)
3966 return 0;
3968 if (! ((*insn_data[icode].operand[0].predicate)
3969 (x, insn_data[icode].operand[0].mode))
3970 || ! ((*insn_data[icode].operand[1].predicate)
3971 (x, insn_data[icode].operand[1].mode))
3972 || ! ((*insn_data[icode].operand[2].predicate)
3973 (y, insn_data[icode].operand[2].mode)))
3974 return 0;
3976 return 1;
3979 /* Generate and return an insn body to subtract Y from X. */
3982 gen_sub2_insn (x, y)
3983 rtx x, y;
3985 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3987 if (! ((*insn_data[icode].operand[0].predicate)
3988 (x, insn_data[icode].operand[0].mode))
3989 || ! ((*insn_data[icode].operand[1].predicate)
3990 (x, insn_data[icode].operand[1].mode))
3991 || ! ((*insn_data[icode].operand[2].predicate)
3992 (y, insn_data[icode].operand[2].mode)))
3993 abort ();
3995 return (GEN_FCN (icode) (x, x, y));
3998 /* Generate and return an insn body to subtract r1 and c,
3999 storing the result in r0. */
4001 gen_sub3_insn (r0, r1, c)
4002 rtx r0, r1, c;
4004 int icode = (int) sub_optab->handlers[(int) GET_MODE (r0)].insn_code;
4006 if (icode == CODE_FOR_nothing
4007 || ! ((*insn_data[icode].operand[0].predicate)
4008 (r0, insn_data[icode].operand[0].mode))
4009 || ! ((*insn_data[icode].operand[1].predicate)
4010 (r1, insn_data[icode].operand[1].mode))
4011 || ! ((*insn_data[icode].operand[2].predicate)
4012 (c, insn_data[icode].operand[2].mode)))
4013 return NULL_RTX;
4015 return (GEN_FCN (icode) (r0, r1, c));
4019 have_sub2_insn (x, y)
4020 rtx x, y;
4022 int icode;
4024 if (GET_MODE (x) == VOIDmode)
4025 abort ();
4027 icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
4029 if (icode == CODE_FOR_nothing)
4030 return 0;
4032 if (! ((*insn_data[icode].operand[0].predicate)
4033 (x, insn_data[icode].operand[0].mode))
4034 || ! ((*insn_data[icode].operand[1].predicate)
4035 (x, insn_data[icode].operand[1].mode))
4036 || ! ((*insn_data[icode].operand[2].predicate)
4037 (y, insn_data[icode].operand[2].mode)))
4038 return 0;
4040 return 1;
4043 /* Generate the body of an instruction to copy Y into X.
4044 It may be a SEQUENCE, if one insn isn't enough. */
4047 gen_move_insn (x, y)
4048 rtx x, y;
4050 enum machine_mode mode = GET_MODE (x);
4051 enum insn_code insn_code;
4052 rtx seq;
4054 if (mode == VOIDmode)
4055 mode = GET_MODE (y);
4057 insn_code = mov_optab->handlers[(int) mode].insn_code;
4059 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
4060 find a mode to do it in. If we have a movcc, use it. Otherwise,
4061 find the MODE_INT mode of the same width. */
4063 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
4065 enum machine_mode tmode = VOIDmode;
4066 rtx x1 = x, y1 = y;
4068 if (mode != CCmode
4069 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
4070 tmode = CCmode;
4071 else
4072 for (tmode = QImode; tmode != VOIDmode;
4073 tmode = GET_MODE_WIDER_MODE (tmode))
4074 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
4075 break;
4077 if (tmode == VOIDmode)
4078 abort ();
4080 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
4081 may call change_address which is not appropriate if we were
4082 called when a reload was in progress. We don't have to worry
4083 about changing the address since the size in bytes is supposed to
4084 be the same. Copy the MEM to change the mode and move any
4085 substitutions from the old MEM to the new one. */
4087 if (reload_in_progress)
4089 x = gen_lowpart_common (tmode, x1);
4090 if (x == 0 && GET_CODE (x1) == MEM)
4092 x = adjust_address_nv (x1, tmode, 0);
4093 copy_replacements (x1, x);
4096 y = gen_lowpart_common (tmode, y1);
4097 if (y == 0 && GET_CODE (y1) == MEM)
4099 y = adjust_address_nv (y1, tmode, 0);
4100 copy_replacements (y1, y);
4103 else
4105 x = gen_lowpart (tmode, x);
4106 y = gen_lowpart (tmode, y);
4109 insn_code = mov_optab->handlers[(int) tmode].insn_code;
4110 return (GEN_FCN (insn_code) (x, y));
4113 start_sequence ();
4114 emit_move_insn_1 (x, y);
4115 seq = gen_sequence ();
4116 end_sequence ();
4117 return seq;
4120 /* Return the insn code used to extend FROM_MODE to TO_MODE.
4121 UNSIGNEDP specifies zero-extension instead of sign-extension. If
4122 no such operation exists, CODE_FOR_nothing will be returned. */
4124 enum insn_code
4125 can_extend_p (to_mode, from_mode, unsignedp)
4126 enum machine_mode to_mode, from_mode;
4127 int unsignedp;
4129 #ifdef HAVE_ptr_extend
4130 if (unsignedp < 0)
4131 return CODE_FOR_ptr_extend;
4132 else
4133 #endif
4134 return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
4137 /* Generate the body of an insn to extend Y (with mode MFROM)
4138 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
4141 gen_extend_insn (x, y, mto, mfrom, unsignedp)
4142 rtx x, y;
4143 enum machine_mode mto, mfrom;
4144 int unsignedp;
4146 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
4149 /* can_fix_p and can_float_p say whether the target machine
4150 can directly convert a given fixed point type to
4151 a given floating point type, or vice versa.
4152 The returned value is the CODE_FOR_... value to use,
4153 or CODE_FOR_nothing if these modes cannot be directly converted.
4155 *TRUNCP_PTR is set to 1 if it is necessary to output
4156 an explicit FTRUNC insn before the fix insn; otherwise 0. */
4158 static enum insn_code
4159 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
4160 enum machine_mode fltmode, fixmode;
4161 int unsignedp;
4162 int *truncp_ptr;
4164 *truncp_ptr = 0;
4165 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
4166 != CODE_FOR_nothing)
4167 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
4169 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
4171 *truncp_ptr = 1;
4172 return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
4174 return CODE_FOR_nothing;
4177 static enum insn_code
4178 can_float_p (fltmode, fixmode, unsignedp)
4179 enum machine_mode fixmode, fltmode;
4180 int unsignedp;
4182 return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
4185 /* Generate code to convert FROM to floating point
4186 and store in TO. FROM must be fixed point and not VOIDmode.
4187 UNSIGNEDP nonzero means regard FROM as unsigned.
4188 Normally this is done by correcting the final value
4189 if it is negative. */
4191 void
4192 expand_float (to, from, unsignedp)
4193 rtx to, from;
4194 int unsignedp;
4196 enum insn_code icode;
4197 rtx target = to;
4198 enum machine_mode fmode, imode;
4200 /* Crash now, because we won't be able to decide which mode to use. */
4201 if (GET_MODE (from) == VOIDmode)
4202 abort ();
4204 /* Look for an insn to do the conversion. Do it in the specified
4205 modes if possible; otherwise convert either input, output or both to
4206 wider mode. If the integer mode is wider than the mode of FROM,
4207 we can do the conversion signed even if the input is unsigned. */
4209 for (imode = GET_MODE (from); imode != VOIDmode;
4210 imode = GET_MODE_WIDER_MODE (imode))
4211 for (fmode = GET_MODE (to); fmode != VOIDmode;
4212 fmode = GET_MODE_WIDER_MODE (fmode))
4214 int doing_unsigned = unsignedp;
4216 if (fmode != GET_MODE (to)
4217 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
4218 continue;
4220 icode = can_float_p (fmode, imode, unsignedp);
4221 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
4222 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
4224 if (icode != CODE_FOR_nothing)
4226 to = protect_from_queue (to, 1);
4227 from = protect_from_queue (from, 0);
4229 if (imode != GET_MODE (from))
4230 from = convert_to_mode (imode, from, unsignedp);
4232 if (fmode != GET_MODE (to))
4233 target = gen_reg_rtx (fmode);
4235 emit_unop_insn (icode, target, from,
4236 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
4238 if (target != to)
4239 convert_move (to, target, 0);
4240 return;
4244 /* Unsigned integer, and no way to convert directly.
4245 Convert as signed, then conditionally adjust the result. */
4246 if (unsignedp)
4248 rtx label = gen_label_rtx ();
4249 rtx temp;
4250 REAL_VALUE_TYPE offset;
4252 emit_queue ();
4254 to = protect_from_queue (to, 1);
4255 from = protect_from_queue (from, 0);
4257 if (flag_force_mem)
4258 from = force_not_mem (from);
4260 /* Look for a usable floating mode FMODE wider than the source and at
4261 least as wide as the target. Using FMODE will avoid rounding woes
4262 with unsigned values greater than the signed maximum value. */
4264 for (fmode = GET_MODE (to); fmode != VOIDmode;
4265 fmode = GET_MODE_WIDER_MODE (fmode))
4266 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4267 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4268 break;
4270 if (fmode == VOIDmode)
4272 /* There is no such mode. Pretend the target is wide enough. */
4273 fmode = GET_MODE (to);
4275 /* Avoid double-rounding when TO is narrower than FROM. */
4276 if ((significand_size (fmode) + 1)
4277 < GET_MODE_BITSIZE (GET_MODE (from)))
4279 rtx temp1;
4280 rtx neglabel = gen_label_rtx ();
4282 /* Don't use TARGET if it isn't a register, is a hard register,
4283 or is the wrong mode. */
4284 if (GET_CODE (target) != REG
4285 || REGNO (target) < FIRST_PSEUDO_REGISTER
4286 || GET_MODE (target) != fmode)
4287 target = gen_reg_rtx (fmode);
4289 imode = GET_MODE (from);
4290 do_pending_stack_adjust ();
4292 /* Test whether the sign bit is set. */
4293 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4294 0, neglabel);
4296 /* The sign bit is not set. Convert as signed. */
4297 expand_float (target, from, 0);
4298 emit_jump_insn (gen_jump (label));
4299 emit_barrier ();
4301 /* The sign bit is set.
4302 Convert to a usable (positive signed) value by shifting right
4303 one bit, while remembering if a nonzero bit was shifted
4304 out; i.e., compute (from & 1) | (from >> 1). */
4306 emit_label (neglabel);
4307 temp = expand_binop (imode, and_optab, from, const1_rtx,
4308 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4309 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4310 NULL_RTX, 1);
4311 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4312 OPTAB_LIB_WIDEN);
4313 expand_float (target, temp, 0);
4315 /* Multiply by 2 to undo the shift above. */
4316 temp = expand_binop (fmode, add_optab, target, target,
4317 target, 0, OPTAB_LIB_WIDEN);
4318 if (temp != target)
4319 emit_move_insn (target, temp);
4321 do_pending_stack_adjust ();
4322 emit_label (label);
4323 goto done;
4327 /* If we are about to do some arithmetic to correct for an
4328 unsigned operand, do it in a pseudo-register. */
4330 if (GET_MODE (to) != fmode
4331 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4332 target = gen_reg_rtx (fmode);
4334 /* Convert as signed integer to floating. */
4335 expand_float (target, from, 0);
4337 /* If FROM is negative (and therefore TO is negative),
4338 correct its value by 2**bitwidth. */
4340 do_pending_stack_adjust ();
4341 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4342 0, label);
4344 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4345 Rather than setting up a dconst_dot_5, let's hope SCO
4346 fixes the bug. */
4347 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4348 temp = expand_binop (fmode, add_optab, target,
4349 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4350 target, 0, OPTAB_LIB_WIDEN);
4351 if (temp != target)
4352 emit_move_insn (target, temp);
4354 do_pending_stack_adjust ();
4355 emit_label (label);
4356 goto done;
4359 /* No hardware instruction available; call a library routine to convert from
4360 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4362 rtx libfcn;
4363 rtx insns;
4364 rtx value;
4366 to = protect_from_queue (to, 1);
4367 from = protect_from_queue (from, 0);
4369 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4370 from = convert_to_mode (SImode, from, unsignedp);
4372 if (flag_force_mem)
4373 from = force_not_mem (from);
4375 if (GET_MODE (to) == SFmode)
4377 if (GET_MODE (from) == SImode)
4378 libfcn = floatsisf_libfunc;
4379 else if (GET_MODE (from) == DImode)
4380 libfcn = floatdisf_libfunc;
4381 else if (GET_MODE (from) == TImode)
4382 libfcn = floattisf_libfunc;
4383 else
4384 abort ();
4386 else if (GET_MODE (to) == DFmode)
4388 if (GET_MODE (from) == SImode)
4389 libfcn = floatsidf_libfunc;
4390 else if (GET_MODE (from) == DImode)
4391 libfcn = floatdidf_libfunc;
4392 else if (GET_MODE (from) == TImode)
4393 libfcn = floattidf_libfunc;
4394 else
4395 abort ();
4397 else if (GET_MODE (to) == XFmode)
4399 if (GET_MODE (from) == SImode)
4400 libfcn = floatsixf_libfunc;
4401 else if (GET_MODE (from) == DImode)
4402 libfcn = floatdixf_libfunc;
4403 else if (GET_MODE (from) == TImode)
4404 libfcn = floattixf_libfunc;
4405 else
4406 abort ();
4408 else if (GET_MODE (to) == TFmode)
4410 if (GET_MODE (from) == SImode)
4411 libfcn = floatsitf_libfunc;
4412 else if (GET_MODE (from) == DImode)
4413 libfcn = floatditf_libfunc;
4414 else if (GET_MODE (from) == TImode)
4415 libfcn = floattitf_libfunc;
4416 else
4417 abort ();
4419 else
4420 abort ();
4422 start_sequence ();
4424 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4425 GET_MODE (to), 1, from,
4426 GET_MODE (from));
4427 insns = get_insns ();
4428 end_sequence ();
4430 emit_libcall_block (insns, target, value,
4431 gen_rtx_FLOAT (GET_MODE (to), from));
4434 done:
4436 /* Copy result to requested destination
4437 if we have been computing in a temp location. */
4439 if (target != to)
4441 if (GET_MODE (target) == GET_MODE (to))
4442 emit_move_insn (to, target);
4443 else
4444 convert_move (to, target, 0);
4448 /* expand_fix: generate code to convert FROM to fixed point
4449 and store in TO. FROM must be floating point. */
4451 static rtx
4452 ftruncify (x)
4453 rtx x;
4455 rtx temp = gen_reg_rtx (GET_MODE (x));
4456 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4459 void
4460 expand_fix (to, from, unsignedp)
4461 rtx to, from;
4462 int unsignedp;
4464 enum insn_code icode;
4465 rtx target = to;
4466 enum machine_mode fmode, imode;
4467 int must_trunc = 0;
4468 rtx libfcn = 0;
4470 /* We first try to find a pair of modes, one real and one integer, at
4471 least as wide as FROM and TO, respectively, in which we can open-code
4472 this conversion. If the integer mode is wider than the mode of TO,
4473 we can do the conversion either signed or unsigned. */
4475 for (fmode = GET_MODE (from); fmode != VOIDmode;
4476 fmode = GET_MODE_WIDER_MODE (fmode))
4477 for (imode = GET_MODE (to); imode != VOIDmode;
4478 imode = GET_MODE_WIDER_MODE (imode))
4480 int doing_unsigned = unsignedp;
4482 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4483 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4484 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4486 if (icode != CODE_FOR_nothing)
4488 to = protect_from_queue (to, 1);
4489 from = protect_from_queue (from, 0);
4491 if (fmode != GET_MODE (from))
4492 from = convert_to_mode (fmode, from, 0);
4494 if (must_trunc)
4495 from = ftruncify (from);
4497 if (imode != GET_MODE (to))
4498 target = gen_reg_rtx (imode);
4500 emit_unop_insn (icode, target, from,
4501 doing_unsigned ? UNSIGNED_FIX : FIX);
4502 if (target != to)
4503 convert_move (to, target, unsignedp);
4504 return;
4508 /* For an unsigned conversion, there is one more way to do it.
4509 If we have a signed conversion, we generate code that compares
4510 the real value to the largest representable positive number. If if
4511 is smaller, the conversion is done normally. Otherwise, subtract
4512 one plus the highest signed number, convert, and add it back.
4514 We only need to check all real modes, since we know we didn't find
4515 anything with a wider integer mode. */
4517 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4518 for (fmode = GET_MODE (from); fmode != VOIDmode;
4519 fmode = GET_MODE_WIDER_MODE (fmode))
4520 /* Make sure we won't lose significant bits doing this. */
4521 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4522 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4523 &must_trunc))
4525 int bitsize;
4526 REAL_VALUE_TYPE offset;
4527 rtx limit, lab1, lab2, insn;
4529 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4530 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4531 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4532 lab1 = gen_label_rtx ();
4533 lab2 = gen_label_rtx ();
4535 emit_queue ();
4536 to = protect_from_queue (to, 1);
4537 from = protect_from_queue (from, 0);
4539 if (flag_force_mem)
4540 from = force_not_mem (from);
4542 if (fmode != GET_MODE (from))
4543 from = convert_to_mode (fmode, from, 0);
4545 /* See if we need to do the subtraction. */
4546 do_pending_stack_adjust ();
4547 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4548 0, lab1);
4550 /* If not, do the signed "fix" and branch around fixup code. */
4551 expand_fix (to, from, 0);
4552 emit_jump_insn (gen_jump (lab2));
4553 emit_barrier ();
4555 /* Otherwise, subtract 2**(N-1), convert to signed number,
4556 then add 2**(N-1). Do the addition using XOR since this
4557 will often generate better code. */
4558 emit_label (lab1);
4559 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4560 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4561 expand_fix (to, target, 0);
4562 target = expand_binop (GET_MODE (to), xor_optab, to,
4563 GEN_INT (trunc_int_for_mode
4564 ((HOST_WIDE_INT) 1 << (bitsize - 1),
4565 GET_MODE (to))),
4566 to, 1, OPTAB_LIB_WIDEN);
4568 if (target != to)
4569 emit_move_insn (to, target);
4571 emit_label (lab2);
4573 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4574 != CODE_FOR_nothing)
4576 /* Make a place for a REG_NOTE and add it. */
4577 insn = emit_move_insn (to, to);
4578 set_unique_reg_note (insn,
4579 REG_EQUAL,
4580 gen_rtx_fmt_e (UNSIGNED_FIX,
4581 GET_MODE (to),
4582 copy_rtx (from)));
4585 return;
4588 /* We can't do it with an insn, so use a library call. But first ensure
4589 that the mode of TO is at least as wide as SImode, since those are the
4590 only library calls we know about. */
4592 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4594 target = gen_reg_rtx (SImode);
4596 expand_fix (target, from, unsignedp);
4598 else if (GET_MODE (from) == SFmode)
4600 if (GET_MODE (to) == SImode)
4601 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4602 else if (GET_MODE (to) == DImode)
4603 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4604 else if (GET_MODE (to) == TImode)
4605 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4606 else
4607 abort ();
4609 else if (GET_MODE (from) == DFmode)
4611 if (GET_MODE (to) == SImode)
4612 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4613 else if (GET_MODE (to) == DImode)
4614 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4615 else if (GET_MODE (to) == TImode)
4616 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4617 else
4618 abort ();
4620 else if (GET_MODE (from) == XFmode)
4622 if (GET_MODE (to) == SImode)
4623 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4624 else if (GET_MODE (to) == DImode)
4625 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4626 else if (GET_MODE (to) == TImode)
4627 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4628 else
4629 abort ();
4631 else if (GET_MODE (from) == TFmode)
4633 if (GET_MODE (to) == SImode)
4634 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4635 else if (GET_MODE (to) == DImode)
4636 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4637 else if (GET_MODE (to) == TImode)
4638 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4639 else
4640 abort ();
4642 else
4643 abort ();
4645 if (libfcn)
4647 rtx insns;
4648 rtx value;
4650 to = protect_from_queue (to, 1);
4651 from = protect_from_queue (from, 0);
4653 if (flag_force_mem)
4654 from = force_not_mem (from);
4656 start_sequence ();
4658 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4659 GET_MODE (to), 1, from,
4660 GET_MODE (from));
4661 insns = get_insns ();
4662 end_sequence ();
4664 emit_libcall_block (insns, target, value,
4665 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4666 GET_MODE (to), from));
4669 if (target != to)
4671 if (GET_MODE (to) == GET_MODE (target))
4672 emit_move_insn (to, target);
4673 else
4674 convert_move (to, target, 0);
4678 /* Report whether we have an instruction to perform the operation
4679 specified by CODE on operands of mode MODE. */
4681 have_insn_for (code, mode)
4682 enum rtx_code code;
4683 enum machine_mode mode;
4685 return (code_to_optab[(int) code] != 0
4686 && (code_to_optab[(int) code]->handlers[(int) mode].insn_code
4687 != CODE_FOR_nothing));
4690 /* Create a blank optab. */
4691 static optab
4692 new_optab ()
4694 int i;
4695 optab op = (optab) xmalloc (sizeof (struct optab));
4696 for (i = 0; i < NUM_MACHINE_MODES; i++)
4698 op->handlers[i].insn_code = CODE_FOR_nothing;
4699 op->handlers[i].libfunc = 0;
4702 return op;
4705 /* Same, but fill in its code as CODE, and write it into the
4706 code_to_optab table. */
4707 static inline optab
4708 init_optab (code)
4709 enum rtx_code code;
4711 optab op = new_optab ();
4712 op->code = code;
4713 code_to_optab[(int) code] = op;
4714 return op;
4717 /* Same, but fill in its code as CODE, and do _not_ write it into
4718 the code_to_optab table. */
4719 static inline optab
4720 init_optabv (code)
4721 enum rtx_code code;
4723 optab op = new_optab ();
4724 op->code = code;
4725 return op;
4728 /* Initialize the libfunc fields of an entire group of entries in some
4729 optab. Each entry is set equal to a string consisting of a leading
4730 pair of underscores followed by a generic operation name followed by
4731 a mode name (downshifted to lower case) followed by a single character
4732 representing the number of operands for the given operation (which is
4733 usually one of the characters '2', '3', or '4').
4735 OPTABLE is the table in which libfunc fields are to be initialized.
4736 FIRST_MODE is the first machine mode index in the given optab to
4737 initialize.
4738 LAST_MODE is the last machine mode index in the given optab to
4739 initialize.
4740 OPNAME is the generic (string) name of the operation.
4741 SUFFIX is the character which specifies the number of operands for
4742 the given generic operation.
4745 static void
4746 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4747 optab optable;
4748 int first_mode;
4749 int last_mode;
4750 const char *opname;
4751 int suffix;
4753 int mode;
4754 unsigned opname_len = strlen (opname);
4756 for (mode = first_mode; (int) mode <= (int) last_mode;
4757 mode = (enum machine_mode) ((int) mode + 1))
4759 const char *mname = GET_MODE_NAME(mode);
4760 unsigned mname_len = strlen (mname);
4761 char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4762 char *p;
4763 const char *q;
4765 p = libfunc_name;
4766 *p++ = '_';
4767 *p++ = '_';
4768 for (q = opname; *q; )
4769 *p++ = *q++;
4770 for (q = mname; *q; q++)
4771 *p++ = TOLOWER (*q);
4772 *p++ = suffix;
4773 *p = '\0';
4775 optable->handlers[(int) mode].libfunc
4776 = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
4777 p - libfunc_name));
4781 /* Initialize the libfunc fields of an entire group of entries in some
4782 optab which correspond to all integer mode operations. The parameters
4783 have the same meaning as similarly named ones for the `init_libfuncs'
4784 routine. (See above). */
4786 static void
4787 init_integral_libfuncs (optable, opname, suffix)
4788 optab optable;
4789 const char *opname;
4790 int suffix;
4792 init_libfuncs (optable, SImode, TImode, opname, suffix);
4795 /* Initialize the libfunc fields of an entire group of entries in some
4796 optab which correspond to all real mode operations. The parameters
4797 have the same meaning as similarly named ones for the `init_libfuncs'
4798 routine. (See above). */
4800 static void
4801 init_floating_libfuncs (optable, opname, suffix)
4802 optab optable;
4803 const char *opname;
4804 int suffix;
4806 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4810 init_one_libfunc (name)
4811 const char *name;
4813 /* Create a FUNCTION_DECL that can be passed to ENCODE_SECTION_INFO. */
4814 /* ??? We don't have any type information except for this is
4815 a function. Pretend this is "int foo()". */
4816 tree decl = build_decl (FUNCTION_DECL, get_identifier (name),
4817 build_function_type (integer_type_node, NULL_TREE));
4818 DECL_ARTIFICIAL (decl) = 1;
4819 DECL_EXTERNAL (decl) = 1;
4820 TREE_PUBLIC (decl) = 1;
4822 /* Return the symbol_ref from the mem rtx. */
4823 return XEXP (DECL_RTL (decl), 0);
4826 /* Mark ARG (which is really an OPTAB *) for GC. */
4828 void
4829 mark_optab (arg)
4830 void *arg;
4832 optab o = *(optab *) arg;
4833 int i;
4835 for (i = 0; i < NUM_MACHINE_MODES; ++i)
4836 ggc_mark_rtx (o->handlers[i].libfunc);
4839 /* Call this once to initialize the contents of the optabs
4840 appropriately for the current target machine. */
4842 void
4843 init_optabs ()
4845 unsigned int i, j, k;
4847 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4849 for (i = 0; i < ARRAY_SIZE (fixtab); i++)
4850 for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
4851 for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
4852 fixtab[i][j][k] = CODE_FOR_nothing;
4854 for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
4855 for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
4856 for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
4857 fixtrunctab[i][j][k] = CODE_FOR_nothing;
4859 for (i = 0; i < ARRAY_SIZE (floattab); i++)
4860 for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
4861 for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
4862 floattab[i][j][k] = CODE_FOR_nothing;
4864 for (i = 0; i < ARRAY_SIZE (extendtab); i++)
4865 for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
4866 for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
4867 extendtab[i][j][k] = CODE_FOR_nothing;
4869 for (i = 0; i < NUM_RTX_CODE; i++)
4870 setcc_gen_code[i] = CODE_FOR_nothing;
4872 #ifdef HAVE_conditional_move
4873 for (i = 0; i < NUM_MACHINE_MODES; i++)
4874 movcc_gen_code[i] = CODE_FOR_nothing;
4875 #endif
4877 add_optab = init_optab (PLUS);
4878 addv_optab = init_optabv (PLUS);
4879 sub_optab = init_optab (MINUS);
4880 subv_optab = init_optabv (MINUS);
4881 smul_optab = init_optab (MULT);
4882 smulv_optab = init_optabv (MULT);
4883 smul_highpart_optab = init_optab (UNKNOWN);
4884 umul_highpart_optab = init_optab (UNKNOWN);
4885 smul_widen_optab = init_optab (UNKNOWN);
4886 umul_widen_optab = init_optab (UNKNOWN);
4887 sdiv_optab = init_optab (DIV);
4888 sdivv_optab = init_optabv (DIV);
4889 sdivmod_optab = init_optab (UNKNOWN);
4890 udiv_optab = init_optab (UDIV);
4891 udivmod_optab = init_optab (UNKNOWN);
4892 smod_optab = init_optab (MOD);
4893 umod_optab = init_optab (UMOD);
4894 ftrunc_optab = init_optab (UNKNOWN);
4895 and_optab = init_optab (AND);
4896 ior_optab = init_optab (IOR);
4897 xor_optab = init_optab (XOR);
4898 ashl_optab = init_optab (ASHIFT);
4899 ashr_optab = init_optab (ASHIFTRT);
4900 lshr_optab = init_optab (LSHIFTRT);
4901 rotl_optab = init_optab (ROTATE);
4902 rotr_optab = init_optab (ROTATERT);
4903 smin_optab = init_optab (SMIN);
4904 smax_optab = init_optab (SMAX);
4905 umin_optab = init_optab (UMIN);
4906 umax_optab = init_optab (UMAX);
4908 /* These three have codes assigned exclusively for the sake of
4909 have_insn_for. */
4910 mov_optab = init_optab (SET);
4911 movstrict_optab = init_optab (STRICT_LOW_PART);
4912 cmp_optab = init_optab (COMPARE);
4914 ucmp_optab = init_optab (UNKNOWN);
4915 tst_optab = init_optab (UNKNOWN);
4916 neg_optab = init_optab (NEG);
4917 negv_optab = init_optabv (NEG);
4918 abs_optab = init_optab (ABS);
4919 absv_optab = init_optabv (ABS);
4920 one_cmpl_optab = init_optab (NOT);
4921 ffs_optab = init_optab (FFS);
4922 sqrt_optab = init_optab (SQRT);
4923 sin_optab = init_optab (UNKNOWN);
4924 cos_optab = init_optab (UNKNOWN);
4925 strlen_optab = init_optab (UNKNOWN);
4926 cbranch_optab = init_optab (UNKNOWN);
4927 cmov_optab = init_optab (UNKNOWN);
4928 cstore_optab = init_optab (UNKNOWN);
4929 push_optab = init_optab (UNKNOWN);
4931 for (i = 0; i < NUM_MACHINE_MODES; i++)
4933 movstr_optab[i] = CODE_FOR_nothing;
4934 clrstr_optab[i] = CODE_FOR_nothing;
4936 #ifdef HAVE_SECONDARY_RELOADS
4937 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4938 #endif
4941 /* Fill in the optabs with the insns we support. */
4942 init_all_optabs ();
4944 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4945 /* This flag says the same insns that convert to a signed fixnum
4946 also convert validly to an unsigned one. */
4947 for (i = 0; i < NUM_MACHINE_MODES; i++)
4948 for (j = 0; j < NUM_MACHINE_MODES; j++)
4949 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4950 #endif
4952 /* Initialize the optabs with the names of the library functions. */
4953 init_integral_libfuncs (add_optab, "add", '3');
4954 init_floating_libfuncs (add_optab, "add", '3');
4955 init_integral_libfuncs (addv_optab, "addv", '3');
4956 init_floating_libfuncs (addv_optab, "add", '3');
4957 init_integral_libfuncs (sub_optab, "sub", '3');
4958 init_floating_libfuncs (sub_optab, "sub", '3');
4959 init_integral_libfuncs (subv_optab, "subv", '3');
4960 init_floating_libfuncs (subv_optab, "sub", '3');
4961 init_integral_libfuncs (smul_optab, "mul", '3');
4962 init_floating_libfuncs (smul_optab, "mul", '3');
4963 init_integral_libfuncs (smulv_optab, "mulv", '3');
4964 init_floating_libfuncs (smulv_optab, "mul", '3');
4965 init_integral_libfuncs (sdiv_optab, "div", '3');
4966 init_floating_libfuncs (sdiv_optab, "div", '3');
4967 init_integral_libfuncs (sdivv_optab, "divv", '3');
4968 init_integral_libfuncs (udiv_optab, "udiv", '3');
4969 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4970 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4971 init_integral_libfuncs (smod_optab, "mod", '3');
4972 init_integral_libfuncs (umod_optab, "umod", '3');
4973 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4974 init_integral_libfuncs (and_optab, "and", '3');
4975 init_integral_libfuncs (ior_optab, "ior", '3');
4976 init_integral_libfuncs (xor_optab, "xor", '3');
4977 init_integral_libfuncs (ashl_optab, "ashl", '3');
4978 init_integral_libfuncs (ashr_optab, "ashr", '3');
4979 init_integral_libfuncs (lshr_optab, "lshr", '3');
4980 init_integral_libfuncs (smin_optab, "min", '3');
4981 init_floating_libfuncs (smin_optab, "min", '3');
4982 init_integral_libfuncs (smax_optab, "max", '3');
4983 init_floating_libfuncs (smax_optab, "max", '3');
4984 init_integral_libfuncs (umin_optab, "umin", '3');
4985 init_integral_libfuncs (umax_optab, "umax", '3');
4986 init_integral_libfuncs (neg_optab, "neg", '2');
4987 init_floating_libfuncs (neg_optab, "neg", '2');
4988 init_integral_libfuncs (negv_optab, "negv", '2');
4989 init_floating_libfuncs (negv_optab, "neg", '2');
4990 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4991 init_integral_libfuncs (ffs_optab, "ffs", '2');
4993 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4994 init_integral_libfuncs (cmp_optab, "cmp", '2');
4995 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4996 init_floating_libfuncs (cmp_optab, "cmp", '2');
4998 #ifdef MULSI3_LIBCALL
4999 smul_optab->handlers[(int) SImode].libfunc
5000 = init_one_libfunc (MULSI3_LIBCALL);
5001 #endif
5002 #ifdef MULDI3_LIBCALL
5003 smul_optab->handlers[(int) DImode].libfunc
5004 = init_one_libfunc (MULDI3_LIBCALL);
5005 #endif
5007 #ifdef DIVSI3_LIBCALL
5008 sdiv_optab->handlers[(int) SImode].libfunc
5009 = init_one_libfunc (DIVSI3_LIBCALL);
5010 #endif
5011 #ifdef DIVDI3_LIBCALL
5012 sdiv_optab->handlers[(int) DImode].libfunc
5013 = init_one_libfunc (DIVDI3_LIBCALL);
5014 #endif
5016 #ifdef UDIVSI3_LIBCALL
5017 udiv_optab->handlers[(int) SImode].libfunc
5018 = init_one_libfunc (UDIVSI3_LIBCALL);
5019 #endif
5020 #ifdef UDIVDI3_LIBCALL
5021 udiv_optab->handlers[(int) DImode].libfunc
5022 = init_one_libfunc (UDIVDI3_LIBCALL);
5023 #endif
5025 #ifdef MODSI3_LIBCALL
5026 smod_optab->handlers[(int) SImode].libfunc
5027 = init_one_libfunc (MODSI3_LIBCALL);
5028 #endif
5029 #ifdef MODDI3_LIBCALL
5030 smod_optab->handlers[(int) DImode].libfunc
5031 = init_one_libfunc (MODDI3_LIBCALL);
5032 #endif
5034 #ifdef UMODSI3_LIBCALL
5035 umod_optab->handlers[(int) SImode].libfunc
5036 = init_one_libfunc (UMODSI3_LIBCALL);
5037 #endif
5038 #ifdef UMODDI3_LIBCALL
5039 umod_optab->handlers[(int) DImode].libfunc
5040 = init_one_libfunc (UMODDI3_LIBCALL);
5041 #endif
5043 /* Use cabs for DC complex abs, since systems generally have cabs.
5044 Don't define any libcall for SCmode, so that cabs will be used. */
5045 abs_optab->handlers[(int) DCmode].libfunc
5046 = init_one_libfunc ("cabs");
5048 /* The ffs function operates on `int'. */
5049 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
5050 = init_one_libfunc ("ffs");
5052 extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
5053 extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
5054 extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
5055 extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
5056 extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
5058 truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
5059 truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
5060 trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
5061 truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
5062 trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
5064 memcpy_libfunc = init_one_libfunc ("memcpy");
5065 memmove_libfunc = init_one_libfunc ("memmove");
5066 bcopy_libfunc = init_one_libfunc ("bcopy");
5067 memcmp_libfunc = init_one_libfunc ("memcmp");
5068 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
5069 memset_libfunc = init_one_libfunc ("memset");
5070 bzero_libfunc = init_one_libfunc ("bzero");
5072 unwind_resume_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
5073 ? "_Unwind_SjLj_Resume"
5074 : "_Unwind_Resume");
5075 #ifndef DONT_USE_BUILTIN_SETJMP
5076 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
5077 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
5078 #else
5079 setjmp_libfunc = init_one_libfunc ("setjmp");
5080 longjmp_libfunc = init_one_libfunc ("longjmp");
5081 #endif
5082 unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
5083 unwind_sjlj_unregister_libfunc
5084 = init_one_libfunc ("_Unwind_SjLj_Unregister");
5086 eqhf2_libfunc = init_one_libfunc ("__eqhf2");
5087 nehf2_libfunc = init_one_libfunc ("__nehf2");
5088 gthf2_libfunc = init_one_libfunc ("__gthf2");
5089 gehf2_libfunc = init_one_libfunc ("__gehf2");
5090 lthf2_libfunc = init_one_libfunc ("__lthf2");
5091 lehf2_libfunc = init_one_libfunc ("__lehf2");
5092 unordhf2_libfunc = init_one_libfunc ("__unordhf2");
5094 eqsf2_libfunc = init_one_libfunc ("__eqsf2");
5095 nesf2_libfunc = init_one_libfunc ("__nesf2");
5096 gtsf2_libfunc = init_one_libfunc ("__gtsf2");
5097 gesf2_libfunc = init_one_libfunc ("__gesf2");
5098 ltsf2_libfunc = init_one_libfunc ("__ltsf2");
5099 lesf2_libfunc = init_one_libfunc ("__lesf2");
5100 unordsf2_libfunc = init_one_libfunc ("__unordsf2");
5102 eqdf2_libfunc = init_one_libfunc ("__eqdf2");
5103 nedf2_libfunc = init_one_libfunc ("__nedf2");
5104 gtdf2_libfunc = init_one_libfunc ("__gtdf2");
5105 gedf2_libfunc = init_one_libfunc ("__gedf2");
5106 ltdf2_libfunc = init_one_libfunc ("__ltdf2");
5107 ledf2_libfunc = init_one_libfunc ("__ledf2");
5108 unorddf2_libfunc = init_one_libfunc ("__unorddf2");
5110 eqxf2_libfunc = init_one_libfunc ("__eqxf2");
5111 nexf2_libfunc = init_one_libfunc ("__nexf2");
5112 gtxf2_libfunc = init_one_libfunc ("__gtxf2");
5113 gexf2_libfunc = init_one_libfunc ("__gexf2");
5114 ltxf2_libfunc = init_one_libfunc ("__ltxf2");
5115 lexf2_libfunc = init_one_libfunc ("__lexf2");
5116 unordxf2_libfunc = init_one_libfunc ("__unordxf2");
5118 eqtf2_libfunc = init_one_libfunc ("__eqtf2");
5119 netf2_libfunc = init_one_libfunc ("__netf2");
5120 gttf2_libfunc = init_one_libfunc ("__gttf2");
5121 getf2_libfunc = init_one_libfunc ("__getf2");
5122 lttf2_libfunc = init_one_libfunc ("__lttf2");
5123 letf2_libfunc = init_one_libfunc ("__letf2");
5124 unordtf2_libfunc = init_one_libfunc ("__unordtf2");
5126 floatsisf_libfunc = init_one_libfunc ("__floatsisf");
5127 floatdisf_libfunc = init_one_libfunc ("__floatdisf");
5128 floattisf_libfunc = init_one_libfunc ("__floattisf");
5130 floatsidf_libfunc = init_one_libfunc ("__floatsidf");
5131 floatdidf_libfunc = init_one_libfunc ("__floatdidf");
5132 floattidf_libfunc = init_one_libfunc ("__floattidf");
5134 floatsixf_libfunc = init_one_libfunc ("__floatsixf");
5135 floatdixf_libfunc = init_one_libfunc ("__floatdixf");
5136 floattixf_libfunc = init_one_libfunc ("__floattixf");
5138 floatsitf_libfunc = init_one_libfunc ("__floatsitf");
5139 floatditf_libfunc = init_one_libfunc ("__floatditf");
5140 floattitf_libfunc = init_one_libfunc ("__floattitf");
5142 fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
5143 fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
5144 fixsfti_libfunc = init_one_libfunc ("__fixsfti");
5146 fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
5147 fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
5148 fixdfti_libfunc = init_one_libfunc ("__fixdfti");
5150 fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
5151 fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
5152 fixxfti_libfunc = init_one_libfunc ("__fixxfti");
5154 fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
5155 fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
5156 fixtfti_libfunc = init_one_libfunc ("__fixtfti");
5158 fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
5159 fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
5160 fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
5162 fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
5163 fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
5164 fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
5166 fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
5167 fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
5168 fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
5170 fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
5171 fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
5172 fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
5174 /* For function entry/exit instrumentation. */
5175 profile_function_entry_libfunc
5176 = init_one_libfunc ("__cyg_profile_func_enter");
5177 profile_function_exit_libfunc
5178 = init_one_libfunc ("__cyg_profile_func_exit");
5180 #ifdef HAVE_conditional_trap
5181 init_traps ();
5182 #endif
5184 #ifdef INIT_TARGET_OPTABS
5185 /* Allow the target to add more libcalls or rename some, etc. */
5186 INIT_TARGET_OPTABS;
5187 #endif
5189 /* Add these GC roots. */
5190 ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
5191 ggc_add_rtx_root (libfunc_table, LTI_MAX);
5194 #ifdef HAVE_conditional_trap
5195 /* The insn generating function can not take an rtx_code argument.
5196 TRAP_RTX is used as an rtx argument. Its code is replaced with
5197 the code to be used in the trap insn and all other fields are
5198 ignored. */
5199 static rtx trap_rtx;
5201 static void
5202 init_traps ()
5204 if (HAVE_conditional_trap)
5206 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
5207 ggc_add_rtx_root (&trap_rtx, 1);
5210 #endif
5212 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
5213 CODE. Return 0 on failure. */
5216 gen_cond_trap (code, op1, op2, tcode)
5217 enum rtx_code code ATTRIBUTE_UNUSED;
5218 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
5220 enum machine_mode mode = GET_MODE (op1);
5222 if (mode == VOIDmode)
5223 return 0;
5225 #ifdef HAVE_conditional_trap
5226 if (HAVE_conditional_trap
5227 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
5229 rtx insn;
5230 start_sequence();
5231 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
5232 PUT_CODE (trap_rtx, code);
5233 insn = gen_conditional_trap (trap_rtx, tcode);
5234 if (insn)
5236 emit_insn (insn);
5237 insn = gen_sequence ();
5239 end_sequence();
5240 return insn;
5242 #endif
5244 return 0;