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