* loop.h (struct movables): Remove `num'.
[official-gcc.git] / gcc / optabs.c
blob4c290dc15f22e8200ba8a67f0403ee84ed0f49d6
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 "insn-flags.h"
35 #include "insn-codes.h"
36 #include "function.h"
37 #include "expr.h"
38 #include "recog.h"
39 #include "reload.h"
40 #include "ggc.h"
41 #include "real.h"
43 /* Each optab contains info on how this target machine
44 can perform a particular operation
45 for all sizes and kinds of operands.
47 The operation to be performed is often specified
48 by passing one of these optabs as an argument.
50 See expr.h for documentation of these optabs. */
52 optab optab_table[OTI_MAX];
54 rtx libfunc_table[LTI_MAX];
56 /* Tables of patterns for extending one integer mode to another. */
57 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
59 /* Tables of patterns for converting between fixed and floating point. */
60 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
61 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
62 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
64 /* Contains the optab used for each rtx code. */
65 optab code_to_optab[NUM_RTX_CODE + 1];
67 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
68 gives the gen_function to make a branch to test that condition. */
70 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
72 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
73 gives the insn code to make a store-condition insn
74 to test that condition. */
76 enum insn_code setcc_gen_code[NUM_RTX_CODE];
78 #ifdef HAVE_conditional_move
79 /* Indexed by the machine mode, gives the insn code to make a conditional
80 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
81 setcc_gen_code to cut down on the number of named patterns. Consider a day
82 when a lot more rtx codes are conditional (eg: for the ARM). */
84 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
85 #endif
87 static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
88 static rtx widen_operand PARAMS ((rtx, enum machine_mode,
89 enum machine_mode, int, int));
90 static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
91 rtx, rtx, enum machine_mode,
92 int, enum optab_methods,
93 enum mode_class, optab));
94 static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
95 rtx, rtx, enum machine_mode,
96 int, enum optab_methods,
97 enum mode_class, optab));
98 static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode,
99 int, int *));
100 static enum insn_code can_float_p PARAMS ((enum machine_mode, enum machine_mode,
101 int));
102 static rtx ftruncify PARAMS ((rtx));
103 static optab init_optab PARAMS ((enum rtx_code));
104 static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
105 static void init_integral_libfuncs PARAMS ((optab, const char *, int));
106 static void init_floating_libfuncs PARAMS ((optab, const char *, int));
107 #ifdef HAVE_conditional_trap
108 static void init_traps PARAMS ((void));
109 #endif
110 static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
111 enum rtx_code, int, rtx));
112 static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
113 enum machine_mode *, int *));
115 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
116 the result of operation CODE applied to OP0 (and OP1 if it is a binary
117 operation).
119 If the last insn does not set TARGET, don't do anything, but return 1.
121 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
122 don't add the REG_EQUAL note but return 0. Our caller can then try
123 again, ensuring that TARGET is not one of the operands. */
125 static int
126 add_equal_note (seq, target, code, op0, op1)
127 rtx seq;
128 rtx target;
129 enum rtx_code code;
130 rtx op0, op1;
132 rtx set;
133 int i;
134 rtx note;
136 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
137 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
138 || GET_CODE (seq) != SEQUENCE
139 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
140 || GET_CODE (target) == ZERO_EXTRACT
141 || (! rtx_equal_p (SET_DEST (set), target)
142 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
143 SUBREG. */
144 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
145 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
146 target))))
147 return 1;
149 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
150 besides the last insn. */
151 if (reg_overlap_mentioned_p (target, op0)
152 || (op1 && reg_overlap_mentioned_p (target, op1)))
153 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
154 if (reg_set_p (target, XVECEXP (seq, 0, i)))
155 return 0;
157 if (GET_RTX_CLASS (code) == '1')
158 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
159 else
160 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
162 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
164 return 1;
167 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
168 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
169 not actually do a sign-extend or zero-extend, but can leave the
170 higher-order bits of the result rtx undefined, for example, in the case
171 of logical operations, but not right shifts. */
173 static rtx
174 widen_operand (op, mode, oldmode, unsignedp, no_extend)
175 rtx op;
176 enum machine_mode mode, oldmode;
177 int unsignedp;
178 int no_extend;
180 rtx result;
182 /* If we must extend do so. If OP is either a constant or a SUBREG
183 for a promoted object, also extend since it will be more efficient to
184 do so. */
185 if (! no_extend
186 || GET_MODE (op) == VOIDmode
187 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
188 return convert_modes (mode, oldmode, op, unsignedp);
190 /* If MODE is no wider than a single word, we return a paradoxical
191 SUBREG. */
192 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
193 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
195 /* Otherwise, get an object of MODE, clobber it, and set the low-order
196 part to OP. */
198 result = gen_reg_rtx (mode);
199 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
200 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
201 return result;
204 /* Generate code to perform a straightforward complex divide. */
206 static int
207 expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
208 unsignedp, methods, class, binoptab)
209 rtx real0, real1, imag0, imag1, realr, imagr;
210 enum machine_mode submode;
211 int unsignedp;
212 enum optab_methods methods;
213 enum mode_class class;
214 optab binoptab;
216 rtx divisor;
217 rtx real_t, imag_t;
218 rtx temp1, temp2;
219 rtx res;
220 optab this_add_optab = add_optab;
221 optab this_sub_optab = sub_optab;
222 optab this_neg_optab = neg_optab;
223 optab this_mul_optab = smul_optab;
225 if (binoptab == sdivv_optab)
227 this_add_optab = addv_optab;
228 this_sub_optab = subv_optab;
229 this_neg_optab = negv_optab;
230 this_mul_optab = smulv_optab;
233 /* Don't fetch these from memory more than once. */
234 real0 = force_reg (submode, real0);
235 real1 = force_reg (submode, real1);
237 if (imag0 != 0)
238 imag0 = force_reg (submode, imag0);
240 imag1 = force_reg (submode, imag1);
242 /* Divisor: c*c + d*d. */
243 temp1 = expand_binop (submode, this_mul_optab, real1, real1,
244 NULL_RTX, unsignedp, methods);
246 temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
247 NULL_RTX, unsignedp, methods);
249 if (temp1 == 0 || temp2 == 0)
250 return 0;
252 divisor = expand_binop (submode, this_add_optab, temp1, temp2,
253 NULL_RTX, unsignedp, methods);
254 if (divisor == 0)
255 return 0;
257 if (imag0 == 0)
259 /* Mathematically, ((a)(c-id))/divisor. */
260 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
262 /* Calculate the dividend. */
263 real_t = expand_binop (submode, this_mul_optab, real0, real1,
264 NULL_RTX, unsignedp, methods);
266 imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
267 NULL_RTX, unsignedp, methods);
269 if (real_t == 0 || imag_t == 0)
270 return 0;
272 imag_t = expand_unop (submode, this_neg_optab, imag_t,
273 NULL_RTX, unsignedp);
275 else
277 /* Mathematically, ((a+ib)(c-id))/divider. */
278 /* Calculate the dividend. */
279 temp1 = expand_binop (submode, this_mul_optab, real0, real1,
280 NULL_RTX, unsignedp, methods);
282 temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
283 NULL_RTX, unsignedp, methods);
285 if (temp1 == 0 || temp2 == 0)
286 return 0;
288 real_t = expand_binop (submode, this_add_optab, temp1, temp2,
289 NULL_RTX, unsignedp, methods);
291 temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
292 NULL_RTX, unsignedp, methods);
294 temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
295 NULL_RTX, unsignedp, methods);
297 if (temp1 == 0 || temp2 == 0)
298 return 0;
300 imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
301 NULL_RTX, unsignedp, methods);
303 if (real_t == 0 || imag_t == 0)
304 return 0;
307 if (class == MODE_COMPLEX_FLOAT)
308 res = expand_binop (submode, binoptab, real_t, divisor,
309 realr, unsignedp, methods);
310 else
311 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
312 real_t, divisor, realr, unsignedp);
314 if (res == 0)
315 return 0;
317 if (res != realr)
318 emit_move_insn (realr, res);
320 if (class == MODE_COMPLEX_FLOAT)
321 res = expand_binop (submode, binoptab, imag_t, divisor,
322 imagr, unsignedp, methods);
323 else
324 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
325 imag_t, divisor, imagr, unsignedp);
327 if (res == 0)
328 return 0;
330 if (res != imagr)
331 emit_move_insn (imagr, res);
333 return 1;
336 /* Generate code to perform a wide-input-range-acceptable complex divide. */
338 static int
339 expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
340 unsignedp, methods, class, binoptab)
341 rtx real0, real1, imag0, imag1, realr, imagr;
342 enum machine_mode submode;
343 int unsignedp;
344 enum optab_methods methods;
345 enum mode_class class;
346 optab binoptab;
348 rtx ratio, divisor;
349 rtx real_t, imag_t;
350 rtx temp1, temp2, lab1, lab2;
351 enum machine_mode mode;
352 int align;
353 rtx res;
354 optab this_add_optab = add_optab;
355 optab this_sub_optab = sub_optab;
356 optab this_neg_optab = neg_optab;
357 optab this_mul_optab = smul_optab;
359 if (binoptab == sdivv_optab)
361 this_add_optab = addv_optab;
362 this_sub_optab = subv_optab;
363 this_neg_optab = negv_optab;
364 this_mul_optab = smulv_optab;
367 /* Don't fetch these from memory more than once. */
368 real0 = force_reg (submode, real0);
369 real1 = force_reg (submode, real1);
371 if (imag0 != 0)
372 imag0 = force_reg (submode, imag0);
374 imag1 = force_reg (submode, imag1);
376 /* XXX What's an "unsigned" complex number? */
377 if (unsignedp)
379 temp1 = real1;
380 temp2 = imag1;
382 else
384 temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
385 temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
388 if (temp1 == 0 || temp2 == 0)
389 return 0;
391 mode = GET_MODE (temp1);
392 align = GET_MODE_ALIGNMENT (mode);
393 lab1 = gen_label_rtx ();
394 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
395 mode, unsignedp, align, lab1);
397 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
399 if (class == MODE_COMPLEX_FLOAT)
400 ratio = expand_binop (submode, binoptab, imag1, real1,
401 NULL_RTX, unsignedp, methods);
402 else
403 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
404 imag1, real1, NULL_RTX, unsignedp);
406 if (ratio == 0)
407 return 0;
409 /* Calculate divisor. */
411 temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
412 NULL_RTX, unsignedp, methods);
414 if (temp1 == 0)
415 return 0;
417 divisor = expand_binop (submode, this_add_optab, temp1, real1,
418 NULL_RTX, unsignedp, methods);
420 if (divisor == 0)
421 return 0;
423 /* Calculate dividend. */
425 if (imag0 == 0)
427 real_t = real0;
429 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
431 imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
432 NULL_RTX, unsignedp, methods);
434 if (imag_t == 0)
435 return 0;
437 imag_t = expand_unop (submode, this_neg_optab, imag_t,
438 NULL_RTX, unsignedp);
440 if (real_t == 0 || imag_t == 0)
441 return 0;
443 else
445 /* Compute (a+ib)/(c+id) as
446 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
448 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
449 NULL_RTX, unsignedp, methods);
451 if (temp1 == 0)
452 return 0;
454 real_t = expand_binop (submode, this_add_optab, temp1, real0,
455 NULL_RTX, unsignedp, methods);
457 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
458 NULL_RTX, unsignedp, methods);
460 if (temp1 == 0)
461 return 0;
463 imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
464 NULL_RTX, unsignedp, methods);
466 if (real_t == 0 || imag_t == 0)
467 return 0;
470 if (class == MODE_COMPLEX_FLOAT)
471 res = expand_binop (submode, binoptab, real_t, divisor,
472 realr, unsignedp, methods);
473 else
474 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
475 real_t, divisor, realr, unsignedp);
477 if (res == 0)
478 return 0;
480 if (res != realr)
481 emit_move_insn (realr, res);
483 if (class == MODE_COMPLEX_FLOAT)
484 res = expand_binop (submode, binoptab, imag_t, divisor,
485 imagr, unsignedp, methods);
486 else
487 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
488 imag_t, divisor, imagr, unsignedp);
490 if (res == 0)
491 return 0;
493 if (res != imagr)
494 emit_move_insn (imagr, res);
496 lab2 = gen_label_rtx ();
497 emit_jump_insn (gen_jump (lab2));
498 emit_barrier ();
500 emit_label (lab1);
502 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
504 if (class == MODE_COMPLEX_FLOAT)
505 ratio = expand_binop (submode, binoptab, real1, imag1,
506 NULL_RTX, unsignedp, methods);
507 else
508 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
509 real1, imag1, NULL_RTX, unsignedp);
511 if (ratio == 0)
512 return 0;
514 /* Calculate divisor. */
516 temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
517 NULL_RTX, unsignedp, methods);
519 if (temp1 == 0)
520 return 0;
522 divisor = expand_binop (submode, this_add_optab, temp1, imag1,
523 NULL_RTX, unsignedp, methods);
525 if (divisor == 0)
526 return 0;
528 /* Calculate dividend. */
530 if (imag0 == 0)
532 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
534 real_t = expand_binop (submode, this_mul_optab, real0, ratio,
535 NULL_RTX, unsignedp, methods);
537 imag_t = expand_unop (submode, this_neg_optab, real0,
538 NULL_RTX, unsignedp);
540 if (real_t == 0 || imag_t == 0)
541 return 0;
543 else
545 /* Compute (a+ib)/(c+id) as
546 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
548 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
549 NULL_RTX, unsignedp, methods);
551 if (temp1 == 0)
552 return 0;
554 real_t = expand_binop (submode, this_add_optab, temp1, imag0,
555 NULL_RTX, unsignedp, methods);
557 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
558 NULL_RTX, unsignedp, methods);
560 if (temp1 == 0)
561 return 0;
563 imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
564 NULL_RTX, unsignedp, methods);
566 if (real_t == 0 || imag_t == 0)
567 return 0;
570 if (class == MODE_COMPLEX_FLOAT)
571 res = expand_binop (submode, binoptab, real_t, divisor,
572 realr, unsignedp, methods);
573 else
574 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
575 real_t, divisor, realr, unsignedp);
577 if (res == 0)
578 return 0;
580 if (res != realr)
581 emit_move_insn (realr, res);
583 if (class == MODE_COMPLEX_FLOAT)
584 res = expand_binop (submode, binoptab, imag_t, divisor,
585 imagr, unsignedp, methods);
586 else
587 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
588 imag_t, divisor, imagr, unsignedp);
590 if (res == 0)
591 return 0;
593 if (res != imagr)
594 emit_move_insn (imagr, res);
596 emit_label (lab2);
598 return 1;
601 /* Generate code to perform an operation specified by BINOPTAB
602 on operands OP0 and OP1, with result having machine-mode MODE.
604 UNSIGNEDP is for the case where we have to widen the operands
605 to perform the operation. It says to use zero-extension.
607 If TARGET is nonzero, the value
608 is generated there, if it is convenient to do so.
609 In all cases an rtx is returned for the locus of the value;
610 this may or may not be TARGET. */
613 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
614 enum machine_mode mode;
615 optab binoptab;
616 rtx op0, op1;
617 rtx target;
618 int unsignedp;
619 enum optab_methods methods;
621 enum optab_methods next_methods
622 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
623 ? OPTAB_WIDEN : methods);
624 enum mode_class class;
625 enum machine_mode wider_mode;
626 register rtx temp;
627 int commutative_op = 0;
628 int shift_op = (binoptab->code == ASHIFT
629 || binoptab->code == ASHIFTRT
630 || binoptab->code == LSHIFTRT
631 || binoptab->code == ROTATE
632 || binoptab->code == ROTATERT);
633 rtx entry_last = get_last_insn ();
634 rtx last;
636 class = GET_MODE_CLASS (mode);
638 op0 = protect_from_queue (op0, 0);
639 op1 = protect_from_queue (op1, 0);
640 if (target)
641 target = protect_from_queue (target, 1);
643 if (flag_force_mem)
645 op0 = force_not_mem (op0);
646 op1 = force_not_mem (op1);
649 /* If subtracting an integer constant, convert this into an addition of
650 the negated constant. */
652 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
654 op1 = negate_rtx (mode, op1);
655 binoptab = add_optab;
658 /* If we are inside an appropriately-short loop and one operand is an
659 expensive constant, force it into a register. */
660 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
661 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
662 op0 = force_reg (mode, op0);
664 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
665 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
666 op1 = force_reg (mode, op1);
668 /* Record where to delete back to if we backtrack. */
669 last = get_last_insn ();
671 /* If operation is commutative,
672 try to make the first operand a register.
673 Even better, try to make it the same as the target.
674 Also try to make the last operand a constant. */
675 if (GET_RTX_CLASS (binoptab->code) == 'c'
676 || binoptab == smul_widen_optab
677 || binoptab == umul_widen_optab
678 || binoptab == smul_highpart_optab
679 || binoptab == umul_highpart_optab)
681 commutative_op = 1;
683 if (((target == 0 || GET_CODE (target) == REG)
684 ? ((GET_CODE (op1) == REG
685 && GET_CODE (op0) != REG)
686 || target == op1)
687 : rtx_equal_p (op1, target))
688 || GET_CODE (op0) == CONST_INT)
690 temp = op1;
691 op1 = op0;
692 op0 = temp;
696 /* If we can do it with a three-operand insn, do so. */
698 if (methods != OPTAB_MUST_WIDEN
699 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
701 int icode = (int) binoptab->handlers[(int) mode].insn_code;
702 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
703 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
704 rtx pat;
705 rtx xop0 = op0, xop1 = op1;
707 if (target)
708 temp = target;
709 else
710 temp = gen_reg_rtx (mode);
712 /* If it is a commutative operator and the modes would match
713 if we would swap the operands, we can save the conversions. */
714 if (commutative_op)
716 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
717 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
719 register rtx tmp;
721 tmp = op0; op0 = op1; op1 = tmp;
722 tmp = xop0; xop0 = xop1; xop1 = tmp;
726 /* In case the insn wants input operands in modes different from
727 the result, convert the operands. */
729 if (GET_MODE (op0) != VOIDmode
730 && GET_MODE (op0) != mode0
731 && mode0 != VOIDmode)
732 xop0 = convert_to_mode (mode0, xop0, unsignedp);
734 if (GET_MODE (xop1) != VOIDmode
735 && GET_MODE (xop1) != mode1
736 && mode1 != VOIDmode)
737 xop1 = convert_to_mode (mode1, xop1, unsignedp);
739 /* Now, if insn's predicates don't allow our operands, put them into
740 pseudo regs. */
742 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
743 && mode0 != VOIDmode)
744 xop0 = copy_to_mode_reg (mode0, xop0);
746 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
747 && mode1 != VOIDmode)
748 xop1 = copy_to_mode_reg (mode1, xop1);
750 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
751 temp = gen_reg_rtx (mode);
753 pat = GEN_FCN (icode) (temp, xop0, xop1);
754 if (pat)
756 /* If PAT is a multi-insn sequence, try to add an appropriate
757 REG_EQUAL note to it. If we can't because TEMP conflicts with an
758 operand, call ourselves again, this time without a target. */
759 if (GET_CODE (pat) == SEQUENCE
760 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
762 delete_insns_since (last);
763 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
764 unsignedp, methods);
767 emit_insn (pat);
768 return temp;
770 else
771 delete_insns_since (last);
774 /* If this is a multiply, see if we can do a widening operation that
775 takes operands of this mode and makes a wider mode. */
777 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
778 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
779 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
780 != CODE_FOR_nothing))
782 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
783 unsignedp ? umul_widen_optab : smul_widen_optab,
784 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
786 if (temp != 0)
788 if (GET_MODE_CLASS (mode) == MODE_INT)
789 return gen_lowpart (mode, temp);
790 else
791 return convert_to_mode (mode, temp, unsignedp);
795 /* Look for a wider mode of the same class for which we think we
796 can open-code the operation. Check for a widening multiply at the
797 wider mode as well. */
799 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
800 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
801 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
802 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
804 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
805 || (binoptab == smul_optab
806 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
807 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
808 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
809 != CODE_FOR_nothing)))
811 rtx xop0 = op0, xop1 = op1;
812 int no_extend = 0;
814 /* For certain integer operations, we need not actually extend
815 the narrow operands, as long as we will truncate
816 the results to the same narrowness. */
818 if ((binoptab == ior_optab || binoptab == and_optab
819 || binoptab == xor_optab
820 || binoptab == add_optab || binoptab == sub_optab
821 || binoptab == smul_optab || binoptab == ashl_optab)
822 && class == MODE_INT)
823 no_extend = 1;
825 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
827 /* The second operand of a shift must always be extended. */
828 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
829 no_extend && binoptab != ashl_optab);
831 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
832 unsignedp, OPTAB_DIRECT);
833 if (temp)
835 if (class != MODE_INT)
837 if (target == 0)
838 target = gen_reg_rtx (mode);
839 convert_move (target, temp, 0);
840 return target;
842 else
843 return gen_lowpart (mode, temp);
845 else
846 delete_insns_since (last);
850 /* These can be done a word at a time. */
851 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
852 && class == MODE_INT
853 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
854 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
856 unsigned int i;
857 rtx insns;
858 rtx equiv_value;
860 /* If TARGET is the same as one of the operands, the REG_EQUAL note
861 won't be accurate, so use a new target. */
862 if (target == 0 || target == op0 || target == op1)
863 target = gen_reg_rtx (mode);
865 start_sequence ();
867 /* Do the actual arithmetic. */
868 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
870 rtx target_piece = operand_subword (target, i, 1, mode);
871 rtx x = expand_binop (word_mode, binoptab,
872 operand_subword_force (op0, i, mode),
873 operand_subword_force (op1, i, mode),
874 target_piece, unsignedp, next_methods);
876 if (x == 0)
877 break;
879 if (target_piece != x)
880 emit_move_insn (target_piece, x);
883 insns = get_insns ();
884 end_sequence ();
886 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
888 if (binoptab->code != UNKNOWN)
889 equiv_value
890 = gen_rtx_fmt_ee (binoptab->code, mode,
891 copy_rtx (op0), copy_rtx (op1));
892 else
893 equiv_value = 0;
895 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
896 return target;
900 /* Synthesize double word shifts from single word shifts. */
901 if ((binoptab == lshr_optab || binoptab == ashl_optab
902 || binoptab == ashr_optab)
903 && class == MODE_INT
904 && GET_CODE (op1) == CONST_INT
905 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
906 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
907 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
908 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
910 rtx insns, inter, equiv_value;
911 rtx into_target, outof_target;
912 rtx into_input, outof_input;
913 int shift_count, left_shift, outof_word;
915 /* If TARGET is the same as one of the operands, the REG_EQUAL note
916 won't be accurate, so use a new target. */
917 if (target == 0 || target == op0 || target == op1)
918 target = gen_reg_rtx (mode);
920 start_sequence ();
922 shift_count = INTVAL (op1);
924 /* OUTOF_* is the word we are shifting bits away from, and
925 INTO_* is the word that we are shifting bits towards, thus
926 they differ depending on the direction of the shift and
927 WORDS_BIG_ENDIAN. */
929 left_shift = binoptab == ashl_optab;
930 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
932 outof_target = operand_subword (target, outof_word, 1, mode);
933 into_target = operand_subword (target, 1 - outof_word, 1, mode);
935 outof_input = operand_subword_force (op0, outof_word, mode);
936 into_input = operand_subword_force (op0, 1 - outof_word, mode);
938 if (shift_count >= BITS_PER_WORD)
940 inter = expand_binop (word_mode, binoptab,
941 outof_input,
942 GEN_INT (shift_count - BITS_PER_WORD),
943 into_target, unsignedp, next_methods);
945 if (inter != 0 && inter != into_target)
946 emit_move_insn (into_target, inter);
948 /* For a signed right shift, we must fill the word we are shifting
949 out of with copies of the sign bit. Otherwise it is zeroed. */
950 if (inter != 0 && binoptab != ashr_optab)
951 inter = CONST0_RTX (word_mode);
952 else if (inter != 0)
953 inter = expand_binop (word_mode, binoptab,
954 outof_input,
955 GEN_INT (BITS_PER_WORD - 1),
956 outof_target, unsignedp, next_methods);
958 if (inter != 0 && inter != outof_target)
959 emit_move_insn (outof_target, inter);
961 else
963 rtx carries;
964 optab reverse_unsigned_shift, unsigned_shift;
966 /* For a shift of less then BITS_PER_WORD, to compute the carry,
967 we must do a logical shift in the opposite direction of the
968 desired shift. */
970 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
972 /* For a shift of less than BITS_PER_WORD, to compute the word
973 shifted towards, we need to unsigned shift the orig value of
974 that word. */
976 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
978 carries = expand_binop (word_mode, reverse_unsigned_shift,
979 outof_input,
980 GEN_INT (BITS_PER_WORD - shift_count),
981 0, unsignedp, next_methods);
983 if (carries == 0)
984 inter = 0;
985 else
986 inter = expand_binop (word_mode, unsigned_shift, into_input,
987 op1, 0, unsignedp, next_methods);
989 if (inter != 0)
990 inter = expand_binop (word_mode, ior_optab, carries, inter,
991 into_target, unsignedp, next_methods);
993 if (inter != 0 && inter != into_target)
994 emit_move_insn (into_target, inter);
996 if (inter != 0)
997 inter = expand_binop (word_mode, binoptab, outof_input,
998 op1, outof_target, unsignedp, next_methods);
1000 if (inter != 0 && inter != outof_target)
1001 emit_move_insn (outof_target, inter);
1004 insns = get_insns ();
1005 end_sequence ();
1007 if (inter != 0)
1009 if (binoptab->code != UNKNOWN)
1010 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1011 else
1012 equiv_value = 0;
1014 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1015 return target;
1019 /* Synthesize double word rotates from single word shifts. */
1020 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1021 && class == MODE_INT
1022 && GET_CODE (op1) == CONST_INT
1023 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1024 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1025 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1027 rtx insns, equiv_value;
1028 rtx into_target, outof_target;
1029 rtx into_input, outof_input;
1030 rtx inter;
1031 int shift_count, left_shift, outof_word;
1033 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1034 won't be accurate, so use a new target. */
1035 if (target == 0 || target == op0 || target == op1)
1036 target = gen_reg_rtx (mode);
1038 start_sequence ();
1040 shift_count = INTVAL (op1);
1042 /* OUTOF_* is the word we are shifting bits away from, and
1043 INTO_* is the word that we are shifting bits towards, thus
1044 they differ depending on the direction of the shift and
1045 WORDS_BIG_ENDIAN. */
1047 left_shift = (binoptab == rotl_optab);
1048 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1050 outof_target = operand_subword (target, outof_word, 1, mode);
1051 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1053 outof_input = operand_subword_force (op0, outof_word, mode);
1054 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1056 if (shift_count == BITS_PER_WORD)
1058 /* This is just a word swap. */
1059 emit_move_insn (outof_target, into_input);
1060 emit_move_insn (into_target, outof_input);
1061 inter = const0_rtx;
1063 else
1065 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1066 rtx first_shift_count, second_shift_count;
1067 optab reverse_unsigned_shift, unsigned_shift;
1069 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1070 ? lshr_optab : ashl_optab);
1072 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1073 ? ashl_optab : lshr_optab);
1075 if (shift_count > BITS_PER_WORD)
1077 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1078 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1080 else
1082 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1083 second_shift_count = GEN_INT (shift_count);
1086 into_temp1 = expand_binop (word_mode, unsigned_shift,
1087 outof_input, first_shift_count,
1088 NULL_RTX, unsignedp, next_methods);
1089 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1090 into_input, second_shift_count,
1091 into_target, unsignedp, next_methods);
1093 if (into_temp1 != 0 && into_temp2 != 0)
1094 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1095 into_target, unsignedp, next_methods);
1096 else
1097 inter = 0;
1099 if (inter != 0 && inter != into_target)
1100 emit_move_insn (into_target, inter);
1102 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1103 into_input, first_shift_count,
1104 NULL_RTX, unsignedp, next_methods);
1105 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1106 outof_input, second_shift_count,
1107 outof_target, unsignedp, next_methods);
1109 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1110 inter = expand_binop (word_mode, ior_optab,
1111 outof_temp1, outof_temp2,
1112 outof_target, unsignedp, next_methods);
1114 if (inter != 0 && inter != outof_target)
1115 emit_move_insn (outof_target, inter);
1118 insns = get_insns ();
1119 end_sequence ();
1121 if (inter != 0)
1123 if (binoptab->code != UNKNOWN)
1124 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1125 else
1126 equiv_value = 0;
1128 /* We can't make this a no conflict block if this is a word swap,
1129 because the word swap case fails if the input and output values
1130 are in the same register. */
1131 if (shift_count != BITS_PER_WORD)
1132 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1133 else
1134 emit_insns (insns);
1137 return target;
1141 /* These can be done a word at a time by propagating carries. */
1142 if ((binoptab == add_optab || binoptab == sub_optab)
1143 && class == MODE_INT
1144 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1145 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1147 unsigned int i;
1148 rtx carry_tmp = gen_reg_rtx (word_mode);
1149 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1150 unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1151 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1152 rtx xop0, xop1;
1154 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1155 value is one of those, use it. Otherwise, use 1 since it is the
1156 one easiest to get. */
1157 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1158 int normalizep = STORE_FLAG_VALUE;
1159 #else
1160 int normalizep = 1;
1161 #endif
1163 /* Prepare the operands. */
1164 xop0 = force_reg (mode, op0);
1165 xop1 = force_reg (mode, op1);
1167 if (target == 0 || GET_CODE (target) != REG
1168 || target == xop0 || target == xop1)
1169 target = gen_reg_rtx (mode);
1171 /* Indicate for flow that the entire target reg is being set. */
1172 if (GET_CODE (target) == REG)
1173 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1175 /* Do the actual arithmetic. */
1176 for (i = 0; i < nwords; i++)
1178 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1179 rtx target_piece = operand_subword (target, index, 1, mode);
1180 rtx op0_piece = operand_subword_force (xop0, index, mode);
1181 rtx op1_piece = operand_subword_force (xop1, index, mode);
1182 rtx x;
1184 /* Main add/subtract of the input operands. */
1185 x = expand_binop (word_mode, binoptab,
1186 op0_piece, op1_piece,
1187 target_piece, unsignedp, next_methods);
1188 if (x == 0)
1189 break;
1191 if (i + 1 < nwords)
1193 /* Store carry from main add/subtract. */
1194 carry_out = gen_reg_rtx (word_mode);
1195 carry_out = emit_store_flag_force (carry_out,
1196 (binoptab == add_optab
1197 ? LT : GT),
1198 x, op0_piece,
1199 word_mode, 1, normalizep);
1202 if (i > 0)
1204 /* Add/subtract previous carry to main result. */
1205 x = expand_binop (word_mode,
1206 normalizep == 1 ? binoptab : otheroptab,
1207 x, carry_in,
1208 target_piece, 1, next_methods);
1209 if (x == 0)
1210 break;
1211 else if (target_piece != x)
1212 emit_move_insn (target_piece, x);
1214 if (i + 1 < nwords)
1216 /* THIS CODE HAS NOT BEEN TESTED. */
1217 /* Get out carry from adding/subtracting carry in. */
1218 carry_tmp = emit_store_flag_force (carry_tmp,
1219 binoptab == add_optab
1220 ? LT : GT,
1221 x, carry_in,
1222 word_mode, 1, normalizep);
1224 /* Logical-ior the two poss. carry together. */
1225 carry_out = expand_binop (word_mode, ior_optab,
1226 carry_out, carry_tmp,
1227 carry_out, 0, next_methods);
1228 if (carry_out == 0)
1229 break;
1233 carry_in = carry_out;
1236 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1238 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1240 rtx temp = emit_move_insn (target, target);
1242 set_unique_reg_note (temp,
1243 REG_EQUAL,
1244 gen_rtx_fmt_ee (binoptab->code, mode,
1245 copy_rtx (xop0),
1246 copy_rtx (xop1)));
1249 return target;
1252 else
1253 delete_insns_since (last);
1256 /* If we want to multiply two two-word values and have normal and widening
1257 multiplies of single-word values, we can do this with three smaller
1258 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1259 because we are not operating on one word at a time.
1261 The multiplication proceeds as follows:
1262 _______________________
1263 [__op0_high_|__op0_low__]
1264 _______________________
1265 * [__op1_high_|__op1_low__]
1266 _______________________________________________
1267 _______________________
1268 (1) [__op0_low__*__op1_low__]
1269 _______________________
1270 (2a) [__op0_low__*__op1_high_]
1271 _______________________
1272 (2b) [__op0_high_*__op1_low__]
1273 _______________________
1274 (3) [__op0_high_*__op1_high_]
1277 This gives a 4-word result. Since we are only interested in the
1278 lower 2 words, partial result (3) and the upper words of (2a) and
1279 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1280 calculated using non-widening multiplication.
1282 (1), however, needs to be calculated with an unsigned widening
1283 multiplication. If this operation is not directly supported we
1284 try using a signed widening multiplication and adjust the result.
1285 This adjustment works as follows:
1287 If both operands are positive then no adjustment is needed.
1289 If the operands have different signs, for example op0_low < 0 and
1290 op1_low >= 0, the instruction treats the most significant bit of
1291 op0_low as a sign bit instead of a bit with significance
1292 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1293 with 2**BITS_PER_WORD - op0_low, and two's complements the
1294 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1295 the result.
1297 Similarly, if both operands are negative, we need to add
1298 (op0_low + op1_low) * 2**BITS_PER_WORD.
1300 We use a trick to adjust quickly. We logically shift op0_low right
1301 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1302 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1303 logical shift exists, we do an arithmetic right shift and subtract
1304 the 0 or -1. */
1306 if (binoptab == smul_optab
1307 && class == MODE_INT
1308 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1309 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1310 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1311 && ((umul_widen_optab->handlers[(int) mode].insn_code
1312 != CODE_FOR_nothing)
1313 || (smul_widen_optab->handlers[(int) mode].insn_code
1314 != CODE_FOR_nothing)))
1316 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1317 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1318 rtx op0_high = operand_subword_force (op0, high, mode);
1319 rtx op0_low = operand_subword_force (op0, low, mode);
1320 rtx op1_high = operand_subword_force (op1, high, mode);
1321 rtx op1_low = operand_subword_force (op1, low, mode);
1322 rtx product = 0;
1323 rtx op0_xhigh = NULL_RTX;
1324 rtx op1_xhigh = NULL_RTX;
1326 /* If the target is the same as one of the inputs, don't use it. This
1327 prevents problems with the REG_EQUAL note. */
1328 if (target == op0 || target == op1
1329 || (target != 0 && GET_CODE (target) != REG))
1330 target = 0;
1332 /* Multiply the two lower words to get a double-word product.
1333 If unsigned widening multiplication is available, use that;
1334 otherwise use the signed form and compensate. */
1336 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1338 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1339 target, 1, OPTAB_DIRECT);
1341 /* If we didn't succeed, delete everything we did so far. */
1342 if (product == 0)
1343 delete_insns_since (last);
1344 else
1345 op0_xhigh = op0_high, op1_xhigh = op1_high;
1348 if (product == 0
1349 && smul_widen_optab->handlers[(int) mode].insn_code
1350 != CODE_FOR_nothing)
1352 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1353 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1354 target, 1, OPTAB_DIRECT);
1355 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1356 NULL_RTX, 1, next_methods);
1357 if (op0_xhigh)
1358 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1359 op0_xhigh, op0_xhigh, 0, next_methods);
1360 else
1362 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1363 NULL_RTX, 0, next_methods);
1364 if (op0_xhigh)
1365 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1366 op0_xhigh, op0_xhigh, 0,
1367 next_methods);
1370 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1371 NULL_RTX, 1, next_methods);
1372 if (op1_xhigh)
1373 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1374 op1_xhigh, op1_xhigh, 0, next_methods);
1375 else
1377 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1378 NULL_RTX, 0, next_methods);
1379 if (op1_xhigh)
1380 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1381 op1_xhigh, op1_xhigh, 0,
1382 next_methods);
1386 /* If we have been able to directly compute the product of the
1387 low-order words of the operands and perform any required adjustments
1388 of the operands, we proceed by trying two more multiplications
1389 and then computing the appropriate sum.
1391 We have checked above that the required addition is provided.
1392 Full-word addition will normally always succeed, especially if
1393 it is provided at all, so we don't worry about its failure. The
1394 multiplication may well fail, however, so we do handle that. */
1396 if (product && op0_xhigh && op1_xhigh)
1398 rtx product_high = operand_subword (product, high, 1, mode);
1399 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1400 NULL_RTX, 0, OPTAB_DIRECT);
1402 if (temp != 0)
1403 temp = expand_binop (word_mode, add_optab, temp, product_high,
1404 product_high, 0, next_methods);
1406 if (temp != 0 && temp != product_high)
1407 emit_move_insn (product_high, temp);
1409 if (temp != 0)
1410 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1411 NULL_RTX, 0, OPTAB_DIRECT);
1413 if (temp != 0)
1414 temp = expand_binop (word_mode, add_optab, temp,
1415 product_high, product_high,
1416 0, next_methods);
1418 if (temp != 0 && temp != product_high)
1419 emit_move_insn (product_high, temp);
1421 if (temp != 0)
1423 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1425 temp = emit_move_insn (product, product);
1426 set_unique_reg_note (temp,
1427 REG_EQUAL,
1428 gen_rtx_fmt_ee (MULT, mode,
1429 copy_rtx (op0),
1430 copy_rtx (op1)));
1433 return product;
1437 /* If we get here, we couldn't do it for some reason even though we
1438 originally thought we could. Delete anything we've emitted in
1439 trying to do it. */
1441 delete_insns_since (last);
1444 /* We need to open-code the complex type operations: '+, -, * and /' */
1446 /* At this point we allow operations between two similar complex
1447 numbers, and also if one of the operands is not a complex number
1448 but rather of MODE_FLOAT or MODE_INT. However, the caller
1449 must make sure that the MODE of the non-complex operand matches
1450 the SUBMODE of the complex operand. */
1452 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1454 rtx real0 = 0, imag0 = 0;
1455 rtx real1 = 0, imag1 = 0;
1456 rtx realr, imagr, res;
1457 rtx seq;
1458 rtx equiv_value;
1459 int ok = 0;
1461 /* Find the correct mode for the real and imaginary parts */
1462 enum machine_mode submode
1463 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1464 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1467 if (submode == BLKmode)
1468 abort ();
1470 if (! target)
1471 target = gen_reg_rtx (mode);
1473 start_sequence ();
1475 realr = gen_realpart (submode, target);
1476 imagr = gen_imagpart (submode, target);
1478 if (GET_MODE (op0) == mode)
1480 real0 = gen_realpart (submode, op0);
1481 imag0 = gen_imagpart (submode, op0);
1483 else
1484 real0 = op0;
1486 if (GET_MODE (op1) == mode)
1488 real1 = gen_realpart (submode, op1);
1489 imag1 = gen_imagpart (submode, op1);
1491 else
1492 real1 = op1;
1494 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1495 abort ();
1497 switch (binoptab->code)
1499 case PLUS:
1500 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1501 case MINUS:
1502 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1503 res = expand_binop (submode, binoptab, real0, real1,
1504 realr, unsignedp, methods);
1506 if (res == 0)
1507 break;
1508 else if (res != realr)
1509 emit_move_insn (realr, res);
1511 if (imag0 && imag1)
1512 res = expand_binop (submode, binoptab, imag0, imag1,
1513 imagr, unsignedp, methods);
1514 else if (imag0)
1515 res = imag0;
1516 else if (binoptab->code == MINUS)
1517 res = expand_unop (submode,
1518 binoptab == subv_optab ? negv_optab : neg_optab,
1519 imag1, imagr, unsignedp);
1520 else
1521 res = imag1;
1523 if (res == 0)
1524 break;
1525 else if (res != imagr)
1526 emit_move_insn (imagr, res);
1528 ok = 1;
1529 break;
1531 case MULT:
1532 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1534 if (imag0 && imag1)
1536 rtx temp1, temp2;
1538 /* Don't fetch these from memory more than once. */
1539 real0 = force_reg (submode, real0);
1540 real1 = force_reg (submode, real1);
1541 imag0 = force_reg (submode, imag0);
1542 imag1 = force_reg (submode, imag1);
1544 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1545 unsignedp, methods);
1547 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1548 unsignedp, methods);
1550 if (temp1 == 0 || temp2 == 0)
1551 break;
1553 res = (expand_binop
1554 (submode,
1555 binoptab == smulv_optab ? subv_optab : sub_optab,
1556 temp1, temp2, realr, unsignedp, methods));
1558 if (res == 0)
1559 break;
1560 else if (res != realr)
1561 emit_move_insn (realr, res);
1563 temp1 = expand_binop (submode, binoptab, real0, imag1,
1564 NULL_RTX, unsignedp, methods);
1566 temp2 = expand_binop (submode, binoptab, real1, imag0,
1567 NULL_RTX, unsignedp, methods);
1569 if (temp1 == 0 || temp2 == 0)
1570 break;
1572 res = (expand_binop
1573 (submode,
1574 binoptab == smulv_optab ? addv_optab : add_optab,
1575 temp1, temp2, imagr, unsignedp, methods));
1577 if (res == 0)
1578 break;
1579 else if (res != imagr)
1580 emit_move_insn (imagr, res);
1582 ok = 1;
1584 else
1586 /* Don't fetch these from memory more than once. */
1587 real0 = force_reg (submode, real0);
1588 real1 = force_reg (submode, real1);
1590 res = expand_binop (submode, binoptab, real0, real1,
1591 realr, unsignedp, methods);
1592 if (res == 0)
1593 break;
1594 else if (res != realr)
1595 emit_move_insn (realr, res);
1597 if (imag0 != 0)
1598 res = expand_binop (submode, binoptab,
1599 real1, imag0, imagr, unsignedp, methods);
1600 else
1601 res = expand_binop (submode, binoptab,
1602 real0, imag1, imagr, unsignedp, methods);
1604 if (res == 0)
1605 break;
1606 else if (res != imagr)
1607 emit_move_insn (imagr, res);
1609 ok = 1;
1611 break;
1613 case DIV:
1614 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1616 if (imag1 == 0)
1618 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1620 /* Don't fetch these from memory more than once. */
1621 real1 = force_reg (submode, real1);
1623 /* Simply divide the real and imaginary parts by `c' */
1624 if (class == MODE_COMPLEX_FLOAT)
1625 res = expand_binop (submode, binoptab, real0, real1,
1626 realr, unsignedp, methods);
1627 else
1628 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1629 real0, real1, realr, unsignedp);
1631 if (res == 0)
1632 break;
1633 else if (res != realr)
1634 emit_move_insn (realr, res);
1636 if (class == MODE_COMPLEX_FLOAT)
1637 res = expand_binop (submode, binoptab, imag0, real1,
1638 imagr, unsignedp, methods);
1639 else
1640 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1641 imag0, real1, imagr, unsignedp);
1643 if (res == 0)
1644 break;
1645 else if (res != imagr)
1646 emit_move_insn (imagr, res);
1648 ok = 1;
1650 else
1652 switch (flag_complex_divide_method)
1654 case 0:
1655 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1656 realr, imagr, submode,
1657 unsignedp, methods,
1658 class, binoptab);
1659 break;
1661 case 1:
1662 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1663 realr, imagr, submode,
1664 unsignedp, methods,
1665 class, binoptab);
1666 break;
1668 default:
1669 abort ();
1672 break;
1674 default:
1675 abort ();
1678 seq = get_insns ();
1679 end_sequence ();
1681 if (ok)
1683 if (binoptab->code != UNKNOWN)
1684 equiv_value
1685 = gen_rtx_fmt_ee (binoptab->code, mode,
1686 copy_rtx (op0), copy_rtx (op1));
1687 else
1688 equiv_value = 0;
1690 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1692 return target;
1696 /* It can't be open-coded in this mode.
1697 Use a library call if one is available and caller says that's ok. */
1699 if (binoptab->handlers[(int) mode].libfunc
1700 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1702 rtx insns;
1703 rtx op1x = op1;
1704 enum machine_mode op1_mode = mode;
1705 rtx value;
1707 start_sequence ();
1709 if (shift_op)
1711 op1_mode = word_mode;
1712 /* Specify unsigned here,
1713 since negative shift counts are meaningless. */
1714 op1x = convert_to_mode (word_mode, op1, 1);
1717 if (GET_MODE (op0) != VOIDmode
1718 && GET_MODE (op0) != mode)
1719 op0 = convert_to_mode (mode, op0, unsignedp);
1721 /* Pass 1 for NO_QUEUE so we don't lose any increments
1722 if the libcall is cse'd or moved. */
1723 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1724 NULL_RTX, LCT_CONST, mode, 2,
1725 op0, mode, op1x, op1_mode);
1727 insns = get_insns ();
1728 end_sequence ();
1730 target = gen_reg_rtx (mode);
1731 emit_libcall_block (insns, target, value,
1732 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1734 return target;
1737 delete_insns_since (last);
1739 /* It can't be done in this mode. Can we do it in a wider mode? */
1741 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1742 || methods == OPTAB_MUST_WIDEN))
1744 /* Caller says, don't even try. */
1745 delete_insns_since (entry_last);
1746 return 0;
1749 /* Compute the value of METHODS to pass to recursive calls.
1750 Don't allow widening to be tried recursively. */
1752 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1754 /* Look for a wider mode of the same class for which it appears we can do
1755 the operation. */
1757 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1759 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1760 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1762 if ((binoptab->handlers[(int) wider_mode].insn_code
1763 != CODE_FOR_nothing)
1764 || (methods == OPTAB_LIB
1765 && binoptab->handlers[(int) wider_mode].libfunc))
1767 rtx xop0 = op0, xop1 = op1;
1768 int no_extend = 0;
1770 /* For certain integer operations, we need not actually extend
1771 the narrow operands, as long as we will truncate
1772 the results to the same narrowness. */
1774 if ((binoptab == ior_optab || binoptab == and_optab
1775 || binoptab == xor_optab
1776 || binoptab == add_optab || binoptab == sub_optab
1777 || binoptab == smul_optab || binoptab == ashl_optab)
1778 && class == MODE_INT)
1779 no_extend = 1;
1781 xop0 = widen_operand (xop0, wider_mode, mode,
1782 unsignedp, no_extend);
1784 /* The second operand of a shift must always be extended. */
1785 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1786 no_extend && binoptab != ashl_optab);
1788 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1789 unsignedp, methods);
1790 if (temp)
1792 if (class != MODE_INT)
1794 if (target == 0)
1795 target = gen_reg_rtx (mode);
1796 convert_move (target, temp, 0);
1797 return target;
1799 else
1800 return gen_lowpart (mode, temp);
1802 else
1803 delete_insns_since (last);
1808 delete_insns_since (entry_last);
1809 return 0;
1812 /* Expand a binary operator which has both signed and unsigned forms.
1813 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1814 signed operations.
1816 If we widen unsigned operands, we may use a signed wider operation instead
1817 of an unsigned wider operation, since the result would be the same. */
1820 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1821 enum machine_mode mode;
1822 optab uoptab, soptab;
1823 rtx op0, op1, target;
1824 int unsignedp;
1825 enum optab_methods methods;
1827 register rtx temp;
1828 optab direct_optab = unsignedp ? uoptab : soptab;
1829 struct optab wide_soptab;
1831 /* Do it without widening, if possible. */
1832 temp = expand_binop (mode, direct_optab, op0, op1, target,
1833 unsignedp, OPTAB_DIRECT);
1834 if (temp || methods == OPTAB_DIRECT)
1835 return temp;
1837 /* Try widening to a signed int. Make a fake signed optab that
1838 hides any signed insn for direct use. */
1839 wide_soptab = *soptab;
1840 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1841 wide_soptab.handlers[(int) mode].libfunc = 0;
1843 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1844 unsignedp, OPTAB_WIDEN);
1846 /* For unsigned operands, try widening to an unsigned int. */
1847 if (temp == 0 && unsignedp)
1848 temp = expand_binop (mode, uoptab, op0, op1, target,
1849 unsignedp, OPTAB_WIDEN);
1850 if (temp || methods == OPTAB_WIDEN)
1851 return temp;
1853 /* Use the right width lib call if that exists. */
1854 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1855 if (temp || methods == OPTAB_LIB)
1856 return temp;
1858 /* Must widen and use a lib call, use either signed or unsigned. */
1859 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1860 unsignedp, methods);
1861 if (temp != 0)
1862 return temp;
1863 if (unsignedp)
1864 return expand_binop (mode, uoptab, op0, op1, target,
1865 unsignedp, methods);
1866 return 0;
1869 /* Generate code to perform an operation specified by BINOPTAB
1870 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1871 We assume that the order of the operands for the instruction
1872 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1873 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1875 Either TARG0 or TARG1 may be zero, but what that means is that
1876 the result is not actually wanted. We will generate it into
1877 a dummy pseudo-reg and discard it. They may not both be zero.
1879 Returns 1 if this operation can be performed; 0 if not. */
1882 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1883 optab binoptab;
1884 rtx op0, op1;
1885 rtx targ0, targ1;
1886 int unsignedp;
1888 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1889 enum mode_class class;
1890 enum machine_mode wider_mode;
1891 rtx entry_last = get_last_insn ();
1892 rtx last;
1894 class = GET_MODE_CLASS (mode);
1896 op0 = protect_from_queue (op0, 0);
1897 op1 = protect_from_queue (op1, 0);
1899 if (flag_force_mem)
1901 op0 = force_not_mem (op0);
1902 op1 = force_not_mem (op1);
1905 /* If we are inside an appropriately-short loop and one operand is an
1906 expensive constant, force it into a register. */
1907 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1908 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1909 op0 = force_reg (mode, op0);
1911 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1912 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1913 op1 = force_reg (mode, op1);
1915 if (targ0)
1916 targ0 = protect_from_queue (targ0, 1);
1917 else
1918 targ0 = gen_reg_rtx (mode);
1919 if (targ1)
1920 targ1 = protect_from_queue (targ1, 1);
1921 else
1922 targ1 = gen_reg_rtx (mode);
1924 /* Record where to go back to if we fail. */
1925 last = get_last_insn ();
1927 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1929 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1930 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1931 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1932 rtx pat;
1933 rtx xop0 = op0, xop1 = op1;
1935 /* In case this insn wants input operands in modes different from the
1936 result, convert the operands. */
1937 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1938 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1940 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1941 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1943 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1944 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
1945 xop0 = copy_to_mode_reg (mode0, xop0);
1947 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
1948 xop1 = copy_to_mode_reg (mode1, xop1);
1950 /* We could handle this, but we should always be called with a pseudo
1951 for our targets and all insns should take them as outputs. */
1952 if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
1953 || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
1954 abort ();
1956 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1957 if (pat)
1959 emit_insn (pat);
1960 return 1;
1962 else
1963 delete_insns_since (last);
1966 /* It can't be done in this mode. Can we do it in a wider mode? */
1968 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1970 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1971 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1973 if (binoptab->handlers[(int) wider_mode].insn_code
1974 != CODE_FOR_nothing)
1976 register rtx t0 = gen_reg_rtx (wider_mode);
1977 register rtx t1 = gen_reg_rtx (wider_mode);
1979 if (expand_twoval_binop (binoptab,
1980 convert_modes (wider_mode, mode, op0,
1981 unsignedp),
1982 convert_modes (wider_mode, mode, op1,
1983 unsignedp),
1984 t0, t1, unsignedp))
1986 convert_move (targ0, t0, unsignedp);
1987 convert_move (targ1, t1, unsignedp);
1988 return 1;
1990 else
1991 delete_insns_since (last);
1996 delete_insns_since (entry_last);
1997 return 0;
2000 /* Generate code to perform an operation specified by UNOPTAB
2001 on operand OP0, with result having machine-mode MODE.
2003 UNSIGNEDP is for the case where we have to widen the operands
2004 to perform the operation. It says to use zero-extension.
2006 If TARGET is nonzero, the value
2007 is generated there, if it is convenient to do so.
2008 In all cases an rtx is returned for the locus of the value;
2009 this may or may not be TARGET. */
2012 expand_unop (mode, unoptab, op0, target, unsignedp)
2013 enum machine_mode mode;
2014 optab unoptab;
2015 rtx op0;
2016 rtx target;
2017 int unsignedp;
2019 enum mode_class class;
2020 enum machine_mode wider_mode;
2021 register rtx temp;
2022 rtx last = get_last_insn ();
2023 rtx pat;
2025 class = GET_MODE_CLASS (mode);
2027 op0 = protect_from_queue (op0, 0);
2029 if (flag_force_mem)
2031 op0 = force_not_mem (op0);
2034 if (target)
2035 target = protect_from_queue (target, 1);
2037 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2039 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2040 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2041 rtx xop0 = op0;
2043 if (target)
2044 temp = target;
2045 else
2046 temp = gen_reg_rtx (mode);
2048 if (GET_MODE (xop0) != VOIDmode
2049 && GET_MODE (xop0) != mode0)
2050 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2052 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2054 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2055 xop0 = copy_to_mode_reg (mode0, xop0);
2057 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2058 temp = gen_reg_rtx (mode);
2060 pat = GEN_FCN (icode) (temp, xop0);
2061 if (pat)
2063 if (GET_CODE (pat) == SEQUENCE
2064 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2066 delete_insns_since (last);
2067 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2070 emit_insn (pat);
2072 return temp;
2074 else
2075 delete_insns_since (last);
2078 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2080 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2081 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2082 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2084 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2086 rtx xop0 = op0;
2088 /* For certain operations, we need not actually extend
2089 the narrow operand, as long as we will truncate the
2090 results to the same narrowness. */
2092 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2093 (unoptab == neg_optab
2094 || unoptab == one_cmpl_optab)
2095 && class == MODE_INT);
2097 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2098 unsignedp);
2100 if (temp)
2102 if (class != MODE_INT)
2104 if (target == 0)
2105 target = gen_reg_rtx (mode);
2106 convert_move (target, temp, 0);
2107 return target;
2109 else
2110 return gen_lowpart (mode, temp);
2112 else
2113 delete_insns_since (last);
2117 /* These can be done a word at a time. */
2118 if (unoptab == one_cmpl_optab
2119 && class == MODE_INT
2120 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2121 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2123 unsigned int i;
2124 rtx insns;
2126 if (target == 0 || target == op0)
2127 target = gen_reg_rtx (mode);
2129 start_sequence ();
2131 /* Do the actual arithmetic. */
2132 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2134 rtx target_piece = operand_subword (target, i, 1, mode);
2135 rtx x = expand_unop (word_mode, unoptab,
2136 operand_subword_force (op0, i, mode),
2137 target_piece, unsignedp);
2138 if (target_piece != x)
2139 emit_move_insn (target_piece, x);
2142 insns = get_insns ();
2143 end_sequence ();
2145 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2146 gen_rtx_fmt_e (unoptab->code, mode,
2147 copy_rtx (op0)));
2148 return target;
2151 /* Open-code the complex negation operation. */
2152 else if (unoptab->code == NEG
2153 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2155 rtx target_piece;
2156 rtx x;
2157 rtx seq;
2159 /* Find the correct mode for the real and imaginary parts */
2160 enum machine_mode submode
2161 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2162 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2165 if (submode == BLKmode)
2166 abort ();
2168 if (target == 0)
2169 target = gen_reg_rtx (mode);
2171 start_sequence ();
2173 target_piece = gen_imagpart (submode, target);
2174 x = expand_unop (submode, unoptab,
2175 gen_imagpart (submode, op0),
2176 target_piece, unsignedp);
2177 if (target_piece != x)
2178 emit_move_insn (target_piece, x);
2180 target_piece = gen_realpart (submode, target);
2181 x = expand_unop (submode, unoptab,
2182 gen_realpart (submode, op0),
2183 target_piece, unsignedp);
2184 if (target_piece != x)
2185 emit_move_insn (target_piece, x);
2187 seq = get_insns ();
2188 end_sequence ();
2190 emit_no_conflict_block (seq, target, op0, 0,
2191 gen_rtx_fmt_e (unoptab->code, mode,
2192 copy_rtx (op0)));
2193 return target;
2196 /* Now try a library call in this mode. */
2197 if (unoptab->handlers[(int) mode].libfunc)
2199 rtx insns;
2200 rtx value;
2202 start_sequence ();
2204 /* Pass 1 for NO_QUEUE so we don't lose any increments
2205 if the libcall is cse'd or moved. */
2206 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2207 NULL_RTX, LCT_CONST, mode, 1, op0, mode);
2208 insns = get_insns ();
2209 end_sequence ();
2211 target = gen_reg_rtx (mode);
2212 emit_libcall_block (insns, target, value,
2213 gen_rtx_fmt_e (unoptab->code, mode, op0));
2215 return target;
2218 /* It can't be done in this mode. Can we do it in a wider mode? */
2220 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2222 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2223 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2225 if ((unoptab->handlers[(int) wider_mode].insn_code
2226 != CODE_FOR_nothing)
2227 || unoptab->handlers[(int) wider_mode].libfunc)
2229 rtx xop0 = op0;
2231 /* For certain operations, we need not actually extend
2232 the narrow operand, as long as we will truncate the
2233 results to the same narrowness. */
2235 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2236 (unoptab == neg_optab
2237 || unoptab == one_cmpl_optab)
2238 && class == MODE_INT);
2240 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2241 unsignedp);
2243 if (temp)
2245 if (class != MODE_INT)
2247 if (target == 0)
2248 target = gen_reg_rtx (mode);
2249 convert_move (target, temp, 0);
2250 return target;
2252 else
2253 return gen_lowpart (mode, temp);
2255 else
2256 delete_insns_since (last);
2261 /* If there is no negate operation, try doing a subtract from zero.
2262 The US Software GOFAST library needs this. */
2263 if (unoptab->code == NEG)
2265 rtx temp;
2266 temp = expand_binop (mode,
2267 unoptab == negv_optab ? subv_optab : sub_optab,
2268 CONST0_RTX (mode), op0,
2269 target, unsignedp, OPTAB_LIB_WIDEN);
2270 if (temp)
2271 return temp;
2274 return 0;
2277 /* Emit code to compute the absolute value of OP0, with result to
2278 TARGET if convenient. (TARGET may be 0.) The return value says
2279 where the result actually is to be found.
2281 MODE is the mode of the operand; the mode of the result is
2282 different but can be deduced from MODE.
2287 expand_abs (mode, op0, target, result_unsignedp, safe)
2288 enum machine_mode mode;
2289 rtx op0;
2290 rtx target;
2291 int result_unsignedp;
2292 int safe;
2294 rtx temp, op1;
2296 if (! flag_trapv)
2297 result_unsignedp = 1;
2299 /* First try to do it with a special abs instruction. */
2300 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2301 op0, target, 0);
2302 if (temp != 0)
2303 return temp;
2305 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2306 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2308 rtx last = get_last_insn ();
2310 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2311 if (temp != 0)
2312 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2313 OPTAB_WIDEN);
2315 if (temp != 0)
2316 return temp;
2318 delete_insns_since (last);
2321 /* If this machine has expensive jumps, we can do integer absolute
2322 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2323 where W is the width of MODE. But don't do this if the machine has
2324 conditional arithmetic since the branches will be converted into
2325 a conditional negation insn. */
2327 #ifndef HAVE_conditional_arithmetic
2328 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2330 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2331 size_int (GET_MODE_BITSIZE (mode) - 1),
2332 NULL_RTX, 0);
2334 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2335 OPTAB_LIB_WIDEN);
2336 if (temp != 0)
2337 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2338 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2340 if (temp != 0)
2341 return temp;
2343 #endif
2345 /* If that does not win, use conditional jump and negate. */
2347 /* It is safe to use the target if it is the same
2348 as the source if this is also a pseudo register */
2349 if (op0 == target && GET_CODE (op0) == REG
2350 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2351 safe = 1;
2353 op1 = gen_label_rtx ();
2354 if (target == 0 || ! safe
2355 || GET_MODE (target) != mode
2356 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2357 || (GET_CODE (target) == REG
2358 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2359 target = gen_reg_rtx (mode);
2361 emit_move_insn (target, op0);
2362 NO_DEFER_POP;
2364 /* If this mode is an integer too wide to compare properly,
2365 compare word by word. Rely on CSE to optimize constant cases. */
2366 if (GET_MODE_CLASS (mode) == MODE_INT
2367 && ! can_compare_p (GE, mode, ccp_jump))
2368 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2369 NULL_RTX, op1);
2370 else
2371 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2372 NULL_RTX, 0, NULL_RTX, op1);
2374 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2375 target, target, 0);
2376 if (op0 != target)
2377 emit_move_insn (target, op0);
2378 emit_label (op1);
2379 OK_DEFER_POP;
2380 return target;
2383 /* Emit code to compute the absolute value of OP0, with result to
2384 TARGET if convenient. (TARGET may be 0.) The return value says
2385 where the result actually is to be found.
2387 MODE is the mode of the operand; the mode of the result is
2388 different but can be deduced from MODE.
2390 UNSIGNEDP is relevant for complex integer modes. */
2393 expand_complex_abs (mode, op0, target, unsignedp)
2394 enum machine_mode mode;
2395 rtx op0;
2396 rtx target;
2397 int unsignedp;
2399 enum mode_class class = GET_MODE_CLASS (mode);
2400 enum machine_mode wider_mode;
2401 register rtx temp;
2402 rtx entry_last = get_last_insn ();
2403 rtx last;
2404 rtx pat;
2405 optab this_abs_optab;
2407 /* Find the correct mode for the real and imaginary parts. */
2408 enum machine_mode submode
2409 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2410 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2413 if (submode == BLKmode)
2414 abort ();
2416 op0 = protect_from_queue (op0, 0);
2418 if (flag_force_mem)
2420 op0 = force_not_mem (op0);
2423 last = get_last_insn ();
2425 if (target)
2426 target = protect_from_queue (target, 1);
2428 this_abs_optab = ! unsignedp && flag_trapv
2429 && (GET_MODE_CLASS(mode) == MODE_INT)
2430 ? absv_optab : abs_optab;
2432 if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2434 int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2435 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2436 rtx xop0 = op0;
2438 if (target)
2439 temp = target;
2440 else
2441 temp = gen_reg_rtx (submode);
2443 if (GET_MODE (xop0) != VOIDmode
2444 && GET_MODE (xop0) != mode0)
2445 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2447 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2449 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2450 xop0 = copy_to_mode_reg (mode0, xop0);
2452 if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2453 temp = gen_reg_rtx (submode);
2455 pat = GEN_FCN (icode) (temp, xop0);
2456 if (pat)
2458 if (GET_CODE (pat) == SEQUENCE
2459 && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
2460 NULL_RTX))
2462 delete_insns_since (last);
2463 return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
2464 unsignedp);
2467 emit_insn (pat);
2469 return temp;
2471 else
2472 delete_insns_since (last);
2475 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2477 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2478 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2480 if (this_abs_optab->handlers[(int) wider_mode].insn_code
2481 != CODE_FOR_nothing)
2483 rtx xop0 = op0;
2485 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2486 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2488 if (temp)
2490 if (class != MODE_COMPLEX_INT)
2492 if (target == 0)
2493 target = gen_reg_rtx (submode);
2494 convert_move (target, temp, 0);
2495 return target;
2497 else
2498 return gen_lowpart (submode, temp);
2500 else
2501 delete_insns_since (last);
2505 /* Open-code the complex absolute-value operation
2506 if we can open-code sqrt. Otherwise it's not worth while. */
2507 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2508 && ! flag_trapv)
2510 rtx real, imag, total;
2512 real = gen_realpart (submode, op0);
2513 imag = gen_imagpart (submode, op0);
2515 /* Square both parts. */
2516 real = expand_mult (submode, real, real, NULL_RTX, 0);
2517 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2519 /* Sum the parts. */
2520 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2521 0, OPTAB_LIB_WIDEN);
2523 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2524 target = expand_unop (submode, sqrt_optab, total, target, 0);
2525 if (target == 0)
2526 delete_insns_since (last);
2527 else
2528 return target;
2531 /* Now try a library call in this mode. */
2532 if (this_abs_optab->handlers[(int) mode].libfunc)
2534 rtx insns;
2535 rtx value;
2537 start_sequence ();
2539 /* Pass 1 for NO_QUEUE so we don't lose any increments
2540 if the libcall is cse'd or moved. */
2541 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2542 NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2543 insns = get_insns ();
2544 end_sequence ();
2546 target = gen_reg_rtx (submode);
2547 emit_libcall_block (insns, target, value,
2548 gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2550 return target;
2553 /* It can't be done in this mode. Can we do it in a wider mode? */
2555 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2556 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2558 if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2559 != CODE_FOR_nothing)
2560 || this_abs_optab->handlers[(int) wider_mode].libfunc)
2562 rtx xop0 = op0;
2564 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2566 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2568 if (temp)
2570 if (class != MODE_COMPLEX_INT)
2572 if (target == 0)
2573 target = gen_reg_rtx (submode);
2574 convert_move (target, temp, 0);
2575 return target;
2577 else
2578 return gen_lowpart (submode, temp);
2580 else
2581 delete_insns_since (last);
2585 delete_insns_since (entry_last);
2586 return 0;
2589 /* Generate an instruction whose insn-code is INSN_CODE,
2590 with two operands: an output TARGET and an input OP0.
2591 TARGET *must* be nonzero, and the output is always stored there.
2592 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2593 the value that is stored into TARGET. */
2595 void
2596 emit_unop_insn (icode, target, op0, code)
2597 int icode;
2598 rtx target;
2599 rtx op0;
2600 enum rtx_code code;
2602 register rtx temp;
2603 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2604 rtx pat;
2606 temp = target = protect_from_queue (target, 1);
2608 op0 = protect_from_queue (op0, 0);
2610 /* Sign and zero extension from memory is often done specially on
2611 RISC machines, so forcing into a register here can pessimize
2612 code. */
2613 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2614 op0 = force_not_mem (op0);
2616 /* Now, if insn does not accept our operands, put them into pseudos. */
2618 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2619 op0 = copy_to_mode_reg (mode0, op0);
2621 if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2622 || (flag_force_mem && GET_CODE (temp) == MEM))
2623 temp = gen_reg_rtx (GET_MODE (temp));
2625 pat = GEN_FCN (icode) (temp, op0);
2627 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2628 add_equal_note (pat, temp, code, op0, NULL_RTX);
2630 emit_insn (pat);
2632 if (temp != target)
2633 emit_move_insn (target, temp);
2636 /* Emit code to perform a series of operations on a multi-word quantity, one
2637 word at a time.
2639 Such a block is preceded by a CLOBBER of the output, consists of multiple
2640 insns, each setting one word of the output, and followed by a SET copying
2641 the output to itself.
2643 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2644 note indicating that it doesn't conflict with the (also multi-word)
2645 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2646 notes.
2648 INSNS is a block of code generated to perform the operation, not including
2649 the CLOBBER and final copy. All insns that compute intermediate values
2650 are first emitted, followed by the block as described above.
2652 TARGET, OP0, and OP1 are the output and inputs of the operations,
2653 respectively. OP1 may be zero for a unary operation.
2655 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2656 on the last insn.
2658 If TARGET is not a register, INSNS is simply emitted with no special
2659 processing. Likewise if anything in INSNS is not an INSN or if
2660 there is a libcall block inside INSNS.
2662 The final insn emitted is returned. */
2665 emit_no_conflict_block (insns, target, op0, op1, equiv)
2666 rtx insns;
2667 rtx target;
2668 rtx op0, op1;
2669 rtx equiv;
2671 rtx prev, next, first, last, insn;
2673 if (GET_CODE (target) != REG || reload_in_progress)
2674 return emit_insns (insns);
2675 else
2676 for (insn = insns; insn; insn = NEXT_INSN (insn))
2677 if (GET_CODE (insn) != INSN
2678 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2679 return emit_insns (insns);
2681 /* First emit all insns that do not store into words of the output and remove
2682 these from the list. */
2683 for (insn = insns; insn; insn = next)
2685 rtx set = 0;
2686 int i;
2688 next = NEXT_INSN (insn);
2690 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
2691 || GET_CODE (PATTERN (insn)) == CLOBBER)
2692 set = PATTERN (insn);
2693 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2695 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2696 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2698 set = XVECEXP (PATTERN (insn), 0, i);
2699 break;
2703 if (set == 0)
2704 abort ();
2706 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2708 if (PREV_INSN (insn))
2709 NEXT_INSN (PREV_INSN (insn)) = next;
2710 else
2711 insns = next;
2713 if (next)
2714 PREV_INSN (next) = PREV_INSN (insn);
2716 add_insn (insn);
2720 prev = get_last_insn ();
2722 /* Now write the CLOBBER of the output, followed by the setting of each
2723 of the words, followed by the final copy. */
2724 if (target != op0 && target != op1)
2725 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2727 for (insn = insns; insn; insn = next)
2729 next = NEXT_INSN (insn);
2730 add_insn (insn);
2732 if (op1 && GET_CODE (op1) == REG)
2733 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2734 REG_NOTES (insn));
2736 if (op0 && GET_CODE (op0) == REG)
2737 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2738 REG_NOTES (insn));
2741 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2742 != CODE_FOR_nothing)
2744 last = emit_move_insn (target, target);
2745 if (equiv)
2746 set_unique_reg_note (last, REG_EQUAL, equiv);
2748 else
2750 last = get_last_insn ();
2752 /* Remove any existing REG_EQUAL note from "last", or else it will
2753 be mistaken for a note referring to the full contents of the
2754 alleged libcall value when found together with the REG_RETVAL
2755 note added below. An existing note can come from an insn
2756 expansion at "last". */
2757 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2760 if (prev == 0)
2761 first = get_insns ();
2762 else
2763 first = NEXT_INSN (prev);
2765 /* Encapsulate the block so it gets manipulated as a unit. */
2766 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2767 REG_NOTES (first));
2768 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2770 return last;
2773 /* Emit code to make a call to a constant function or a library call.
2775 INSNS is a list containing all insns emitted in the call.
2776 These insns leave the result in RESULT. Our block is to copy RESULT
2777 to TARGET, which is logically equivalent to EQUIV.
2779 We first emit any insns that set a pseudo on the assumption that these are
2780 loading constants into registers; doing so allows them to be safely cse'ed
2781 between blocks. Then we emit all the other insns in the block, followed by
2782 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2783 note with an operand of EQUIV.
2785 Moving assignments to pseudos outside of the block is done to improve
2786 the generated code, but is not required to generate correct code,
2787 hence being unable to move an assignment is not grounds for not making
2788 a libcall block. There are two reasons why it is safe to leave these
2789 insns inside the block: First, we know that these pseudos cannot be
2790 used in generated RTL outside the block since they are created for
2791 temporary purposes within the block. Second, CSE will not record the
2792 values of anything set inside a libcall block, so we know they must
2793 be dead at the end of the block.
2795 Except for the first group of insns (the ones setting pseudos), the
2796 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2798 void
2799 emit_libcall_block (insns, target, result, equiv)
2800 rtx insns;
2801 rtx target;
2802 rtx result;
2803 rtx equiv;
2805 rtx final_dest = target;
2806 rtx prev, next, first, last, insn;
2808 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2809 into a MEM later. Protect the libcall block from this change. */
2810 if (! REG_P (target) || REG_USERVAR_P (target))
2811 target = gen_reg_rtx (GET_MODE (target));
2813 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2814 reg note to indicate that this call cannot throw or execute a nonlocal
2815 goto (unless there is already a REG_EH_REGION note, in which case
2816 we update it). */
2818 for (insn = insns; insn; insn = NEXT_INSN (insn))
2819 if (GET_CODE (insn) == CALL_INSN)
2821 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2823 if (note != 0)
2824 XEXP (note, 0) = GEN_INT (-1);
2825 else
2826 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2827 REG_NOTES (insn));
2830 /* First emit all insns that set pseudos. Remove them from the list as
2831 we go. Avoid insns that set pseudos which were referenced in previous
2832 insns. These can be generated by move_by_pieces, for example,
2833 to update an address. Similarly, avoid insns that reference things
2834 set in previous insns. */
2836 for (insn = insns; insn; insn = next)
2838 rtx set = single_set (insn);
2840 next = NEXT_INSN (insn);
2842 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2843 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2844 && (insn == insns
2845 || ((! INSN_P(insns)
2846 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
2847 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2848 && ! modified_in_p (SET_SRC (set), insns)
2849 && ! modified_between_p (SET_SRC (set), insns, insn))))
2851 if (PREV_INSN (insn))
2852 NEXT_INSN (PREV_INSN (insn)) = next;
2853 else
2854 insns = next;
2856 if (next)
2857 PREV_INSN (next) = PREV_INSN (insn);
2859 add_insn (insn);
2863 prev = get_last_insn ();
2865 /* Write the remaining insns followed by the final copy. */
2867 for (insn = insns; insn; insn = next)
2869 next = NEXT_INSN (insn);
2871 add_insn (insn);
2874 last = emit_move_insn (target, result);
2875 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2876 != CODE_FOR_nothing)
2877 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2878 else
2880 /* Remove any existing REG_EQUAL note from "last", or else it will
2881 be mistaken for a note referring to the full contents of the
2882 libcall value when found together with the REG_RETVAL note added
2883 below. An existing note can come from an insn expansion at
2884 "last". */
2885 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2888 if (final_dest != target)
2889 emit_move_insn (final_dest, target);
2891 if (prev == 0)
2892 first = get_insns ();
2893 else
2894 first = NEXT_INSN (prev);
2896 /* Encapsulate the block so it gets manipulated as a unit. */
2897 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2898 REG_NOTES (first));
2899 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2902 /* Generate code to store zero in X. */
2904 void
2905 emit_clr_insn (x)
2906 rtx x;
2908 emit_move_insn (x, const0_rtx);
2911 /* Generate code to store 1 in X
2912 assuming it contains zero beforehand. */
2914 void
2915 emit_0_to_1_insn (x)
2916 rtx x;
2918 emit_move_insn (x, const1_rtx);
2921 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2922 PURPOSE describes how this comparison will be used. CODE is the rtx
2923 comparison code we will be using.
2925 ??? Actually, CODE is slightly weaker than that. A target is still
2926 required to implement all of the normal bcc operations, but not
2927 required to implement all (or any) of the unordered bcc operations. */
2930 can_compare_p (code, mode, purpose)
2931 enum rtx_code code;
2932 enum machine_mode mode;
2933 enum can_compare_purpose purpose;
2937 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2939 if (purpose == ccp_jump)
2940 return bcc_gen_fctn[(int)code] != NULL;
2941 else if (purpose == ccp_store_flag)
2942 return setcc_gen_code[(int)code] != CODE_FOR_nothing;
2943 else
2944 /* There's only one cmov entry point, and it's allowed to fail. */
2945 return 1;
2947 if (purpose == ccp_jump
2948 && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2949 return 1;
2950 if (purpose == ccp_cmov
2951 && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2952 return 1;
2953 if (purpose == ccp_store_flag
2954 && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2955 return 1;
2957 mode = GET_MODE_WIDER_MODE (mode);
2959 while (mode != VOIDmode);
2961 return 0;
2964 /* This function is called when we are going to emit a compare instruction that
2965 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2967 *PMODE is the mode of the inputs (in case they are const_int).
2968 *PUNSIGNEDP nonzero says that the operands are unsigned;
2969 this matters if they need to be widened.
2971 If they have mode BLKmode, then SIZE specifies the size of both operands,
2972 and ALIGN specifies the known shared alignment of the operands.
2974 This function performs all the setup necessary so that the caller only has
2975 to emit a single comparison insn. This setup can involve doing a BLKmode
2976 comparison or emitting a library call to perform the comparison if no insn
2977 is available to handle it.
2978 The values which are passed in through pointers can be modified; the caller
2979 should perform the comparison on the modified values. */
2981 void
2982 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
2983 purpose)
2984 rtx *px, *py;
2985 enum rtx_code *pcomparison;
2986 rtx size;
2987 enum machine_mode *pmode;
2988 int *punsignedp;
2989 int align ATTRIBUTE_UNUSED;
2990 enum can_compare_purpose purpose;
2992 enum machine_mode mode = *pmode;
2993 rtx x = *px, y = *py;
2994 int unsignedp = *punsignedp;
2995 enum mode_class class;
2996 rtx opalign ATTRIBUTE_UNUSED = GEN_INT (align / BITS_PER_UNIT);;
2998 class = GET_MODE_CLASS (mode);
3000 /* They could both be VOIDmode if both args are immediate constants,
3001 but we should fold that at an earlier stage.
3002 With no special code here, this will call abort,
3003 reminding the programmer to implement such folding. */
3005 if (mode != BLKmode && flag_force_mem)
3007 x = force_not_mem (x);
3008 y = force_not_mem (y);
3011 /* If we are inside an appropriately-short loop and one operand is an
3012 expensive constant, force it into a register. */
3013 if (CONSTANT_P (x) && preserve_subexpressions_p ()
3014 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3015 x = force_reg (mode, x);
3017 if (CONSTANT_P (y) && preserve_subexpressions_p ()
3018 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3019 y = force_reg (mode, y);
3021 #ifdef HAVE_cc0
3022 /* Abort if we have a non-canonical comparison. The RTL documentation
3023 states that canonical comparisons are required only for targets which
3024 have cc0. */
3025 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3026 abort();
3027 #endif
3029 /* Don't let both operands fail to indicate the mode. */
3030 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3031 x = force_reg (mode, x);
3033 /* Handle all BLKmode compares. */
3035 if (mode == BLKmode)
3037 rtx result;
3038 enum machine_mode result_mode;
3040 emit_queue ();
3041 x = protect_from_queue (x, 0);
3042 y = protect_from_queue (y, 0);
3044 if (size == 0)
3045 abort ();
3046 #ifdef HAVE_cmpstrqi
3047 if (HAVE_cmpstrqi
3048 && GET_CODE (size) == CONST_INT
3049 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3051 result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3052 result = gen_reg_rtx (result_mode);
3053 emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3055 else
3056 #endif
3057 #ifdef HAVE_cmpstrhi
3058 if (HAVE_cmpstrhi
3059 && GET_CODE (size) == CONST_INT
3060 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3062 result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3063 result = gen_reg_rtx (result_mode);
3064 emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3066 else
3067 #endif
3068 #ifdef HAVE_cmpstrsi
3069 if (HAVE_cmpstrsi)
3071 result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3072 result = gen_reg_rtx (result_mode);
3073 size = protect_from_queue (size, 0);
3074 emit_insn (gen_cmpstrsi (result, x, y,
3075 convert_to_mode (SImode, size, 1),
3076 opalign));
3078 else
3079 #endif
3081 #ifdef TARGET_MEM_FUNCTIONS
3082 emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3083 TYPE_MODE (integer_type_node), 3,
3084 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3085 convert_to_mode (TYPE_MODE (sizetype), size,
3086 TREE_UNSIGNED (sizetype)),
3087 TYPE_MODE (sizetype));
3088 #else
3089 emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3090 TYPE_MODE (integer_type_node), 3,
3091 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3092 convert_to_mode (TYPE_MODE (integer_type_node),
3093 size,
3094 TREE_UNSIGNED (integer_type_node)),
3095 TYPE_MODE (integer_type_node));
3096 #endif
3098 /* Immediately move the result of the libcall into a pseudo
3099 register so reload doesn't clobber the value if it needs
3100 the return register for a spill reg. */
3101 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3102 result_mode = TYPE_MODE (integer_type_node);
3103 emit_move_insn (result,
3104 hard_libcall_value (result_mode));
3106 *px = result;
3107 *py = const0_rtx;
3108 *pmode = result_mode;
3109 return;
3112 *px = x;
3113 *py = y;
3114 if (can_compare_p (*pcomparison, mode, purpose))
3115 return;
3117 /* Handle a lib call just for the mode we are using. */
3119 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3121 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3122 rtx result;
3124 /* If we want unsigned, and this mode has a distinct unsigned
3125 comparison routine, use that. */
3126 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3127 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3129 emit_library_call (libfunc, 1,
3130 word_mode, 2, x, mode, y, mode);
3132 /* Immediately move the result of the libcall into a pseudo
3133 register so reload doesn't clobber the value if it needs
3134 the return register for a spill reg. */
3135 result = gen_reg_rtx (word_mode);
3136 emit_move_insn (result, hard_libcall_value (word_mode));
3138 /* Integer comparison returns a result that must be compared against 1,
3139 so that even if we do an unsigned compare afterward,
3140 there is still a value that can represent the result "less than". */
3141 *px = result;
3142 *py = const1_rtx;
3143 *pmode = word_mode;
3144 return;
3147 if (class == MODE_FLOAT)
3148 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3150 else
3151 abort ();
3154 /* Before emitting an insn with code ICODE, make sure that X, which is going
3155 to be used for operand OPNUM of the insn, is converted from mode MODE to
3156 WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3157 that it is accepted by the operand predicate. Return the new value. */
3160 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3161 int icode;
3162 rtx x;
3163 int opnum;
3164 enum machine_mode mode, wider_mode;
3165 int unsignedp;
3167 x = protect_from_queue (x, 0);
3169 if (mode != wider_mode)
3170 x = convert_modes (wider_mode, mode, x, unsignedp);
3172 if (! (*insn_data[icode].operand[opnum].predicate)
3173 (x, insn_data[icode].operand[opnum].mode))
3174 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3175 return x;
3178 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3179 we can do the comparison.
3180 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3181 be NULL_RTX which indicates that only a comparison is to be generated. */
3183 static void
3184 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3185 rtx x, y;
3186 enum machine_mode mode;
3187 enum rtx_code comparison;
3188 int unsignedp;
3189 rtx label;
3191 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3192 enum mode_class class = GET_MODE_CLASS (mode);
3193 enum machine_mode wider_mode = mode;
3195 /* Try combined insns first. */
3198 enum insn_code icode;
3199 PUT_MODE (test, wider_mode);
3201 if (label)
3203 icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3205 if (icode != CODE_FOR_nothing
3206 && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3208 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3209 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3210 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3211 return;
3215 /* Handle some compares against zero. */
3216 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3217 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3219 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3220 emit_insn (GEN_FCN (icode) (x));
3221 if (label)
3222 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3223 return;
3226 /* Handle compares for which there is a directly suitable insn. */
3228 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3229 if (icode != CODE_FOR_nothing)
3231 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3232 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3233 emit_insn (GEN_FCN (icode) (x, y));
3234 if (label)
3235 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3236 return;
3239 if (class != MODE_INT && class != MODE_FLOAT
3240 && class != MODE_COMPLEX_FLOAT)
3241 break;
3243 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3244 } while (wider_mode != VOIDmode);
3246 abort ();
3249 /* Generate code to compare X with Y so that the condition codes are
3250 set and to jump to LABEL if the condition is true. If X is a
3251 constant and Y is not a constant, then the comparison is swapped to
3252 ensure that the comparison RTL has the canonical form.
3254 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3255 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3256 the proper branch condition code.
3258 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3259 and ALIGN specifies the known shared alignment of X and Y.
3261 MODE is the mode of the inputs (in case they are const_int).
3263 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3264 be passed unchanged to emit_cmp_insn, then potentially converted into an
3265 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3267 void
3268 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3269 rtx x, y;
3270 enum rtx_code comparison;
3271 rtx size;
3272 enum machine_mode mode;
3273 int unsignedp;
3274 unsigned int align;
3275 rtx label;
3277 rtx op0;
3278 rtx op1;
3280 if ((CONSTANT_P (x) && ! CONSTANT_P (y))
3281 || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
3283 /* Swap operands and condition to ensure canonical RTL. */
3284 op0 = y;
3285 op1 = x;
3286 comparison = swap_condition (comparison);
3288 else
3290 op0 = x;
3291 op1 = y;
3294 #ifdef HAVE_cc0
3295 /* If OP0 is still a constant, then both X and Y must be constants. Force
3296 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3297 RTL. */
3298 if (CONSTANT_P (op0))
3299 op0 = force_reg (mode, op0);
3300 #endif
3302 emit_queue ();
3303 if (unsignedp)
3304 comparison = unsigned_condition (comparison);
3305 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, align,
3306 ccp_jump);
3307 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3310 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3312 void
3313 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3314 rtx x, y;
3315 enum rtx_code comparison;
3316 rtx size;
3317 enum machine_mode mode;
3318 int unsignedp;
3319 unsigned int align;
3321 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
3324 /* Emit a library call comparison between floating point X and Y.
3325 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3327 static void
3328 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3329 rtx *px, *py;
3330 enum rtx_code *pcomparison;
3331 enum machine_mode *pmode;
3332 int *punsignedp;
3334 enum rtx_code comparison = *pcomparison;
3335 rtx x = *px = protect_from_queue (*px, 0);
3336 rtx y = *py = protect_from_queue (*py, 0);
3337 enum machine_mode mode = GET_MODE (x);
3338 rtx libfunc = 0;
3339 rtx result;
3341 if (mode == HFmode)
3342 switch (comparison)
3344 case EQ:
3345 libfunc = eqhf2_libfunc;
3346 break;
3348 case NE:
3349 libfunc = nehf2_libfunc;
3350 break;
3352 case GT:
3353 libfunc = gthf2_libfunc;
3354 break;
3356 case GE:
3357 libfunc = gehf2_libfunc;
3358 break;
3360 case LT:
3361 libfunc = lthf2_libfunc;
3362 break;
3364 case LE:
3365 libfunc = lehf2_libfunc;
3366 break;
3368 case UNORDERED:
3369 libfunc = unordhf2_libfunc;
3370 break;
3372 default:
3373 break;
3375 else if (mode == SFmode)
3376 switch (comparison)
3378 case EQ:
3379 libfunc = eqsf2_libfunc;
3380 break;
3382 case NE:
3383 libfunc = nesf2_libfunc;
3384 break;
3386 case GT:
3387 libfunc = gtsf2_libfunc;
3388 break;
3390 case GE:
3391 libfunc = gesf2_libfunc;
3392 break;
3394 case LT:
3395 libfunc = ltsf2_libfunc;
3396 break;
3398 case LE:
3399 libfunc = lesf2_libfunc;
3400 break;
3402 case UNORDERED:
3403 libfunc = unordsf2_libfunc;
3404 break;
3406 default:
3407 break;
3409 else if (mode == DFmode)
3410 switch (comparison)
3412 case EQ:
3413 libfunc = eqdf2_libfunc;
3414 break;
3416 case NE:
3417 libfunc = nedf2_libfunc;
3418 break;
3420 case GT:
3421 libfunc = gtdf2_libfunc;
3422 break;
3424 case GE:
3425 libfunc = gedf2_libfunc;
3426 break;
3428 case LT:
3429 libfunc = ltdf2_libfunc;
3430 break;
3432 case LE:
3433 libfunc = ledf2_libfunc;
3434 break;
3436 case UNORDERED:
3437 libfunc = unorddf2_libfunc;
3438 break;
3440 default:
3441 break;
3443 else if (mode == XFmode)
3444 switch (comparison)
3446 case EQ:
3447 libfunc = eqxf2_libfunc;
3448 break;
3450 case NE:
3451 libfunc = nexf2_libfunc;
3452 break;
3454 case GT:
3455 libfunc = gtxf2_libfunc;
3456 break;
3458 case GE:
3459 libfunc = gexf2_libfunc;
3460 break;
3462 case LT:
3463 libfunc = ltxf2_libfunc;
3464 break;
3466 case LE:
3467 libfunc = lexf2_libfunc;
3468 break;
3470 case UNORDERED:
3471 libfunc = unordxf2_libfunc;
3472 break;
3474 default:
3475 break;
3477 else if (mode == TFmode)
3478 switch (comparison)
3480 case EQ:
3481 libfunc = eqtf2_libfunc;
3482 break;
3484 case NE:
3485 libfunc = netf2_libfunc;
3486 break;
3488 case GT:
3489 libfunc = gttf2_libfunc;
3490 break;
3492 case GE:
3493 libfunc = getf2_libfunc;
3494 break;
3496 case LT:
3497 libfunc = lttf2_libfunc;
3498 break;
3500 case LE:
3501 libfunc = letf2_libfunc;
3502 break;
3504 case UNORDERED:
3505 libfunc = unordtf2_libfunc;
3506 break;
3508 default:
3509 break;
3511 else
3513 enum machine_mode wider_mode;
3515 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3516 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3518 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3519 != CODE_FOR_nothing)
3520 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3522 x = protect_from_queue (x, 0);
3523 y = protect_from_queue (y, 0);
3524 *px = convert_to_mode (wider_mode, x, 0);
3525 *py = convert_to_mode (wider_mode, y, 0);
3526 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3527 return;
3530 abort ();
3533 if (libfunc == 0)
3534 abort ();
3536 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
3537 mode);
3539 /* Immediately move the result of the libcall into a pseudo
3540 register so reload doesn't clobber the value if it needs
3541 the return register for a spill reg. */
3542 result = gen_reg_rtx (word_mode);
3543 emit_move_insn (result, hard_libcall_value (word_mode));
3544 *px = result;
3545 *py = const0_rtx;
3546 *pmode = word_mode;
3547 if (comparison == UNORDERED)
3548 *pcomparison = NE;
3549 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3550 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3551 *pcomparison = NE;
3552 #endif
3553 *punsignedp = 0;
3556 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3558 void
3559 emit_indirect_jump (loc)
3560 rtx loc;
3562 if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
3563 (loc, Pmode)))
3564 loc = copy_to_mode_reg (Pmode, loc);
3566 emit_jump_insn (gen_indirect_jump (loc));
3567 emit_barrier ();
3570 #ifdef HAVE_conditional_move
3572 /* Emit a conditional move instruction if the machine supports one for that
3573 condition and machine mode.
3575 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3576 the mode to use should they be constants. If it is VOIDmode, they cannot
3577 both be constants.
3579 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3580 should be stored there. MODE is the mode to use should they be constants.
3581 If it is VOIDmode, they cannot both be constants.
3583 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3584 is not supported. */
3587 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3588 unsignedp)
3589 rtx target;
3590 enum rtx_code code;
3591 rtx op0, op1;
3592 enum machine_mode cmode;
3593 rtx op2, op3;
3594 enum machine_mode mode;
3595 int unsignedp;
3597 rtx tem, subtarget, comparison, insn;
3598 enum insn_code icode;
3600 /* If one operand is constant, make it the second one. Only do this
3601 if the other operand is not constant as well. */
3603 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3604 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3606 tem = op0;
3607 op0 = op1;
3608 op1 = tem;
3609 code = swap_condition (code);
3612 /* get_condition will prefer to generate LT and GT even if the old
3613 comparison was against zero, so undo that canonicalization here since
3614 comparisons against zero are cheaper. */
3615 if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
3616 code = LE, op1 = const0_rtx;
3617 else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
3618 code = GE, op1 = const0_rtx;
3620 if (cmode == VOIDmode)
3621 cmode = GET_MODE (op0);
3623 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3624 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3625 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3626 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3628 tem = op2;
3629 op2 = op3;
3630 op3 = tem;
3631 code = reverse_condition (code);
3634 if (mode == VOIDmode)
3635 mode = GET_MODE (op2);
3637 icode = movcc_gen_code[mode];
3639 if (icode == CODE_FOR_nothing)
3640 return 0;
3642 if (flag_force_mem)
3644 op2 = force_not_mem (op2);
3645 op3 = force_not_mem (op3);
3648 if (target)
3649 target = protect_from_queue (target, 1);
3650 else
3651 target = gen_reg_rtx (mode);
3653 subtarget = target;
3655 emit_queue ();
3657 op2 = protect_from_queue (op2, 0);
3658 op3 = protect_from_queue (op3, 0);
3660 /* If the insn doesn't accept these operands, put them in pseudos. */
3662 if (! (*insn_data[icode].operand[0].predicate)
3663 (subtarget, insn_data[icode].operand[0].mode))
3664 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3666 if (! (*insn_data[icode].operand[2].predicate)
3667 (op2, insn_data[icode].operand[2].mode))
3668 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3670 if (! (*insn_data[icode].operand[3].predicate)
3671 (op3, insn_data[icode].operand[3].mode))
3672 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3674 /* Everything should now be in the suitable form, so emit the compare insn
3675 and then the conditional move. */
3677 comparison
3678 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3680 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3681 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3682 return NULL and let the caller figure out how best to deal with this
3683 situation. */
3684 if (GET_CODE (comparison) != code)
3685 return NULL_RTX;
3687 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3689 /* If that failed, then give up. */
3690 if (insn == 0)
3691 return 0;
3693 emit_insn (insn);
3695 if (subtarget != target)
3696 convert_move (target, subtarget, 0);
3698 return target;
3701 /* Return non-zero if a conditional move of mode MODE is supported.
3703 This function is for combine so it can tell whether an insn that looks
3704 like a conditional move is actually supported by the hardware. If we
3705 guess wrong we lose a bit on optimization, but that's it. */
3706 /* ??? sparc64 supports conditionally moving integers values based on fp
3707 comparisons, and vice versa. How do we handle them? */
3710 can_conditionally_move_p (mode)
3711 enum machine_mode mode;
3713 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3714 return 1;
3716 return 0;
3719 #endif /* HAVE_conditional_move */
3721 /* These three functions generate an insn body and return it
3722 rather than emitting the insn.
3724 They do not protect from queued increments,
3725 because they may be used 1) in protect_from_queue itself
3726 and 2) in other passes where there is no queue. */
3728 /* Generate and return an insn body to add Y to X. */
3731 gen_add2_insn (x, y)
3732 rtx x, y;
3734 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3736 if (! ((*insn_data[icode].operand[0].predicate)
3737 (x, insn_data[icode].operand[0].mode))
3738 || ! ((*insn_data[icode].operand[1].predicate)
3739 (x, insn_data[icode].operand[1].mode))
3740 || ! ((*insn_data[icode].operand[2].predicate)
3741 (y, insn_data[icode].operand[2].mode)))
3742 abort ();
3744 return (GEN_FCN (icode) (x, x, y));
3748 have_add2_insn (mode)
3749 enum machine_mode mode;
3751 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3754 /* Generate and return an insn body to subtract Y from X. */
3757 gen_sub2_insn (x, y)
3758 rtx x, y;
3760 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3762 if (! ((*insn_data[icode].operand[0].predicate)
3763 (x, insn_data[icode].operand[0].mode))
3764 || ! ((*insn_data[icode].operand[1].predicate)
3765 (x, insn_data[icode].operand[1].mode))
3766 || ! ((*insn_data[icode].operand[2].predicate)
3767 (y, insn_data[icode].operand[2].mode)))
3768 abort ();
3770 return (GEN_FCN (icode) (x, x, y));
3774 have_sub2_insn (mode)
3775 enum machine_mode mode;
3777 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3780 /* Generate the body of an instruction to copy Y into X.
3781 It may be a SEQUENCE, if one insn isn't enough. */
3784 gen_move_insn (x, y)
3785 rtx x, y;
3787 register enum machine_mode mode = GET_MODE (x);
3788 enum insn_code insn_code;
3789 rtx seq;
3791 if (mode == VOIDmode)
3792 mode = GET_MODE (y);
3794 insn_code = mov_optab->handlers[(int) mode].insn_code;
3796 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3797 find a mode to do it in. If we have a movcc, use it. Otherwise,
3798 find the MODE_INT mode of the same width. */
3800 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3802 enum machine_mode tmode = VOIDmode;
3803 rtx x1 = x, y1 = y;
3805 if (mode != CCmode
3806 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3807 tmode = CCmode;
3808 else
3809 for (tmode = QImode; tmode != VOIDmode;
3810 tmode = GET_MODE_WIDER_MODE (tmode))
3811 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3812 break;
3814 if (tmode == VOIDmode)
3815 abort ();
3817 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3818 may call change_address which is not appropriate if we were
3819 called when a reload was in progress. We don't have to worry
3820 about changing the address since the size in bytes is supposed to
3821 be the same. Copy the MEM to change the mode and move any
3822 substitutions from the old MEM to the new one. */
3824 if (reload_in_progress)
3826 x = gen_lowpart_common (tmode, x1);
3827 if (x == 0 && GET_CODE (x1) == MEM)
3829 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3830 MEM_COPY_ATTRIBUTES (x, x1);
3831 copy_replacements (x1, x);
3834 y = gen_lowpart_common (tmode, y1);
3835 if (y == 0 && GET_CODE (y1) == MEM)
3837 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3838 MEM_COPY_ATTRIBUTES (y, y1);
3839 copy_replacements (y1, y);
3842 else
3844 x = gen_lowpart (tmode, x);
3845 y = gen_lowpart (tmode, y);
3848 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3849 return (GEN_FCN (insn_code) (x, y));
3852 start_sequence ();
3853 emit_move_insn_1 (x, y);
3854 seq = gen_sequence ();
3855 end_sequence ();
3856 return seq;
3859 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3860 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3861 no such operation exists, CODE_FOR_nothing will be returned. */
3863 enum insn_code
3864 can_extend_p (to_mode, from_mode, unsignedp)
3865 enum machine_mode to_mode, from_mode;
3866 int unsignedp;
3868 return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
3871 /* Generate the body of an insn to extend Y (with mode MFROM)
3872 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3875 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3876 rtx x, y;
3877 enum machine_mode mto, mfrom;
3878 int unsignedp;
3880 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
3883 /* can_fix_p and can_float_p say whether the target machine
3884 can directly convert a given fixed point type to
3885 a given floating point type, or vice versa.
3886 The returned value is the CODE_FOR_... value to use,
3887 or CODE_FOR_nothing if these modes cannot be directly converted.
3889 *TRUNCP_PTR is set to 1 if it is necessary to output
3890 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3892 static enum insn_code
3893 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3894 enum machine_mode fltmode, fixmode;
3895 int unsignedp;
3896 int *truncp_ptr;
3898 *truncp_ptr = 0;
3899 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
3900 != CODE_FOR_nothing)
3901 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
3903 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3905 *truncp_ptr = 1;
3906 return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
3908 return CODE_FOR_nothing;
3911 static enum insn_code
3912 can_float_p (fltmode, fixmode, unsignedp)
3913 enum machine_mode fixmode, fltmode;
3914 int unsignedp;
3916 return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
3919 /* Generate code to convert FROM to floating point
3920 and store in TO. FROM must be fixed point and not VOIDmode.
3921 UNSIGNEDP nonzero means regard FROM as unsigned.
3922 Normally this is done by correcting the final value
3923 if it is negative. */
3925 void
3926 expand_float (to, from, unsignedp)
3927 rtx to, from;
3928 int unsignedp;
3930 enum insn_code icode;
3931 register rtx target = to;
3932 enum machine_mode fmode, imode;
3934 /* Crash now, because we won't be able to decide which mode to use. */
3935 if (GET_MODE (from) == VOIDmode)
3936 abort ();
3938 /* Look for an insn to do the conversion. Do it in the specified
3939 modes if possible; otherwise convert either input, output or both to
3940 wider mode. If the integer mode is wider than the mode of FROM,
3941 we can do the conversion signed even if the input is unsigned. */
3943 for (imode = GET_MODE (from); imode != VOIDmode;
3944 imode = GET_MODE_WIDER_MODE (imode))
3945 for (fmode = GET_MODE (to); fmode != VOIDmode;
3946 fmode = GET_MODE_WIDER_MODE (fmode))
3948 int doing_unsigned = unsignedp;
3950 if (fmode != GET_MODE (to)
3951 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
3952 continue;
3954 icode = can_float_p (fmode, imode, unsignedp);
3955 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3956 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3958 if (icode != CODE_FOR_nothing)
3960 to = protect_from_queue (to, 1);
3961 from = protect_from_queue (from, 0);
3963 if (imode != GET_MODE (from))
3964 from = convert_to_mode (imode, from, unsignedp);
3966 if (fmode != GET_MODE (to))
3967 target = gen_reg_rtx (fmode);
3969 emit_unop_insn (icode, target, from,
3970 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3972 if (target != to)
3973 convert_move (to, target, 0);
3974 return;
3978 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3980 /* Unsigned integer, and no way to convert directly.
3981 Convert as signed, then conditionally adjust the result. */
3982 if (unsignedp)
3984 rtx label = gen_label_rtx ();
3985 rtx temp;
3986 REAL_VALUE_TYPE offset;
3988 emit_queue ();
3990 to = protect_from_queue (to, 1);
3991 from = protect_from_queue (from, 0);
3993 if (flag_force_mem)
3994 from = force_not_mem (from);
3996 /* Look for a usable floating mode FMODE wider than the source and at
3997 least as wide as the target. Using FMODE will avoid rounding woes
3998 with unsigned values greater than the signed maximum value. */
4000 for (fmode = GET_MODE (to); fmode != VOIDmode;
4001 fmode = GET_MODE_WIDER_MODE (fmode))
4002 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
4003 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4004 break;
4006 if (fmode == VOIDmode)
4008 /* There is no such mode. Pretend the target is wide enough. */
4009 fmode = GET_MODE (to);
4011 /* Avoid double-rounding when TO is narrower than FROM. */
4012 if ((significand_size (fmode) + 1)
4013 < GET_MODE_BITSIZE (GET_MODE (from)))
4015 rtx temp1;
4016 rtx neglabel = gen_label_rtx ();
4018 /* Don't use TARGET if it isn't a register, is a hard register,
4019 or is the wrong mode. */
4020 if (GET_CODE (target) != REG
4021 || REGNO (target) < FIRST_PSEUDO_REGISTER
4022 || GET_MODE (target) != fmode)
4023 target = gen_reg_rtx (fmode);
4025 imode = GET_MODE (from);
4026 do_pending_stack_adjust ();
4028 /* Test whether the sign bit is set. */
4029 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4030 0, 0, neglabel);
4032 /* The sign bit is not set. Convert as signed. */
4033 expand_float (target, from, 0);
4034 emit_jump_insn (gen_jump (label));
4035 emit_barrier ();
4037 /* The sign bit is set.
4038 Convert to a usable (positive signed) value by shifting right
4039 one bit, while remembering if a nonzero bit was shifted
4040 out; i.e., compute (from & 1) | (from >> 1). */
4042 emit_label (neglabel);
4043 temp = expand_binop (imode, and_optab, from, const1_rtx,
4044 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4045 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4046 NULL_RTX, 1);
4047 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4048 OPTAB_LIB_WIDEN);
4049 expand_float (target, temp, 0);
4051 /* Multiply by 2 to undo the shift above. */
4052 temp = expand_binop (fmode, add_optab, target, target,
4053 target, 0, OPTAB_LIB_WIDEN);
4054 if (temp != target)
4055 emit_move_insn (target, temp);
4057 do_pending_stack_adjust ();
4058 emit_label (label);
4059 goto done;
4063 /* If we are about to do some arithmetic to correct for an
4064 unsigned operand, do it in a pseudo-register. */
4066 if (GET_MODE (to) != fmode
4067 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4068 target = gen_reg_rtx (fmode);
4070 /* Convert as signed integer to floating. */
4071 expand_float (target, from, 0);
4073 /* If FROM is negative (and therefore TO is negative),
4074 correct its value by 2**bitwidth. */
4076 do_pending_stack_adjust ();
4077 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4078 0, 0, label);
4080 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4081 Rather than setting up a dconst_dot_5, let's hope SCO
4082 fixes the bug. */
4083 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4084 temp = expand_binop (fmode, add_optab, target,
4085 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4086 target, 0, OPTAB_LIB_WIDEN);
4087 if (temp != target)
4088 emit_move_insn (target, temp);
4090 do_pending_stack_adjust ();
4091 emit_label (label);
4092 goto done;
4094 #endif
4096 /* No hardware instruction available; call a library routine to convert from
4097 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4099 rtx libfcn;
4100 rtx insns;
4101 rtx value;
4103 to = protect_from_queue (to, 1);
4104 from = protect_from_queue (from, 0);
4106 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4107 from = convert_to_mode (SImode, from, unsignedp);
4109 if (flag_force_mem)
4110 from = force_not_mem (from);
4112 if (GET_MODE (to) == SFmode)
4114 if (GET_MODE (from) == SImode)
4115 libfcn = floatsisf_libfunc;
4116 else if (GET_MODE (from) == DImode)
4117 libfcn = floatdisf_libfunc;
4118 else if (GET_MODE (from) == TImode)
4119 libfcn = floattisf_libfunc;
4120 else
4121 abort ();
4123 else if (GET_MODE (to) == DFmode)
4125 if (GET_MODE (from) == SImode)
4126 libfcn = floatsidf_libfunc;
4127 else if (GET_MODE (from) == DImode)
4128 libfcn = floatdidf_libfunc;
4129 else if (GET_MODE (from) == TImode)
4130 libfcn = floattidf_libfunc;
4131 else
4132 abort ();
4134 else if (GET_MODE (to) == XFmode)
4136 if (GET_MODE (from) == SImode)
4137 libfcn = floatsixf_libfunc;
4138 else if (GET_MODE (from) == DImode)
4139 libfcn = floatdixf_libfunc;
4140 else if (GET_MODE (from) == TImode)
4141 libfcn = floattixf_libfunc;
4142 else
4143 abort ();
4145 else if (GET_MODE (to) == TFmode)
4147 if (GET_MODE (from) == SImode)
4148 libfcn = floatsitf_libfunc;
4149 else if (GET_MODE (from) == DImode)
4150 libfcn = floatditf_libfunc;
4151 else if (GET_MODE (from) == TImode)
4152 libfcn = floattitf_libfunc;
4153 else
4154 abort ();
4156 else
4157 abort ();
4159 start_sequence ();
4161 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4162 GET_MODE (to), 1, from,
4163 GET_MODE (from));
4164 insns = get_insns ();
4165 end_sequence ();
4167 emit_libcall_block (insns, target, value,
4168 gen_rtx_FLOAT (GET_MODE (to), from));
4171 done:
4173 /* Copy result to requested destination
4174 if we have been computing in a temp location. */
4176 if (target != to)
4178 if (GET_MODE (target) == GET_MODE (to))
4179 emit_move_insn (to, target);
4180 else
4181 convert_move (to, target, 0);
4185 /* expand_fix: generate code to convert FROM to fixed point
4186 and store in TO. FROM must be floating point. */
4188 static rtx
4189 ftruncify (x)
4190 rtx x;
4192 rtx temp = gen_reg_rtx (GET_MODE (x));
4193 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4196 void
4197 expand_fix (to, from, unsignedp)
4198 register rtx to, from;
4199 int unsignedp;
4201 enum insn_code icode;
4202 register rtx target = to;
4203 enum machine_mode fmode, imode;
4204 int must_trunc = 0;
4205 rtx libfcn = 0;
4207 /* We first try to find a pair of modes, one real and one integer, at
4208 least as wide as FROM and TO, respectively, in which we can open-code
4209 this conversion. If the integer mode is wider than the mode of TO,
4210 we can do the conversion either signed or unsigned. */
4212 for (imode = GET_MODE (to); imode != VOIDmode;
4213 imode = GET_MODE_WIDER_MODE (imode))
4214 for (fmode = GET_MODE (from); fmode != VOIDmode;
4215 fmode = GET_MODE_WIDER_MODE (fmode))
4217 int doing_unsigned = unsignedp;
4219 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4220 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4221 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4223 if (icode != CODE_FOR_nothing)
4225 to = protect_from_queue (to, 1);
4226 from = protect_from_queue (from, 0);
4228 if (fmode != GET_MODE (from))
4229 from = convert_to_mode (fmode, from, 0);
4231 if (must_trunc)
4232 from = ftruncify (from);
4234 if (imode != GET_MODE (to))
4235 target = gen_reg_rtx (imode);
4237 emit_unop_insn (icode, target, from,
4238 doing_unsigned ? UNSIGNED_FIX : FIX);
4239 if (target != to)
4240 convert_move (to, target, unsignedp);
4241 return;
4245 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4246 /* For an unsigned conversion, there is one more way to do it.
4247 If we have a signed conversion, we generate code that compares
4248 the real value to the largest representable positive number. If if
4249 is smaller, the conversion is done normally. Otherwise, subtract
4250 one plus the highest signed number, convert, and add it back.
4252 We only need to check all real modes, since we know we didn't find
4253 anything with a wider integer mode. */
4255 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4256 for (fmode = GET_MODE (from); fmode != VOIDmode;
4257 fmode = GET_MODE_WIDER_MODE (fmode))
4258 /* Make sure we won't lose significant bits doing this. */
4259 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4260 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4261 &must_trunc))
4263 int bitsize;
4264 REAL_VALUE_TYPE offset;
4265 rtx limit, lab1, lab2, insn;
4267 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4268 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4269 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4270 lab1 = gen_label_rtx ();
4271 lab2 = gen_label_rtx ();
4273 emit_queue ();
4274 to = protect_from_queue (to, 1);
4275 from = protect_from_queue (from, 0);
4277 if (flag_force_mem)
4278 from = force_not_mem (from);
4280 if (fmode != GET_MODE (from))
4281 from = convert_to_mode (fmode, from, 0);
4283 /* See if we need to do the subtraction. */
4284 do_pending_stack_adjust ();
4285 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4286 0, 0, lab1);
4288 /* If not, do the signed "fix" and branch around fixup code. */
4289 expand_fix (to, from, 0);
4290 emit_jump_insn (gen_jump (lab2));
4291 emit_barrier ();
4293 /* Otherwise, subtract 2**(N-1), convert to signed number,
4294 then add 2**(N-1). Do the addition using XOR since this
4295 will often generate better code. */
4296 emit_label (lab1);
4297 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4298 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4299 expand_fix (to, target, 0);
4300 target = expand_binop (GET_MODE (to), xor_optab, to,
4301 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4302 to, 1, OPTAB_LIB_WIDEN);
4304 if (target != to)
4305 emit_move_insn (to, target);
4307 emit_label (lab2);
4309 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4310 != CODE_FOR_nothing)
4312 /* Make a place for a REG_NOTE and add it. */
4313 insn = emit_move_insn (to, to);
4314 set_unique_reg_note (insn,
4315 REG_EQUAL,
4316 gen_rtx_fmt_e (UNSIGNED_FIX,
4317 GET_MODE (to),
4318 copy_rtx (from)));
4321 return;
4323 #endif
4325 /* We can't do it with an insn, so use a library call. But first ensure
4326 that the mode of TO is at least as wide as SImode, since those are the
4327 only library calls we know about. */
4329 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4331 target = gen_reg_rtx (SImode);
4333 expand_fix (target, from, unsignedp);
4335 else if (GET_MODE (from) == SFmode)
4337 if (GET_MODE (to) == SImode)
4338 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4339 else if (GET_MODE (to) == DImode)
4340 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4341 else if (GET_MODE (to) == TImode)
4342 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4343 else
4344 abort ();
4346 else if (GET_MODE (from) == DFmode)
4348 if (GET_MODE (to) == SImode)
4349 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4350 else if (GET_MODE (to) == DImode)
4351 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4352 else if (GET_MODE (to) == TImode)
4353 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4354 else
4355 abort ();
4357 else if (GET_MODE (from) == XFmode)
4359 if (GET_MODE (to) == SImode)
4360 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4361 else if (GET_MODE (to) == DImode)
4362 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4363 else if (GET_MODE (to) == TImode)
4364 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4365 else
4366 abort ();
4368 else if (GET_MODE (from) == TFmode)
4370 if (GET_MODE (to) == SImode)
4371 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4372 else if (GET_MODE (to) == DImode)
4373 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4374 else if (GET_MODE (to) == TImode)
4375 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4376 else
4377 abort ();
4379 else
4380 abort ();
4382 if (libfcn)
4384 rtx insns;
4385 rtx value;
4387 to = protect_from_queue (to, 1);
4388 from = protect_from_queue (from, 0);
4390 if (flag_force_mem)
4391 from = force_not_mem (from);
4393 start_sequence ();
4395 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4396 GET_MODE (to), 1, from,
4397 GET_MODE (from));
4398 insns = get_insns ();
4399 end_sequence ();
4401 emit_libcall_block (insns, target, value,
4402 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4403 GET_MODE (to), from));
4406 if (target != to)
4408 if (GET_MODE (to) == GET_MODE (target))
4409 emit_move_insn (to, target);
4410 else
4411 convert_move (to, target, 0);
4415 static optab
4416 init_optab (code)
4417 enum rtx_code code;
4419 int i;
4420 optab op = (optab) xmalloc (sizeof (struct optab));
4421 op->code = code;
4422 for (i = 0; i < NUM_MACHINE_MODES; i++)
4424 op->handlers[i].insn_code = CODE_FOR_nothing;
4425 op->handlers[i].libfunc = 0;
4428 if (code != UNKNOWN)
4429 code_to_optab[(int) code] = op;
4431 return op;
4434 /* Initialize the libfunc fields of an entire group of entries in some
4435 optab. Each entry is set equal to a string consisting of a leading
4436 pair of underscores followed by a generic operation name followed by
4437 a mode name (downshifted to lower case) followed by a single character
4438 representing the number of operands for the given operation (which is
4439 usually one of the characters '2', '3', or '4').
4441 OPTABLE is the table in which libfunc fields are to be initialized.
4442 FIRST_MODE is the first machine mode index in the given optab to
4443 initialize.
4444 LAST_MODE is the last machine mode index in the given optab to
4445 initialize.
4446 OPNAME is the generic (string) name of the operation.
4447 SUFFIX is the character which specifies the number of operands for
4448 the given generic operation.
4451 static void
4452 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4453 register optab optable;
4454 register int first_mode;
4455 register int last_mode;
4456 register const char *opname;
4457 register int suffix;
4459 register int mode;
4460 register unsigned opname_len = strlen (opname);
4462 for (mode = first_mode; (int) mode <= (int) last_mode;
4463 mode = (enum machine_mode) ((int) mode + 1))
4465 register const char *mname = GET_MODE_NAME(mode);
4466 register unsigned mname_len = strlen (mname);
4467 register char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4468 register char *p;
4469 register const char *q;
4471 p = libfunc_name;
4472 *p++ = '_';
4473 *p++ = '_';
4474 for (q = opname; *q; )
4475 *p++ = *q++;
4476 for (q = mname; *q; q++)
4477 *p++ = TOLOWER (*q);
4478 *p++ = suffix;
4479 *p = '\0';
4481 optable->handlers[(int) mode].libfunc
4482 = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
4483 p - libfunc_name));
4487 /* Initialize the libfunc fields of an entire group of entries in some
4488 optab which correspond to all integer mode operations. The parameters
4489 have the same meaning as similarly named ones for the `init_libfuncs'
4490 routine. (See above). */
4492 static void
4493 init_integral_libfuncs (optable, opname, suffix)
4494 register optab optable;
4495 register const char *opname;
4496 register int suffix;
4498 init_libfuncs (optable, SImode, TImode, opname, suffix);
4501 /* Initialize the libfunc fields of an entire group of entries in some
4502 optab which correspond to all real mode operations. The parameters
4503 have the same meaning as similarly named ones for the `init_libfuncs'
4504 routine. (See above). */
4506 static void
4507 init_floating_libfuncs (optable, opname, suffix)
4508 register optab optable;
4509 register const char *opname;
4510 register int suffix;
4512 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4516 init_one_libfunc (name)
4517 register const char *name;
4519 name = ggc_strdup (name);
4521 return gen_rtx_SYMBOL_REF (Pmode, name);
4524 /* Mark ARG (which is really an OPTAB *) for GC. */
4526 void
4527 mark_optab (arg)
4528 void *arg;
4530 optab o = *(optab *) arg;
4531 int i;
4533 for (i = 0; i < NUM_MACHINE_MODES; ++i)
4534 ggc_mark_rtx (o->handlers[i].libfunc);
4537 /* Call this once to initialize the contents of the optabs
4538 appropriately for the current target machine. */
4540 void
4541 init_optabs ()
4543 unsigned int i, j, k;
4545 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4547 for (i = 0; i < ARRAY_SIZE (fixtab); i++)
4548 for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
4549 for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
4550 fixtab[i][j][k] = CODE_FOR_nothing;
4552 for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
4553 for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
4554 for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
4555 fixtrunctab[i][j][k] = CODE_FOR_nothing;
4557 for (i = 0; i < ARRAY_SIZE (floattab); i++)
4558 for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
4559 for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
4560 floattab[i][j][k] = CODE_FOR_nothing;
4562 for (i = 0; i < ARRAY_SIZE (extendtab); i++)
4563 for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
4564 for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
4565 extendtab[i][j][k] = CODE_FOR_nothing;
4567 for (i = 0; i < NUM_RTX_CODE; i++)
4568 setcc_gen_code[i] = CODE_FOR_nothing;
4570 #ifdef HAVE_conditional_move
4571 for (i = 0; i < NUM_MACHINE_MODES; i++)
4572 movcc_gen_code[i] = CODE_FOR_nothing;
4573 #endif
4575 add_optab = init_optab (PLUS);
4576 addv_optab = init_optab (PLUS);
4577 sub_optab = init_optab (MINUS);
4578 subv_optab = init_optab (MINUS);
4579 smul_optab = init_optab (MULT);
4580 smulv_optab = init_optab (MULT);
4581 smul_highpart_optab = init_optab (UNKNOWN);
4582 umul_highpart_optab = init_optab (UNKNOWN);
4583 smul_widen_optab = init_optab (UNKNOWN);
4584 umul_widen_optab = init_optab (UNKNOWN);
4585 sdiv_optab = init_optab (DIV);
4586 sdivv_optab = init_optab (DIV);
4587 sdivmod_optab = init_optab (UNKNOWN);
4588 udiv_optab = init_optab (UDIV);
4589 udivmod_optab = init_optab (UNKNOWN);
4590 smod_optab = init_optab (MOD);
4591 umod_optab = init_optab (UMOD);
4592 flodiv_optab = init_optab (DIV);
4593 ftrunc_optab = init_optab (UNKNOWN);
4594 and_optab = init_optab (AND);
4595 ior_optab = init_optab (IOR);
4596 xor_optab = init_optab (XOR);
4597 ashl_optab = init_optab (ASHIFT);
4598 ashr_optab = init_optab (ASHIFTRT);
4599 lshr_optab = init_optab (LSHIFTRT);
4600 rotl_optab = init_optab (ROTATE);
4601 rotr_optab = init_optab (ROTATERT);
4602 smin_optab = init_optab (SMIN);
4603 smax_optab = init_optab (SMAX);
4604 umin_optab = init_optab (UMIN);
4605 umax_optab = init_optab (UMAX);
4606 mov_optab = init_optab (UNKNOWN);
4607 movstrict_optab = init_optab (UNKNOWN);
4608 cmp_optab = init_optab (UNKNOWN);
4609 ucmp_optab = init_optab (UNKNOWN);
4610 tst_optab = init_optab (UNKNOWN);
4611 neg_optab = init_optab (NEG);
4612 negv_optab = init_optab (NEG);
4613 abs_optab = init_optab (ABS);
4614 absv_optab = init_optab (ABS);
4615 one_cmpl_optab = init_optab (NOT);
4616 ffs_optab = init_optab (FFS);
4617 sqrt_optab = init_optab (SQRT);
4618 sin_optab = init_optab (UNKNOWN);
4619 cos_optab = init_optab (UNKNOWN);
4620 strlen_optab = init_optab (UNKNOWN);
4621 cbranch_optab = init_optab (UNKNOWN);
4622 cmov_optab = init_optab (UNKNOWN);
4623 cstore_optab = init_optab (UNKNOWN);
4625 for (i = 0; i < NUM_MACHINE_MODES; i++)
4627 movstr_optab[i] = CODE_FOR_nothing;
4628 clrstr_optab[i] = CODE_FOR_nothing;
4630 #ifdef HAVE_SECONDARY_RELOADS
4631 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4632 #endif
4635 /* Fill in the optabs with the insns we support. */
4636 init_all_optabs ();
4638 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4639 /* This flag says the same insns that convert to a signed fixnum
4640 also convert validly to an unsigned one. */
4641 for (i = 0; i < NUM_MACHINE_MODES; i++)
4642 for (j = 0; j < NUM_MACHINE_MODES; j++)
4643 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4644 #endif
4646 /* Initialize the optabs with the names of the library functions. */
4647 init_integral_libfuncs (add_optab, "add", '3');
4648 init_floating_libfuncs (add_optab, "add", '3');
4649 init_integral_libfuncs (addv_optab, "addv", '3');
4650 init_floating_libfuncs (addv_optab, "add", '3');
4651 init_integral_libfuncs (sub_optab, "sub", '3');
4652 init_floating_libfuncs (sub_optab, "sub", '3');
4653 init_integral_libfuncs (subv_optab, "subv", '3');
4654 init_floating_libfuncs (subv_optab, "sub", '3');
4655 init_integral_libfuncs (smul_optab, "mul", '3');
4656 init_floating_libfuncs (smul_optab, "mul", '3');
4657 init_integral_libfuncs (smulv_optab, "mulv", '3');
4658 init_floating_libfuncs (smulv_optab, "mul", '3');
4659 init_integral_libfuncs (sdiv_optab, "div", '3');
4660 init_integral_libfuncs (sdivv_optab, "divv", '3');
4661 init_integral_libfuncs (udiv_optab, "udiv", '3');
4662 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4663 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4664 init_integral_libfuncs (smod_optab, "mod", '3');
4665 init_integral_libfuncs (umod_optab, "umod", '3');
4666 init_floating_libfuncs (flodiv_optab, "div", '3');
4667 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4668 init_integral_libfuncs (and_optab, "and", '3');
4669 init_integral_libfuncs (ior_optab, "ior", '3');
4670 init_integral_libfuncs (xor_optab, "xor", '3');
4671 init_integral_libfuncs (ashl_optab, "ashl", '3');
4672 init_integral_libfuncs (ashr_optab, "ashr", '3');
4673 init_integral_libfuncs (lshr_optab, "lshr", '3');
4674 init_integral_libfuncs (smin_optab, "min", '3');
4675 init_floating_libfuncs (smin_optab, "min", '3');
4676 init_integral_libfuncs (smax_optab, "max", '3');
4677 init_floating_libfuncs (smax_optab, "max", '3');
4678 init_integral_libfuncs (umin_optab, "umin", '3');
4679 init_integral_libfuncs (umax_optab, "umax", '3');
4680 init_integral_libfuncs (neg_optab, "neg", '2');
4681 init_floating_libfuncs (neg_optab, "neg", '2');
4682 init_integral_libfuncs (negv_optab, "negv", '2');
4683 init_floating_libfuncs (negv_optab, "neg", '2');
4684 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4685 init_integral_libfuncs (ffs_optab, "ffs", '2');
4687 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4688 init_integral_libfuncs (cmp_optab, "cmp", '2');
4689 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4690 init_floating_libfuncs (cmp_optab, "cmp", '2');
4692 #ifdef MULSI3_LIBCALL
4693 smul_optab->handlers[(int) SImode].libfunc
4694 = init_one_libfunc (MULSI3_LIBCALL);
4695 #endif
4696 #ifdef MULDI3_LIBCALL
4697 smul_optab->handlers[(int) DImode].libfunc
4698 = init_one_libfunc (MULDI3_LIBCALL);
4699 #endif
4701 #ifdef DIVSI3_LIBCALL
4702 sdiv_optab->handlers[(int) SImode].libfunc
4703 = init_one_libfunc (DIVSI3_LIBCALL);
4704 #endif
4705 #ifdef DIVDI3_LIBCALL
4706 sdiv_optab->handlers[(int) DImode].libfunc
4707 = init_one_libfunc (DIVDI3_LIBCALL);
4708 #endif
4710 #ifdef UDIVSI3_LIBCALL
4711 udiv_optab->handlers[(int) SImode].libfunc
4712 = init_one_libfunc (UDIVSI3_LIBCALL);
4713 #endif
4714 #ifdef UDIVDI3_LIBCALL
4715 udiv_optab->handlers[(int) DImode].libfunc
4716 = init_one_libfunc (UDIVDI3_LIBCALL);
4717 #endif
4719 #ifdef MODSI3_LIBCALL
4720 smod_optab->handlers[(int) SImode].libfunc
4721 = init_one_libfunc (MODSI3_LIBCALL);
4722 #endif
4723 #ifdef MODDI3_LIBCALL
4724 smod_optab->handlers[(int) DImode].libfunc
4725 = init_one_libfunc (MODDI3_LIBCALL);
4726 #endif
4728 #ifdef UMODSI3_LIBCALL
4729 umod_optab->handlers[(int) SImode].libfunc
4730 = init_one_libfunc (UMODSI3_LIBCALL);
4731 #endif
4732 #ifdef UMODDI3_LIBCALL
4733 umod_optab->handlers[(int) DImode].libfunc
4734 = init_one_libfunc (UMODDI3_LIBCALL);
4735 #endif
4737 /* Use cabs for DC complex abs, since systems generally have cabs.
4738 Don't define any libcall for SCmode, so that cabs will be used. */
4739 abs_optab->handlers[(int) DCmode].libfunc
4740 = init_one_libfunc ("cabs");
4742 /* The ffs function operates on `int'. */
4743 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
4744 = init_one_libfunc ("ffs");
4746 extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
4747 extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
4748 extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
4749 extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
4750 extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
4752 truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
4753 truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
4754 trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
4755 truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
4756 trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
4758 memcpy_libfunc = init_one_libfunc ("memcpy");
4759 memmove_libfunc = init_one_libfunc ("memmove");
4760 bcopy_libfunc = init_one_libfunc ("bcopy");
4761 memcmp_libfunc = init_one_libfunc ("memcmp");
4762 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
4763 memset_libfunc = init_one_libfunc ("memset");
4764 bzero_libfunc = init_one_libfunc ("bzero");
4766 throw_libfunc = init_one_libfunc ("__throw");
4767 rethrow_libfunc = init_one_libfunc ("__rethrow");
4768 sjthrow_libfunc = init_one_libfunc ("__sjthrow");
4769 sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
4770 terminate_libfunc = init_one_libfunc ("__terminate");
4771 eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
4772 #ifndef DONT_USE_BUILTIN_SETJMP
4773 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
4774 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
4775 #else
4776 setjmp_libfunc = init_one_libfunc ("setjmp");
4777 longjmp_libfunc = init_one_libfunc ("longjmp");
4778 #endif
4780 eqhf2_libfunc = init_one_libfunc ("__eqhf2");
4781 nehf2_libfunc = init_one_libfunc ("__nehf2");
4782 gthf2_libfunc = init_one_libfunc ("__gthf2");
4783 gehf2_libfunc = init_one_libfunc ("__gehf2");
4784 lthf2_libfunc = init_one_libfunc ("__lthf2");
4785 lehf2_libfunc = init_one_libfunc ("__lehf2");
4786 unordhf2_libfunc = init_one_libfunc ("__unordhf2");
4788 eqsf2_libfunc = init_one_libfunc ("__eqsf2");
4789 nesf2_libfunc = init_one_libfunc ("__nesf2");
4790 gtsf2_libfunc = init_one_libfunc ("__gtsf2");
4791 gesf2_libfunc = init_one_libfunc ("__gesf2");
4792 ltsf2_libfunc = init_one_libfunc ("__ltsf2");
4793 lesf2_libfunc = init_one_libfunc ("__lesf2");
4794 unordsf2_libfunc = init_one_libfunc ("__unordsf2");
4796 eqdf2_libfunc = init_one_libfunc ("__eqdf2");
4797 nedf2_libfunc = init_one_libfunc ("__nedf2");
4798 gtdf2_libfunc = init_one_libfunc ("__gtdf2");
4799 gedf2_libfunc = init_one_libfunc ("__gedf2");
4800 ltdf2_libfunc = init_one_libfunc ("__ltdf2");
4801 ledf2_libfunc = init_one_libfunc ("__ledf2");
4802 unorddf2_libfunc = init_one_libfunc ("__unorddf2");
4804 eqxf2_libfunc = init_one_libfunc ("__eqxf2");
4805 nexf2_libfunc = init_one_libfunc ("__nexf2");
4806 gtxf2_libfunc = init_one_libfunc ("__gtxf2");
4807 gexf2_libfunc = init_one_libfunc ("__gexf2");
4808 ltxf2_libfunc = init_one_libfunc ("__ltxf2");
4809 lexf2_libfunc = init_one_libfunc ("__lexf2");
4810 unordxf2_libfunc = init_one_libfunc ("__unordxf2");
4812 eqtf2_libfunc = init_one_libfunc ("__eqtf2");
4813 netf2_libfunc = init_one_libfunc ("__netf2");
4814 gttf2_libfunc = init_one_libfunc ("__gttf2");
4815 getf2_libfunc = init_one_libfunc ("__getf2");
4816 lttf2_libfunc = init_one_libfunc ("__lttf2");
4817 letf2_libfunc = init_one_libfunc ("__letf2");
4818 unordtf2_libfunc = init_one_libfunc ("__unordtf2");
4820 floatsisf_libfunc = init_one_libfunc ("__floatsisf");
4821 floatdisf_libfunc = init_one_libfunc ("__floatdisf");
4822 floattisf_libfunc = init_one_libfunc ("__floattisf");
4824 floatsidf_libfunc = init_one_libfunc ("__floatsidf");
4825 floatdidf_libfunc = init_one_libfunc ("__floatdidf");
4826 floattidf_libfunc = init_one_libfunc ("__floattidf");
4828 floatsixf_libfunc = init_one_libfunc ("__floatsixf");
4829 floatdixf_libfunc = init_one_libfunc ("__floatdixf");
4830 floattixf_libfunc = init_one_libfunc ("__floattixf");
4832 floatsitf_libfunc = init_one_libfunc ("__floatsitf");
4833 floatditf_libfunc = init_one_libfunc ("__floatditf");
4834 floattitf_libfunc = init_one_libfunc ("__floattitf");
4836 fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
4837 fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
4838 fixsfti_libfunc = init_one_libfunc ("__fixsfti");
4840 fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
4841 fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
4842 fixdfti_libfunc = init_one_libfunc ("__fixdfti");
4844 fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
4845 fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
4846 fixxfti_libfunc = init_one_libfunc ("__fixxfti");
4848 fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
4849 fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
4850 fixtfti_libfunc = init_one_libfunc ("__fixtfti");
4852 fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
4853 fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
4854 fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
4856 fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
4857 fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
4858 fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
4860 fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
4861 fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
4862 fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
4864 fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
4865 fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
4866 fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
4868 /* For check-memory-usage. */
4869 chkr_check_addr_libfunc = init_one_libfunc ("chkr_check_addr");
4870 chkr_set_right_libfunc = init_one_libfunc ("chkr_set_right");
4871 chkr_copy_bitmap_libfunc = init_one_libfunc ("chkr_copy_bitmap");
4872 chkr_check_exec_libfunc = init_one_libfunc ("chkr_check_exec");
4873 chkr_check_str_libfunc = init_one_libfunc ("chkr_check_str");
4875 /* For function entry/exit instrumentation. */
4876 profile_function_entry_libfunc
4877 = init_one_libfunc ("__cyg_profile_func_enter");
4878 profile_function_exit_libfunc
4879 = init_one_libfunc ("__cyg_profile_func_exit");
4881 #ifdef HAVE_conditional_trap
4882 init_traps ();
4883 #endif
4885 #ifdef INIT_TARGET_OPTABS
4886 /* Allow the target to add more libcalls or rename some, etc. */
4887 INIT_TARGET_OPTABS;
4888 #endif
4890 /* Add these GC roots. */
4891 ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
4892 ggc_add_rtx_root (libfunc_table, LTI_MAX);
4895 #ifdef BROKEN_LDEXP
4897 /* SCO 3.2 apparently has a broken ldexp. */
4899 double
4900 ldexp(x,n)
4901 double x;
4902 int n;
4904 if (n > 0)
4905 while (n--)
4906 x *= 2;
4908 return x;
4910 #endif /* BROKEN_LDEXP */
4912 #ifdef HAVE_conditional_trap
4913 /* The insn generating function can not take an rtx_code argument.
4914 TRAP_RTX is used as an rtx argument. Its code is replaced with
4915 the code to be used in the trap insn and all other fields are
4916 ignored. */
4917 static rtx trap_rtx;
4919 static void
4920 init_traps ()
4922 if (HAVE_conditional_trap)
4924 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4925 ggc_add_rtx_root (&trap_rtx, 1);
4928 #endif
4930 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4931 CODE. Return 0 on failure. */
4934 gen_cond_trap (code, op1, op2, tcode)
4935 enum rtx_code code ATTRIBUTE_UNUSED;
4936 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4938 enum machine_mode mode = GET_MODE (op1);
4940 if (mode == VOIDmode)
4941 return 0;
4943 #ifdef HAVE_conditional_trap
4944 if (HAVE_conditional_trap
4945 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4947 rtx insn;
4948 start_sequence();
4949 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4950 PUT_CODE (trap_rtx, code);
4951 insn = gen_conditional_trap (trap_rtx, tcode);
4952 if (insn)
4954 emit_insn (insn);
4955 insn = gen_sequence ();
4957 end_sequence();
4958 return insn;
4960 #endif
4962 return 0;