* Makefile.in (SYSTEM_H): Define.
[official-gcc.git] / gcc / optabs.c
blob0322510300d2a84571343363709398a3a5d58ddf
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2001 Free Software Foundation, Inc.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #include "config.h"
24 #include "system.h"
25 #include "toplev.h"
27 /* Include insn-config.h before expr.h so that HAVE_conditional_move
28 is properly defined. */
29 #include "insn-config.h"
30 #include "rtl.h"
31 #include "tree.h"
32 #include "tm_p.h"
33 #include "flags.h"
34 #include "function.h"
35 #include "expr.h"
36 #include "recog.h"
37 #include "reload.h"
38 #include "ggc.h"
39 #include "real.h"
41 /* Each optab contains info on how this target machine
42 can perform a particular operation
43 for all sizes and kinds of operands.
45 The operation to be performed is often specified
46 by passing one of these optabs as an argument.
48 See expr.h for documentation of these optabs. */
50 optab optab_table[OTI_MAX];
52 rtx libfunc_table[LTI_MAX];
54 /* Tables of patterns for extending one integer mode to another. */
55 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
57 /* Tables of patterns for converting between fixed and floating point. */
58 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
59 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
60 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
62 /* Contains the optab used for each rtx code. */
63 optab code_to_optab[NUM_RTX_CODE + 1];
65 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
66 gives the gen_function to make a branch to test that condition. */
68 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
70 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
71 gives the insn code to make a store-condition insn
72 to test that condition. */
74 enum insn_code setcc_gen_code[NUM_RTX_CODE];
76 #ifdef HAVE_conditional_move
77 /* Indexed by the machine mode, gives the insn code to make a conditional
78 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
79 setcc_gen_code to cut down on the number of named patterns. Consider a day
80 when a lot more rtx codes are conditional (eg: for the ARM). */
82 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
83 #endif
85 static int add_equal_note PARAMS ((rtx, rtx, enum rtx_code, rtx, rtx));
86 static rtx widen_operand PARAMS ((rtx, enum machine_mode,
87 enum machine_mode, int, int));
88 static int expand_cmplxdiv_straight PARAMS ((rtx, rtx, rtx, rtx,
89 rtx, rtx, enum machine_mode,
90 int, enum optab_methods,
91 enum mode_class, optab));
92 static int expand_cmplxdiv_wide PARAMS ((rtx, rtx, rtx, rtx,
93 rtx, rtx, enum machine_mode,
94 int, enum optab_methods,
95 enum mode_class, optab));
96 static enum insn_code can_fix_p PARAMS ((enum machine_mode, enum machine_mode,
97 int, int *));
98 static enum insn_code can_float_p PARAMS ((enum machine_mode, enum machine_mode,
99 int));
100 static rtx ftruncify PARAMS ((rtx));
101 static optab init_optab PARAMS ((enum rtx_code));
102 static void init_libfuncs PARAMS ((optab, int, int, const char *, int));
103 static void init_integral_libfuncs PARAMS ((optab, const char *, int));
104 static void init_floating_libfuncs PARAMS ((optab, const char *, int));
105 #ifdef HAVE_conditional_trap
106 static void init_traps PARAMS ((void));
107 #endif
108 static void emit_cmp_and_jump_insn_1 PARAMS ((rtx, rtx, enum machine_mode,
109 enum rtx_code, int, rtx));
110 static void prepare_float_lib_cmp PARAMS ((rtx *, rtx *, enum rtx_code *,
111 enum machine_mode *, int *));
113 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
114 the result of operation CODE applied to OP0 (and OP1 if it is a binary
115 operation).
117 If the last insn does not set TARGET, don't do anything, but return 1.
119 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
120 don't add the REG_EQUAL note but return 0. Our caller can then try
121 again, ensuring that TARGET is not one of the operands. */
123 static int
124 add_equal_note (seq, target, code, op0, op1)
125 rtx seq;
126 rtx target;
127 enum rtx_code code;
128 rtx op0, op1;
130 rtx set;
131 int i;
132 rtx note;
134 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
135 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
136 || GET_CODE (seq) != SEQUENCE
137 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
138 || GET_CODE (target) == ZERO_EXTRACT
139 || (! rtx_equal_p (SET_DEST (set), target)
140 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
141 SUBREG. */
142 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
143 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
144 target))))
145 return 1;
147 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
148 besides the last insn. */
149 if (reg_overlap_mentioned_p (target, op0)
150 || (op1 && reg_overlap_mentioned_p (target, op1)))
151 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
152 if (reg_set_p (target, XVECEXP (seq, 0, i)))
153 return 0;
155 if (GET_RTX_CLASS (code) == '1')
156 note = gen_rtx_fmt_e (code, GET_MODE (target), copy_rtx (op0));
157 else
158 note = gen_rtx_fmt_ee (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
160 set_unique_reg_note (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1), REG_EQUAL, note);
162 return 1;
165 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
166 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
167 not actually do a sign-extend or zero-extend, but can leave the
168 higher-order bits of the result rtx undefined, for example, in the case
169 of logical operations, but not right shifts. */
171 static rtx
172 widen_operand (op, mode, oldmode, unsignedp, no_extend)
173 rtx op;
174 enum machine_mode mode, oldmode;
175 int unsignedp;
176 int no_extend;
178 rtx result;
180 /* If we must extend do so. If OP is either a constant or a SUBREG
181 for a promoted object, also extend since it will be more efficient to
182 do so. */
183 if (! no_extend
184 || GET_MODE (op) == VOIDmode
185 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
186 return convert_modes (mode, oldmode, op, unsignedp);
188 /* If MODE is no wider than a single word, we return a paradoxical
189 SUBREG. */
190 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
191 return gen_rtx_SUBREG (mode, force_reg (GET_MODE (op), op), 0);
193 /* Otherwise, get an object of MODE, clobber it, and set the low-order
194 part to OP. */
196 result = gen_reg_rtx (mode);
197 emit_insn (gen_rtx_CLOBBER (VOIDmode, result));
198 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
199 return result;
202 /* Generate code to perform a straightforward complex divide. */
204 static int
205 expand_cmplxdiv_straight (real0, real1, imag0, imag1, realr, imagr, submode,
206 unsignedp, methods, class, binoptab)
207 rtx real0, real1, imag0, imag1, realr, imagr;
208 enum machine_mode submode;
209 int unsignedp;
210 enum optab_methods methods;
211 enum mode_class class;
212 optab binoptab;
214 rtx divisor;
215 rtx real_t, imag_t;
216 rtx temp1, temp2;
217 rtx res;
218 optab this_add_optab = add_optab;
219 optab this_sub_optab = sub_optab;
220 optab this_neg_optab = neg_optab;
221 optab this_mul_optab = smul_optab;
223 if (binoptab == sdivv_optab)
225 this_add_optab = addv_optab;
226 this_sub_optab = subv_optab;
227 this_neg_optab = negv_optab;
228 this_mul_optab = smulv_optab;
231 /* Don't fetch these from memory more than once. */
232 real0 = force_reg (submode, real0);
233 real1 = force_reg (submode, real1);
235 if (imag0 != 0)
236 imag0 = force_reg (submode, imag0);
238 imag1 = force_reg (submode, imag1);
240 /* Divisor: c*c + d*d. */
241 temp1 = expand_binop (submode, this_mul_optab, real1, real1,
242 NULL_RTX, unsignedp, methods);
244 temp2 = expand_binop (submode, this_mul_optab, imag1, imag1,
245 NULL_RTX, unsignedp, methods);
247 if (temp1 == 0 || temp2 == 0)
248 return 0;
250 divisor = expand_binop (submode, this_add_optab, temp1, temp2,
251 NULL_RTX, unsignedp, methods);
252 if (divisor == 0)
253 return 0;
255 if (imag0 == 0)
257 /* Mathematically, ((a)(c-id))/divisor. */
258 /* Computationally, (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)). */
260 /* Calculate the dividend. */
261 real_t = expand_binop (submode, this_mul_optab, real0, real1,
262 NULL_RTX, unsignedp, methods);
264 imag_t = expand_binop (submode, this_mul_optab, real0, imag1,
265 NULL_RTX, unsignedp, methods);
267 if (real_t == 0 || imag_t == 0)
268 return 0;
270 imag_t = expand_unop (submode, this_neg_optab, imag_t,
271 NULL_RTX, unsignedp);
273 else
275 /* Mathematically, ((a+ib)(c-id))/divider. */
276 /* Calculate the dividend. */
277 temp1 = expand_binop (submode, this_mul_optab, real0, real1,
278 NULL_RTX, unsignedp, methods);
280 temp2 = expand_binop (submode, this_mul_optab, imag0, imag1,
281 NULL_RTX, unsignedp, methods);
283 if (temp1 == 0 || temp2 == 0)
284 return 0;
286 real_t = expand_binop (submode, this_add_optab, temp1, temp2,
287 NULL_RTX, unsignedp, methods);
289 temp1 = expand_binop (submode, this_mul_optab, imag0, real1,
290 NULL_RTX, unsignedp, methods);
292 temp2 = expand_binop (submode, this_mul_optab, real0, imag1,
293 NULL_RTX, unsignedp, methods);
295 if (temp1 == 0 || temp2 == 0)
296 return 0;
298 imag_t = expand_binop (submode, this_sub_optab, temp1, temp2,
299 NULL_RTX, unsignedp, methods);
301 if (real_t == 0 || imag_t == 0)
302 return 0;
305 if (class == MODE_COMPLEX_FLOAT)
306 res = expand_binop (submode, binoptab, real_t, divisor,
307 realr, unsignedp, methods);
308 else
309 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
310 real_t, divisor, realr, unsignedp);
312 if (res == 0)
313 return 0;
315 if (res != realr)
316 emit_move_insn (realr, res);
318 if (class == MODE_COMPLEX_FLOAT)
319 res = expand_binop (submode, binoptab, imag_t, divisor,
320 imagr, unsignedp, methods);
321 else
322 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
323 imag_t, divisor, imagr, unsignedp);
325 if (res == 0)
326 return 0;
328 if (res != imagr)
329 emit_move_insn (imagr, res);
331 return 1;
334 /* Generate code to perform a wide-input-range-acceptable complex divide. */
336 static int
337 expand_cmplxdiv_wide (real0, real1, imag0, imag1, realr, imagr, submode,
338 unsignedp, methods, class, binoptab)
339 rtx real0, real1, imag0, imag1, realr, imagr;
340 enum machine_mode submode;
341 int unsignedp;
342 enum optab_methods methods;
343 enum mode_class class;
344 optab binoptab;
346 rtx ratio, divisor;
347 rtx real_t, imag_t;
348 rtx temp1, temp2, lab1, lab2;
349 enum machine_mode mode;
350 int align;
351 rtx res;
352 optab this_add_optab = add_optab;
353 optab this_sub_optab = sub_optab;
354 optab this_neg_optab = neg_optab;
355 optab this_mul_optab = smul_optab;
357 if (binoptab == sdivv_optab)
359 this_add_optab = addv_optab;
360 this_sub_optab = subv_optab;
361 this_neg_optab = negv_optab;
362 this_mul_optab = smulv_optab;
365 /* Don't fetch these from memory more than once. */
366 real0 = force_reg (submode, real0);
367 real1 = force_reg (submode, real1);
369 if (imag0 != 0)
370 imag0 = force_reg (submode, imag0);
372 imag1 = force_reg (submode, imag1);
374 /* XXX What's an "unsigned" complex number? */
375 if (unsignedp)
377 temp1 = real1;
378 temp2 = imag1;
380 else
382 temp1 = expand_abs (submode, real1, NULL_RTX, unsignedp, 1);
383 temp2 = expand_abs (submode, imag1, NULL_RTX, unsignedp, 1);
386 if (temp1 == 0 || temp2 == 0)
387 return 0;
389 mode = GET_MODE (temp1);
390 align = GET_MODE_ALIGNMENT (mode);
391 lab1 = gen_label_rtx ();
392 emit_cmp_and_jump_insns (temp1, temp2, LT, NULL_RTX,
393 mode, unsignedp, align, lab1);
395 /* |c| >= |d|; use ratio d/c to scale dividend and divisor. */
397 if (class == MODE_COMPLEX_FLOAT)
398 ratio = expand_binop (submode, binoptab, imag1, real1,
399 NULL_RTX, unsignedp, methods);
400 else
401 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
402 imag1, real1, NULL_RTX, unsignedp);
404 if (ratio == 0)
405 return 0;
407 /* Calculate divisor. */
409 temp1 = expand_binop (submode, this_mul_optab, imag1, ratio,
410 NULL_RTX, unsignedp, methods);
412 if (temp1 == 0)
413 return 0;
415 divisor = expand_binop (submode, this_add_optab, temp1, real1,
416 NULL_RTX, unsignedp, methods);
418 if (divisor == 0)
419 return 0;
421 /* Calculate dividend. */
423 if (imag0 == 0)
425 real_t = real0;
427 /* Compute a / (c+id) as a / (c+d(d/c)) + i (-a(d/c)) / (c+d(d/c)). */
429 imag_t = expand_binop (submode, this_mul_optab, real0, ratio,
430 NULL_RTX, unsignedp, methods);
432 if (imag_t == 0)
433 return 0;
435 imag_t = expand_unop (submode, this_neg_optab, imag_t,
436 NULL_RTX, unsignedp);
438 if (real_t == 0 || imag_t == 0)
439 return 0;
441 else
443 /* Compute (a+ib)/(c+id) as
444 (a+b(d/c))/(c+d(d/c) + i(b-a(d/c))/(c+d(d/c)). */
446 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
447 NULL_RTX, unsignedp, methods);
449 if (temp1 == 0)
450 return 0;
452 real_t = expand_binop (submode, this_add_optab, temp1, real0,
453 NULL_RTX, unsignedp, methods);
455 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
456 NULL_RTX, unsignedp, methods);
458 if (temp1 == 0)
459 return 0;
461 imag_t = expand_binop (submode, this_sub_optab, imag0, temp1,
462 NULL_RTX, unsignedp, methods);
464 if (real_t == 0 || imag_t == 0)
465 return 0;
468 if (class == MODE_COMPLEX_FLOAT)
469 res = expand_binop (submode, binoptab, real_t, divisor,
470 realr, unsignedp, methods);
471 else
472 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
473 real_t, divisor, realr, unsignedp);
475 if (res == 0)
476 return 0;
478 if (res != realr)
479 emit_move_insn (realr, res);
481 if (class == MODE_COMPLEX_FLOAT)
482 res = expand_binop (submode, binoptab, imag_t, divisor,
483 imagr, unsignedp, methods);
484 else
485 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
486 imag_t, divisor, imagr, unsignedp);
488 if (res == 0)
489 return 0;
491 if (res != imagr)
492 emit_move_insn (imagr, res);
494 lab2 = gen_label_rtx ();
495 emit_jump_insn (gen_jump (lab2));
496 emit_barrier ();
498 emit_label (lab1);
500 /* |d| > |c|; use ratio c/d to scale dividend and divisor. */
502 if (class == MODE_COMPLEX_FLOAT)
503 ratio = expand_binop (submode, binoptab, real1, imag1,
504 NULL_RTX, unsignedp, methods);
505 else
506 ratio = expand_divmod (0, TRUNC_DIV_EXPR, submode,
507 real1, imag1, NULL_RTX, unsignedp);
509 if (ratio == 0)
510 return 0;
512 /* Calculate divisor. */
514 temp1 = expand_binop (submode, this_mul_optab, real1, ratio,
515 NULL_RTX, unsignedp, methods);
517 if (temp1 == 0)
518 return 0;
520 divisor = expand_binop (submode, this_add_optab, temp1, imag1,
521 NULL_RTX, unsignedp, methods);
523 if (divisor == 0)
524 return 0;
526 /* Calculate dividend. */
528 if (imag0 == 0)
530 /* Compute a / (c+id) as a(c/d) / (c(c/d)+d) + i (-a) / (c(c/d)+d). */
532 real_t = expand_binop (submode, this_mul_optab, real0, ratio,
533 NULL_RTX, unsignedp, methods);
535 imag_t = expand_unop (submode, this_neg_optab, real0,
536 NULL_RTX, unsignedp);
538 if (real_t == 0 || imag_t == 0)
539 return 0;
541 else
543 /* Compute (a+ib)/(c+id) as
544 (a(c/d)+b)/(c(c/d)+d) + i (b(c/d)-a)/(c(c/d)+d). */
546 temp1 = expand_binop (submode, this_mul_optab, real0, ratio,
547 NULL_RTX, unsignedp, methods);
549 if (temp1 == 0)
550 return 0;
552 real_t = expand_binop (submode, this_add_optab, temp1, imag0,
553 NULL_RTX, unsignedp, methods);
555 temp1 = expand_binop (submode, this_mul_optab, imag0, ratio,
556 NULL_RTX, unsignedp, methods);
558 if (temp1 == 0)
559 return 0;
561 imag_t = expand_binop (submode, this_sub_optab, temp1, real0,
562 NULL_RTX, unsignedp, methods);
564 if (real_t == 0 || imag_t == 0)
565 return 0;
568 if (class == MODE_COMPLEX_FLOAT)
569 res = expand_binop (submode, binoptab, real_t, divisor,
570 realr, unsignedp, methods);
571 else
572 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
573 real_t, divisor, realr, unsignedp);
575 if (res == 0)
576 return 0;
578 if (res != realr)
579 emit_move_insn (realr, res);
581 if (class == MODE_COMPLEX_FLOAT)
582 res = expand_binop (submode, binoptab, imag_t, divisor,
583 imagr, unsignedp, methods);
584 else
585 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
586 imag_t, divisor, imagr, unsignedp);
588 if (res == 0)
589 return 0;
591 if (res != imagr)
592 emit_move_insn (imagr, res);
594 emit_label (lab2);
596 return 1;
599 /* Generate code to perform an operation specified by BINOPTAB
600 on operands OP0 and OP1, with result having machine-mode MODE.
602 UNSIGNEDP is for the case where we have to widen the operands
603 to perform the operation. It says to use zero-extension.
605 If TARGET is nonzero, the value
606 is generated there, if it is convenient to do so.
607 In all cases an rtx is returned for the locus of the value;
608 this may or may not be TARGET. */
611 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
612 enum machine_mode mode;
613 optab binoptab;
614 rtx op0, op1;
615 rtx target;
616 int unsignedp;
617 enum optab_methods methods;
619 enum optab_methods next_methods
620 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
621 ? OPTAB_WIDEN : methods);
622 enum mode_class class;
623 enum machine_mode wider_mode;
624 register rtx temp;
625 int commutative_op = 0;
626 int shift_op = (binoptab->code == ASHIFT
627 || binoptab->code == ASHIFTRT
628 || binoptab->code == LSHIFTRT
629 || binoptab->code == ROTATE
630 || binoptab->code == ROTATERT);
631 rtx entry_last = get_last_insn ();
632 rtx last;
634 class = GET_MODE_CLASS (mode);
636 op0 = protect_from_queue (op0, 0);
637 op1 = protect_from_queue (op1, 0);
638 if (target)
639 target = protect_from_queue (target, 1);
641 if (flag_force_mem)
643 op0 = force_not_mem (op0);
644 op1 = force_not_mem (op1);
647 /* If subtracting an integer constant, convert this into an addition of
648 the negated constant. */
650 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
652 op1 = negate_rtx (mode, op1);
653 binoptab = add_optab;
656 /* If we are inside an appropriately-short loop and one operand is an
657 expensive constant, force it into a register. */
658 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
659 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
660 op0 = force_reg (mode, op0);
662 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
663 && ! shift_op && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
664 op1 = force_reg (mode, op1);
666 /* Record where to delete back to if we backtrack. */
667 last = get_last_insn ();
669 /* If operation is commutative,
670 try to make the first operand a register.
671 Even better, try to make it the same as the target.
672 Also try to make the last operand a constant. */
673 if (GET_RTX_CLASS (binoptab->code) == 'c'
674 || binoptab == smul_widen_optab
675 || binoptab == umul_widen_optab
676 || binoptab == smul_highpart_optab
677 || binoptab == umul_highpart_optab)
679 commutative_op = 1;
681 if (((target == 0 || GET_CODE (target) == REG)
682 ? ((GET_CODE (op1) == REG
683 && GET_CODE (op0) != REG)
684 || target == op1)
685 : rtx_equal_p (op1, target))
686 || GET_CODE (op0) == CONST_INT)
688 temp = op1;
689 op1 = op0;
690 op0 = temp;
694 /* If we can do it with a three-operand insn, do so. */
696 if (methods != OPTAB_MUST_WIDEN
697 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
699 int icode = (int) binoptab->handlers[(int) mode].insn_code;
700 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
701 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
702 rtx pat;
703 rtx xop0 = op0, xop1 = op1;
705 if (target)
706 temp = target;
707 else
708 temp = gen_reg_rtx (mode);
710 /* If it is a commutative operator and the modes would match
711 if we would swap the operands, we can save the conversions. */
712 if (commutative_op)
714 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
715 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
717 register rtx tmp;
719 tmp = op0; op0 = op1; op1 = tmp;
720 tmp = xop0; xop0 = xop1; xop1 = tmp;
724 /* In case the insn wants input operands in modes different from
725 the result, convert the operands. */
727 if (GET_MODE (op0) != VOIDmode
728 && GET_MODE (op0) != mode0
729 && mode0 != VOIDmode)
730 xop0 = convert_to_mode (mode0, xop0, unsignedp);
732 if (GET_MODE (xop1) != VOIDmode
733 && GET_MODE (xop1) != mode1
734 && mode1 != VOIDmode)
735 xop1 = convert_to_mode (mode1, xop1, unsignedp);
737 /* Now, if insn's predicates don't allow our operands, put them into
738 pseudo regs. */
740 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0)
741 && mode0 != VOIDmode)
742 xop0 = copy_to_mode_reg (mode0, xop0);
744 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1)
745 && mode1 != VOIDmode)
746 xop1 = copy_to_mode_reg (mode1, xop1);
748 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
749 temp = gen_reg_rtx (mode);
751 pat = GEN_FCN (icode) (temp, xop0, xop1);
752 if (pat)
754 /* If PAT is a multi-insn sequence, try to add an appropriate
755 REG_EQUAL note to it. If we can't because TEMP conflicts with an
756 operand, call ourselves again, this time without a target. */
757 if (GET_CODE (pat) == SEQUENCE
758 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
760 delete_insns_since (last);
761 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
762 unsignedp, methods);
765 emit_insn (pat);
766 return temp;
768 else
769 delete_insns_since (last);
772 /* If this is a multiply, see if we can do a widening operation that
773 takes operands of this mode and makes a wider mode. */
775 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
776 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
777 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
778 != CODE_FOR_nothing))
780 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
781 unsignedp ? umul_widen_optab : smul_widen_optab,
782 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
784 if (temp != 0)
786 if (GET_MODE_CLASS (mode) == MODE_INT)
787 return gen_lowpart (mode, temp);
788 else
789 return convert_to_mode (mode, temp, unsignedp);
793 /* Look for a wider mode of the same class for which we think we
794 can open-code the operation. Check for a widening multiply at the
795 wider mode as well. */
797 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
798 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
799 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
800 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
802 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
803 || (binoptab == smul_optab
804 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
805 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
806 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
807 != CODE_FOR_nothing)))
809 rtx xop0 = op0, xop1 = op1;
810 int no_extend = 0;
812 /* For certain integer operations, we need not actually extend
813 the narrow operands, as long as we will truncate
814 the results to the same narrowness. */
816 if ((binoptab == ior_optab || binoptab == and_optab
817 || binoptab == xor_optab
818 || binoptab == add_optab || binoptab == sub_optab
819 || binoptab == smul_optab || binoptab == ashl_optab)
820 && class == MODE_INT)
821 no_extend = 1;
823 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
825 /* The second operand of a shift must always be extended. */
826 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
827 no_extend && binoptab != ashl_optab);
829 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
830 unsignedp, OPTAB_DIRECT);
831 if (temp)
833 if (class != MODE_INT)
835 if (target == 0)
836 target = gen_reg_rtx (mode);
837 convert_move (target, temp, 0);
838 return target;
840 else
841 return gen_lowpart (mode, temp);
843 else
844 delete_insns_since (last);
848 /* These can be done a word at a time. */
849 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
850 && class == MODE_INT
851 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
852 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
854 unsigned int i;
855 rtx insns;
856 rtx equiv_value;
858 /* If TARGET is the same as one of the operands, the REG_EQUAL note
859 won't be accurate, so use a new target. */
860 if (target == 0 || target == op0 || target == op1)
861 target = gen_reg_rtx (mode);
863 start_sequence ();
865 /* Do the actual arithmetic. */
866 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
868 rtx target_piece = operand_subword (target, i, 1, mode);
869 rtx x = expand_binop (word_mode, binoptab,
870 operand_subword_force (op0, i, mode),
871 operand_subword_force (op1, i, mode),
872 target_piece, unsignedp, next_methods);
874 if (x == 0)
875 break;
877 if (target_piece != x)
878 emit_move_insn (target_piece, x);
881 insns = get_insns ();
882 end_sequence ();
884 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
886 if (binoptab->code != UNKNOWN)
887 equiv_value
888 = gen_rtx_fmt_ee (binoptab->code, mode,
889 copy_rtx (op0), copy_rtx (op1));
890 else
891 equiv_value = 0;
893 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
894 return target;
898 /* Synthesize double word shifts from single word shifts. */
899 if ((binoptab == lshr_optab || binoptab == ashl_optab
900 || binoptab == ashr_optab)
901 && class == MODE_INT
902 && GET_CODE (op1) == CONST_INT
903 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
904 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
905 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
906 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
908 rtx insns, inter, equiv_value;
909 rtx into_target, outof_target;
910 rtx into_input, outof_input;
911 int shift_count, left_shift, outof_word;
913 /* If TARGET is the same as one of the operands, the REG_EQUAL note
914 won't be accurate, so use a new target. */
915 if (target == 0 || target == op0 || target == op1)
916 target = gen_reg_rtx (mode);
918 start_sequence ();
920 shift_count = INTVAL (op1);
922 /* OUTOF_* is the word we are shifting bits away from, and
923 INTO_* is the word that we are shifting bits towards, thus
924 they differ depending on the direction of the shift and
925 WORDS_BIG_ENDIAN. */
927 left_shift = binoptab == ashl_optab;
928 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
930 outof_target = operand_subword (target, outof_word, 1, mode);
931 into_target = operand_subword (target, 1 - outof_word, 1, mode);
933 outof_input = operand_subword_force (op0, outof_word, mode);
934 into_input = operand_subword_force (op0, 1 - outof_word, mode);
936 if (shift_count >= BITS_PER_WORD)
938 inter = expand_binop (word_mode, binoptab,
939 outof_input,
940 GEN_INT (shift_count - BITS_PER_WORD),
941 into_target, unsignedp, next_methods);
943 if (inter != 0 && inter != into_target)
944 emit_move_insn (into_target, inter);
946 /* For a signed right shift, we must fill the word we are shifting
947 out of with copies of the sign bit. Otherwise it is zeroed. */
948 if (inter != 0 && binoptab != ashr_optab)
949 inter = CONST0_RTX (word_mode);
950 else if (inter != 0)
951 inter = expand_binop (word_mode, binoptab,
952 outof_input,
953 GEN_INT (BITS_PER_WORD - 1),
954 outof_target, unsignedp, next_methods);
956 if (inter != 0 && inter != outof_target)
957 emit_move_insn (outof_target, inter);
959 else
961 rtx carries;
962 optab reverse_unsigned_shift, unsigned_shift;
964 /* For a shift of less then BITS_PER_WORD, to compute the carry,
965 we must do a logical shift in the opposite direction of the
966 desired shift. */
968 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
970 /* For a shift of less than BITS_PER_WORD, to compute the word
971 shifted towards, we need to unsigned shift the orig value of
972 that word. */
974 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
976 carries = expand_binop (word_mode, reverse_unsigned_shift,
977 outof_input,
978 GEN_INT (BITS_PER_WORD - shift_count),
979 0, unsignedp, next_methods);
981 if (carries == 0)
982 inter = 0;
983 else
984 inter = expand_binop (word_mode, unsigned_shift, into_input,
985 op1, 0, unsignedp, next_methods);
987 if (inter != 0)
988 inter = expand_binop (word_mode, ior_optab, carries, inter,
989 into_target, unsignedp, next_methods);
991 if (inter != 0 && inter != into_target)
992 emit_move_insn (into_target, inter);
994 if (inter != 0)
995 inter = expand_binop (word_mode, binoptab, outof_input,
996 op1, outof_target, unsignedp, next_methods);
998 if (inter != 0 && inter != outof_target)
999 emit_move_insn (outof_target, inter);
1002 insns = get_insns ();
1003 end_sequence ();
1005 if (inter != 0)
1007 if (binoptab->code != UNKNOWN)
1008 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1009 else
1010 equiv_value = 0;
1012 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1013 return target;
1017 /* Synthesize double word rotates from single word shifts. */
1018 if ((binoptab == rotl_optab || binoptab == rotr_optab)
1019 && class == MODE_INT
1020 && GET_CODE (op1) == CONST_INT
1021 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1022 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1023 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1025 rtx insns, equiv_value;
1026 rtx into_target, outof_target;
1027 rtx into_input, outof_input;
1028 rtx inter;
1029 int shift_count, left_shift, outof_word;
1031 /* If TARGET is the same as one of the operands, the REG_EQUAL note
1032 won't be accurate, so use a new target. */
1033 if (target == 0 || target == op0 || target == op1)
1034 target = gen_reg_rtx (mode);
1036 start_sequence ();
1038 shift_count = INTVAL (op1);
1040 /* OUTOF_* is the word we are shifting bits away from, and
1041 INTO_* is the word that we are shifting bits towards, thus
1042 they differ depending on the direction of the shift and
1043 WORDS_BIG_ENDIAN. */
1045 left_shift = (binoptab == rotl_optab);
1046 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
1048 outof_target = operand_subword (target, outof_word, 1, mode);
1049 into_target = operand_subword (target, 1 - outof_word, 1, mode);
1051 outof_input = operand_subword_force (op0, outof_word, mode);
1052 into_input = operand_subword_force (op0, 1 - outof_word, mode);
1054 if (shift_count == BITS_PER_WORD)
1056 /* This is just a word swap. */
1057 emit_move_insn (outof_target, into_input);
1058 emit_move_insn (into_target, outof_input);
1059 inter = const0_rtx;
1061 else
1063 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
1064 rtx first_shift_count, second_shift_count;
1065 optab reverse_unsigned_shift, unsigned_shift;
1067 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1068 ? lshr_optab : ashl_optab);
1070 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
1071 ? ashl_optab : lshr_optab);
1073 if (shift_count > BITS_PER_WORD)
1075 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
1076 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
1078 else
1080 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
1081 second_shift_count = GEN_INT (shift_count);
1084 into_temp1 = expand_binop (word_mode, unsigned_shift,
1085 outof_input, first_shift_count,
1086 NULL_RTX, unsignedp, next_methods);
1087 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1088 into_input, second_shift_count,
1089 into_target, unsignedp, next_methods);
1091 if (into_temp1 != 0 && into_temp2 != 0)
1092 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
1093 into_target, unsignedp, next_methods);
1094 else
1095 inter = 0;
1097 if (inter != 0 && inter != into_target)
1098 emit_move_insn (into_target, inter);
1100 outof_temp1 = expand_binop (word_mode, unsigned_shift,
1101 into_input, first_shift_count,
1102 NULL_RTX, unsignedp, next_methods);
1103 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
1104 outof_input, second_shift_count,
1105 outof_target, unsignedp, next_methods);
1107 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
1108 inter = expand_binop (word_mode, ior_optab,
1109 outof_temp1, outof_temp2,
1110 outof_target, unsignedp, next_methods);
1112 if (inter != 0 && inter != outof_target)
1113 emit_move_insn (outof_target, inter);
1116 insns = get_insns ();
1117 end_sequence ();
1119 if (inter != 0)
1121 if (binoptab->code != UNKNOWN)
1122 equiv_value = gen_rtx_fmt_ee (binoptab->code, mode, op0, op1);
1123 else
1124 equiv_value = 0;
1126 /* We can't make this a no conflict block if this is a word swap,
1127 because the word swap case fails if the input and output values
1128 are in the same register. */
1129 if (shift_count != BITS_PER_WORD)
1130 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
1131 else
1132 emit_insns (insns);
1135 return target;
1139 /* These can be done a word at a time by propagating carries. */
1140 if ((binoptab == add_optab || binoptab == sub_optab)
1141 && class == MODE_INT
1142 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
1143 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1145 unsigned int i;
1146 rtx carry_tmp = gen_reg_rtx (word_mode);
1147 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
1148 unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
1149 rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
1150 rtx xop0, xop1;
1152 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
1153 value is one of those, use it. Otherwise, use 1 since it is the
1154 one easiest to get. */
1155 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
1156 int normalizep = STORE_FLAG_VALUE;
1157 #else
1158 int normalizep = 1;
1159 #endif
1161 /* Prepare the operands. */
1162 xop0 = force_reg (mode, op0);
1163 xop1 = force_reg (mode, op1);
1165 if (target == 0 || GET_CODE (target) != REG
1166 || target == xop0 || target == xop1)
1167 target = gen_reg_rtx (mode);
1169 /* Indicate for flow that the entire target reg is being set. */
1170 if (GET_CODE (target) == REG)
1171 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
1173 /* Do the actual arithmetic. */
1174 for (i = 0; i < nwords; i++)
1176 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
1177 rtx target_piece = operand_subword (target, index, 1, mode);
1178 rtx op0_piece = operand_subword_force (xop0, index, mode);
1179 rtx op1_piece = operand_subword_force (xop1, index, mode);
1180 rtx x;
1182 /* Main add/subtract of the input operands. */
1183 x = expand_binop (word_mode, binoptab,
1184 op0_piece, op1_piece,
1185 target_piece, unsignedp, next_methods);
1186 if (x == 0)
1187 break;
1189 if (i + 1 < nwords)
1191 /* Store carry from main add/subtract. */
1192 carry_out = gen_reg_rtx (word_mode);
1193 carry_out = emit_store_flag_force (carry_out,
1194 (binoptab == add_optab
1195 ? LT : GT),
1196 x, op0_piece,
1197 word_mode, 1, normalizep);
1200 if (i > 0)
1202 /* Add/subtract previous carry to main result. */
1203 x = expand_binop (word_mode,
1204 normalizep == 1 ? binoptab : otheroptab,
1205 x, carry_in,
1206 target_piece, 1, next_methods);
1207 if (x == 0)
1208 break;
1209 else if (target_piece != x)
1210 emit_move_insn (target_piece, x);
1212 if (i + 1 < nwords)
1214 /* THIS CODE HAS NOT BEEN TESTED. */
1215 /* Get out carry from adding/subtracting carry in. */
1216 carry_tmp = emit_store_flag_force (carry_tmp,
1217 binoptab == add_optab
1218 ? LT : GT,
1219 x, carry_in,
1220 word_mode, 1, normalizep);
1222 /* Logical-ior the two poss. carry together. */
1223 carry_out = expand_binop (word_mode, ior_optab,
1224 carry_out, carry_tmp,
1225 carry_out, 0, next_methods);
1226 if (carry_out == 0)
1227 break;
1231 carry_in = carry_out;
1234 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
1236 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1238 rtx temp = emit_move_insn (target, target);
1240 set_unique_reg_note (temp,
1241 REG_EQUAL,
1242 gen_rtx_fmt_ee (binoptab->code, mode,
1243 copy_rtx (xop0),
1244 copy_rtx (xop1)));
1247 return target;
1250 else
1251 delete_insns_since (last);
1254 /* If we want to multiply two two-word values and have normal and widening
1255 multiplies of single-word values, we can do this with three smaller
1256 multiplications. Note that we do not make a REG_NO_CONFLICT block here
1257 because we are not operating on one word at a time.
1259 The multiplication proceeds as follows:
1260 _______________________
1261 [__op0_high_|__op0_low__]
1262 _______________________
1263 * [__op1_high_|__op1_low__]
1264 _______________________________________________
1265 _______________________
1266 (1) [__op0_low__*__op1_low__]
1267 _______________________
1268 (2a) [__op0_low__*__op1_high_]
1269 _______________________
1270 (2b) [__op0_high_*__op1_low__]
1271 _______________________
1272 (3) [__op0_high_*__op1_high_]
1275 This gives a 4-word result. Since we are only interested in the
1276 lower 2 words, partial result (3) and the upper words of (2a) and
1277 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1278 calculated using non-widening multiplication.
1280 (1), however, needs to be calculated with an unsigned widening
1281 multiplication. If this operation is not directly supported we
1282 try using a signed widening multiplication and adjust the result.
1283 This adjustment works as follows:
1285 If both operands are positive then no adjustment is needed.
1287 If the operands have different signs, for example op0_low < 0 and
1288 op1_low >= 0, the instruction treats the most significant bit of
1289 op0_low as a sign bit instead of a bit with significance
1290 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1291 with 2**BITS_PER_WORD - op0_low, and two's complements the
1292 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1293 the result.
1295 Similarly, if both operands are negative, we need to add
1296 (op0_low + op1_low) * 2**BITS_PER_WORD.
1298 We use a trick to adjust quickly. We logically shift op0_low right
1299 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1300 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1301 logical shift exists, we do an arithmetic right shift and subtract
1302 the 0 or -1. */
1304 if (binoptab == smul_optab
1305 && class == MODE_INT
1306 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1307 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1308 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1309 && ((umul_widen_optab->handlers[(int) mode].insn_code
1310 != CODE_FOR_nothing)
1311 || (smul_widen_optab->handlers[(int) mode].insn_code
1312 != CODE_FOR_nothing)))
1314 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1315 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1316 rtx op0_high = operand_subword_force (op0, high, mode);
1317 rtx op0_low = operand_subword_force (op0, low, mode);
1318 rtx op1_high = operand_subword_force (op1, high, mode);
1319 rtx op1_low = operand_subword_force (op1, low, mode);
1320 rtx product = 0;
1321 rtx op0_xhigh = NULL_RTX;
1322 rtx op1_xhigh = NULL_RTX;
1324 /* If the target is the same as one of the inputs, don't use it. This
1325 prevents problems with the REG_EQUAL note. */
1326 if (target == op0 || target == op1
1327 || (target != 0 && GET_CODE (target) != REG))
1328 target = 0;
1330 /* Multiply the two lower words to get a double-word product.
1331 If unsigned widening multiplication is available, use that;
1332 otherwise use the signed form and compensate. */
1334 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1336 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1337 target, 1, OPTAB_DIRECT);
1339 /* If we didn't succeed, delete everything we did so far. */
1340 if (product == 0)
1341 delete_insns_since (last);
1342 else
1343 op0_xhigh = op0_high, op1_xhigh = op1_high;
1346 if (product == 0
1347 && smul_widen_optab->handlers[(int) mode].insn_code
1348 != CODE_FOR_nothing)
1350 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1351 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1352 target, 1, OPTAB_DIRECT);
1353 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1354 NULL_RTX, 1, next_methods);
1355 if (op0_xhigh)
1356 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1357 op0_xhigh, op0_xhigh, 0, next_methods);
1358 else
1360 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1361 NULL_RTX, 0, next_methods);
1362 if (op0_xhigh)
1363 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1364 op0_xhigh, op0_xhigh, 0,
1365 next_methods);
1368 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1369 NULL_RTX, 1, next_methods);
1370 if (op1_xhigh)
1371 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1372 op1_xhigh, op1_xhigh, 0, next_methods);
1373 else
1375 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1376 NULL_RTX, 0, next_methods);
1377 if (op1_xhigh)
1378 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1379 op1_xhigh, op1_xhigh, 0,
1380 next_methods);
1384 /* If we have been able to directly compute the product of the
1385 low-order words of the operands and perform any required adjustments
1386 of the operands, we proceed by trying two more multiplications
1387 and then computing the appropriate sum.
1389 We have checked above that the required addition is provided.
1390 Full-word addition will normally always succeed, especially if
1391 it is provided at all, so we don't worry about its failure. The
1392 multiplication may well fail, however, so we do handle that. */
1394 if (product && op0_xhigh && op1_xhigh)
1396 rtx product_high = operand_subword (product, high, 1, mode);
1397 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1398 NULL_RTX, 0, OPTAB_DIRECT);
1400 if (temp != 0)
1401 temp = expand_binop (word_mode, add_optab, temp, product_high,
1402 product_high, 0, next_methods);
1404 if (temp != 0 && temp != product_high)
1405 emit_move_insn (product_high, temp);
1407 if (temp != 0)
1408 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1409 NULL_RTX, 0, OPTAB_DIRECT);
1411 if (temp != 0)
1412 temp = expand_binop (word_mode, add_optab, temp,
1413 product_high, product_high,
1414 0, next_methods);
1416 if (temp != 0 && temp != product_high)
1417 emit_move_insn (product_high, temp);
1419 if (temp != 0)
1421 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1423 temp = emit_move_insn (product, product);
1424 set_unique_reg_note (temp,
1425 REG_EQUAL,
1426 gen_rtx_fmt_ee (MULT, mode,
1427 copy_rtx (op0),
1428 copy_rtx (op1)));
1431 return product;
1435 /* If we get here, we couldn't do it for some reason even though we
1436 originally thought we could. Delete anything we've emitted in
1437 trying to do it. */
1439 delete_insns_since (last);
1442 /* We need to open-code the complex type operations: '+, -, * and /' */
1444 /* At this point we allow operations between two similar complex
1445 numbers, and also if one of the operands is not a complex number
1446 but rather of MODE_FLOAT or MODE_INT. However, the caller
1447 must make sure that the MODE of the non-complex operand matches
1448 the SUBMODE of the complex operand. */
1450 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1452 rtx real0 = 0, imag0 = 0;
1453 rtx real1 = 0, imag1 = 0;
1454 rtx realr, imagr, res;
1455 rtx seq;
1456 rtx equiv_value;
1457 int ok = 0;
1459 /* Find the correct mode for the real and imaginary parts */
1460 enum machine_mode submode
1461 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1462 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1465 if (submode == BLKmode)
1466 abort ();
1468 if (! target)
1469 target = gen_reg_rtx (mode);
1471 start_sequence ();
1473 realr = gen_realpart (submode, target);
1474 imagr = gen_imagpart (submode, target);
1476 if (GET_MODE (op0) == mode)
1478 real0 = gen_realpart (submode, op0);
1479 imag0 = gen_imagpart (submode, op0);
1481 else
1482 real0 = op0;
1484 if (GET_MODE (op1) == mode)
1486 real1 = gen_realpart (submode, op1);
1487 imag1 = gen_imagpart (submode, op1);
1489 else
1490 real1 = op1;
1492 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1493 abort ();
1495 switch (binoptab->code)
1497 case PLUS:
1498 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1499 case MINUS:
1500 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1501 res = expand_binop (submode, binoptab, real0, real1,
1502 realr, unsignedp, methods);
1504 if (res == 0)
1505 break;
1506 else if (res != realr)
1507 emit_move_insn (realr, res);
1509 if (imag0 && imag1)
1510 res = expand_binop (submode, binoptab, imag0, imag1,
1511 imagr, unsignedp, methods);
1512 else if (imag0)
1513 res = imag0;
1514 else if (binoptab->code == MINUS)
1515 res = expand_unop (submode,
1516 binoptab == subv_optab ? negv_optab : neg_optab,
1517 imag1, imagr, unsignedp);
1518 else
1519 res = imag1;
1521 if (res == 0)
1522 break;
1523 else if (res != imagr)
1524 emit_move_insn (imagr, res);
1526 ok = 1;
1527 break;
1529 case MULT:
1530 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1532 if (imag0 && imag1)
1534 rtx temp1, temp2;
1536 /* Don't fetch these from memory more than once. */
1537 real0 = force_reg (submode, real0);
1538 real1 = force_reg (submode, real1);
1539 imag0 = force_reg (submode, imag0);
1540 imag1 = force_reg (submode, imag1);
1542 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1543 unsignedp, methods);
1545 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1546 unsignedp, methods);
1548 if (temp1 == 0 || temp2 == 0)
1549 break;
1551 res = (expand_binop
1552 (submode,
1553 binoptab == smulv_optab ? subv_optab : sub_optab,
1554 temp1, temp2, realr, unsignedp, methods));
1556 if (res == 0)
1557 break;
1558 else if (res != realr)
1559 emit_move_insn (realr, res);
1561 temp1 = expand_binop (submode, binoptab, real0, imag1,
1562 NULL_RTX, unsignedp, methods);
1564 temp2 = expand_binop (submode, binoptab, real1, imag0,
1565 NULL_RTX, unsignedp, methods);
1567 if (temp1 == 0 || temp2 == 0)
1568 break;
1570 res = (expand_binop
1571 (submode,
1572 binoptab == smulv_optab ? addv_optab : add_optab,
1573 temp1, temp2, imagr, unsignedp, methods));
1575 if (res == 0)
1576 break;
1577 else if (res != imagr)
1578 emit_move_insn (imagr, res);
1580 ok = 1;
1582 else
1584 /* Don't fetch these from memory more than once. */
1585 real0 = force_reg (submode, real0);
1586 real1 = force_reg (submode, real1);
1588 res = expand_binop (submode, binoptab, real0, real1,
1589 realr, unsignedp, methods);
1590 if (res == 0)
1591 break;
1592 else if (res != realr)
1593 emit_move_insn (realr, res);
1595 if (imag0 != 0)
1596 res = expand_binop (submode, binoptab,
1597 real1, imag0, imagr, unsignedp, methods);
1598 else
1599 res = expand_binop (submode, binoptab,
1600 real0, imag1, imagr, unsignedp, methods);
1602 if (res == 0)
1603 break;
1604 else if (res != imagr)
1605 emit_move_insn (imagr, res);
1607 ok = 1;
1609 break;
1611 case DIV:
1612 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1614 if (imag1 == 0)
1616 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1618 /* Don't fetch these from memory more than once. */
1619 real1 = force_reg (submode, real1);
1621 /* Simply divide the real and imaginary parts by `c' */
1622 if (class == MODE_COMPLEX_FLOAT)
1623 res = expand_binop (submode, binoptab, real0, real1,
1624 realr, unsignedp, methods);
1625 else
1626 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1627 real0, real1, realr, unsignedp);
1629 if (res == 0)
1630 break;
1631 else if (res != realr)
1632 emit_move_insn (realr, res);
1634 if (class == MODE_COMPLEX_FLOAT)
1635 res = expand_binop (submode, binoptab, imag0, real1,
1636 imagr, unsignedp, methods);
1637 else
1638 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1639 imag0, real1, imagr, unsignedp);
1641 if (res == 0)
1642 break;
1643 else if (res != imagr)
1644 emit_move_insn (imagr, res);
1646 ok = 1;
1648 else
1650 switch (flag_complex_divide_method)
1652 case 0:
1653 ok = expand_cmplxdiv_straight (real0, real1, imag0, imag1,
1654 realr, imagr, submode,
1655 unsignedp, methods,
1656 class, binoptab);
1657 break;
1659 case 1:
1660 ok = expand_cmplxdiv_wide (real0, real1, imag0, imag1,
1661 realr, imagr, submode,
1662 unsignedp, methods,
1663 class, binoptab);
1664 break;
1666 default:
1667 abort ();
1670 break;
1672 default:
1673 abort ();
1676 seq = get_insns ();
1677 end_sequence ();
1679 if (ok)
1681 if (binoptab->code != UNKNOWN)
1682 equiv_value
1683 = gen_rtx_fmt_ee (binoptab->code, mode,
1684 copy_rtx (op0), copy_rtx (op1));
1685 else
1686 equiv_value = 0;
1688 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1690 return target;
1694 /* It can't be open-coded in this mode.
1695 Use a library call if one is available and caller says that's ok. */
1697 if (binoptab->handlers[(int) mode].libfunc
1698 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1700 rtx insns;
1701 rtx op1x = op1;
1702 enum machine_mode op1_mode = mode;
1703 rtx value;
1705 start_sequence ();
1707 if (shift_op)
1709 op1_mode = word_mode;
1710 /* Specify unsigned here,
1711 since negative shift counts are meaningless. */
1712 op1x = convert_to_mode (word_mode, op1, 1);
1715 if (GET_MODE (op0) != VOIDmode
1716 && GET_MODE (op0) != mode)
1717 op0 = convert_to_mode (mode, op0, unsignedp);
1719 /* Pass 1 for NO_QUEUE so we don't lose any increments
1720 if the libcall is cse'd or moved. */
1721 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1722 NULL_RTX, LCT_CONST, mode, 2,
1723 op0, mode, op1x, op1_mode);
1725 insns = get_insns ();
1726 end_sequence ();
1728 target = gen_reg_rtx (mode);
1729 emit_libcall_block (insns, target, value,
1730 gen_rtx_fmt_ee (binoptab->code, mode, op0, op1));
1732 return target;
1735 delete_insns_since (last);
1737 /* It can't be done in this mode. Can we do it in a wider mode? */
1739 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1740 || methods == OPTAB_MUST_WIDEN))
1742 /* Caller says, don't even try. */
1743 delete_insns_since (entry_last);
1744 return 0;
1747 /* Compute the value of METHODS to pass to recursive calls.
1748 Don't allow widening to be tried recursively. */
1750 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1752 /* Look for a wider mode of the same class for which it appears we can do
1753 the operation. */
1755 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1757 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1758 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1760 if ((binoptab->handlers[(int) wider_mode].insn_code
1761 != CODE_FOR_nothing)
1762 || (methods == OPTAB_LIB
1763 && binoptab->handlers[(int) wider_mode].libfunc))
1765 rtx xop0 = op0, xop1 = op1;
1766 int no_extend = 0;
1768 /* For certain integer operations, we need not actually extend
1769 the narrow operands, as long as we will truncate
1770 the results to the same narrowness. */
1772 if ((binoptab == ior_optab || binoptab == and_optab
1773 || binoptab == xor_optab
1774 || binoptab == add_optab || binoptab == sub_optab
1775 || binoptab == smul_optab || binoptab == ashl_optab)
1776 && class == MODE_INT)
1777 no_extend = 1;
1779 xop0 = widen_operand (xop0, wider_mode, mode,
1780 unsignedp, no_extend);
1782 /* The second operand of a shift must always be extended. */
1783 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1784 no_extend && binoptab != ashl_optab);
1786 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1787 unsignedp, methods);
1788 if (temp)
1790 if (class != MODE_INT)
1792 if (target == 0)
1793 target = gen_reg_rtx (mode);
1794 convert_move (target, temp, 0);
1795 return target;
1797 else
1798 return gen_lowpart (mode, temp);
1800 else
1801 delete_insns_since (last);
1806 delete_insns_since (entry_last);
1807 return 0;
1810 /* Expand a binary operator which has both signed and unsigned forms.
1811 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1812 signed operations.
1814 If we widen unsigned operands, we may use a signed wider operation instead
1815 of an unsigned wider operation, since the result would be the same. */
1818 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1819 enum machine_mode mode;
1820 optab uoptab, soptab;
1821 rtx op0, op1, target;
1822 int unsignedp;
1823 enum optab_methods methods;
1825 register rtx temp;
1826 optab direct_optab = unsignedp ? uoptab : soptab;
1827 struct optab wide_soptab;
1829 /* Do it without widening, if possible. */
1830 temp = expand_binop (mode, direct_optab, op0, op1, target,
1831 unsignedp, OPTAB_DIRECT);
1832 if (temp || methods == OPTAB_DIRECT)
1833 return temp;
1835 /* Try widening to a signed int. Make a fake signed optab that
1836 hides any signed insn for direct use. */
1837 wide_soptab = *soptab;
1838 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1839 wide_soptab.handlers[(int) mode].libfunc = 0;
1841 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1842 unsignedp, OPTAB_WIDEN);
1844 /* For unsigned operands, try widening to an unsigned int. */
1845 if (temp == 0 && unsignedp)
1846 temp = expand_binop (mode, uoptab, op0, op1, target,
1847 unsignedp, OPTAB_WIDEN);
1848 if (temp || methods == OPTAB_WIDEN)
1849 return temp;
1851 /* Use the right width lib call if that exists. */
1852 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1853 if (temp || methods == OPTAB_LIB)
1854 return temp;
1856 /* Must widen and use a lib call, use either signed or unsigned. */
1857 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1858 unsignedp, methods);
1859 if (temp != 0)
1860 return temp;
1861 if (unsignedp)
1862 return expand_binop (mode, uoptab, op0, op1, target,
1863 unsignedp, methods);
1864 return 0;
1867 /* Generate code to perform an operation specified by BINOPTAB
1868 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1869 We assume that the order of the operands for the instruction
1870 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1871 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1873 Either TARG0 or TARG1 may be zero, but what that means is that
1874 the result is not actually wanted. We will generate it into
1875 a dummy pseudo-reg and discard it. They may not both be zero.
1877 Returns 1 if this operation can be performed; 0 if not. */
1880 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1881 optab binoptab;
1882 rtx op0, op1;
1883 rtx targ0, targ1;
1884 int unsignedp;
1886 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1887 enum mode_class class;
1888 enum machine_mode wider_mode;
1889 rtx entry_last = get_last_insn ();
1890 rtx last;
1892 class = GET_MODE_CLASS (mode);
1894 op0 = protect_from_queue (op0, 0);
1895 op1 = protect_from_queue (op1, 0);
1897 if (flag_force_mem)
1899 op0 = force_not_mem (op0);
1900 op1 = force_not_mem (op1);
1903 /* If we are inside an appropriately-short loop and one operand is an
1904 expensive constant, force it into a register. */
1905 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1906 && rtx_cost (op0, binoptab->code) > COSTS_N_INSNS (1))
1907 op0 = force_reg (mode, op0);
1909 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1910 && rtx_cost (op1, binoptab->code) > COSTS_N_INSNS (1))
1911 op1 = force_reg (mode, op1);
1913 if (targ0)
1914 targ0 = protect_from_queue (targ0, 1);
1915 else
1916 targ0 = gen_reg_rtx (mode);
1917 if (targ1)
1918 targ1 = protect_from_queue (targ1, 1);
1919 else
1920 targ1 = gen_reg_rtx (mode);
1922 /* Record where to go back to if we fail. */
1923 last = get_last_insn ();
1925 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1927 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1928 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1929 enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1930 rtx pat;
1931 rtx xop0 = op0, xop1 = op1;
1933 /* In case this insn wants input operands in modes different from the
1934 result, convert the operands. */
1935 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1936 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1938 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1939 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1941 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1942 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
1943 xop0 = copy_to_mode_reg (mode0, xop0);
1945 if (! (*insn_data[icode].operand[2].predicate) (xop1, mode1))
1946 xop1 = copy_to_mode_reg (mode1, xop1);
1948 /* We could handle this, but we should always be called with a pseudo
1949 for our targets and all insns should take them as outputs. */
1950 if (! (*insn_data[icode].operand[0].predicate) (targ0, mode)
1951 || ! (*insn_data[icode].operand[3].predicate) (targ1, mode))
1952 abort ();
1954 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1955 if (pat)
1957 emit_insn (pat);
1958 return 1;
1960 else
1961 delete_insns_since (last);
1964 /* It can't be done in this mode. Can we do it in a wider mode? */
1966 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1968 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1969 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1971 if (binoptab->handlers[(int) wider_mode].insn_code
1972 != CODE_FOR_nothing)
1974 register rtx t0 = gen_reg_rtx (wider_mode);
1975 register rtx t1 = gen_reg_rtx (wider_mode);
1977 if (expand_twoval_binop (binoptab,
1978 convert_modes (wider_mode, mode, op0,
1979 unsignedp),
1980 convert_modes (wider_mode, mode, op1,
1981 unsignedp),
1982 t0, t1, unsignedp))
1984 convert_move (targ0, t0, unsignedp);
1985 convert_move (targ1, t1, unsignedp);
1986 return 1;
1988 else
1989 delete_insns_since (last);
1994 delete_insns_since (entry_last);
1995 return 0;
1998 /* Generate code to perform an operation specified by UNOPTAB
1999 on operand OP0, with result having machine-mode MODE.
2001 UNSIGNEDP is for the case where we have to widen the operands
2002 to perform the operation. It says to use zero-extension.
2004 If TARGET is nonzero, the value
2005 is generated there, if it is convenient to do so.
2006 In all cases an rtx is returned for the locus of the value;
2007 this may or may not be TARGET. */
2010 expand_unop (mode, unoptab, op0, target, unsignedp)
2011 enum machine_mode mode;
2012 optab unoptab;
2013 rtx op0;
2014 rtx target;
2015 int unsignedp;
2017 enum mode_class class;
2018 enum machine_mode wider_mode;
2019 register rtx temp;
2020 rtx last = get_last_insn ();
2021 rtx pat;
2023 class = GET_MODE_CLASS (mode);
2025 op0 = protect_from_queue (op0, 0);
2027 if (flag_force_mem)
2029 op0 = force_not_mem (op0);
2032 if (target)
2033 target = protect_from_queue (target, 1);
2035 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2037 int icode = (int) unoptab->handlers[(int) mode].insn_code;
2038 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2039 rtx xop0 = op0;
2041 if (target)
2042 temp = target;
2043 else
2044 temp = gen_reg_rtx (mode);
2046 if (GET_MODE (xop0) != VOIDmode
2047 && GET_MODE (xop0) != mode0)
2048 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2050 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2052 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2053 xop0 = copy_to_mode_reg (mode0, xop0);
2055 if (! (*insn_data[icode].operand[0].predicate) (temp, mode))
2056 temp = gen_reg_rtx (mode);
2058 pat = GEN_FCN (icode) (temp, xop0);
2059 if (pat)
2061 if (GET_CODE (pat) == SEQUENCE
2062 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
2064 delete_insns_since (last);
2065 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
2068 emit_insn (pat);
2070 return temp;
2072 else
2073 delete_insns_since (last);
2076 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2078 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2079 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2080 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2082 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2084 rtx xop0 = op0;
2086 /* For certain operations, we need not actually extend
2087 the narrow operand, as long as we will truncate the
2088 results to the same narrowness. */
2090 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2091 (unoptab == neg_optab
2092 || unoptab == one_cmpl_optab)
2093 && class == MODE_INT);
2095 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2096 unsignedp);
2098 if (temp)
2100 if (class != MODE_INT)
2102 if (target == 0)
2103 target = gen_reg_rtx (mode);
2104 convert_move (target, temp, 0);
2105 return target;
2107 else
2108 return gen_lowpart (mode, temp);
2110 else
2111 delete_insns_since (last);
2115 /* These can be done a word at a time. */
2116 if (unoptab == one_cmpl_optab
2117 && class == MODE_INT
2118 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
2119 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
2121 unsigned int i;
2122 rtx insns;
2124 if (target == 0 || target == op0)
2125 target = gen_reg_rtx (mode);
2127 start_sequence ();
2129 /* Do the actual arithmetic. */
2130 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
2132 rtx target_piece = operand_subword (target, i, 1, mode);
2133 rtx x = expand_unop (word_mode, unoptab,
2134 operand_subword_force (op0, i, mode),
2135 target_piece, unsignedp);
2136 if (target_piece != x)
2137 emit_move_insn (target_piece, x);
2140 insns = get_insns ();
2141 end_sequence ();
2143 emit_no_conflict_block (insns, target, op0, NULL_RTX,
2144 gen_rtx_fmt_e (unoptab->code, mode,
2145 copy_rtx (op0)));
2146 return target;
2149 /* Open-code the complex negation operation. */
2150 else if (unoptab->code == NEG
2151 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
2153 rtx target_piece;
2154 rtx x;
2155 rtx seq;
2157 /* Find the correct mode for the real and imaginary parts */
2158 enum machine_mode submode
2159 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2160 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2163 if (submode == BLKmode)
2164 abort ();
2166 if (target == 0)
2167 target = gen_reg_rtx (mode);
2169 start_sequence ();
2171 target_piece = gen_imagpart (submode, target);
2172 x = expand_unop (submode, unoptab,
2173 gen_imagpart (submode, op0),
2174 target_piece, unsignedp);
2175 if (target_piece != x)
2176 emit_move_insn (target_piece, x);
2178 target_piece = gen_realpart (submode, target);
2179 x = expand_unop (submode, unoptab,
2180 gen_realpart (submode, op0),
2181 target_piece, unsignedp);
2182 if (target_piece != x)
2183 emit_move_insn (target_piece, x);
2185 seq = get_insns ();
2186 end_sequence ();
2188 emit_no_conflict_block (seq, target, op0, 0,
2189 gen_rtx_fmt_e (unoptab->code, mode,
2190 copy_rtx (op0)));
2191 return target;
2194 /* Now try a library call in this mode. */
2195 if (unoptab->handlers[(int) mode].libfunc)
2197 rtx insns;
2198 rtx value;
2200 start_sequence ();
2202 /* Pass 1 for NO_QUEUE so we don't lose any increments
2203 if the libcall is cse'd or moved. */
2204 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2205 NULL_RTX, LCT_CONST, mode, 1, op0, mode);
2206 insns = get_insns ();
2207 end_sequence ();
2209 target = gen_reg_rtx (mode);
2210 emit_libcall_block (insns, target, value,
2211 gen_rtx_fmt_e (unoptab->code, mode, op0));
2213 return target;
2216 /* It can't be done in this mode. Can we do it in a wider mode? */
2218 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2220 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2221 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2223 if ((unoptab->handlers[(int) wider_mode].insn_code
2224 != CODE_FOR_nothing)
2225 || unoptab->handlers[(int) wider_mode].libfunc)
2227 rtx xop0 = op0;
2229 /* For certain operations, we need not actually extend
2230 the narrow operand, as long as we will truncate the
2231 results to the same narrowness. */
2233 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2234 (unoptab == neg_optab
2235 || unoptab == one_cmpl_optab)
2236 && class == MODE_INT);
2238 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2239 unsignedp);
2241 if (temp)
2243 if (class != MODE_INT)
2245 if (target == 0)
2246 target = gen_reg_rtx (mode);
2247 convert_move (target, temp, 0);
2248 return target;
2250 else
2251 return gen_lowpart (mode, temp);
2253 else
2254 delete_insns_since (last);
2259 /* If there is no negate operation, try doing a subtract from zero.
2260 The US Software GOFAST library needs this. */
2261 if (unoptab->code == NEG)
2263 rtx temp;
2264 temp = expand_binop (mode,
2265 unoptab == negv_optab ? subv_optab : sub_optab,
2266 CONST0_RTX (mode), op0,
2267 target, unsignedp, OPTAB_LIB_WIDEN);
2268 if (temp)
2269 return temp;
2272 return 0;
2275 /* Emit code to compute the absolute value of OP0, with result to
2276 TARGET if convenient. (TARGET may be 0.) The return value says
2277 where the result actually is to be found.
2279 MODE is the mode of the operand; the mode of the result is
2280 different but can be deduced from MODE.
2285 expand_abs (mode, op0, target, result_unsignedp, safe)
2286 enum machine_mode mode;
2287 rtx op0;
2288 rtx target;
2289 int result_unsignedp;
2290 int safe;
2292 rtx temp, op1;
2294 if (! flag_trapv)
2295 result_unsignedp = 1;
2297 /* First try to do it with a special abs instruction. */
2298 temp = expand_unop (mode, result_unsignedp ? abs_optab : absv_optab,
2299 op0, target, 0);
2300 if (temp != 0)
2301 return temp;
2303 /* If we have a MAX insn, we can do this as MAX (x, -x). */
2304 if (smax_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2306 rtx last = get_last_insn ();
2308 temp = expand_unop (mode, neg_optab, op0, NULL_RTX, 0);
2309 if (temp != 0)
2310 temp = expand_binop (mode, smax_optab, op0, temp, target, 0,
2311 OPTAB_WIDEN);
2313 if (temp != 0)
2314 return temp;
2316 delete_insns_since (last);
2319 /* If this machine has expensive jumps, we can do integer absolute
2320 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2321 where W is the width of MODE. */
2323 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2325 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2326 size_int (GET_MODE_BITSIZE (mode) - 1),
2327 NULL_RTX, 0);
2329 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2330 OPTAB_LIB_WIDEN);
2331 if (temp != 0)
2332 temp = expand_binop (mode, result_unsignedp ? sub_optab : subv_optab,
2333 temp, extended, target, 0, OPTAB_LIB_WIDEN);
2335 if (temp != 0)
2336 return temp;
2339 /* If that does not win, use conditional jump and negate. */
2341 /* It is safe to use the target if it is the same
2342 as the source if this is also a pseudo register */
2343 if (op0 == target && GET_CODE (op0) == REG
2344 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2345 safe = 1;
2347 op1 = gen_label_rtx ();
2348 if (target == 0 || ! safe
2349 || GET_MODE (target) != mode
2350 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2351 || (GET_CODE (target) == REG
2352 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2353 target = gen_reg_rtx (mode);
2355 emit_move_insn (target, op0);
2356 NO_DEFER_POP;
2358 /* If this mode is an integer too wide to compare properly,
2359 compare word by word. Rely on CSE to optimize constant cases. */
2360 if (GET_MODE_CLASS (mode) == MODE_INT
2361 && ! can_compare_p (GE, mode, ccp_jump))
2362 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2363 NULL_RTX, op1);
2364 else
2365 do_compare_rtx_and_jump (target, CONST0_RTX (mode), GE, 0, mode,
2366 NULL_RTX, 0, NULL_RTX, op1);
2368 op0 = expand_unop (mode, result_unsignedp ? neg_optab : negv_optab,
2369 target, target, 0);
2370 if (op0 != target)
2371 emit_move_insn (target, op0);
2372 emit_label (op1);
2373 OK_DEFER_POP;
2374 return target;
2377 /* Emit code to compute the absolute value of OP0, with result to
2378 TARGET if convenient. (TARGET may be 0.) The return value says
2379 where the result actually is to be found.
2381 MODE is the mode of the operand; the mode of the result is
2382 different but can be deduced from MODE.
2384 UNSIGNEDP is relevant for complex integer modes. */
2387 expand_complex_abs (mode, op0, target, unsignedp)
2388 enum machine_mode mode;
2389 rtx op0;
2390 rtx target;
2391 int unsignedp;
2393 enum mode_class class = GET_MODE_CLASS (mode);
2394 enum machine_mode wider_mode;
2395 register rtx temp;
2396 rtx entry_last = get_last_insn ();
2397 rtx last;
2398 rtx pat;
2399 optab this_abs_optab;
2401 /* Find the correct mode for the real and imaginary parts. */
2402 enum machine_mode submode
2403 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2404 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2407 if (submode == BLKmode)
2408 abort ();
2410 op0 = protect_from_queue (op0, 0);
2412 if (flag_force_mem)
2414 op0 = force_not_mem (op0);
2417 last = get_last_insn ();
2419 if (target)
2420 target = protect_from_queue (target, 1);
2422 this_abs_optab = ! unsignedp && flag_trapv
2423 && (GET_MODE_CLASS(mode) == MODE_INT)
2424 ? absv_optab : abs_optab;
2426 if (this_abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2428 int icode = (int) this_abs_optab->handlers[(int) mode].insn_code;
2429 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2430 rtx xop0 = op0;
2432 if (target)
2433 temp = target;
2434 else
2435 temp = gen_reg_rtx (submode);
2437 if (GET_MODE (xop0) != VOIDmode
2438 && GET_MODE (xop0) != mode0)
2439 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2441 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2443 if (! (*insn_data[icode].operand[1].predicate) (xop0, mode0))
2444 xop0 = copy_to_mode_reg (mode0, xop0);
2446 if (! (*insn_data[icode].operand[0].predicate) (temp, submode))
2447 temp = gen_reg_rtx (submode);
2449 pat = GEN_FCN (icode) (temp, xop0);
2450 if (pat)
2452 if (GET_CODE (pat) == SEQUENCE
2453 && ! add_equal_note (pat, temp, this_abs_optab->code, xop0,
2454 NULL_RTX))
2456 delete_insns_since (last);
2457 return expand_unop (mode, this_abs_optab, op0, NULL_RTX,
2458 unsignedp);
2461 emit_insn (pat);
2463 return temp;
2465 else
2466 delete_insns_since (last);
2469 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2471 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2472 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2474 if (this_abs_optab->handlers[(int) wider_mode].insn_code
2475 != CODE_FOR_nothing)
2477 rtx xop0 = op0;
2479 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2480 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2482 if (temp)
2484 if (class != MODE_COMPLEX_INT)
2486 if (target == 0)
2487 target = gen_reg_rtx (submode);
2488 convert_move (target, temp, 0);
2489 return target;
2491 else
2492 return gen_lowpart (submode, temp);
2494 else
2495 delete_insns_since (last);
2499 /* Open-code the complex absolute-value operation
2500 if we can open-code sqrt. Otherwise it's not worth while. */
2501 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing
2502 && ! flag_trapv)
2504 rtx real, imag, total;
2506 real = gen_realpart (submode, op0);
2507 imag = gen_imagpart (submode, op0);
2509 /* Square both parts. */
2510 real = expand_mult (submode, real, real, NULL_RTX, 0);
2511 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2513 /* Sum the parts. */
2514 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2515 0, OPTAB_LIB_WIDEN);
2517 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2518 target = expand_unop (submode, sqrt_optab, total, target, 0);
2519 if (target == 0)
2520 delete_insns_since (last);
2521 else
2522 return target;
2525 /* Now try a library call in this mode. */
2526 if (this_abs_optab->handlers[(int) mode].libfunc)
2528 rtx insns;
2529 rtx value;
2531 start_sequence ();
2533 /* Pass 1 for NO_QUEUE so we don't lose any increments
2534 if the libcall is cse'd or moved. */
2535 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2536 NULL_RTX, LCT_CONST, submode, 1, op0, mode);
2537 insns = get_insns ();
2538 end_sequence ();
2540 target = gen_reg_rtx (submode);
2541 emit_libcall_block (insns, target, value,
2542 gen_rtx_fmt_e (this_abs_optab->code, mode, op0));
2544 return target;
2547 /* It can't be done in this mode. Can we do it in a wider mode? */
2549 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2550 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2552 if ((this_abs_optab->handlers[(int) wider_mode].insn_code
2553 != CODE_FOR_nothing)
2554 || this_abs_optab->handlers[(int) wider_mode].libfunc)
2556 rtx xop0 = op0;
2558 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2560 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2562 if (temp)
2564 if (class != MODE_COMPLEX_INT)
2566 if (target == 0)
2567 target = gen_reg_rtx (submode);
2568 convert_move (target, temp, 0);
2569 return target;
2571 else
2572 return gen_lowpart (submode, temp);
2574 else
2575 delete_insns_since (last);
2579 delete_insns_since (entry_last);
2580 return 0;
2583 /* Generate an instruction whose insn-code is INSN_CODE,
2584 with two operands: an output TARGET and an input OP0.
2585 TARGET *must* be nonzero, and the output is always stored there.
2586 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2587 the value that is stored into TARGET. */
2589 void
2590 emit_unop_insn (icode, target, op0, code)
2591 int icode;
2592 rtx target;
2593 rtx op0;
2594 enum rtx_code code;
2596 register rtx temp;
2597 enum machine_mode mode0 = insn_data[icode].operand[1].mode;
2598 rtx pat;
2600 temp = target = protect_from_queue (target, 1);
2602 op0 = protect_from_queue (op0, 0);
2604 /* Sign and zero extension from memory is often done specially on
2605 RISC machines, so forcing into a register here can pessimize
2606 code. */
2607 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2608 op0 = force_not_mem (op0);
2610 /* Now, if insn does not accept our operands, put them into pseudos. */
2612 if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
2613 op0 = copy_to_mode_reg (mode0, op0);
2615 if (! (*insn_data[icode].operand[0].predicate) (temp, GET_MODE (temp))
2616 || (flag_force_mem && GET_CODE (temp) == MEM))
2617 temp = gen_reg_rtx (GET_MODE (temp));
2619 pat = GEN_FCN (icode) (temp, op0);
2621 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2622 add_equal_note (pat, temp, code, op0, NULL_RTX);
2624 emit_insn (pat);
2626 if (temp != target)
2627 emit_move_insn (target, temp);
2630 /* Emit code to perform a series of operations on a multi-word quantity, one
2631 word at a time.
2633 Such a block is preceded by a CLOBBER of the output, consists of multiple
2634 insns, each setting one word of the output, and followed by a SET copying
2635 the output to itself.
2637 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2638 note indicating that it doesn't conflict with the (also multi-word)
2639 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2640 notes.
2642 INSNS is a block of code generated to perform the operation, not including
2643 the CLOBBER and final copy. All insns that compute intermediate values
2644 are first emitted, followed by the block as described above.
2646 TARGET, OP0, and OP1 are the output and inputs of the operations,
2647 respectively. OP1 may be zero for a unary operation.
2649 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2650 on the last insn.
2652 If TARGET is not a register, INSNS is simply emitted with no special
2653 processing. Likewise if anything in INSNS is not an INSN or if
2654 there is a libcall block inside INSNS.
2656 The final insn emitted is returned. */
2659 emit_no_conflict_block (insns, target, op0, op1, equiv)
2660 rtx insns;
2661 rtx target;
2662 rtx op0, op1;
2663 rtx equiv;
2665 rtx prev, next, first, last, insn;
2667 if (GET_CODE (target) != REG || reload_in_progress)
2668 return emit_insns (insns);
2669 else
2670 for (insn = insns; insn; insn = NEXT_INSN (insn))
2671 if (GET_CODE (insn) != INSN
2672 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2673 return emit_insns (insns);
2675 /* First emit all insns that do not store into words of the output and remove
2676 these from the list. */
2677 for (insn = insns; insn; insn = next)
2679 rtx set = 0;
2680 int i;
2682 next = NEXT_INSN (insn);
2684 if (GET_CODE (PATTERN (insn)) == SET || GET_CODE (PATTERN (insn)) == USE
2685 || GET_CODE (PATTERN (insn)) == CLOBBER)
2686 set = PATTERN (insn);
2687 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2689 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2690 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2692 set = XVECEXP (PATTERN (insn), 0, i);
2693 break;
2697 if (set == 0)
2698 abort ();
2700 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2702 if (PREV_INSN (insn))
2703 NEXT_INSN (PREV_INSN (insn)) = next;
2704 else
2705 insns = next;
2707 if (next)
2708 PREV_INSN (next) = PREV_INSN (insn);
2710 add_insn (insn);
2714 prev = get_last_insn ();
2716 /* Now write the CLOBBER of the output, followed by the setting of each
2717 of the words, followed by the final copy. */
2718 if (target != op0 && target != op1)
2719 emit_insn (gen_rtx_CLOBBER (VOIDmode, target));
2721 for (insn = insns; insn; insn = next)
2723 next = NEXT_INSN (insn);
2724 add_insn (insn);
2726 if (op1 && GET_CODE (op1) == REG)
2727 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op1,
2728 REG_NOTES (insn));
2730 if (op0 && GET_CODE (op0) == REG)
2731 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_NO_CONFLICT, op0,
2732 REG_NOTES (insn));
2735 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2736 != CODE_FOR_nothing)
2738 last = emit_move_insn (target, target);
2739 if (equiv)
2740 set_unique_reg_note (last, REG_EQUAL, equiv);
2742 else
2744 last = get_last_insn ();
2746 /* Remove any existing REG_EQUAL note from "last", or else it will
2747 be mistaken for a note referring to the full contents of the
2748 alleged libcall value when found together with the REG_RETVAL
2749 note added below. An existing note can come from an insn
2750 expansion at "last". */
2751 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2754 if (prev == 0)
2755 first = get_insns ();
2756 else
2757 first = NEXT_INSN (prev);
2759 /* Encapsulate the block so it gets manipulated as a unit. */
2760 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2761 REG_NOTES (first));
2762 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2764 return last;
2767 /* Emit code to make a call to a constant function or a library call.
2769 INSNS is a list containing all insns emitted in the call.
2770 These insns leave the result in RESULT. Our block is to copy RESULT
2771 to TARGET, which is logically equivalent to EQUIV.
2773 We first emit any insns that set a pseudo on the assumption that these are
2774 loading constants into registers; doing so allows them to be safely cse'ed
2775 between blocks. Then we emit all the other insns in the block, followed by
2776 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2777 note with an operand of EQUIV.
2779 Moving assignments to pseudos outside of the block is done to improve
2780 the generated code, but is not required to generate correct code,
2781 hence being unable to move an assignment is not grounds for not making
2782 a libcall block. There are two reasons why it is safe to leave these
2783 insns inside the block: First, we know that these pseudos cannot be
2784 used in generated RTL outside the block since they are created for
2785 temporary purposes within the block. Second, CSE will not record the
2786 values of anything set inside a libcall block, so we know they must
2787 be dead at the end of the block.
2789 Except for the first group of insns (the ones setting pseudos), the
2790 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2792 void
2793 emit_libcall_block (insns, target, result, equiv)
2794 rtx insns;
2795 rtx target;
2796 rtx result;
2797 rtx equiv;
2799 rtx final_dest = target;
2800 rtx prev, next, first, last, insn;
2802 /* If this is a reg with REG_USERVAR_P set, then it could possibly turn
2803 into a MEM later. Protect the libcall block from this change. */
2804 if (! REG_P (target) || REG_USERVAR_P (target))
2805 target = gen_reg_rtx (GET_MODE (target));
2807 /* look for any CALL_INSNs in this sequence, and attach a REG_EH_REGION
2808 reg note to indicate that this call cannot throw or execute a nonlocal
2809 goto (unless there is already a REG_EH_REGION note, in which case
2810 we update it). Also set the CONST_CALL_P flag. */
2812 for (insn = insns; insn; insn = NEXT_INSN (insn))
2813 if (GET_CODE (insn) == CALL_INSN)
2815 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
2817 CONST_CALL_P (insn) = 1;
2818 if (note != 0)
2819 XEXP (note, 0) = GEN_INT (-1);
2820 else
2821 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
2822 REG_NOTES (insn));
2825 /* First emit all insns that set pseudos. Remove them from the list as
2826 we go. Avoid insns that set pseudos which were referenced in previous
2827 insns. These can be generated by move_by_pieces, for example,
2828 to update an address. Similarly, avoid insns that reference things
2829 set in previous insns. */
2831 for (insn = insns; insn; insn = next)
2833 rtx set = single_set (insn);
2835 next = NEXT_INSN (insn);
2837 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2838 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2839 && (insn == insns
2840 || ((! INSN_P(insns)
2841 || ! reg_mentioned_p (SET_DEST (set), PATTERN (insns)))
2842 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2843 && ! modified_in_p (SET_SRC (set), insns)
2844 && ! modified_between_p (SET_SRC (set), insns, insn))))
2846 if (PREV_INSN (insn))
2847 NEXT_INSN (PREV_INSN (insn)) = next;
2848 else
2849 insns = next;
2851 if (next)
2852 PREV_INSN (next) = PREV_INSN (insn);
2854 add_insn (insn);
2858 prev = get_last_insn ();
2860 /* Write the remaining insns followed by the final copy. */
2862 for (insn = insns; insn; insn = next)
2864 next = NEXT_INSN (insn);
2866 add_insn (insn);
2869 last = emit_move_insn (target, result);
2870 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2871 != CODE_FOR_nothing)
2872 set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
2873 else
2875 /* Remove any existing REG_EQUAL note from "last", or else it will
2876 be mistaken for a note referring to the full contents of the
2877 libcall value when found together with the REG_RETVAL note added
2878 below. An existing note can come from an insn expansion at
2879 "last". */
2880 remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
2883 if (final_dest != target)
2884 emit_move_insn (final_dest, target);
2886 if (prev == 0)
2887 first = get_insns ();
2888 else
2889 first = NEXT_INSN (prev);
2891 /* Encapsulate the block so it gets manipulated as a unit. */
2892 REG_NOTES (first) = gen_rtx_INSN_LIST (REG_LIBCALL, last,
2893 REG_NOTES (first));
2894 REG_NOTES (last) = gen_rtx_INSN_LIST (REG_RETVAL, first, REG_NOTES (last));
2897 /* Generate code to store zero in X. */
2899 void
2900 emit_clr_insn (x)
2901 rtx x;
2903 emit_move_insn (x, const0_rtx);
2906 /* Generate code to store 1 in X
2907 assuming it contains zero beforehand. */
2909 void
2910 emit_0_to_1_insn (x)
2911 rtx x;
2913 emit_move_insn (x, const1_rtx);
2916 /* Nonzero if we can perform a comparison of mode MODE straightforwardly.
2917 PURPOSE describes how this comparison will be used. CODE is the rtx
2918 comparison code we will be using.
2920 ??? Actually, CODE is slightly weaker than that. A target is still
2921 required to implement all of the normal bcc operations, but not
2922 required to implement all (or any) of the unordered bcc operations. */
2925 can_compare_p (code, mode, purpose)
2926 enum rtx_code code;
2927 enum machine_mode mode;
2928 enum can_compare_purpose purpose;
2932 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2934 if (purpose == ccp_jump)
2935 return bcc_gen_fctn[(int)code] != NULL;
2936 else if (purpose == ccp_store_flag)
2937 return setcc_gen_code[(int)code] != CODE_FOR_nothing;
2938 else
2939 /* There's only one cmov entry point, and it's allowed to fail. */
2940 return 1;
2942 if (purpose == ccp_jump
2943 && cbranch_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2944 return 1;
2945 if (purpose == ccp_cmov
2946 && cmov_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2947 return 1;
2948 if (purpose == ccp_store_flag
2949 && cstore_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2950 return 1;
2952 mode = GET_MODE_WIDER_MODE (mode);
2954 while (mode != VOIDmode);
2956 return 0;
2959 /* This function is called when we are going to emit a compare instruction that
2960 compares the values found in *PX and *PY, using the rtl operator COMPARISON.
2962 *PMODE is the mode of the inputs (in case they are const_int).
2963 *PUNSIGNEDP nonzero says that the operands are unsigned;
2964 this matters if they need to be widened.
2966 If they have mode BLKmode, then SIZE specifies the size of both operands,
2967 and ALIGN specifies the known shared alignment of the operands.
2969 This function performs all the setup necessary so that the caller only has
2970 to emit a single comparison insn. This setup can involve doing a BLKmode
2971 comparison or emitting a library call to perform the comparison if no insn
2972 is available to handle it.
2973 The values which are passed in through pointers can be modified; the caller
2974 should perform the comparison on the modified values. */
2976 void
2977 prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
2978 purpose)
2979 rtx *px, *py;
2980 enum rtx_code *pcomparison;
2981 rtx size;
2982 enum machine_mode *pmode;
2983 int *punsignedp;
2984 int align ATTRIBUTE_UNUSED;
2985 enum can_compare_purpose purpose;
2987 enum machine_mode mode = *pmode;
2988 rtx x = *px, y = *py;
2989 int unsignedp = *punsignedp;
2990 enum mode_class class;
2991 rtx opalign ATTRIBUTE_UNUSED = GEN_INT (align / BITS_PER_UNIT);;
2993 class = GET_MODE_CLASS (mode);
2995 /* They could both be VOIDmode if both args are immediate constants,
2996 but we should fold that at an earlier stage.
2997 With no special code here, this will call abort,
2998 reminding the programmer to implement such folding. */
3000 if (mode != BLKmode && flag_force_mem)
3002 x = force_not_mem (x);
3003 y = force_not_mem (y);
3006 /* If we are inside an appropriately-short loop and one operand is an
3007 expensive constant, force it into a register. */
3008 if (CONSTANT_P (x) && preserve_subexpressions_p ()
3009 && rtx_cost (x, COMPARE) > COSTS_N_INSNS (1))
3010 x = force_reg (mode, x);
3012 if (CONSTANT_P (y) && preserve_subexpressions_p ()
3013 && rtx_cost (y, COMPARE) > COSTS_N_INSNS (1))
3014 y = force_reg (mode, y);
3016 #ifdef HAVE_cc0
3017 /* Abort if we have a non-canonical comparison. The RTL documentation
3018 states that canonical comparisons are required only for targets which
3019 have cc0. */
3020 if (CONSTANT_P (x) && ! CONSTANT_P (y))
3021 abort();
3022 #endif
3024 /* Don't let both operands fail to indicate the mode. */
3025 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
3026 x = force_reg (mode, x);
3028 /* Handle all BLKmode compares. */
3030 if (mode == BLKmode)
3032 rtx result;
3033 enum machine_mode result_mode;
3035 emit_queue ();
3036 x = protect_from_queue (x, 0);
3037 y = protect_from_queue (y, 0);
3039 if (size == 0)
3040 abort ();
3041 #ifdef HAVE_cmpstrqi
3042 if (HAVE_cmpstrqi
3043 && GET_CODE (size) == CONST_INT
3044 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
3046 result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
3047 result = gen_reg_rtx (result_mode);
3048 emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
3050 else
3051 #endif
3052 #ifdef HAVE_cmpstrhi
3053 if (HAVE_cmpstrhi
3054 && GET_CODE (size) == CONST_INT
3055 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
3057 result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
3058 result = gen_reg_rtx (result_mode);
3059 emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
3061 else
3062 #endif
3063 #ifdef HAVE_cmpstrsi
3064 if (HAVE_cmpstrsi)
3066 result_mode = insn_data[(int) CODE_FOR_cmpstrsi].operand[0].mode;
3067 result = gen_reg_rtx (result_mode);
3068 size = protect_from_queue (size, 0);
3069 emit_insn (gen_cmpstrsi (result, x, y,
3070 convert_to_mode (SImode, size, 1),
3071 opalign));
3073 else
3074 #endif
3076 #ifdef TARGET_MEM_FUNCTIONS
3077 emit_library_call (memcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3078 TYPE_MODE (integer_type_node), 3,
3079 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3080 convert_to_mode (TYPE_MODE (sizetype), size,
3081 TREE_UNSIGNED (sizetype)),
3082 TYPE_MODE (sizetype));
3083 #else
3084 emit_library_call (bcmp_libfunc, LCT_PURE_MAKE_BLOCK,
3085 TYPE_MODE (integer_type_node), 3,
3086 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
3087 convert_to_mode (TYPE_MODE (integer_type_node),
3088 size,
3089 TREE_UNSIGNED (integer_type_node)),
3090 TYPE_MODE (integer_type_node));
3091 #endif
3093 /* Immediately move the result of the libcall into a pseudo
3094 register so reload doesn't clobber the value if it needs
3095 the return register for a spill reg. */
3096 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
3097 result_mode = TYPE_MODE (integer_type_node);
3098 emit_move_insn (result,
3099 hard_libcall_value (result_mode));
3101 *px = result;
3102 *py = const0_rtx;
3103 *pmode = result_mode;
3104 return;
3107 *px = x;
3108 *py = y;
3109 if (can_compare_p (*pcomparison, mode, purpose))
3110 return;
3112 /* Handle a lib call just for the mode we are using. */
3114 if (cmp_optab->handlers[(int) mode].libfunc && class != MODE_FLOAT)
3116 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
3117 rtx result;
3119 /* If we want unsigned, and this mode has a distinct unsigned
3120 comparison routine, use that. */
3121 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
3122 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
3124 emit_library_call (libfunc, 1,
3125 word_mode, 2, x, mode, y, mode);
3127 /* Immediately move the result of the libcall into a pseudo
3128 register so reload doesn't clobber the value if it needs
3129 the return register for a spill reg. */
3130 result = gen_reg_rtx (word_mode);
3131 emit_move_insn (result, hard_libcall_value (word_mode));
3133 /* Integer comparison returns a result that must be compared against 1,
3134 so that even if we do an unsigned compare afterward,
3135 there is still a value that can represent the result "less than". */
3136 *px = result;
3137 *py = const1_rtx;
3138 *pmode = word_mode;
3139 return;
3142 if (class == MODE_FLOAT)
3143 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3145 else
3146 abort ();
3149 /* Before emitting an insn with code ICODE, make sure that X, which is going
3150 to be used for operand OPNUM of the insn, is converted from mode MODE to
3151 WIDER_MODE (UNSIGNEDP determines whether it is a unsigned conversion), and
3152 that it is accepted by the operand predicate. Return the new value. */
3155 prepare_operand (icode, x, opnum, mode, wider_mode, unsignedp)
3156 int icode;
3157 rtx x;
3158 int opnum;
3159 enum machine_mode mode, wider_mode;
3160 int unsignedp;
3162 x = protect_from_queue (x, 0);
3164 if (mode != wider_mode)
3165 x = convert_modes (wider_mode, mode, x, unsignedp);
3167 if (! (*insn_data[icode].operand[opnum].predicate)
3168 (x, insn_data[icode].operand[opnum].mode))
3169 x = copy_to_mode_reg (insn_data[icode].operand[opnum].mode, x);
3170 return x;
3173 /* Subroutine of emit_cmp_and_jump_insns; this function is called when we know
3174 we can do the comparison.
3175 The arguments are the same as for emit_cmp_and_jump_insns; but LABEL may
3176 be NULL_RTX which indicates that only a comparison is to be generated. */
3178 static void
3179 emit_cmp_and_jump_insn_1 (x, y, mode, comparison, unsignedp, label)
3180 rtx x, y;
3181 enum machine_mode mode;
3182 enum rtx_code comparison;
3183 int unsignedp;
3184 rtx label;
3186 rtx test = gen_rtx_fmt_ee (comparison, mode, x, y);
3187 enum mode_class class = GET_MODE_CLASS (mode);
3188 enum machine_mode wider_mode = mode;
3190 /* Try combined insns first. */
3193 enum insn_code icode;
3194 PUT_MODE (test, wider_mode);
3196 if (label)
3198 icode = cbranch_optab->handlers[(int)wider_mode].insn_code;
3200 if (icode != CODE_FOR_nothing
3201 && (*insn_data[icode].operand[0].predicate) (test, wider_mode))
3203 x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
3204 y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
3205 emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
3206 return;
3210 /* Handle some compares against zero. */
3211 icode = (int) tst_optab->handlers[(int) wider_mode].insn_code;
3212 if (y == CONST0_RTX (mode) && icode != CODE_FOR_nothing)
3214 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3215 emit_insn (GEN_FCN (icode) (x));
3216 if (label)
3217 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3218 return;
3221 /* Handle compares for which there is a directly suitable insn. */
3223 icode = (int) cmp_optab->handlers[(int) wider_mode].insn_code;
3224 if (icode != CODE_FOR_nothing)
3226 x = prepare_operand (icode, x, 0, mode, wider_mode, unsignedp);
3227 y = prepare_operand (icode, y, 1, mode, wider_mode, unsignedp);
3228 emit_insn (GEN_FCN (icode) (x, y));
3229 if (label)
3230 emit_jump_insn ((*bcc_gen_fctn[(int) comparison]) (label));
3231 return;
3234 if (class != MODE_INT && class != MODE_FLOAT
3235 && class != MODE_COMPLEX_FLOAT)
3236 break;
3238 wider_mode = GET_MODE_WIDER_MODE (wider_mode);
3239 } while (wider_mode != VOIDmode);
3241 abort ();
3244 /* Generate code to compare X with Y so that the condition codes are
3245 set and to jump to LABEL if the condition is true. If X is a
3246 constant and Y is not a constant, then the comparison is swapped to
3247 ensure that the comparison RTL has the canonical form.
3249 UNSIGNEDP nonzero says that X and Y are unsigned; this matters if they
3250 need to be widened by emit_cmp_insn. UNSIGNEDP is also used to select
3251 the proper branch condition code.
3253 If X and Y have mode BLKmode, then SIZE specifies the size of both X and Y,
3254 and ALIGN specifies the known shared alignment of X and Y.
3256 MODE is the mode of the inputs (in case they are const_int).
3258 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). It will
3259 be passed unchanged to emit_cmp_insn, then potentially converted into an
3260 unsigned variant based on UNSIGNEDP to select a proper jump instruction. */
3262 void
3263 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
3264 rtx x, y;
3265 enum rtx_code comparison;
3266 rtx size;
3267 enum machine_mode mode;
3268 int unsignedp;
3269 unsigned int align;
3270 rtx label;
3272 rtx op0;
3273 rtx op1;
3275 if ((CONSTANT_P (x) && ! CONSTANT_P (y))
3276 || (GET_CODE (x) == CONST_INT && GET_CODE (y) != CONST_INT))
3278 /* Swap operands and condition to ensure canonical RTL. */
3279 op0 = y;
3280 op1 = x;
3281 comparison = swap_condition (comparison);
3283 else
3285 op0 = x;
3286 op1 = y;
3289 #ifdef HAVE_cc0
3290 /* If OP0 is still a constant, then both X and Y must be constants. Force
3291 X into a register to avoid aborting in emit_cmp_insn due to non-canonical
3292 RTL. */
3293 if (CONSTANT_P (op0))
3294 op0 = force_reg (mode, op0);
3295 #endif
3297 emit_queue ();
3298 if (unsignedp)
3299 comparison = unsigned_condition (comparison);
3300 prepare_cmp_insn (&op0, &op1, &comparison, size, &mode, &unsignedp, align,
3301 ccp_jump);
3302 emit_cmp_and_jump_insn_1 (op0, op1, mode, comparison, unsignedp, label);
3305 /* Like emit_cmp_and_jump_insns, but generate only the comparison. */
3307 void
3308 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
3309 rtx x, y;
3310 enum rtx_code comparison;
3311 rtx size;
3312 enum machine_mode mode;
3313 int unsignedp;
3314 unsigned int align;
3316 emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
3319 /* Emit a library call comparison between floating point X and Y.
3320 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
3322 static void
3323 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp)
3324 rtx *px, *py;
3325 enum rtx_code *pcomparison;
3326 enum machine_mode *pmode;
3327 int *punsignedp;
3329 enum rtx_code comparison = *pcomparison;
3330 rtx x = *px = protect_from_queue (*px, 0);
3331 rtx y = *py = protect_from_queue (*py, 0);
3332 enum machine_mode mode = GET_MODE (x);
3333 rtx libfunc = 0;
3334 rtx result;
3336 if (mode == HFmode)
3337 switch (comparison)
3339 case EQ:
3340 libfunc = eqhf2_libfunc;
3341 break;
3343 case NE:
3344 libfunc = nehf2_libfunc;
3345 break;
3347 case GT:
3348 libfunc = gthf2_libfunc;
3349 break;
3351 case GE:
3352 libfunc = gehf2_libfunc;
3353 break;
3355 case LT:
3356 libfunc = lthf2_libfunc;
3357 break;
3359 case LE:
3360 libfunc = lehf2_libfunc;
3361 break;
3363 case UNORDERED:
3364 libfunc = unordhf2_libfunc;
3365 break;
3367 default:
3368 break;
3370 else if (mode == SFmode)
3371 switch (comparison)
3373 case EQ:
3374 libfunc = eqsf2_libfunc;
3375 break;
3377 case NE:
3378 libfunc = nesf2_libfunc;
3379 break;
3381 case GT:
3382 libfunc = gtsf2_libfunc;
3383 break;
3385 case GE:
3386 libfunc = gesf2_libfunc;
3387 break;
3389 case LT:
3390 libfunc = ltsf2_libfunc;
3391 break;
3393 case LE:
3394 libfunc = lesf2_libfunc;
3395 break;
3397 case UNORDERED:
3398 libfunc = unordsf2_libfunc;
3399 break;
3401 default:
3402 break;
3404 else if (mode == DFmode)
3405 switch (comparison)
3407 case EQ:
3408 libfunc = eqdf2_libfunc;
3409 break;
3411 case NE:
3412 libfunc = nedf2_libfunc;
3413 break;
3415 case GT:
3416 libfunc = gtdf2_libfunc;
3417 break;
3419 case GE:
3420 libfunc = gedf2_libfunc;
3421 break;
3423 case LT:
3424 libfunc = ltdf2_libfunc;
3425 break;
3427 case LE:
3428 libfunc = ledf2_libfunc;
3429 break;
3431 case UNORDERED:
3432 libfunc = unorddf2_libfunc;
3433 break;
3435 default:
3436 break;
3438 else if (mode == XFmode)
3439 switch (comparison)
3441 case EQ:
3442 libfunc = eqxf2_libfunc;
3443 break;
3445 case NE:
3446 libfunc = nexf2_libfunc;
3447 break;
3449 case GT:
3450 libfunc = gtxf2_libfunc;
3451 break;
3453 case GE:
3454 libfunc = gexf2_libfunc;
3455 break;
3457 case LT:
3458 libfunc = ltxf2_libfunc;
3459 break;
3461 case LE:
3462 libfunc = lexf2_libfunc;
3463 break;
3465 case UNORDERED:
3466 libfunc = unordxf2_libfunc;
3467 break;
3469 default:
3470 break;
3472 else if (mode == TFmode)
3473 switch (comparison)
3475 case EQ:
3476 libfunc = eqtf2_libfunc;
3477 break;
3479 case NE:
3480 libfunc = netf2_libfunc;
3481 break;
3483 case GT:
3484 libfunc = gttf2_libfunc;
3485 break;
3487 case GE:
3488 libfunc = getf2_libfunc;
3489 break;
3491 case LT:
3492 libfunc = lttf2_libfunc;
3493 break;
3495 case LE:
3496 libfunc = letf2_libfunc;
3497 break;
3499 case UNORDERED:
3500 libfunc = unordtf2_libfunc;
3501 break;
3503 default:
3504 break;
3506 else
3508 enum machine_mode wider_mode;
3510 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3511 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3513 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3514 != CODE_FOR_nothing)
3515 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3517 x = protect_from_queue (x, 0);
3518 y = protect_from_queue (y, 0);
3519 *px = convert_to_mode (wider_mode, x, 0);
3520 *py = convert_to_mode (wider_mode, y, 0);
3521 prepare_float_lib_cmp (px, py, pcomparison, pmode, punsignedp);
3522 return;
3525 abort ();
3528 if (libfunc == 0)
3529 abort ();
3531 emit_library_call (libfunc, LCT_CONST_MAKE_BLOCK, word_mode, 2, x, mode, y,
3532 mode);
3534 /* Immediately move the result of the libcall into a pseudo
3535 register so reload doesn't clobber the value if it needs
3536 the return register for a spill reg. */
3537 result = gen_reg_rtx (word_mode);
3538 emit_move_insn (result, hard_libcall_value (word_mode));
3539 *px = result;
3540 *py = const0_rtx;
3541 *pmode = word_mode;
3542 if (comparison == UNORDERED)
3543 *pcomparison = NE;
3544 #ifdef FLOAT_LIB_COMPARE_RETURNS_BOOL
3545 else if (FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
3546 *pcomparison = NE;
3547 #endif
3548 *punsignedp = 0;
3551 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3553 void
3554 emit_indirect_jump (loc)
3555 rtx loc;
3557 if (! ((*insn_data[(int)CODE_FOR_indirect_jump].operand[0].predicate)
3558 (loc, Pmode)))
3559 loc = copy_to_mode_reg (Pmode, loc);
3561 emit_jump_insn (gen_indirect_jump (loc));
3562 emit_barrier ();
3565 #ifdef HAVE_conditional_move
3567 /* Emit a conditional move instruction if the machine supports one for that
3568 condition and machine mode.
3570 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3571 the mode to use should they be constants. If it is VOIDmode, they cannot
3572 both be constants.
3574 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3575 should be stored there. MODE is the mode to use should they be constants.
3576 If it is VOIDmode, they cannot both be constants.
3578 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3579 is not supported. */
3582 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3583 unsignedp)
3584 rtx target;
3585 enum rtx_code code;
3586 rtx op0, op1;
3587 enum machine_mode cmode;
3588 rtx op2, op3;
3589 enum machine_mode mode;
3590 int unsignedp;
3592 rtx tem, subtarget, comparison, insn;
3593 enum insn_code icode;
3595 /* If one operand is constant, make it the second one. Only do this
3596 if the other operand is not constant as well. */
3598 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3599 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3601 tem = op0;
3602 op0 = op1;
3603 op1 = tem;
3604 code = swap_condition (code);
3607 /* get_condition will prefer to generate LT and GT even if the old
3608 comparison was against zero, so undo that canonicalization here since
3609 comparisons against zero are cheaper. */
3610 if (code == LT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == 1)
3611 code = LE, op1 = const0_rtx;
3612 else if (code == GT && GET_CODE (op1) == CONST_INT && INTVAL (op1) == -1)
3613 code = GE, op1 = const0_rtx;
3615 if (cmode == VOIDmode)
3616 cmode = GET_MODE (op0);
3618 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3619 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3620 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3621 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
3622 || flag_unsafe_math_optimizations))
3624 tem = op2;
3625 op2 = op3;
3626 op3 = tem;
3627 code = reverse_condition (code);
3630 if (mode == VOIDmode)
3631 mode = GET_MODE (op2);
3633 icode = movcc_gen_code[mode];
3635 if (icode == CODE_FOR_nothing)
3636 return 0;
3638 if (flag_force_mem)
3640 op2 = force_not_mem (op2);
3641 op3 = force_not_mem (op3);
3644 if (target)
3645 target = protect_from_queue (target, 1);
3646 else
3647 target = gen_reg_rtx (mode);
3649 subtarget = target;
3651 emit_queue ();
3653 op2 = protect_from_queue (op2, 0);
3654 op3 = protect_from_queue (op3, 0);
3656 /* If the insn doesn't accept these operands, put them in pseudos. */
3658 if (! (*insn_data[icode].operand[0].predicate)
3659 (subtarget, insn_data[icode].operand[0].mode))
3660 subtarget = gen_reg_rtx (insn_data[icode].operand[0].mode);
3662 if (! (*insn_data[icode].operand[2].predicate)
3663 (op2, insn_data[icode].operand[2].mode))
3664 op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
3666 if (! (*insn_data[icode].operand[3].predicate)
3667 (op3, insn_data[icode].operand[3].mode))
3668 op3 = copy_to_mode_reg (insn_data[icode].operand[3].mode, op3);
3670 /* Everything should now be in the suitable form, so emit the compare insn
3671 and then the conditional move. */
3673 comparison
3674 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3676 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3677 /* We can get const0_rtx or const_true_rtx in some circumstances. Just
3678 return NULL and let the caller figure out how best to deal with this
3679 situation. */
3680 if (GET_CODE (comparison) != code)
3681 return NULL_RTX;
3683 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3685 /* If that failed, then give up. */
3686 if (insn == 0)
3687 return 0;
3689 emit_insn (insn);
3691 if (subtarget != target)
3692 convert_move (target, subtarget, 0);
3694 return target;
3697 /* Return non-zero if a conditional move of mode MODE is supported.
3699 This function is for combine so it can tell whether an insn that looks
3700 like a conditional move is actually supported by the hardware. If we
3701 guess wrong we lose a bit on optimization, but that's it. */
3702 /* ??? sparc64 supports conditionally moving integers values based on fp
3703 comparisons, and vice versa. How do we handle them? */
3706 can_conditionally_move_p (mode)
3707 enum machine_mode mode;
3709 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3710 return 1;
3712 return 0;
3715 #endif /* HAVE_conditional_move */
3717 /* These three functions generate an insn body and return it
3718 rather than emitting the insn.
3720 They do not protect from queued increments,
3721 because they may be used 1) in protect_from_queue itself
3722 and 2) in other passes where there is no queue. */
3724 /* Generate and return an insn body to add Y to X. */
3727 gen_add2_insn (x, y)
3728 rtx x, y;
3730 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3732 if (! ((*insn_data[icode].operand[0].predicate)
3733 (x, insn_data[icode].operand[0].mode))
3734 || ! ((*insn_data[icode].operand[1].predicate)
3735 (x, insn_data[icode].operand[1].mode))
3736 || ! ((*insn_data[icode].operand[2].predicate)
3737 (y, insn_data[icode].operand[2].mode)))
3738 abort ();
3740 return (GEN_FCN (icode) (x, x, y));
3744 have_add2_insn (mode)
3745 enum machine_mode mode;
3747 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3750 /* Generate and return an insn body to subtract Y from X. */
3753 gen_sub2_insn (x, y)
3754 rtx x, y;
3756 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3758 if (! ((*insn_data[icode].operand[0].predicate)
3759 (x, insn_data[icode].operand[0].mode))
3760 || ! ((*insn_data[icode].operand[1].predicate)
3761 (x, insn_data[icode].operand[1].mode))
3762 || ! ((*insn_data[icode].operand[2].predicate)
3763 (y, insn_data[icode].operand[2].mode)))
3764 abort ();
3766 return (GEN_FCN (icode) (x, x, y));
3770 have_sub2_insn (mode)
3771 enum machine_mode mode;
3773 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3776 /* Generate the body of an instruction to copy Y into X.
3777 It may be a SEQUENCE, if one insn isn't enough. */
3780 gen_move_insn (x, y)
3781 rtx x, y;
3783 register enum machine_mode mode = GET_MODE (x);
3784 enum insn_code insn_code;
3785 rtx seq;
3787 if (mode == VOIDmode)
3788 mode = GET_MODE (y);
3790 insn_code = mov_optab->handlers[(int) mode].insn_code;
3792 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3793 find a mode to do it in. If we have a movcc, use it. Otherwise,
3794 find the MODE_INT mode of the same width. */
3796 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3798 enum machine_mode tmode = VOIDmode;
3799 rtx x1 = x, y1 = y;
3801 if (mode != CCmode
3802 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3803 tmode = CCmode;
3804 else
3805 for (tmode = QImode; tmode != VOIDmode;
3806 tmode = GET_MODE_WIDER_MODE (tmode))
3807 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3808 break;
3810 if (tmode == VOIDmode)
3811 abort ();
3813 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3814 may call change_address which is not appropriate if we were
3815 called when a reload was in progress. We don't have to worry
3816 about changing the address since the size in bytes is supposed to
3817 be the same. Copy the MEM to change the mode and move any
3818 substitutions from the old MEM to the new one. */
3820 if (reload_in_progress)
3822 x = gen_lowpart_common (tmode, x1);
3823 if (x == 0 && GET_CODE (x1) == MEM)
3825 x = gen_rtx_MEM (tmode, XEXP (x1, 0));
3826 MEM_COPY_ATTRIBUTES (x, x1);
3827 copy_replacements (x1, x);
3830 y = gen_lowpart_common (tmode, y1);
3831 if (y == 0 && GET_CODE (y1) == MEM)
3833 y = gen_rtx_MEM (tmode, XEXP (y1, 0));
3834 MEM_COPY_ATTRIBUTES (y, y1);
3835 copy_replacements (y1, y);
3838 else
3840 x = gen_lowpart (tmode, x);
3841 y = gen_lowpart (tmode, y);
3844 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3845 return (GEN_FCN (insn_code) (x, y));
3848 start_sequence ();
3849 emit_move_insn_1 (x, y);
3850 seq = gen_sequence ();
3851 end_sequence ();
3852 return seq;
3855 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3856 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3857 no such operation exists, CODE_FOR_nothing will be returned. */
3859 enum insn_code
3860 can_extend_p (to_mode, from_mode, unsignedp)
3861 enum machine_mode to_mode, from_mode;
3862 int unsignedp;
3864 return extendtab[(int) to_mode][(int) from_mode][unsignedp != 0];
3867 /* Generate the body of an insn to extend Y (with mode MFROM)
3868 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3871 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3872 rtx x, y;
3873 enum machine_mode mto, mfrom;
3874 int unsignedp;
3876 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp != 0]) (x, y));
3879 /* can_fix_p and can_float_p say whether the target machine
3880 can directly convert a given fixed point type to
3881 a given floating point type, or vice versa.
3882 The returned value is the CODE_FOR_... value to use,
3883 or CODE_FOR_nothing if these modes cannot be directly converted.
3885 *TRUNCP_PTR is set to 1 if it is necessary to output
3886 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3888 static enum insn_code
3889 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3890 enum machine_mode fltmode, fixmode;
3891 int unsignedp;
3892 int *truncp_ptr;
3894 *truncp_ptr = 0;
3895 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0]
3896 != CODE_FOR_nothing)
3897 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp != 0];
3899 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3901 *truncp_ptr = 1;
3902 return fixtab[(int) fltmode][(int) fixmode][unsignedp != 0];
3904 return CODE_FOR_nothing;
3907 static enum insn_code
3908 can_float_p (fltmode, fixmode, unsignedp)
3909 enum machine_mode fixmode, fltmode;
3910 int unsignedp;
3912 return floattab[(int) fltmode][(int) fixmode][unsignedp != 0];
3915 /* Generate code to convert FROM to floating point
3916 and store in TO. FROM must be fixed point and not VOIDmode.
3917 UNSIGNEDP nonzero means regard FROM as unsigned.
3918 Normally this is done by correcting the final value
3919 if it is negative. */
3921 void
3922 expand_float (to, from, unsignedp)
3923 rtx to, from;
3924 int unsignedp;
3926 enum insn_code icode;
3927 register rtx target = to;
3928 enum machine_mode fmode, imode;
3930 /* Crash now, because we won't be able to decide which mode to use. */
3931 if (GET_MODE (from) == VOIDmode)
3932 abort ();
3934 /* Look for an insn to do the conversion. Do it in the specified
3935 modes if possible; otherwise convert either input, output or both to
3936 wider mode. If the integer mode is wider than the mode of FROM,
3937 we can do the conversion signed even if the input is unsigned. */
3939 for (imode = GET_MODE (from); imode != VOIDmode;
3940 imode = GET_MODE_WIDER_MODE (imode))
3941 for (fmode = GET_MODE (to); fmode != VOIDmode;
3942 fmode = GET_MODE_WIDER_MODE (fmode))
3944 int doing_unsigned = unsignedp;
3946 if (fmode != GET_MODE (to)
3947 && significand_size (fmode) < GET_MODE_BITSIZE (GET_MODE (from)))
3948 continue;
3950 icode = can_float_p (fmode, imode, unsignedp);
3951 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3952 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3954 if (icode != CODE_FOR_nothing)
3956 to = protect_from_queue (to, 1);
3957 from = protect_from_queue (from, 0);
3959 if (imode != GET_MODE (from))
3960 from = convert_to_mode (imode, from, unsignedp);
3962 if (fmode != GET_MODE (to))
3963 target = gen_reg_rtx (fmode);
3965 emit_unop_insn (icode, target, from,
3966 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3968 if (target != to)
3969 convert_move (to, target, 0);
3970 return;
3974 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3976 /* Unsigned integer, and no way to convert directly.
3977 Convert as signed, then conditionally adjust the result. */
3978 if (unsignedp)
3980 rtx label = gen_label_rtx ();
3981 rtx temp;
3982 REAL_VALUE_TYPE offset;
3984 emit_queue ();
3986 to = protect_from_queue (to, 1);
3987 from = protect_from_queue (from, 0);
3989 if (flag_force_mem)
3990 from = force_not_mem (from);
3992 /* Look for a usable floating mode FMODE wider than the source and at
3993 least as wide as the target. Using FMODE will avoid rounding woes
3994 with unsigned values greater than the signed maximum value. */
3996 for (fmode = GET_MODE (to); fmode != VOIDmode;
3997 fmode = GET_MODE_WIDER_MODE (fmode))
3998 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3999 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
4000 break;
4002 if (fmode == VOIDmode)
4004 /* There is no such mode. Pretend the target is wide enough. */
4005 fmode = GET_MODE (to);
4007 /* Avoid double-rounding when TO is narrower than FROM. */
4008 if ((significand_size (fmode) + 1)
4009 < GET_MODE_BITSIZE (GET_MODE (from)))
4011 rtx temp1;
4012 rtx neglabel = gen_label_rtx ();
4014 /* Don't use TARGET if it isn't a register, is a hard register,
4015 or is the wrong mode. */
4016 if (GET_CODE (target) != REG
4017 || REGNO (target) < FIRST_PSEUDO_REGISTER
4018 || GET_MODE (target) != fmode)
4019 target = gen_reg_rtx (fmode);
4021 imode = GET_MODE (from);
4022 do_pending_stack_adjust ();
4024 /* Test whether the sign bit is set. */
4025 emit_cmp_and_jump_insns (from, const0_rtx, LT, NULL_RTX, imode,
4026 0, 0, neglabel);
4028 /* The sign bit is not set. Convert as signed. */
4029 expand_float (target, from, 0);
4030 emit_jump_insn (gen_jump (label));
4031 emit_barrier ();
4033 /* The sign bit is set.
4034 Convert to a usable (positive signed) value by shifting right
4035 one bit, while remembering if a nonzero bit was shifted
4036 out; i.e., compute (from & 1) | (from >> 1). */
4038 emit_label (neglabel);
4039 temp = expand_binop (imode, and_optab, from, const1_rtx,
4040 NULL_RTX, 1, OPTAB_LIB_WIDEN);
4041 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
4042 NULL_RTX, 1);
4043 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
4044 OPTAB_LIB_WIDEN);
4045 expand_float (target, temp, 0);
4047 /* Multiply by 2 to undo the shift above. */
4048 temp = expand_binop (fmode, add_optab, target, target,
4049 target, 0, OPTAB_LIB_WIDEN);
4050 if (temp != target)
4051 emit_move_insn (target, temp);
4053 do_pending_stack_adjust ();
4054 emit_label (label);
4055 goto done;
4059 /* If we are about to do some arithmetic to correct for an
4060 unsigned operand, do it in a pseudo-register. */
4062 if (GET_MODE (to) != fmode
4063 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
4064 target = gen_reg_rtx (fmode);
4066 /* Convert as signed integer to floating. */
4067 expand_float (target, from, 0);
4069 /* If FROM is negative (and therefore TO is negative),
4070 correct its value by 2**bitwidth. */
4072 do_pending_stack_adjust ();
4073 emit_cmp_and_jump_insns (from, const0_rtx, GE, NULL_RTX, GET_MODE (from),
4074 0, 0, label);
4076 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
4077 Rather than setting up a dconst_dot_5, let's hope SCO
4078 fixes the bug. */
4079 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
4080 temp = expand_binop (fmode, add_optab, target,
4081 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
4082 target, 0, OPTAB_LIB_WIDEN);
4083 if (temp != target)
4084 emit_move_insn (target, temp);
4086 do_pending_stack_adjust ();
4087 emit_label (label);
4088 goto done;
4090 #endif
4092 /* No hardware instruction available; call a library routine to convert from
4093 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
4095 rtx libfcn;
4096 rtx insns;
4097 rtx value;
4099 to = protect_from_queue (to, 1);
4100 from = protect_from_queue (from, 0);
4102 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
4103 from = convert_to_mode (SImode, from, unsignedp);
4105 if (flag_force_mem)
4106 from = force_not_mem (from);
4108 if (GET_MODE (to) == SFmode)
4110 if (GET_MODE (from) == SImode)
4111 libfcn = floatsisf_libfunc;
4112 else if (GET_MODE (from) == DImode)
4113 libfcn = floatdisf_libfunc;
4114 else if (GET_MODE (from) == TImode)
4115 libfcn = floattisf_libfunc;
4116 else
4117 abort ();
4119 else if (GET_MODE (to) == DFmode)
4121 if (GET_MODE (from) == SImode)
4122 libfcn = floatsidf_libfunc;
4123 else if (GET_MODE (from) == DImode)
4124 libfcn = floatdidf_libfunc;
4125 else if (GET_MODE (from) == TImode)
4126 libfcn = floattidf_libfunc;
4127 else
4128 abort ();
4130 else if (GET_MODE (to) == XFmode)
4132 if (GET_MODE (from) == SImode)
4133 libfcn = floatsixf_libfunc;
4134 else if (GET_MODE (from) == DImode)
4135 libfcn = floatdixf_libfunc;
4136 else if (GET_MODE (from) == TImode)
4137 libfcn = floattixf_libfunc;
4138 else
4139 abort ();
4141 else if (GET_MODE (to) == TFmode)
4143 if (GET_MODE (from) == SImode)
4144 libfcn = floatsitf_libfunc;
4145 else if (GET_MODE (from) == DImode)
4146 libfcn = floatditf_libfunc;
4147 else if (GET_MODE (from) == TImode)
4148 libfcn = floattitf_libfunc;
4149 else
4150 abort ();
4152 else
4153 abort ();
4155 start_sequence ();
4157 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4158 GET_MODE (to), 1, from,
4159 GET_MODE (from));
4160 insns = get_insns ();
4161 end_sequence ();
4163 emit_libcall_block (insns, target, value,
4164 gen_rtx_FLOAT (GET_MODE (to), from));
4167 done:
4169 /* Copy result to requested destination
4170 if we have been computing in a temp location. */
4172 if (target != to)
4174 if (GET_MODE (target) == GET_MODE (to))
4175 emit_move_insn (to, target);
4176 else
4177 convert_move (to, target, 0);
4181 /* expand_fix: generate code to convert FROM to fixed point
4182 and store in TO. FROM must be floating point. */
4184 static rtx
4185 ftruncify (x)
4186 rtx x;
4188 rtx temp = gen_reg_rtx (GET_MODE (x));
4189 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
4192 void
4193 expand_fix (to, from, unsignedp)
4194 register rtx to, from;
4195 int unsignedp;
4197 enum insn_code icode;
4198 register rtx target = to;
4199 enum machine_mode fmode, imode;
4200 int must_trunc = 0;
4201 rtx libfcn = 0;
4203 /* We first try to find a pair of modes, one real and one integer, at
4204 least as wide as FROM and TO, respectively, in which we can open-code
4205 this conversion. If the integer mode is wider than the mode of TO,
4206 we can do the conversion either signed or unsigned. */
4208 for (imode = GET_MODE (to); imode != VOIDmode;
4209 imode = GET_MODE_WIDER_MODE (imode))
4210 for (fmode = GET_MODE (from); fmode != VOIDmode;
4211 fmode = GET_MODE_WIDER_MODE (fmode))
4213 int doing_unsigned = unsignedp;
4215 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
4216 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
4217 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
4219 if (icode != CODE_FOR_nothing)
4221 to = protect_from_queue (to, 1);
4222 from = protect_from_queue (from, 0);
4224 if (fmode != GET_MODE (from))
4225 from = convert_to_mode (fmode, from, 0);
4227 if (must_trunc)
4228 from = ftruncify (from);
4230 if (imode != GET_MODE (to))
4231 target = gen_reg_rtx (imode);
4233 emit_unop_insn (icode, target, from,
4234 doing_unsigned ? UNSIGNED_FIX : FIX);
4235 if (target != to)
4236 convert_move (to, target, unsignedp);
4237 return;
4241 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
4242 /* For an unsigned conversion, there is one more way to do it.
4243 If we have a signed conversion, we generate code that compares
4244 the real value to the largest representable positive number. If if
4245 is smaller, the conversion is done normally. Otherwise, subtract
4246 one plus the highest signed number, convert, and add it back.
4248 We only need to check all real modes, since we know we didn't find
4249 anything with a wider integer mode. */
4251 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
4252 for (fmode = GET_MODE (from); fmode != VOIDmode;
4253 fmode = GET_MODE_WIDER_MODE (fmode))
4254 /* Make sure we won't lose significant bits doing this. */
4255 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
4256 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
4257 &must_trunc))
4259 int bitsize;
4260 REAL_VALUE_TYPE offset;
4261 rtx limit, lab1, lab2, insn;
4263 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
4264 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
4265 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
4266 lab1 = gen_label_rtx ();
4267 lab2 = gen_label_rtx ();
4269 emit_queue ();
4270 to = protect_from_queue (to, 1);
4271 from = protect_from_queue (from, 0);
4273 if (flag_force_mem)
4274 from = force_not_mem (from);
4276 if (fmode != GET_MODE (from))
4277 from = convert_to_mode (fmode, from, 0);
4279 /* See if we need to do the subtraction. */
4280 do_pending_stack_adjust ();
4281 emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from),
4282 0, 0, lab1);
4284 /* If not, do the signed "fix" and branch around fixup code. */
4285 expand_fix (to, from, 0);
4286 emit_jump_insn (gen_jump (lab2));
4287 emit_barrier ();
4289 /* Otherwise, subtract 2**(N-1), convert to signed number,
4290 then add 2**(N-1). Do the addition using XOR since this
4291 will often generate better code. */
4292 emit_label (lab1);
4293 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
4294 NULL_RTX, 0, OPTAB_LIB_WIDEN);
4295 expand_fix (to, target, 0);
4296 target = expand_binop (GET_MODE (to), xor_optab, to,
4297 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
4298 to, 1, OPTAB_LIB_WIDEN);
4300 if (target != to)
4301 emit_move_insn (to, target);
4303 emit_label (lab2);
4305 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
4306 != CODE_FOR_nothing)
4308 /* Make a place for a REG_NOTE and add it. */
4309 insn = emit_move_insn (to, to);
4310 set_unique_reg_note (insn,
4311 REG_EQUAL,
4312 gen_rtx_fmt_e (UNSIGNED_FIX,
4313 GET_MODE (to),
4314 copy_rtx (from)));
4317 return;
4319 #endif
4321 /* We can't do it with an insn, so use a library call. But first ensure
4322 that the mode of TO is at least as wide as SImode, since those are the
4323 only library calls we know about. */
4325 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
4327 target = gen_reg_rtx (SImode);
4329 expand_fix (target, from, unsignedp);
4331 else if (GET_MODE (from) == SFmode)
4333 if (GET_MODE (to) == SImode)
4334 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
4335 else if (GET_MODE (to) == DImode)
4336 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
4337 else if (GET_MODE (to) == TImode)
4338 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
4339 else
4340 abort ();
4342 else if (GET_MODE (from) == DFmode)
4344 if (GET_MODE (to) == SImode)
4345 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
4346 else if (GET_MODE (to) == DImode)
4347 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
4348 else if (GET_MODE (to) == TImode)
4349 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
4350 else
4351 abort ();
4353 else if (GET_MODE (from) == XFmode)
4355 if (GET_MODE (to) == SImode)
4356 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
4357 else if (GET_MODE (to) == DImode)
4358 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
4359 else if (GET_MODE (to) == TImode)
4360 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
4361 else
4362 abort ();
4364 else if (GET_MODE (from) == TFmode)
4366 if (GET_MODE (to) == SImode)
4367 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
4368 else if (GET_MODE (to) == DImode)
4369 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
4370 else if (GET_MODE (to) == TImode)
4371 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
4372 else
4373 abort ();
4375 else
4376 abort ();
4378 if (libfcn)
4380 rtx insns;
4381 rtx value;
4383 to = protect_from_queue (to, 1);
4384 from = protect_from_queue (from, 0);
4386 if (flag_force_mem)
4387 from = force_not_mem (from);
4389 start_sequence ();
4391 value = emit_library_call_value (libfcn, NULL_RTX, LCT_CONST,
4392 GET_MODE (to), 1, from,
4393 GET_MODE (from));
4394 insns = get_insns ();
4395 end_sequence ();
4397 emit_libcall_block (insns, target, value,
4398 gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
4399 GET_MODE (to), from));
4402 if (target != to)
4404 if (GET_MODE (to) == GET_MODE (target))
4405 emit_move_insn (to, target);
4406 else
4407 convert_move (to, target, 0);
4411 static optab
4412 init_optab (code)
4413 enum rtx_code code;
4415 int i;
4416 optab op = (optab) xmalloc (sizeof (struct optab));
4417 op->code = code;
4418 for (i = 0; i < NUM_MACHINE_MODES; i++)
4420 op->handlers[i].insn_code = CODE_FOR_nothing;
4421 op->handlers[i].libfunc = 0;
4424 if (code != UNKNOWN)
4425 code_to_optab[(int) code] = op;
4427 return op;
4430 /* Initialize the libfunc fields of an entire group of entries in some
4431 optab. Each entry is set equal to a string consisting of a leading
4432 pair of underscores followed by a generic operation name followed by
4433 a mode name (downshifted to lower case) followed by a single character
4434 representing the number of operands for the given operation (which is
4435 usually one of the characters '2', '3', or '4').
4437 OPTABLE is the table in which libfunc fields are to be initialized.
4438 FIRST_MODE is the first machine mode index in the given optab to
4439 initialize.
4440 LAST_MODE is the last machine mode index in the given optab to
4441 initialize.
4442 OPNAME is the generic (string) name of the operation.
4443 SUFFIX is the character which specifies the number of operands for
4444 the given generic operation.
4447 static void
4448 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
4449 register optab optable;
4450 register int first_mode;
4451 register int last_mode;
4452 register const char *opname;
4453 register int suffix;
4455 register int mode;
4456 register unsigned opname_len = strlen (opname);
4458 for (mode = first_mode; (int) mode <= (int) last_mode;
4459 mode = (enum machine_mode) ((int) mode + 1))
4461 register const char *mname = GET_MODE_NAME(mode);
4462 register unsigned mname_len = strlen (mname);
4463 register char *libfunc_name = alloca (2 + opname_len + mname_len + 1 + 1);
4464 register char *p;
4465 register const char *q;
4467 p = libfunc_name;
4468 *p++ = '_';
4469 *p++ = '_';
4470 for (q = opname; *q; )
4471 *p++ = *q++;
4472 for (q = mname; *q; q++)
4473 *p++ = TOLOWER (*q);
4474 *p++ = suffix;
4475 *p = '\0';
4477 optable->handlers[(int) mode].libfunc
4478 = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (libfunc_name,
4479 p - libfunc_name));
4483 /* Initialize the libfunc fields of an entire group of entries in some
4484 optab which correspond to all integer mode operations. The parameters
4485 have the same meaning as similarly named ones for the `init_libfuncs'
4486 routine. (See above). */
4488 static void
4489 init_integral_libfuncs (optable, opname, suffix)
4490 register optab optable;
4491 register const char *opname;
4492 register int suffix;
4494 init_libfuncs (optable, SImode, TImode, opname, suffix);
4497 /* Initialize the libfunc fields of an entire group of entries in some
4498 optab which correspond to all real mode operations. The parameters
4499 have the same meaning as similarly named ones for the `init_libfuncs'
4500 routine. (See above). */
4502 static void
4503 init_floating_libfuncs (optable, opname, suffix)
4504 register optab optable;
4505 register const char *opname;
4506 register int suffix;
4508 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4512 init_one_libfunc (name)
4513 register const char *name;
4515 name = ggc_strdup (name);
4517 return gen_rtx_SYMBOL_REF (Pmode, name);
4520 /* Mark ARG (which is really an OPTAB *) for GC. */
4522 void
4523 mark_optab (arg)
4524 void *arg;
4526 optab o = *(optab *) arg;
4527 int i;
4529 for (i = 0; i < NUM_MACHINE_MODES; ++i)
4530 ggc_mark_rtx (o->handlers[i].libfunc);
4533 /* Call this once to initialize the contents of the optabs
4534 appropriately for the current target machine. */
4536 void
4537 init_optabs ()
4539 unsigned int i, j, k;
4541 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4543 for (i = 0; i < ARRAY_SIZE (fixtab); i++)
4544 for (j = 0; j < ARRAY_SIZE (fixtab[0]); j++)
4545 for (k = 0; k < ARRAY_SIZE (fixtab[0][0]); k++)
4546 fixtab[i][j][k] = CODE_FOR_nothing;
4548 for (i = 0; i < ARRAY_SIZE (fixtrunctab); i++)
4549 for (j = 0; j < ARRAY_SIZE (fixtrunctab[0]); j++)
4550 for (k = 0; k < ARRAY_SIZE (fixtrunctab[0][0]); k++)
4551 fixtrunctab[i][j][k] = CODE_FOR_nothing;
4553 for (i = 0; i < ARRAY_SIZE (floattab); i++)
4554 for (j = 0; j < ARRAY_SIZE (floattab[0]); j++)
4555 for (k = 0; k < ARRAY_SIZE (floattab[0][0]); k++)
4556 floattab[i][j][k] = CODE_FOR_nothing;
4558 for (i = 0; i < ARRAY_SIZE (extendtab); i++)
4559 for (j = 0; j < ARRAY_SIZE (extendtab[0]); j++)
4560 for (k = 0; k < ARRAY_SIZE (extendtab[0][0]); k++)
4561 extendtab[i][j][k] = CODE_FOR_nothing;
4563 for (i = 0; i < NUM_RTX_CODE; i++)
4564 setcc_gen_code[i] = CODE_FOR_nothing;
4566 #ifdef HAVE_conditional_move
4567 for (i = 0; i < NUM_MACHINE_MODES; i++)
4568 movcc_gen_code[i] = CODE_FOR_nothing;
4569 #endif
4571 add_optab = init_optab (PLUS);
4572 addv_optab = init_optab (PLUS);
4573 sub_optab = init_optab (MINUS);
4574 subv_optab = init_optab (MINUS);
4575 smul_optab = init_optab (MULT);
4576 smulv_optab = init_optab (MULT);
4577 smul_highpart_optab = init_optab (UNKNOWN);
4578 umul_highpart_optab = init_optab (UNKNOWN);
4579 smul_widen_optab = init_optab (UNKNOWN);
4580 umul_widen_optab = init_optab (UNKNOWN);
4581 sdiv_optab = init_optab (DIV);
4582 sdivv_optab = init_optab (DIV);
4583 sdivmod_optab = init_optab (UNKNOWN);
4584 udiv_optab = init_optab (UDIV);
4585 udivmod_optab = init_optab (UNKNOWN);
4586 smod_optab = init_optab (MOD);
4587 umod_optab = init_optab (UMOD);
4588 flodiv_optab = init_optab (DIV);
4589 ftrunc_optab = init_optab (UNKNOWN);
4590 and_optab = init_optab (AND);
4591 ior_optab = init_optab (IOR);
4592 xor_optab = init_optab (XOR);
4593 ashl_optab = init_optab (ASHIFT);
4594 ashr_optab = init_optab (ASHIFTRT);
4595 lshr_optab = init_optab (LSHIFTRT);
4596 rotl_optab = init_optab (ROTATE);
4597 rotr_optab = init_optab (ROTATERT);
4598 smin_optab = init_optab (SMIN);
4599 smax_optab = init_optab (SMAX);
4600 umin_optab = init_optab (UMIN);
4601 umax_optab = init_optab (UMAX);
4602 mov_optab = init_optab (UNKNOWN);
4603 movstrict_optab = init_optab (UNKNOWN);
4604 cmp_optab = init_optab (UNKNOWN);
4605 ucmp_optab = init_optab (UNKNOWN);
4606 tst_optab = init_optab (UNKNOWN);
4607 neg_optab = init_optab (NEG);
4608 negv_optab = init_optab (NEG);
4609 abs_optab = init_optab (ABS);
4610 absv_optab = init_optab (ABS);
4611 one_cmpl_optab = init_optab (NOT);
4612 ffs_optab = init_optab (FFS);
4613 sqrt_optab = init_optab (SQRT);
4614 sin_optab = init_optab (UNKNOWN);
4615 cos_optab = init_optab (UNKNOWN);
4616 strlen_optab = init_optab (UNKNOWN);
4617 cbranch_optab = init_optab (UNKNOWN);
4618 cmov_optab = init_optab (UNKNOWN);
4619 cstore_optab = init_optab (UNKNOWN);
4621 for (i = 0; i < NUM_MACHINE_MODES; i++)
4623 movstr_optab[i] = CODE_FOR_nothing;
4624 clrstr_optab[i] = CODE_FOR_nothing;
4626 #ifdef HAVE_SECONDARY_RELOADS
4627 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4628 #endif
4631 /* Fill in the optabs with the insns we support. */
4632 init_all_optabs ();
4634 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4635 /* This flag says the same insns that convert to a signed fixnum
4636 also convert validly to an unsigned one. */
4637 for (i = 0; i < NUM_MACHINE_MODES; i++)
4638 for (j = 0; j < NUM_MACHINE_MODES; j++)
4639 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4640 #endif
4642 /* Initialize the optabs with the names of the library functions. */
4643 init_integral_libfuncs (add_optab, "add", '3');
4644 init_floating_libfuncs (add_optab, "add", '3');
4645 init_integral_libfuncs (addv_optab, "addv", '3');
4646 init_floating_libfuncs (addv_optab, "add", '3');
4647 init_integral_libfuncs (sub_optab, "sub", '3');
4648 init_floating_libfuncs (sub_optab, "sub", '3');
4649 init_integral_libfuncs (subv_optab, "subv", '3');
4650 init_floating_libfuncs (subv_optab, "sub", '3');
4651 init_integral_libfuncs (smul_optab, "mul", '3');
4652 init_floating_libfuncs (smul_optab, "mul", '3');
4653 init_integral_libfuncs (smulv_optab, "mulv", '3');
4654 init_floating_libfuncs (smulv_optab, "mul", '3');
4655 init_integral_libfuncs (sdiv_optab, "div", '3');
4656 init_integral_libfuncs (sdivv_optab, "divv", '3');
4657 init_integral_libfuncs (udiv_optab, "udiv", '3');
4658 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4659 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4660 init_integral_libfuncs (smod_optab, "mod", '3');
4661 init_integral_libfuncs (umod_optab, "umod", '3');
4662 init_floating_libfuncs (flodiv_optab, "div", '3');
4663 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4664 init_integral_libfuncs (and_optab, "and", '3');
4665 init_integral_libfuncs (ior_optab, "ior", '3');
4666 init_integral_libfuncs (xor_optab, "xor", '3');
4667 init_integral_libfuncs (ashl_optab, "ashl", '3');
4668 init_integral_libfuncs (ashr_optab, "ashr", '3');
4669 init_integral_libfuncs (lshr_optab, "lshr", '3');
4670 init_integral_libfuncs (smin_optab, "min", '3');
4671 init_floating_libfuncs (smin_optab, "min", '3');
4672 init_integral_libfuncs (smax_optab, "max", '3');
4673 init_floating_libfuncs (smax_optab, "max", '3');
4674 init_integral_libfuncs (umin_optab, "umin", '3');
4675 init_integral_libfuncs (umax_optab, "umax", '3');
4676 init_integral_libfuncs (neg_optab, "neg", '2');
4677 init_floating_libfuncs (neg_optab, "neg", '2');
4678 init_integral_libfuncs (negv_optab, "negv", '2');
4679 init_floating_libfuncs (negv_optab, "neg", '2');
4680 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4681 init_integral_libfuncs (ffs_optab, "ffs", '2');
4683 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4684 init_integral_libfuncs (cmp_optab, "cmp", '2');
4685 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4686 init_floating_libfuncs (cmp_optab, "cmp", '2');
4688 #ifdef MULSI3_LIBCALL
4689 smul_optab->handlers[(int) SImode].libfunc
4690 = init_one_libfunc (MULSI3_LIBCALL);
4691 #endif
4692 #ifdef MULDI3_LIBCALL
4693 smul_optab->handlers[(int) DImode].libfunc
4694 = init_one_libfunc (MULDI3_LIBCALL);
4695 #endif
4697 #ifdef DIVSI3_LIBCALL
4698 sdiv_optab->handlers[(int) SImode].libfunc
4699 = init_one_libfunc (DIVSI3_LIBCALL);
4700 #endif
4701 #ifdef DIVDI3_LIBCALL
4702 sdiv_optab->handlers[(int) DImode].libfunc
4703 = init_one_libfunc (DIVDI3_LIBCALL);
4704 #endif
4706 #ifdef UDIVSI3_LIBCALL
4707 udiv_optab->handlers[(int) SImode].libfunc
4708 = init_one_libfunc (UDIVSI3_LIBCALL);
4709 #endif
4710 #ifdef UDIVDI3_LIBCALL
4711 udiv_optab->handlers[(int) DImode].libfunc
4712 = init_one_libfunc (UDIVDI3_LIBCALL);
4713 #endif
4715 #ifdef MODSI3_LIBCALL
4716 smod_optab->handlers[(int) SImode].libfunc
4717 = init_one_libfunc (MODSI3_LIBCALL);
4718 #endif
4719 #ifdef MODDI3_LIBCALL
4720 smod_optab->handlers[(int) DImode].libfunc
4721 = init_one_libfunc (MODDI3_LIBCALL);
4722 #endif
4724 #ifdef UMODSI3_LIBCALL
4725 umod_optab->handlers[(int) SImode].libfunc
4726 = init_one_libfunc (UMODSI3_LIBCALL);
4727 #endif
4728 #ifdef UMODDI3_LIBCALL
4729 umod_optab->handlers[(int) DImode].libfunc
4730 = init_one_libfunc (UMODDI3_LIBCALL);
4731 #endif
4733 /* Use cabs for DC complex abs, since systems generally have cabs.
4734 Don't define any libcall for SCmode, so that cabs will be used. */
4735 abs_optab->handlers[(int) DCmode].libfunc
4736 = init_one_libfunc ("cabs");
4738 /* The ffs function operates on `int'. */
4739 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
4740 = init_one_libfunc ("ffs");
4742 extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
4743 extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
4744 extendsftf2_libfunc = init_one_libfunc ("__extendsftf2");
4745 extenddfxf2_libfunc = init_one_libfunc ("__extenddfxf2");
4746 extenddftf2_libfunc = init_one_libfunc ("__extenddftf2");
4748 truncdfsf2_libfunc = init_one_libfunc ("__truncdfsf2");
4749 truncxfsf2_libfunc = init_one_libfunc ("__truncxfsf2");
4750 trunctfsf2_libfunc = init_one_libfunc ("__trunctfsf2");
4751 truncxfdf2_libfunc = init_one_libfunc ("__truncxfdf2");
4752 trunctfdf2_libfunc = init_one_libfunc ("__trunctfdf2");
4754 memcpy_libfunc = init_one_libfunc ("memcpy");
4755 bcopy_libfunc = init_one_libfunc ("bcopy");
4756 memcmp_libfunc = init_one_libfunc ("memcmp");
4757 bcmp_libfunc = init_one_libfunc ("__gcc_bcmp");
4758 memset_libfunc = init_one_libfunc ("memset");
4759 bzero_libfunc = init_one_libfunc ("bzero");
4761 throw_libfunc = init_one_libfunc ("__throw");
4762 rethrow_libfunc = init_one_libfunc ("__rethrow");
4763 sjthrow_libfunc = init_one_libfunc ("__sjthrow");
4764 sjpopnthrow_libfunc = init_one_libfunc ("__sjpopnthrow");
4765 terminate_libfunc = init_one_libfunc ("__terminate");
4766 eh_rtime_match_libfunc = init_one_libfunc ("__eh_rtime_match");
4767 #ifndef DONT_USE_BUILTIN_SETJMP
4768 setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
4769 longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
4770 #else
4771 setjmp_libfunc = init_one_libfunc ("setjmp");
4772 longjmp_libfunc = init_one_libfunc ("longjmp");
4773 #endif
4775 eqhf2_libfunc = init_one_libfunc ("__eqhf2");
4776 nehf2_libfunc = init_one_libfunc ("__nehf2");
4777 gthf2_libfunc = init_one_libfunc ("__gthf2");
4778 gehf2_libfunc = init_one_libfunc ("__gehf2");
4779 lthf2_libfunc = init_one_libfunc ("__lthf2");
4780 lehf2_libfunc = init_one_libfunc ("__lehf2");
4781 unordhf2_libfunc = init_one_libfunc ("__unordhf2");
4783 eqsf2_libfunc = init_one_libfunc ("__eqsf2");
4784 nesf2_libfunc = init_one_libfunc ("__nesf2");
4785 gtsf2_libfunc = init_one_libfunc ("__gtsf2");
4786 gesf2_libfunc = init_one_libfunc ("__gesf2");
4787 ltsf2_libfunc = init_one_libfunc ("__ltsf2");
4788 lesf2_libfunc = init_one_libfunc ("__lesf2");
4789 unordsf2_libfunc = init_one_libfunc ("__unordsf2");
4791 eqdf2_libfunc = init_one_libfunc ("__eqdf2");
4792 nedf2_libfunc = init_one_libfunc ("__nedf2");
4793 gtdf2_libfunc = init_one_libfunc ("__gtdf2");
4794 gedf2_libfunc = init_one_libfunc ("__gedf2");
4795 ltdf2_libfunc = init_one_libfunc ("__ltdf2");
4796 ledf2_libfunc = init_one_libfunc ("__ledf2");
4797 unorddf2_libfunc = init_one_libfunc ("__unorddf2");
4799 eqxf2_libfunc = init_one_libfunc ("__eqxf2");
4800 nexf2_libfunc = init_one_libfunc ("__nexf2");
4801 gtxf2_libfunc = init_one_libfunc ("__gtxf2");
4802 gexf2_libfunc = init_one_libfunc ("__gexf2");
4803 ltxf2_libfunc = init_one_libfunc ("__ltxf2");
4804 lexf2_libfunc = init_one_libfunc ("__lexf2");
4805 unordxf2_libfunc = init_one_libfunc ("__unordxf2");
4807 eqtf2_libfunc = init_one_libfunc ("__eqtf2");
4808 netf2_libfunc = init_one_libfunc ("__netf2");
4809 gttf2_libfunc = init_one_libfunc ("__gttf2");
4810 getf2_libfunc = init_one_libfunc ("__getf2");
4811 lttf2_libfunc = init_one_libfunc ("__lttf2");
4812 letf2_libfunc = init_one_libfunc ("__letf2");
4813 unordtf2_libfunc = init_one_libfunc ("__unordtf2");
4815 floatsisf_libfunc = init_one_libfunc ("__floatsisf");
4816 floatdisf_libfunc = init_one_libfunc ("__floatdisf");
4817 floattisf_libfunc = init_one_libfunc ("__floattisf");
4819 floatsidf_libfunc = init_one_libfunc ("__floatsidf");
4820 floatdidf_libfunc = init_one_libfunc ("__floatdidf");
4821 floattidf_libfunc = init_one_libfunc ("__floattidf");
4823 floatsixf_libfunc = init_one_libfunc ("__floatsixf");
4824 floatdixf_libfunc = init_one_libfunc ("__floatdixf");
4825 floattixf_libfunc = init_one_libfunc ("__floattixf");
4827 floatsitf_libfunc = init_one_libfunc ("__floatsitf");
4828 floatditf_libfunc = init_one_libfunc ("__floatditf");
4829 floattitf_libfunc = init_one_libfunc ("__floattitf");
4831 fixsfsi_libfunc = init_one_libfunc ("__fixsfsi");
4832 fixsfdi_libfunc = init_one_libfunc ("__fixsfdi");
4833 fixsfti_libfunc = init_one_libfunc ("__fixsfti");
4835 fixdfsi_libfunc = init_one_libfunc ("__fixdfsi");
4836 fixdfdi_libfunc = init_one_libfunc ("__fixdfdi");
4837 fixdfti_libfunc = init_one_libfunc ("__fixdfti");
4839 fixxfsi_libfunc = init_one_libfunc ("__fixxfsi");
4840 fixxfdi_libfunc = init_one_libfunc ("__fixxfdi");
4841 fixxfti_libfunc = init_one_libfunc ("__fixxfti");
4843 fixtfsi_libfunc = init_one_libfunc ("__fixtfsi");
4844 fixtfdi_libfunc = init_one_libfunc ("__fixtfdi");
4845 fixtfti_libfunc = init_one_libfunc ("__fixtfti");
4847 fixunssfsi_libfunc = init_one_libfunc ("__fixunssfsi");
4848 fixunssfdi_libfunc = init_one_libfunc ("__fixunssfdi");
4849 fixunssfti_libfunc = init_one_libfunc ("__fixunssfti");
4851 fixunsdfsi_libfunc = init_one_libfunc ("__fixunsdfsi");
4852 fixunsdfdi_libfunc = init_one_libfunc ("__fixunsdfdi");
4853 fixunsdfti_libfunc = init_one_libfunc ("__fixunsdfti");
4855 fixunsxfsi_libfunc = init_one_libfunc ("__fixunsxfsi");
4856 fixunsxfdi_libfunc = init_one_libfunc ("__fixunsxfdi");
4857 fixunsxfti_libfunc = init_one_libfunc ("__fixunsxfti");
4859 fixunstfsi_libfunc = init_one_libfunc ("__fixunstfsi");
4860 fixunstfdi_libfunc = init_one_libfunc ("__fixunstfdi");
4861 fixunstfti_libfunc = init_one_libfunc ("__fixunstfti");
4863 /* For check-memory-usage. */
4864 chkr_check_addr_libfunc = init_one_libfunc ("chkr_check_addr");
4865 chkr_set_right_libfunc = init_one_libfunc ("chkr_set_right");
4866 chkr_copy_bitmap_libfunc = init_one_libfunc ("chkr_copy_bitmap");
4867 chkr_check_exec_libfunc = init_one_libfunc ("chkr_check_exec");
4868 chkr_check_str_libfunc = init_one_libfunc ("chkr_check_str");
4870 /* For function entry/exit instrumentation. */
4871 profile_function_entry_libfunc
4872 = init_one_libfunc ("__cyg_profile_func_enter");
4873 profile_function_exit_libfunc
4874 = init_one_libfunc ("__cyg_profile_func_exit");
4876 #ifdef HAVE_conditional_trap
4877 init_traps ();
4878 #endif
4880 #ifdef INIT_TARGET_OPTABS
4881 /* Allow the target to add more libcalls or rename some, etc. */
4882 INIT_TARGET_OPTABS;
4883 #endif
4885 /* Add these GC roots. */
4886 ggc_add_root (optab_table, OTI_MAX, sizeof(optab), mark_optab);
4887 ggc_add_rtx_root (libfunc_table, LTI_MAX);
4890 #ifdef BROKEN_LDEXP
4892 /* SCO 3.2 apparently has a broken ldexp. */
4894 double
4895 ldexp(x,n)
4896 double x;
4897 int n;
4899 if (n > 0)
4900 while (n--)
4901 x *= 2;
4903 return x;
4905 #endif /* BROKEN_LDEXP */
4907 #ifdef HAVE_conditional_trap
4908 /* The insn generating function can not take an rtx_code argument.
4909 TRAP_RTX is used as an rtx argument. Its code is replaced with
4910 the code to be used in the trap insn and all other fields are
4911 ignored. */
4912 static rtx trap_rtx;
4914 static void
4915 init_traps ()
4917 if (HAVE_conditional_trap)
4919 trap_rtx = gen_rtx_fmt_ee (EQ, VOIDmode, NULL_RTX, NULL_RTX);
4920 ggc_add_rtx_root (&trap_rtx, 1);
4923 #endif
4925 /* Generate insns to trap with code TCODE if OP1 and OP2 satisfy condition
4926 CODE. Return 0 on failure. */
4929 gen_cond_trap (code, op1, op2, tcode)
4930 enum rtx_code code ATTRIBUTE_UNUSED;
4931 rtx op1, op2 ATTRIBUTE_UNUSED, tcode ATTRIBUTE_UNUSED;
4933 enum machine_mode mode = GET_MODE (op1);
4935 if (mode == VOIDmode)
4936 return 0;
4938 #ifdef HAVE_conditional_trap
4939 if (HAVE_conditional_trap
4940 && cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
4942 rtx insn;
4943 start_sequence();
4944 emit_insn (GEN_FCN (cmp_optab->handlers[(int) mode].insn_code) (op1, op2));
4945 PUT_CODE (trap_rtx, code);
4946 insn = gen_conditional_trap (trap_rtx, tcode);
4947 if (insn)
4949 emit_insn (insn);
4950 insn = gen_sequence ();
4952 end_sequence();
4953 return insn;
4955 #endif
4957 return 0;