Update comment.
[official-gcc.git] / gcc / optabs.c
blob97983a864b1309aa1f8486022830a308a73f63d4
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92, 93, 94, 1995 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include "config.h"
22 #include "rtl.h"
23 #include "tree.h"
24 #include "flags.h"
25 #include "insn-flags.h"
26 #include "insn-codes.h"
27 #include "expr.h"
28 #include "insn-config.h"
29 #include "recog.h"
30 #include "reload.h"
31 #include <ctype.h>
33 /* Each optab contains info on how this target machine
34 can perform a particular operation
35 for all sizes and kinds of operands.
37 The operation to be performed is often specified
38 by passing one of these optabs as an argument.
40 See expr.h for documentation of these optabs. */
42 optab add_optab;
43 optab sub_optab;
44 optab smul_optab;
45 optab smul_highpart_optab;
46 optab umul_highpart_optab;
47 optab smul_widen_optab;
48 optab umul_widen_optab;
49 optab sdiv_optab;
50 optab sdivmod_optab;
51 optab udiv_optab;
52 optab udivmod_optab;
53 optab smod_optab;
54 optab umod_optab;
55 optab flodiv_optab;
56 optab ftrunc_optab;
57 optab and_optab;
58 optab ior_optab;
59 optab xor_optab;
60 optab ashl_optab;
61 optab lshr_optab;
62 optab ashr_optab;
63 optab rotl_optab;
64 optab rotr_optab;
65 optab smin_optab;
66 optab smax_optab;
67 optab umin_optab;
68 optab umax_optab;
70 optab mov_optab;
71 optab movstrict_optab;
73 optab neg_optab;
74 optab abs_optab;
75 optab one_cmpl_optab;
76 optab ffs_optab;
77 optab sqrt_optab;
78 optab sin_optab;
79 optab cos_optab;
81 optab cmp_optab;
82 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
83 optab tst_optab;
85 optab strlen_optab;
87 /* Tables of patterns for extending one integer mode to another. */
88 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
90 /* Tables of patterns for converting between fixed and floating point. */
91 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
92 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
95 /* Contains the optab used for each rtx code. */
96 optab code_to_optab[NUM_RTX_CODE + 1];
98 /* SYMBOL_REF rtx's for the library functions that are called
99 implicitly and not via optabs. */
101 rtx extendsfdf2_libfunc;
102 rtx extendsfxf2_libfunc;
103 rtx extendsftf2_libfunc;
104 rtx extenddfxf2_libfunc;
105 rtx extenddftf2_libfunc;
107 rtx truncdfsf2_libfunc;
108 rtx truncxfsf2_libfunc;
109 rtx trunctfsf2_libfunc;
110 rtx truncxfdf2_libfunc;
111 rtx trunctfdf2_libfunc;
113 rtx memcpy_libfunc;
114 rtx bcopy_libfunc;
115 rtx memcmp_libfunc;
116 rtx bcmp_libfunc;
117 rtx memset_libfunc;
118 rtx bzero_libfunc;
120 rtx eqhf2_libfunc;
121 rtx nehf2_libfunc;
122 rtx gthf2_libfunc;
123 rtx gehf2_libfunc;
124 rtx lthf2_libfunc;
125 rtx lehf2_libfunc;
127 rtx eqsf2_libfunc;
128 rtx nesf2_libfunc;
129 rtx gtsf2_libfunc;
130 rtx gesf2_libfunc;
131 rtx ltsf2_libfunc;
132 rtx lesf2_libfunc;
134 rtx eqdf2_libfunc;
135 rtx nedf2_libfunc;
136 rtx gtdf2_libfunc;
137 rtx gedf2_libfunc;
138 rtx ltdf2_libfunc;
139 rtx ledf2_libfunc;
141 rtx eqxf2_libfunc;
142 rtx nexf2_libfunc;
143 rtx gtxf2_libfunc;
144 rtx gexf2_libfunc;
145 rtx ltxf2_libfunc;
146 rtx lexf2_libfunc;
148 rtx eqtf2_libfunc;
149 rtx netf2_libfunc;
150 rtx gttf2_libfunc;
151 rtx getf2_libfunc;
152 rtx lttf2_libfunc;
153 rtx letf2_libfunc;
155 rtx floatsisf_libfunc;
156 rtx floatdisf_libfunc;
157 rtx floattisf_libfunc;
159 rtx floatsidf_libfunc;
160 rtx floatdidf_libfunc;
161 rtx floattidf_libfunc;
163 rtx floatsixf_libfunc;
164 rtx floatdixf_libfunc;
165 rtx floattixf_libfunc;
167 rtx floatsitf_libfunc;
168 rtx floatditf_libfunc;
169 rtx floattitf_libfunc;
171 rtx fixsfsi_libfunc;
172 rtx fixsfdi_libfunc;
173 rtx fixsfti_libfunc;
175 rtx fixdfsi_libfunc;
176 rtx fixdfdi_libfunc;
177 rtx fixdfti_libfunc;
179 rtx fixxfsi_libfunc;
180 rtx fixxfdi_libfunc;
181 rtx fixxfti_libfunc;
183 rtx fixtfsi_libfunc;
184 rtx fixtfdi_libfunc;
185 rtx fixtfti_libfunc;
187 rtx fixunssfsi_libfunc;
188 rtx fixunssfdi_libfunc;
189 rtx fixunssfti_libfunc;
191 rtx fixunsdfsi_libfunc;
192 rtx fixunsdfdi_libfunc;
193 rtx fixunsdfti_libfunc;
195 rtx fixunsxfsi_libfunc;
196 rtx fixunsxfdi_libfunc;
197 rtx fixunsxfti_libfunc;
199 rtx fixunstfsi_libfunc;
200 rtx fixunstfdi_libfunc;
201 rtx fixunstfti_libfunc;
203 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
204 gives the gen_function to make a branch to test that condition. */
206 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
208 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
209 gives the insn code to make a store-condition insn
210 to test that condition. */
212 enum insn_code setcc_gen_code[NUM_RTX_CODE];
214 #ifdef HAVE_conditional_move
215 /* Indexed by the machine mode, gives the insn code to make a conditional
216 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
217 setcc_gen_code to cut down on the number of named patterns. Consider a day
218 when a lot more rtx codes are conditional (eg: for the ARM). */
220 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
221 #endif
223 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
224 static rtx widen_operand PROTO((rtx, enum machine_mode,
225 enum machine_mode, int, int));
226 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
227 int, int *));
228 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
229 int));
230 static rtx ftruncify PROTO((rtx));
231 static optab init_optab PROTO((enum rtx_code));
232 static void init_libfuncs PROTO((optab, int, int, char *, int));
233 static void init_integral_libfuncs PROTO((optab, char *, int));
234 static void init_floating_libfuncs PROTO((optab, char *, int));
235 static void init_complex_libfuncs PROTO((optab, char *, int));
237 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
238 the result of operation CODE applied to OP0 (and OP1 if it is a binary
239 operation).
241 If the last insn does not set TARGET, don't do anything, but return 1.
243 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
244 don't add the REG_EQUAL note but return 0. Our caller can then try
245 again, ensuring that TARGET is not one of the operands. */
247 static int
248 add_equal_note (seq, target, code, op0, op1)
249 rtx seq;
250 rtx target;
251 enum rtx_code code;
252 rtx op0, op1;
254 rtx set;
255 int i;
256 rtx note;
258 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
259 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
260 || GET_CODE (seq) != SEQUENCE
261 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
262 || GET_CODE (target) == ZERO_EXTRACT
263 || (! rtx_equal_p (SET_DEST (set), target)
264 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
265 SUBREG. */
266 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
267 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
268 target))))
269 return 1;
271 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
272 besides the last insn. */
273 if (reg_overlap_mentioned_p (target, op0)
274 || (op1 && reg_overlap_mentioned_p (target, op1)))
275 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
276 if (reg_set_p (target, XVECEXP (seq, 0, i)))
277 return 0;
279 if (GET_RTX_CLASS (code) == '1')
280 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
281 else
282 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
284 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
285 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
286 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
288 return 1;
291 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
292 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
293 not actually do a sign-extend or zero-extend, but can leave the
294 higher-order bits of the result rtx undefined, for example, in the case
295 of logical operations, but not right shifts. */
297 static rtx
298 widen_operand (op, mode, oldmode, unsignedp, no_extend)
299 rtx op;
300 enum machine_mode mode, oldmode;
301 int unsignedp;
302 int no_extend;
304 rtx result;
306 /* If we must extend do so. If OP is either a constant or a SUBREG
307 for a promoted object, also extend since it will be more efficient to
308 do so. */
309 if (! no_extend
310 || GET_MODE (op) == VOIDmode
311 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
312 return convert_modes (mode, oldmode, op, unsignedp);
314 /* If MODE is no wider than a single word, we return a paradoxical
315 SUBREG. */
316 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
317 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
319 /* Otherwise, get an object of MODE, clobber it, and set the low-order
320 part to OP. */
322 result = gen_reg_rtx (mode);
323 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
324 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
325 return result;
328 /* Generate code to perform an operation specified by BINOPTAB
329 on operands OP0 and OP1, with result having machine-mode MODE.
331 UNSIGNEDP is for the case where we have to widen the operands
332 to perform the operation. It says to use zero-extension.
334 If TARGET is nonzero, the value
335 is generated there, if it is convenient to do so.
336 In all cases an rtx is returned for the locus of the value;
337 this may or may not be TARGET. */
340 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
341 enum machine_mode mode;
342 optab binoptab;
343 rtx op0, op1;
344 rtx target;
345 int unsignedp;
346 enum optab_methods methods;
348 enum optab_methods next_methods
349 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
350 ? OPTAB_WIDEN : methods);
351 enum mode_class class;
352 enum machine_mode wider_mode;
353 register rtx temp;
354 int commutative_op = 0;
355 int shift_op = (binoptab->code == ASHIFT
356 || binoptab->code == ASHIFTRT
357 || binoptab->code == LSHIFTRT
358 || binoptab->code == ROTATE
359 || binoptab->code == ROTATERT);
360 rtx entry_last = get_last_insn ();
361 rtx last;
363 class = GET_MODE_CLASS (mode);
365 op0 = protect_from_queue (op0, 0);
366 op1 = protect_from_queue (op1, 0);
367 if (target)
368 target = protect_from_queue (target, 1);
370 if (flag_force_mem)
372 op0 = force_not_mem (op0);
373 op1 = force_not_mem (op1);
376 /* If subtracting an integer constant, convert this into an addition of
377 the negated constant. */
379 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
381 op1 = negate_rtx (mode, op1);
382 binoptab = add_optab;
385 /* If we are inside an appropriately-short loop and one operand is an
386 expensive constant, force it into a register. */
387 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
388 && rtx_cost (op0, binoptab->code) > 2)
389 op0 = force_reg (mode, op0);
391 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
392 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
393 op1 = force_reg (mode, op1);
395 /* Record where to delete back to if we backtrack. */
396 last = get_last_insn ();
398 /* If operation is commutative,
399 try to make the first operand a register.
400 Even better, try to make it the same as the target.
401 Also try to make the last operand a constant. */
402 if (GET_RTX_CLASS (binoptab->code) == 'c'
403 || binoptab == smul_widen_optab
404 || binoptab == umul_widen_optab
405 || binoptab == smul_highpart_optab
406 || binoptab == umul_highpart_optab)
408 commutative_op = 1;
410 if (((target == 0 || GET_CODE (target) == REG)
411 ? ((GET_CODE (op1) == REG
412 && GET_CODE (op0) != REG)
413 || target == op1)
414 : rtx_equal_p (op1, target))
415 || GET_CODE (op0) == CONST_INT)
417 temp = op1;
418 op1 = op0;
419 op0 = temp;
423 /* If we can do it with a three-operand insn, do so. */
425 if (methods != OPTAB_MUST_WIDEN
426 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
428 int icode = (int) binoptab->handlers[(int) mode].insn_code;
429 enum machine_mode mode0 = insn_operand_mode[icode][1];
430 enum machine_mode mode1 = insn_operand_mode[icode][2];
431 rtx pat;
432 rtx xop0 = op0, xop1 = op1;
434 if (target)
435 temp = target;
436 else
437 temp = gen_reg_rtx (mode);
439 /* If it is a commutative operator and the modes would match
440 if we would swap the operands, we can save the conversions. */
441 if (commutative_op)
443 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
444 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
446 register rtx tmp;
448 tmp = op0; op0 = op1; op1 = tmp;
449 tmp = xop0; xop0 = xop1; xop1 = tmp;
453 /* In case the insn wants input operands in modes different from
454 the result, convert the operands. */
456 if (GET_MODE (op0) != VOIDmode
457 && GET_MODE (op0) != mode0
458 && mode0 != VOIDmode)
459 xop0 = convert_to_mode (mode0, xop0, unsignedp);
461 if (GET_MODE (xop1) != VOIDmode
462 && GET_MODE (xop1) != mode1
463 && mode1 != VOIDmode)
464 xop1 = convert_to_mode (mode1, xop1, unsignedp);
466 /* Now, if insn's predicates don't allow our operands, put them into
467 pseudo regs. */
469 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
470 && mode0 != VOIDmode)
471 xop0 = copy_to_mode_reg (mode0, xop0);
473 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
474 && mode1 != VOIDmode)
475 xop1 = copy_to_mode_reg (mode1, xop1);
477 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
478 temp = gen_reg_rtx (mode);
480 pat = GEN_FCN (icode) (temp, xop0, xop1);
481 if (pat)
483 /* If PAT is a multi-insn sequence, try to add an appropriate
484 REG_EQUAL note to it. If we can't because TEMP conflicts with an
485 operand, call ourselves again, this time without a target. */
486 if (GET_CODE (pat) == SEQUENCE
487 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
489 delete_insns_since (last);
490 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
491 unsignedp, methods);
494 emit_insn (pat);
495 return temp;
497 else
498 delete_insns_since (last);
501 /* If this is a multiply, see if we can do a widening operation that
502 takes operands of this mode and makes a wider mode. */
504 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
505 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
506 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
507 != CODE_FOR_nothing))
509 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
510 unsignedp ? umul_widen_optab : smul_widen_optab,
511 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
513 if (temp != 0)
515 if (GET_MODE_CLASS (mode) == MODE_INT)
516 return gen_lowpart (mode, temp);
517 else
518 return convert_to_mode (mode, temp, unsignedp);
522 /* Look for a wider mode of the same class for which we think we
523 can open-code the operation. Check for a widening multiply at the
524 wider mode as well. */
526 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
527 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
528 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
529 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
531 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
532 || (binoptab == smul_optab
533 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
534 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
535 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
536 != CODE_FOR_nothing)))
538 rtx xop0 = op0, xop1 = op1;
539 int no_extend = 0;
541 /* For certain integer operations, we need not actually extend
542 the narrow operands, as long as we will truncate
543 the results to the same narrowness. */
545 if ((binoptab == ior_optab || binoptab == and_optab
546 || binoptab == xor_optab
547 || binoptab == add_optab || binoptab == sub_optab
548 || binoptab == smul_optab || binoptab == ashl_optab)
549 && class == MODE_INT)
550 no_extend = 1;
552 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
554 /* The second operand of a shift must always be extended. */
555 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
556 no_extend && binoptab != ashl_optab);
558 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
559 unsignedp, OPTAB_DIRECT);
560 if (temp)
562 if (class != MODE_INT)
564 if (target == 0)
565 target = gen_reg_rtx (mode);
566 convert_move (target, temp, 0);
567 return target;
569 else
570 return gen_lowpart (mode, temp);
572 else
573 delete_insns_since (last);
577 /* These can be done a word at a time. */
578 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
579 && class == MODE_INT
580 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
581 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
583 int i;
584 rtx insns;
585 rtx equiv_value;
587 /* If TARGET is the same as one of the operands, the REG_EQUAL note
588 won't be accurate, so use a new target. */
589 if (target == 0 || target == op0 || target == op1)
590 target = gen_reg_rtx (mode);
592 start_sequence ();
594 /* Do the actual arithmetic. */
595 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
597 rtx target_piece = operand_subword (target, i, 1, mode);
598 rtx x = expand_binop (word_mode, binoptab,
599 operand_subword_force (op0, i, mode),
600 operand_subword_force (op1, i, mode),
601 target_piece, unsignedp, next_methods);
603 if (x == 0)
604 break;
606 if (target_piece != x)
607 emit_move_insn (target_piece, x);
610 insns = get_insns ();
611 end_sequence ();
613 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
615 if (binoptab->code != UNKNOWN)
616 equiv_value
617 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
618 else
619 equiv_value = 0;
621 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
622 return target;
626 /* Synthesize double word shifts from single word shifts. */
627 if ((binoptab == lshr_optab || binoptab == ashl_optab
628 || binoptab == ashr_optab)
629 && class == MODE_INT
630 && GET_CODE (op1) == CONST_INT
631 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
632 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
633 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
634 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
636 rtx insns, inter, equiv_value;
637 rtx into_target, outof_target;
638 rtx into_input, outof_input;
639 int shift_count, left_shift, outof_word;
641 /* If TARGET is the same as one of the operands, the REG_EQUAL note
642 won't be accurate, so use a new target. */
643 if (target == 0 || target == op0 || target == op1)
644 target = gen_reg_rtx (mode);
646 start_sequence ();
648 shift_count = INTVAL (op1);
650 /* OUTOF_* is the word we are shifting bits away from, and
651 INTO_* is the word that we are shifting bits towards, thus
652 they differ depending on the direction of the shift and
653 WORDS_BIG_ENDIAN. */
655 left_shift = binoptab == ashl_optab;
656 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
658 outof_target = operand_subword (target, outof_word, 1, mode);
659 into_target = operand_subword (target, 1 - outof_word, 1, mode);
661 outof_input = operand_subword_force (op0, outof_word, mode);
662 into_input = operand_subword_force (op0, 1 - outof_word, mode);
664 if (shift_count >= BITS_PER_WORD)
666 inter = expand_binop (word_mode, binoptab,
667 outof_input,
668 GEN_INT (shift_count - BITS_PER_WORD),
669 into_target, unsignedp, next_methods);
671 if (inter != 0 && inter != into_target)
672 emit_move_insn (into_target, inter);
674 /* For a signed right shift, we must fill the word we are shifting
675 out of with copies of the sign bit. Otherwise it is zeroed. */
676 if (inter != 0 && binoptab != ashr_optab)
677 inter = CONST0_RTX (word_mode);
678 else if (inter != 0)
679 inter = expand_binop (word_mode, binoptab,
680 outof_input,
681 GEN_INT (BITS_PER_WORD - 1),
682 outof_target, unsignedp, next_methods);
684 if (inter != 0 && inter != outof_target)
685 emit_move_insn (outof_target, inter);
687 else
689 rtx carries;
690 optab reverse_unsigned_shift, unsigned_shift;
692 /* For a shift of less then BITS_PER_WORD, to compute the carry,
693 we must do a logical shift in the opposite direction of the
694 desired shift. */
696 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
698 /* For a shift of less than BITS_PER_WORD, to compute the word
699 shifted towards, we need to unsigned shift the orig value of
700 that word. */
702 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
704 carries = expand_binop (word_mode, reverse_unsigned_shift,
705 outof_input,
706 GEN_INT (BITS_PER_WORD - shift_count),
707 0, unsignedp, next_methods);
709 if (carries == 0)
710 inter = 0;
711 else
712 inter = expand_binop (word_mode, unsigned_shift, into_input,
713 op1, 0, unsignedp, next_methods);
715 if (inter != 0)
716 inter = expand_binop (word_mode, ior_optab, carries, inter,
717 into_target, unsignedp, next_methods);
719 if (inter != 0 && inter != into_target)
720 emit_move_insn (into_target, inter);
722 if (inter != 0)
723 inter = expand_binop (word_mode, binoptab, outof_input,
724 op1, outof_target, unsignedp, next_methods);
726 if (inter != 0 && inter != outof_target)
727 emit_move_insn (outof_target, inter);
730 insns = get_insns ();
731 end_sequence ();
733 if (inter != 0)
735 if (binoptab->code != UNKNOWN)
736 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
737 else
738 equiv_value = 0;
740 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
741 return target;
745 /* Synthesize double word rotates from single word shifts. */
746 if ((binoptab == rotl_optab || binoptab == rotr_optab)
747 && class == MODE_INT
748 && GET_CODE (op1) == CONST_INT
749 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
750 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
751 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
753 rtx insns, equiv_value;
754 rtx into_target, outof_target;
755 rtx into_input, outof_input;
756 rtx inter;
757 int shift_count, left_shift, outof_word;
759 /* If TARGET is the same as one of the operands, the REG_EQUAL note
760 won't be accurate, so use a new target. */
761 if (target == 0 || target == op0 || target == op1)
762 target = gen_reg_rtx (mode);
764 start_sequence ();
766 shift_count = INTVAL (op1);
768 /* OUTOF_* is the word we are shifting bits away from, and
769 INTO_* is the word that we are shifting bits towards, thus
770 they differ depending on the direction of the shift and
771 WORDS_BIG_ENDIAN. */
773 left_shift = (binoptab == rotl_optab);
774 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
776 outof_target = operand_subword (target, outof_word, 1, mode);
777 into_target = operand_subword (target, 1 - outof_word, 1, mode);
779 outof_input = operand_subword_force (op0, outof_word, mode);
780 into_input = operand_subword_force (op0, 1 - outof_word, mode);
782 if (shift_count == BITS_PER_WORD)
784 /* This is just a word swap. */
785 emit_move_insn (outof_target, into_input);
786 emit_move_insn (into_target, outof_input);
787 inter = const0_rtx;
789 else
791 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
792 rtx first_shift_count, second_shift_count;
793 optab reverse_unsigned_shift, unsigned_shift;
795 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
796 ? lshr_optab : ashl_optab);
798 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
799 ? ashl_optab : lshr_optab);
801 if (shift_count > BITS_PER_WORD)
803 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
804 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
806 else
808 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
809 second_shift_count = GEN_INT (shift_count);
812 into_temp1 = expand_binop (word_mode, unsigned_shift,
813 outof_input, first_shift_count,
814 NULL_RTX, unsignedp, next_methods);
815 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
816 into_input, second_shift_count,
817 into_target, unsignedp, next_methods);
819 if (into_temp1 != 0 && into_temp2 != 0)
820 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
821 into_target, unsignedp, next_methods);
822 else
823 inter = 0;
825 if (inter != 0 && inter != into_target)
826 emit_move_insn (into_target, inter);
828 outof_temp1 = expand_binop (word_mode, unsigned_shift,
829 into_input, first_shift_count,
830 NULL_RTX, unsignedp, next_methods);
831 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
832 outof_input, second_shift_count,
833 outof_target, unsignedp, next_methods);
835 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
836 inter = expand_binop (word_mode, ior_optab,
837 outof_temp1, outof_temp2,
838 outof_target, unsignedp, next_methods);
840 if (inter != 0 && inter != outof_target)
841 emit_move_insn (outof_target, inter);
844 insns = get_insns ();
845 end_sequence ();
847 if (inter != 0)
849 if (binoptab->code != UNKNOWN)
850 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
851 else
852 equiv_value = 0;
854 /* We can't make this a no conflict block if this is a word swap,
855 because the word swap case fails if the input and output values
856 are in the same register. */
857 if (shift_count != BITS_PER_WORD)
858 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
859 else
860 emit_insns (insns);
863 return target;
867 /* These can be done a word at a time by propagating carries. */
868 if ((binoptab == add_optab || binoptab == sub_optab)
869 && class == MODE_INT
870 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
871 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
873 int i;
874 rtx carry_tmp = gen_reg_rtx (word_mode);
875 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
876 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
877 rtx carry_in, carry_out;
878 rtx xop0, xop1;
880 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
881 value is one of those, use it. Otherwise, use 1 since it is the
882 one easiest to get. */
883 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
884 int normalizep = STORE_FLAG_VALUE;
885 #else
886 int normalizep = 1;
887 #endif
889 /* Prepare the operands. */
890 xop0 = force_reg (mode, op0);
891 xop1 = force_reg (mode, op1);
893 if (target == 0 || GET_CODE (target) != REG
894 || target == xop0 || target == xop1)
895 target = gen_reg_rtx (mode);
897 /* Indicate for flow that the entire target reg is being set. */
898 if (GET_CODE (target) == REG)
899 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
901 /* Do the actual arithmetic. */
902 for (i = 0; i < nwords; i++)
904 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
905 rtx target_piece = operand_subword (target, index, 1, mode);
906 rtx op0_piece = operand_subword_force (xop0, index, mode);
907 rtx op1_piece = operand_subword_force (xop1, index, mode);
908 rtx x;
910 /* Main add/subtract of the input operands. */
911 x = expand_binop (word_mode, binoptab,
912 op0_piece, op1_piece,
913 target_piece, unsignedp, next_methods);
914 if (x == 0)
915 break;
917 if (i + 1 < nwords)
919 /* Store carry from main add/subtract. */
920 carry_out = gen_reg_rtx (word_mode);
921 carry_out = emit_store_flag (carry_out,
922 binoptab == add_optab ? LTU : GTU,
923 x, op0_piece,
924 word_mode, 1, normalizep);
925 if (carry_out == 0)
926 break;
929 if (i > 0)
931 /* Add/subtract previous carry to main result. */
932 x = expand_binop (word_mode,
933 normalizep == 1 ? binoptab : otheroptab,
934 x, carry_in,
935 target_piece, 1, next_methods);
936 if (x == 0)
937 break;
938 else if (target_piece != x)
939 emit_move_insn (target_piece, x);
941 if (i + 1 < nwords)
943 /* THIS CODE HAS NOT BEEN TESTED. */
944 /* Get out carry from adding/subtracting carry in. */
945 carry_tmp = emit_store_flag (carry_tmp,
946 binoptab == add_optab
947 ? LTU : GTU,
948 x, carry_in,
949 word_mode, 1, normalizep);
951 /* Logical-ior the two poss. carry together. */
952 carry_out = expand_binop (word_mode, ior_optab,
953 carry_out, carry_tmp,
954 carry_out, 0, next_methods);
955 if (carry_out == 0)
956 break;
960 carry_in = carry_out;
963 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
965 rtx temp = emit_move_insn (target, target);
967 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
968 gen_rtx (binoptab->code, mode,
969 copy_rtx (xop0),
970 copy_rtx (xop1)),
971 REG_NOTES (temp));
972 return target;
974 else
975 delete_insns_since (last);
978 /* If we want to multiply two two-word values and have normal and widening
979 multiplies of single-word values, we can do this with three smaller
980 multiplications. Note that we do not make a REG_NO_CONFLICT block here
981 because we are not operating on one word at a time.
983 The multiplication proceeds as follows:
984 _______________________
985 [__op0_high_|__op0_low__]
986 _______________________
987 * [__op1_high_|__op1_low__]
988 _______________________________________________
989 _______________________
990 (1) [__op0_low__*__op1_low__]
991 _______________________
992 (2a) [__op0_low__*__op1_high_]
993 _______________________
994 (2b) [__op0_high_*__op1_low__]
995 _______________________
996 (3) [__op0_high_*__op1_high_]
999 This gives a 4-word result. Since we are only interested in the
1000 lower 2 words, partial result (3) and the upper words of (2a) and
1001 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1002 calculated using non-widening multiplication.
1004 (1), however, needs to be calculated with an unsigned widening
1005 multiplication. If this operation is not directly supported we
1006 try using a signed widening multiplication and adjust the result.
1007 This adjustment works as follows:
1009 If both operands are positive then no adjustment is needed.
1011 If the operands have different signs, for example op0_low < 0 and
1012 op1_low >= 0, the instruction treats the most significant bit of
1013 op0_low as a sign bit instead of a bit with significance
1014 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1015 with 2**BITS_PER_WORD - op0_low, and two's complements the
1016 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1017 the result.
1019 Similarly, if both operands are negative, we need to add
1020 (op0_low + op1_low) * 2**BITS_PER_WORD.
1022 We use a trick to adjust quickly. We logically shift op0_low right
1023 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1024 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1025 logical shift exists, we do an arithmetic right shift and subtract
1026 the 0 or -1. */
1028 if (binoptab == smul_optab
1029 && class == MODE_INT
1030 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1031 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1032 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1033 && ((umul_widen_optab->handlers[(int) mode].insn_code
1034 != CODE_FOR_nothing)
1035 || (smul_widen_optab->handlers[(int) mode].insn_code
1036 != CODE_FOR_nothing)))
1038 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1039 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1040 rtx op0_high = operand_subword_force (op0, high, mode);
1041 rtx op0_low = operand_subword_force (op0, low, mode);
1042 rtx op1_high = operand_subword_force (op1, high, mode);
1043 rtx op1_low = operand_subword_force (op1, low, mode);
1044 rtx product = 0;
1045 rtx op0_xhigh;
1046 rtx op1_xhigh;
1048 /* If the target is the same as one of the inputs, don't use it. This
1049 prevents problems with the REG_EQUAL note. */
1050 if (target == op0 || target == op1)
1051 target = 0;
1053 /* Multiply the two lower words to get a double-word product.
1054 If unsigned widening multiplication is available, use that;
1055 otherwise use the signed form and compensate. */
1057 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1059 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1060 target, 1, OPTAB_DIRECT);
1062 /* If we didn't succeed, delete everything we did so far. */
1063 if (product == 0)
1064 delete_insns_since (last);
1065 else
1066 op0_xhigh = op0_high, op1_xhigh = op1_high;
1069 if (product == 0
1070 && smul_widen_optab->handlers[(int) mode].insn_code
1071 != CODE_FOR_nothing)
1073 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1074 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1075 target, 1, OPTAB_DIRECT);
1076 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1077 NULL_RTX, 1, next_methods);
1078 if (op0_xhigh)
1079 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1080 op0_xhigh, op0_xhigh, 0, next_methods);
1081 else
1083 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1084 NULL_RTX, 0, next_methods);
1085 if (op0_xhigh)
1086 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1087 op0_xhigh, op0_xhigh, 0,
1088 next_methods);
1091 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1092 NULL_RTX, 1, next_methods);
1093 if (op1_xhigh)
1094 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1095 op1_xhigh, op1_xhigh, 0, next_methods);
1096 else
1098 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1099 NULL_RTX, 0, next_methods);
1100 if (op1_xhigh)
1101 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1102 op1_xhigh, op1_xhigh, 0,
1103 next_methods);
1107 /* If we have been able to directly compute the product of the
1108 low-order words of the operands and perform any required adjustments
1109 of the operands, we proceed by trying two more multiplications
1110 and then computing the appropriate sum.
1112 We have checked above that the required addition is provided.
1113 Full-word addition will normally always succeed, especially if
1114 it is provided at all, so we don't worry about its failure. The
1115 multiplication may well fail, however, so we do handle that. */
1117 if (product && op0_xhigh && op1_xhigh)
1119 rtx product_high = operand_subword (product, high, 1, mode);
1120 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1121 NULL_RTX, 0, OPTAB_DIRECT);
1123 if (temp != 0)
1124 temp = expand_binop (word_mode, add_optab, temp, product_high,
1125 product_high, 0, next_methods);
1127 if (temp != 0 && temp != product_high)
1128 emit_move_insn (product_high, temp);
1130 if (temp != 0)
1131 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1132 NULL_RTX, 0, OPTAB_DIRECT);
1134 if (temp != 0)
1135 temp = expand_binop (word_mode, add_optab, temp,
1136 product_high, product_high,
1137 0, next_methods);
1139 if (temp != 0 && temp != product_high)
1140 emit_move_insn (product_high, temp);
1142 if (temp != 0)
1144 temp = emit_move_insn (product, product);
1145 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1146 gen_rtx (MULT, mode, copy_rtx (op0),
1147 copy_rtx (op1)),
1148 REG_NOTES (temp));
1150 return product;
1154 /* If we get here, we couldn't do it for some reason even though we
1155 originally thought we could. Delete anything we've emitted in
1156 trying to do it. */
1158 delete_insns_since (last);
1161 /* We need to open-code the complex type operations: '+, -, * and /' */
1163 /* At this point we allow operations between two similar complex
1164 numbers, and also if one of the operands is not a complex number
1165 but rather of MODE_FLOAT or MODE_INT. However, the caller
1166 must make sure that the MODE of the non-complex operand matches
1167 the SUBMODE of the complex operand. */
1169 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1171 rtx real0 = 0, imag0 = 0;
1172 rtx real1 = 0, imag1 = 0;
1173 rtx realr, imagr, res;
1174 rtx seq;
1175 rtx equiv_value;
1176 int ok = 0;
1178 /* Find the correct mode for the real and imaginary parts */
1179 enum machine_mode submode
1180 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1181 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1184 if (submode == BLKmode)
1185 abort ();
1187 if (! target)
1188 target = gen_reg_rtx (mode);
1190 start_sequence ();
1192 realr = gen_realpart (submode, target);
1193 imagr = gen_imagpart (submode, target);
1195 if (GET_MODE (op0) == mode)
1197 real0 = gen_realpart (submode, op0);
1198 imag0 = gen_imagpart (submode, op0);
1200 else
1201 real0 = op0;
1203 if (GET_MODE (op1) == mode)
1205 real1 = gen_realpart (submode, op1);
1206 imag1 = gen_imagpart (submode, op1);
1208 else
1209 real1 = op1;
1211 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1212 abort ();
1214 switch (binoptab->code)
1216 case PLUS:
1217 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1218 case MINUS:
1219 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1220 res = expand_binop (submode, binoptab, real0, real1,
1221 realr, unsignedp, methods);
1223 if (res == 0)
1224 break;
1225 else if (res != realr)
1226 emit_move_insn (realr, res);
1228 if (imag0 && imag1)
1229 res = expand_binop (submode, binoptab, imag0, imag1,
1230 imagr, unsignedp, methods);
1231 else if (imag0)
1232 res = imag0;
1233 else if (binoptab->code == MINUS)
1234 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1235 else
1236 res = imag1;
1238 if (res == 0)
1239 break;
1240 else if (res != imagr)
1241 emit_move_insn (imagr, res);
1243 ok = 1;
1244 break;
1246 case MULT:
1247 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1249 if (imag0 && imag1)
1251 rtx temp1, temp2;
1253 /* Don't fetch these from memory more than once. */
1254 real0 = force_reg (submode, real0);
1255 real1 = force_reg (submode, real1);
1256 imag0 = force_reg (submode, imag0);
1257 imag1 = force_reg (submode, imag1);
1259 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1260 unsignedp, methods);
1262 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1263 unsignedp, methods);
1265 if (temp1 == 0 || temp2 == 0)
1266 break;
1268 res = expand_binop (submode, sub_optab, temp1, temp2,
1269 realr, unsignedp, methods);
1271 if (res == 0)
1272 break;
1273 else if (res != realr)
1274 emit_move_insn (realr, res);
1276 temp1 = expand_binop (submode, binoptab, real0, imag1,
1277 NULL_RTX, unsignedp, methods);
1279 temp2 = expand_binop (submode, binoptab, real1, imag0,
1280 NULL_RTX, unsignedp, methods);
1282 if (temp1 == 0 || temp2 == 0)
1283 break;
1285 res = expand_binop (submode, add_optab, temp1, temp2,
1286 imagr, unsignedp, methods);
1288 if (res == 0)
1289 break;
1290 else if (res != imagr)
1291 emit_move_insn (imagr, res);
1293 ok = 1;
1295 else
1297 /* Don't fetch these from memory more than once. */
1298 real0 = force_reg (submode, real0);
1299 real1 = force_reg (submode, real1);
1301 res = expand_binop (submode, binoptab, real0, real1,
1302 realr, unsignedp, methods);
1303 if (res == 0)
1304 break;
1305 else if (res != realr)
1306 emit_move_insn (realr, res);
1308 if (imag0 != 0)
1309 res = expand_binop (submode, binoptab,
1310 real1, imag0, imagr, unsignedp, methods);
1311 else
1312 res = expand_binop (submode, binoptab,
1313 real0, imag1, imagr, unsignedp, methods);
1315 if (res == 0)
1316 break;
1317 else if (res != imagr)
1318 emit_move_insn (imagr, res);
1320 ok = 1;
1322 break;
1324 case DIV:
1325 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1327 if (imag1 == 0)
1329 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1331 /* Don't fetch these from memory more than once. */
1332 real1 = force_reg (submode, real1);
1334 /* Simply divide the real and imaginary parts by `c' */
1335 if (class == MODE_COMPLEX_FLOAT)
1336 res = expand_binop (submode, binoptab, real0, real1,
1337 realr, unsignedp, methods);
1338 else
1339 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1340 real0, real1, realr, unsignedp);
1342 if (res == 0)
1343 break;
1344 else if (res != realr)
1345 emit_move_insn (realr, res);
1347 if (class == MODE_COMPLEX_FLOAT)
1348 res = expand_binop (submode, binoptab, imag0, real1,
1349 imagr, unsignedp, methods);
1350 else
1351 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1352 imag0, real1, imagr, unsignedp);
1354 if (res == 0)
1355 break;
1356 else if (res != imagr)
1357 emit_move_insn (imagr, res);
1359 ok = 1;
1361 else
1363 /* Divisor is of complex type:
1364 X/(a+ib) */
1365 rtx divisor;
1366 rtx real_t, imag_t;
1367 rtx lhs, rhs;
1368 rtx temp1, temp2;
1370 /* Don't fetch these from memory more than once. */
1371 real0 = force_reg (submode, real0);
1372 real1 = force_reg (submode, real1);
1374 if (imag0 != 0)
1375 imag0 = force_reg (submode, imag0);
1377 imag1 = force_reg (submode, imag1);
1379 /* Divisor: c*c + d*d */
1380 temp1 = expand_binop (submode, smul_optab, real1, real1,
1381 NULL_RTX, unsignedp, methods);
1383 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1384 NULL_RTX, unsignedp, methods);
1386 if (temp1 == 0 || temp2 == 0)
1387 break;
1389 divisor = expand_binop (submode, add_optab, temp1, temp2,
1390 NULL_RTX, unsignedp, methods);
1391 if (divisor == 0)
1392 break;
1394 if (imag0 == 0)
1396 /* ((a)(c-id))/divisor */
1397 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1399 /* Calculate the dividend */
1400 real_t = expand_binop (submode, smul_optab, real0, real1,
1401 NULL_RTX, unsignedp, methods);
1403 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1404 NULL_RTX, unsignedp, methods);
1406 if (real_t == 0 || imag_t == 0)
1407 break;
1409 imag_t = expand_unop (submode, neg_optab, imag_t,
1410 NULL_RTX, unsignedp);
1412 else
1414 /* ((a+ib)(c-id))/divider */
1415 /* Calculate the dividend */
1416 temp1 = expand_binop (submode, smul_optab, real0, real1,
1417 NULL_RTX, unsignedp, methods);
1419 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1420 NULL_RTX, unsignedp, methods);
1422 if (temp1 == 0 || temp2 == 0)
1423 break;
1425 real_t = expand_binop (submode, add_optab, temp1, temp2,
1426 NULL_RTX, unsignedp, methods);
1428 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1429 NULL_RTX, unsignedp, methods);
1431 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1432 NULL_RTX, unsignedp, methods);
1434 if (temp1 == 0 || temp2 == 0)
1435 break;
1437 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1438 NULL_RTX, unsignedp, methods);
1440 if (real_t == 0 || imag_t == 0)
1441 break;
1444 if (class == MODE_COMPLEX_FLOAT)
1445 res = expand_binop (submode, binoptab, real_t, divisor,
1446 realr, unsignedp, methods);
1447 else
1448 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1449 real_t, divisor, realr, unsignedp);
1451 if (res == 0)
1452 break;
1453 else if (res != realr)
1454 emit_move_insn (realr, res);
1456 if (class == MODE_COMPLEX_FLOAT)
1457 res = expand_binop (submode, binoptab, imag_t, divisor,
1458 imagr, unsignedp, methods);
1459 else
1460 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1461 imag_t, divisor, imagr, unsignedp);
1463 if (res == 0)
1464 break;
1465 else if (res != imagr)
1466 emit_move_insn (imagr, res);
1468 ok = 1;
1470 break;
1472 default:
1473 abort ();
1476 seq = get_insns ();
1477 end_sequence ();
1479 if (ok)
1481 if (binoptab->code != UNKNOWN)
1482 equiv_value
1483 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1484 else
1485 equiv_value = 0;
1487 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1489 return target;
1493 /* It can't be open-coded in this mode.
1494 Use a library call if one is available and caller says that's ok. */
1496 if (binoptab->handlers[(int) mode].libfunc
1497 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1499 rtx insns;
1500 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1501 rtx op1x = op1;
1502 enum machine_mode op1_mode = mode;
1503 rtx value;
1505 start_sequence ();
1507 if (shift_op)
1509 op1_mode = word_mode;
1510 /* Specify unsigned here,
1511 since negative shift counts are meaningless. */
1512 op1x = convert_to_mode (word_mode, op1, 1);
1515 if (GET_MODE (op0) != mode)
1516 op0 = convert_to_mode (mode, op0, unsignedp);
1518 /* Pass 1 for NO_QUEUE so we don't lose any increments
1519 if the libcall is cse'd or moved. */
1520 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1521 NULL_RTX, 1, mode, 2,
1522 op0, mode, op1x, op1_mode);
1524 insns = get_insns ();
1525 end_sequence ();
1527 target = gen_reg_rtx (mode);
1528 emit_libcall_block (insns, target, value,
1529 gen_rtx (binoptab->code, mode, op0, op1));
1531 return target;
1534 delete_insns_since (last);
1536 /* It can't be done in this mode. Can we do it in a wider mode? */
1538 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1539 || methods == OPTAB_MUST_WIDEN))
1541 /* Caller says, don't even try. */
1542 delete_insns_since (entry_last);
1543 return 0;
1546 /* Compute the value of METHODS to pass to recursive calls.
1547 Don't allow widening to be tried recursively. */
1549 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1551 /* Look for a wider mode of the same class for which it appears we can do
1552 the operation. */
1554 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1556 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1557 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1559 if ((binoptab->handlers[(int) wider_mode].insn_code
1560 != CODE_FOR_nothing)
1561 || (methods == OPTAB_LIB
1562 && binoptab->handlers[(int) wider_mode].libfunc))
1564 rtx xop0 = op0, xop1 = op1;
1565 int no_extend = 0;
1567 /* For certain integer operations, we need not actually extend
1568 the narrow operands, as long as we will truncate
1569 the results to the same narrowness. */
1571 if ((binoptab == ior_optab || binoptab == and_optab
1572 || binoptab == xor_optab
1573 || binoptab == add_optab || binoptab == sub_optab
1574 || binoptab == smul_optab || binoptab == ashl_optab)
1575 && class == MODE_INT)
1576 no_extend = 1;
1578 xop0 = widen_operand (xop0, wider_mode, mode,
1579 unsignedp, no_extend);
1581 /* The second operand of a shift must always be extended. */
1582 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1583 no_extend && binoptab != ashl_optab);
1585 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1586 unsignedp, methods);
1587 if (temp)
1589 if (class != MODE_INT)
1591 if (target == 0)
1592 target = gen_reg_rtx (mode);
1593 convert_move (target, temp, 0);
1594 return target;
1596 else
1597 return gen_lowpart (mode, temp);
1599 else
1600 delete_insns_since (last);
1605 delete_insns_since (entry_last);
1606 return 0;
1609 /* Expand a binary operator which has both signed and unsigned forms.
1610 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1611 signed operations.
1613 If we widen unsigned operands, we may use a signed wider operation instead
1614 of an unsigned wider operation, since the result would be the same. */
1617 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1618 enum machine_mode mode;
1619 optab uoptab, soptab;
1620 rtx op0, op1, target;
1621 int unsignedp;
1622 enum optab_methods methods;
1624 register rtx temp;
1625 optab direct_optab = unsignedp ? uoptab : soptab;
1626 struct optab wide_soptab;
1628 /* Do it without widening, if possible. */
1629 temp = expand_binop (mode, direct_optab, op0, op1, target,
1630 unsignedp, OPTAB_DIRECT);
1631 if (temp || methods == OPTAB_DIRECT)
1632 return temp;
1634 /* Try widening to a signed int. Make a fake signed optab that
1635 hides any signed insn for direct use. */
1636 wide_soptab = *soptab;
1637 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1638 wide_soptab.handlers[(int) mode].libfunc = 0;
1640 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1641 unsignedp, OPTAB_WIDEN);
1643 /* For unsigned operands, try widening to an unsigned int. */
1644 if (temp == 0 && unsignedp)
1645 temp = expand_binop (mode, uoptab, op0, op1, target,
1646 unsignedp, OPTAB_WIDEN);
1647 if (temp || methods == OPTAB_WIDEN)
1648 return temp;
1650 /* Use the right width lib call if that exists. */
1651 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1652 if (temp || methods == OPTAB_LIB)
1653 return temp;
1655 /* Must widen and use a lib call, use either signed or unsigned. */
1656 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1657 unsignedp, methods);
1658 if (temp != 0)
1659 return temp;
1660 if (unsignedp)
1661 return expand_binop (mode, uoptab, op0, op1, target,
1662 unsignedp, methods);
1663 return 0;
1666 /* Generate code to perform an operation specified by BINOPTAB
1667 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1668 We assume that the order of the operands for the instruction
1669 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1670 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1672 Either TARG0 or TARG1 may be zero, but what that means is that
1673 that result is not actually wanted. We will generate it into
1674 a dummy pseudo-reg and discard it. They may not both be zero.
1676 Returns 1 if this operation can be performed; 0 if not. */
1679 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1680 optab binoptab;
1681 rtx op0, op1;
1682 rtx targ0, targ1;
1683 int unsignedp;
1685 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1686 enum mode_class class;
1687 enum machine_mode wider_mode;
1688 rtx entry_last = get_last_insn ();
1689 rtx last;
1691 class = GET_MODE_CLASS (mode);
1693 op0 = protect_from_queue (op0, 0);
1694 op1 = protect_from_queue (op1, 0);
1696 if (flag_force_mem)
1698 op0 = force_not_mem (op0);
1699 op1 = force_not_mem (op1);
1702 /* If we are inside an appropriately-short loop and one operand is an
1703 expensive constant, force it into a register. */
1704 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1705 && rtx_cost (op0, binoptab->code) > 2)
1706 op0 = force_reg (mode, op0);
1708 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1709 && rtx_cost (op1, binoptab->code) > 2)
1710 op1 = force_reg (mode, op1);
1712 if (targ0)
1713 targ0 = protect_from_queue (targ0, 1);
1714 else
1715 targ0 = gen_reg_rtx (mode);
1716 if (targ1)
1717 targ1 = protect_from_queue (targ1, 1);
1718 else
1719 targ1 = gen_reg_rtx (mode);
1721 /* Record where to go back to if we fail. */
1722 last = get_last_insn ();
1724 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1726 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1727 enum machine_mode mode0 = insn_operand_mode[icode][1];
1728 enum machine_mode mode1 = insn_operand_mode[icode][2];
1729 rtx pat;
1730 rtx xop0 = op0, xop1 = op1;
1732 /* In case this insn wants input operands in modes different from the
1733 result, convert the operands. */
1734 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1735 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1737 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1738 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1740 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1741 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1742 xop0 = copy_to_mode_reg (mode0, xop0);
1744 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1745 xop1 = copy_to_mode_reg (mode1, xop1);
1747 /* We could handle this, but we should always be called with a pseudo
1748 for our targets and all insns should take them as outputs. */
1749 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1750 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1751 abort ();
1753 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1754 if (pat)
1756 emit_insn (pat);
1757 return 1;
1759 else
1760 delete_insns_since (last);
1763 /* It can't be done in this mode. Can we do it in a wider mode? */
1765 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1767 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1768 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1770 if (binoptab->handlers[(int) wider_mode].insn_code
1771 != CODE_FOR_nothing)
1773 register rtx t0 = gen_reg_rtx (wider_mode);
1774 register rtx t1 = gen_reg_rtx (wider_mode);
1776 if (expand_twoval_binop (binoptab,
1777 convert_modes (wider_mode, mode, op0,
1778 unsignedp),
1779 convert_modes (wider_mode, mode, op1,
1780 unsignedp),
1781 t0, t1, unsignedp))
1783 convert_move (targ0, t0, unsignedp);
1784 convert_move (targ1, t1, unsignedp);
1785 return 1;
1787 else
1788 delete_insns_since (last);
1793 delete_insns_since (entry_last);
1794 return 0;
1797 /* Generate code to perform an operation specified by UNOPTAB
1798 on operand OP0, with result having machine-mode MODE.
1800 UNSIGNEDP is for the case where we have to widen the operands
1801 to perform the operation. It says to use zero-extension.
1803 If TARGET is nonzero, the value
1804 is generated there, if it is convenient to do so.
1805 In all cases an rtx is returned for the locus of the value;
1806 this may or may not be TARGET. */
1809 expand_unop (mode, unoptab, op0, target, unsignedp)
1810 enum machine_mode mode;
1811 optab unoptab;
1812 rtx op0;
1813 rtx target;
1814 int unsignedp;
1816 enum mode_class class;
1817 enum machine_mode wider_mode;
1818 register rtx temp;
1819 rtx last = get_last_insn ();
1820 rtx pat;
1822 class = GET_MODE_CLASS (mode);
1824 op0 = protect_from_queue (op0, 0);
1826 if (flag_force_mem)
1828 op0 = force_not_mem (op0);
1831 if (target)
1832 target = protect_from_queue (target, 1);
1834 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1836 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1837 enum machine_mode mode0 = insn_operand_mode[icode][1];
1838 rtx xop0 = op0;
1840 if (target)
1841 temp = target;
1842 else
1843 temp = gen_reg_rtx (mode);
1845 if (GET_MODE (xop0) != VOIDmode
1846 && GET_MODE (xop0) != mode0)
1847 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1849 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1851 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1852 xop0 = copy_to_mode_reg (mode0, xop0);
1854 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1855 temp = gen_reg_rtx (mode);
1857 pat = GEN_FCN (icode) (temp, xop0);
1858 if (pat)
1860 if (GET_CODE (pat) == SEQUENCE
1861 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1863 delete_insns_since (last);
1864 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1867 emit_insn (pat);
1869 return temp;
1871 else
1872 delete_insns_since (last);
1875 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1877 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1878 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1879 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1881 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1883 rtx xop0 = op0;
1885 /* For certain operations, we need not actually extend
1886 the narrow operand, as long as we will truncate the
1887 results to the same narrowness. */
1889 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1890 (unoptab == neg_optab
1891 || unoptab == one_cmpl_optab)
1892 && class == MODE_INT);
1894 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1895 unsignedp);
1897 if (temp)
1899 if (class != MODE_INT)
1901 if (target == 0)
1902 target = gen_reg_rtx (mode);
1903 convert_move (target, temp, 0);
1904 return target;
1906 else
1907 return gen_lowpart (mode, temp);
1909 else
1910 delete_insns_since (last);
1914 /* These can be done a word at a time. */
1915 if (unoptab == one_cmpl_optab
1916 && class == MODE_INT
1917 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1918 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1920 int i;
1921 rtx insns;
1923 if (target == 0 || target == op0)
1924 target = gen_reg_rtx (mode);
1926 start_sequence ();
1928 /* Do the actual arithmetic. */
1929 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1931 rtx target_piece = operand_subword (target, i, 1, mode);
1932 rtx x = expand_unop (word_mode, unoptab,
1933 operand_subword_force (op0, i, mode),
1934 target_piece, unsignedp);
1935 if (target_piece != x)
1936 emit_move_insn (target_piece, x);
1939 insns = get_insns ();
1940 end_sequence ();
1942 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1943 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1944 return target;
1947 /* Open-code the complex negation operation. */
1948 else if (unoptab == neg_optab
1949 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1951 rtx target_piece;
1952 rtx x;
1953 rtx seq;
1955 /* Find the correct mode for the real and imaginary parts */
1956 enum machine_mode submode
1957 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1958 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1961 if (submode == BLKmode)
1962 abort ();
1964 if (target == 0)
1965 target = gen_reg_rtx (mode);
1967 start_sequence ();
1969 target_piece = gen_imagpart (submode, target);
1970 x = expand_unop (submode, unoptab,
1971 gen_imagpart (submode, op0),
1972 target_piece, unsignedp);
1973 if (target_piece != x)
1974 emit_move_insn (target_piece, x);
1976 target_piece = gen_realpart (submode, target);
1977 x = expand_unop (submode, unoptab,
1978 gen_realpart (submode, op0),
1979 target_piece, unsignedp);
1980 if (target_piece != x)
1981 emit_move_insn (target_piece, x);
1983 seq = get_insns ();
1984 end_sequence ();
1986 emit_no_conflict_block (seq, target, op0, 0,
1987 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1988 return target;
1991 /* Now try a library call in this mode. */
1992 if (unoptab->handlers[(int) mode].libfunc)
1994 rtx insns;
1995 rtx funexp = unoptab->handlers[(int) mode].libfunc;
1996 rtx value;
1998 start_sequence ();
2000 /* Pass 1 for NO_QUEUE so we don't lose any increments
2001 if the libcall is cse'd or moved. */
2002 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2003 NULL_RTX, 1, mode, 1, op0, mode);
2004 insns = get_insns ();
2005 end_sequence ();
2007 target = gen_reg_rtx (mode);
2008 emit_libcall_block (insns, target, value,
2009 gen_rtx (unoptab->code, mode, op0));
2011 return target;
2014 /* It can't be done in this mode. Can we do it in a wider mode? */
2016 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2018 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2019 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2021 if ((unoptab->handlers[(int) wider_mode].insn_code
2022 != CODE_FOR_nothing)
2023 || unoptab->handlers[(int) wider_mode].libfunc)
2025 rtx xop0 = op0;
2027 /* For certain operations, we need not actually extend
2028 the narrow operand, as long as we will truncate the
2029 results to the same narrowness. */
2031 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2032 (unoptab == neg_optab
2033 || unoptab == one_cmpl_optab)
2034 && class == MODE_INT);
2036 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2037 unsignedp);
2039 if (temp)
2041 if (class != MODE_INT)
2043 if (target == 0)
2044 target = gen_reg_rtx (mode);
2045 convert_move (target, temp, 0);
2046 return target;
2048 else
2049 return gen_lowpart (mode, temp);
2051 else
2052 delete_insns_since (last);
2057 /* If there is no negate operation, try doing a subtract from zero.
2058 The US Software GOFAST library needs this. */
2059 if (unoptab == neg_optab)
2061 rtx temp;
2062 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2063 target, unsignedp, OPTAB_LIB_WIDEN);
2064 if (temp)
2065 return temp;
2068 return 0;
2071 /* Emit code to compute the absolute value of OP0, with result to
2072 TARGET if convenient. (TARGET may be 0.) The return value says
2073 where the result actually is to be found.
2075 MODE is the mode of the operand; the mode of the result is
2076 different but can be deduced from MODE.
2078 UNSIGNEDP is relevant if extension is needed. */
2081 expand_abs (mode, op0, target, unsignedp, safe)
2082 enum machine_mode mode;
2083 rtx op0;
2084 rtx target;
2085 int unsignedp;
2086 int safe;
2088 rtx temp, op1;
2090 /* First try to do it with a special abs instruction. */
2091 temp = expand_unop (mode, abs_optab, op0, target, 0);
2092 if (temp != 0)
2093 return temp;
2095 /* If this machine has expensive jumps, we can do integer absolute
2096 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2097 where W is the width of MODE. */
2099 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2101 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2102 size_int (GET_MODE_BITSIZE (mode) - 1),
2103 NULL_RTX, 0);
2105 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2106 OPTAB_LIB_WIDEN);
2107 if (temp != 0)
2108 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2109 OPTAB_LIB_WIDEN);
2111 if (temp != 0)
2112 return temp;
2115 /* If that does not win, use conditional jump and negate. */
2116 op1 = gen_label_rtx ();
2117 if (target == 0 || ! safe
2118 || GET_MODE (target) != mode
2119 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2120 || (GET_CODE (target) == REG
2121 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2122 target = gen_reg_rtx (mode);
2124 emit_move_insn (target, op0);
2125 NO_DEFER_POP;
2127 /* If this mode is an integer too wide to compare properly,
2128 compare word by word. Rely on CSE to optimize constant cases. */
2129 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2130 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2131 NULL_RTX, op1);
2132 else
2134 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2135 NULL_RTX, 0);
2136 if (temp == const1_rtx)
2137 return target;
2138 else if (temp != const0_rtx)
2140 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2141 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2142 else
2143 abort ();
2147 op0 = expand_unop (mode, neg_optab, target, target, 0);
2148 if (op0 != target)
2149 emit_move_insn (target, op0);
2150 emit_label (op1);
2151 OK_DEFER_POP;
2152 return target;
2155 /* Emit code to compute the absolute value of OP0, with result to
2156 TARGET if convenient. (TARGET may be 0.) The return value says
2157 where the result actually is to be found.
2159 MODE is the mode of the operand; the mode of the result is
2160 different but can be deduced from MODE.
2162 UNSIGNEDP is relevant for complex integer modes. */
2165 expand_complex_abs (mode, op0, target, unsignedp)
2166 enum machine_mode mode;
2167 rtx op0;
2168 rtx target;
2169 int unsignedp;
2171 enum mode_class class = GET_MODE_CLASS (mode);
2172 enum machine_mode wider_mode;
2173 register rtx temp;
2174 rtx entry_last = get_last_insn ();
2175 rtx last;
2176 rtx pat;
2178 /* Find the correct mode for the real and imaginary parts. */
2179 enum machine_mode submode
2180 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2181 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2184 if (submode == BLKmode)
2185 abort ();
2187 op0 = protect_from_queue (op0, 0);
2189 if (flag_force_mem)
2191 op0 = force_not_mem (op0);
2194 last = get_last_insn ();
2196 if (target)
2197 target = protect_from_queue (target, 1);
2199 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2201 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2202 enum machine_mode mode0 = insn_operand_mode[icode][1];
2203 rtx xop0 = op0;
2205 if (target)
2206 temp = target;
2207 else
2208 temp = gen_reg_rtx (submode);
2210 if (GET_MODE (xop0) != VOIDmode
2211 && GET_MODE (xop0) != mode0)
2212 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2214 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2216 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2217 xop0 = copy_to_mode_reg (mode0, xop0);
2219 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2220 temp = gen_reg_rtx (submode);
2222 pat = GEN_FCN (icode) (temp, xop0);
2223 if (pat)
2225 if (GET_CODE (pat) == SEQUENCE
2226 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2228 delete_insns_since (last);
2229 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2232 emit_insn (pat);
2234 return temp;
2236 else
2237 delete_insns_since (last);
2240 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2242 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2243 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2245 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2247 rtx xop0 = op0;
2249 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2250 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2252 if (temp)
2254 if (class != MODE_COMPLEX_INT)
2256 if (target == 0)
2257 target = gen_reg_rtx (submode);
2258 convert_move (target, temp, 0);
2259 return target;
2261 else
2262 return gen_lowpart (submode, temp);
2264 else
2265 delete_insns_since (last);
2269 /* Open-code the complex absolute-value operation
2270 if we can open-code sqrt. Otherwise it's not worth while. */
2271 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2273 rtx real, imag, total;
2275 real = gen_realpart (submode, op0);
2276 imag = gen_imagpart (submode, op0);
2278 /* Square both parts. */
2279 real = expand_mult (submode, real, real, NULL_RTX, 0);
2280 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2282 /* Sum the parts. */
2283 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2284 0, OPTAB_LIB_WIDEN);
2286 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2287 target = expand_unop (submode, sqrt_optab, total, target, 0);
2288 if (target == 0)
2289 delete_insns_since (last);
2290 else
2291 return target;
2294 /* Now try a library call in this mode. */
2295 if (abs_optab->handlers[(int) mode].libfunc)
2297 rtx insns;
2298 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2299 rtx value;
2301 start_sequence ();
2303 /* Pass 1 for NO_QUEUE so we don't lose any increments
2304 if the libcall is cse'd or moved. */
2305 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2306 NULL_RTX, 1, submode, 1, op0, mode);
2307 insns = get_insns ();
2308 end_sequence ();
2310 target = gen_reg_rtx (submode);
2311 emit_libcall_block (insns, target, value,
2312 gen_rtx (abs_optab->code, mode, op0));
2314 return target;
2317 /* It can't be done in this mode. Can we do it in a wider mode? */
2319 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2320 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2322 if ((abs_optab->handlers[(int) wider_mode].insn_code
2323 != CODE_FOR_nothing)
2324 || abs_optab->handlers[(int) wider_mode].libfunc)
2326 rtx xop0 = op0;
2328 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2330 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2332 if (temp)
2334 if (class != MODE_COMPLEX_INT)
2336 if (target == 0)
2337 target = gen_reg_rtx (submode);
2338 convert_move (target, temp, 0);
2339 return target;
2341 else
2342 return gen_lowpart (submode, temp);
2344 else
2345 delete_insns_since (last);
2349 delete_insns_since (entry_last);
2350 return 0;
2353 /* Generate an instruction whose insn-code is INSN_CODE,
2354 with two operands: an output TARGET and an input OP0.
2355 TARGET *must* be nonzero, and the output is always stored there.
2356 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2357 the value that is stored into TARGET. */
2359 void
2360 emit_unop_insn (icode, target, op0, code)
2361 int icode;
2362 rtx target;
2363 rtx op0;
2364 enum rtx_code code;
2366 register rtx temp;
2367 enum machine_mode mode0 = insn_operand_mode[icode][1];
2368 rtx pat;
2370 temp = target = protect_from_queue (target, 1);
2372 op0 = protect_from_queue (op0, 0);
2374 if (flag_force_mem)
2375 op0 = force_not_mem (op0);
2377 /* Now, if insn does not accept our operands, put them into pseudos. */
2379 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2380 op0 = copy_to_mode_reg (mode0, op0);
2382 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2383 || (flag_force_mem && GET_CODE (temp) == MEM))
2384 temp = gen_reg_rtx (GET_MODE (temp));
2386 pat = GEN_FCN (icode) (temp, op0);
2388 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2389 add_equal_note (pat, temp, code, op0, NULL_RTX);
2391 emit_insn (pat);
2393 if (temp != target)
2394 emit_move_insn (target, temp);
2397 /* Emit code to perform a series of operations on a multi-word quantity, one
2398 word at a time.
2400 Such a block is preceded by a CLOBBER of the output, consists of multiple
2401 insns, each setting one word of the output, and followed by a SET copying
2402 the output to itself.
2404 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2405 note indicating that it doesn't conflict with the (also multi-word)
2406 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2407 notes.
2409 INSNS is a block of code generated to perform the operation, not including
2410 the CLOBBER and final copy. All insns that compute intermediate values
2411 are first emitted, followed by the block as described above.
2413 TARGET, OP0, and OP1 are the output and inputs of the operations,
2414 respectively. OP1 may be zero for a unary operation.
2416 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2417 on the last insn.
2419 If TARGET is not a register, INSNS is simply emitted with no special
2420 processing. Likewise if anything in INSNS is not an INSN or if
2421 there is a libcall block inside INSNS.
2423 The final insn emitted is returned. */
2426 emit_no_conflict_block (insns, target, op0, op1, equiv)
2427 rtx insns;
2428 rtx target;
2429 rtx op0, op1;
2430 rtx equiv;
2432 rtx prev, next, first, last, insn;
2434 if (GET_CODE (target) != REG || reload_in_progress)
2435 return emit_insns (insns);
2436 else
2437 for (insn = insns; insn; insn = NEXT_INSN (insn))
2438 if (GET_CODE (insn) != INSN
2439 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2440 return emit_insns (insns);
2442 /* First emit all insns that do not store into words of the output and remove
2443 these from the list. */
2444 for (insn = insns; insn; insn = next)
2446 rtx set = 0;
2447 int i;
2449 next = NEXT_INSN (insn);
2451 if (GET_CODE (PATTERN (insn)) == SET)
2452 set = PATTERN (insn);
2453 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2455 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2456 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2458 set = XVECEXP (PATTERN (insn), 0, i);
2459 break;
2463 if (set == 0)
2464 abort ();
2466 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2468 if (PREV_INSN (insn))
2469 NEXT_INSN (PREV_INSN (insn)) = next;
2470 else
2471 insns = next;
2473 if (next)
2474 PREV_INSN (next) = PREV_INSN (insn);
2476 add_insn (insn);
2480 prev = get_last_insn ();
2482 /* Now write the CLOBBER of the output, followed by the setting of each
2483 of the words, followed by the final copy. */
2484 if (target != op0 && target != op1)
2485 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2487 for (insn = insns; insn; insn = next)
2489 next = NEXT_INSN (insn);
2490 add_insn (insn);
2492 if (op1 && GET_CODE (op1) == REG)
2493 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2494 REG_NOTES (insn));
2496 if (op0 && GET_CODE (op0) == REG)
2497 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2498 REG_NOTES (insn));
2501 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2502 != CODE_FOR_nothing)
2504 last = emit_move_insn (target, target);
2505 if (equiv)
2506 REG_NOTES (last)
2507 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2509 else
2510 last = get_last_insn ();
2512 if (prev == 0)
2513 first = get_insns ();
2514 else
2515 first = NEXT_INSN (prev);
2517 /* Encapsulate the block so it gets manipulated as a unit. */
2518 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2519 REG_NOTES (first));
2520 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2522 return last;
2525 /* Emit code to make a call to a constant function or a library call.
2527 INSNS is a list containing all insns emitted in the call.
2528 These insns leave the result in RESULT. Our block is to copy RESULT
2529 to TARGET, which is logically equivalent to EQUIV.
2531 We first emit any insns that set a pseudo on the assumption that these are
2532 loading constants into registers; doing so allows them to be safely cse'ed
2533 between blocks. Then we emit all the other insns in the block, followed by
2534 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2535 note with an operand of EQUIV.
2537 Moving assignments to pseudos outside of the block is done to improve
2538 the generated code, but is not required to generate correct code,
2539 hence being unable to move an assignment is not grounds for not making
2540 a libcall block. There are two reasons why it is safe to leave these
2541 insns inside the block: First, we know that these pseudos cannot be
2542 used in generated RTL outside the block since they are created for
2543 temporary purposes within the block. Second, CSE will not record the
2544 values of anything set inside a libcall block, so we know they must
2545 be dead at the end of the block.
2547 Except for the first group of insns (the ones setting pseudos), the
2548 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2550 void
2551 emit_libcall_block (insns, target, result, equiv)
2552 rtx insns;
2553 rtx target;
2554 rtx result;
2555 rtx equiv;
2557 rtx prev, next, first, last, insn;
2559 /* First emit all insns that set pseudos. Remove them from the list as
2560 we go. Avoid insns that set pseudos which were referenced in previous
2561 insns. These can be generated by move_by_pieces, for example,
2562 to update an address. Similarly, avoid insns that reference things
2563 set in previous insns. */
2565 for (insn = insns; insn; insn = next)
2567 rtx set = single_set (insn);
2569 next = NEXT_INSN (insn);
2571 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2572 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2573 && (insn == insns
2574 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2575 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2576 && ! modified_in_p (SET_SRC (set), insns)
2577 && ! modified_between_p (SET_SRC (set), insns, insn))))
2579 if (PREV_INSN (insn))
2580 NEXT_INSN (PREV_INSN (insn)) = next;
2581 else
2582 insns = next;
2584 if (next)
2585 PREV_INSN (next) = PREV_INSN (insn);
2587 add_insn (insn);
2591 prev = get_last_insn ();
2593 /* Write the remaining insns followed by the final copy. */
2595 for (insn = insns; insn; insn = next)
2597 next = NEXT_INSN (insn);
2599 add_insn (insn);
2602 last = emit_move_insn (target, result);
2603 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2604 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2606 if (prev == 0)
2607 first = get_insns ();
2608 else
2609 first = NEXT_INSN (prev);
2611 /* Encapsulate the block so it gets manipulated as a unit. */
2612 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2613 REG_NOTES (first));
2614 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2617 /* Generate code to store zero in X. */
2619 void
2620 emit_clr_insn (x)
2621 rtx x;
2623 emit_move_insn (x, const0_rtx);
2626 /* Generate code to store 1 in X
2627 assuming it contains zero beforehand. */
2629 void
2630 emit_0_to_1_insn (x)
2631 rtx x;
2633 emit_move_insn (x, const1_rtx);
2636 /* Generate code to compare X with Y
2637 so that the condition codes are set.
2639 MODE is the mode of the inputs (in case they are const_int).
2640 UNSIGNEDP nonzero says that X and Y are unsigned;
2641 this matters if they need to be widened.
2643 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2644 and ALIGN specifies the known shared alignment of X and Y.
2646 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2647 It is ignored for fixed-point and block comparisons;
2648 it is used only for floating-point comparisons. */
2650 void
2651 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2652 rtx x, y;
2653 enum rtx_code comparison;
2654 rtx size;
2655 enum machine_mode mode;
2656 int unsignedp;
2657 int align;
2659 enum mode_class class;
2660 enum machine_mode wider_mode;
2662 class = GET_MODE_CLASS (mode);
2664 /* They could both be VOIDmode if both args are immediate constants,
2665 but we should fold that at an earlier stage.
2666 With no special code here, this will call abort,
2667 reminding the programmer to implement such folding. */
2669 if (mode != BLKmode && flag_force_mem)
2671 x = force_not_mem (x);
2672 y = force_not_mem (y);
2675 /* If we are inside an appropriately-short loop and one operand is an
2676 expensive constant, force it into a register. */
2677 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2678 x = force_reg (mode, x);
2680 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2681 y = force_reg (mode, y);
2683 /* Don't let both operands fail to indicate the mode. */
2684 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2685 x = force_reg (mode, x);
2687 /* Handle all BLKmode compares. */
2689 if (mode == BLKmode)
2691 emit_queue ();
2692 x = protect_from_queue (x, 0);
2693 y = protect_from_queue (y, 0);
2695 if (size == 0)
2696 abort ();
2697 #ifdef HAVE_cmpstrqi
2698 if (HAVE_cmpstrqi
2699 && GET_CODE (size) == CONST_INT
2700 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2702 enum machine_mode result_mode
2703 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2704 rtx result = gen_reg_rtx (result_mode);
2705 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2706 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2707 result_mode, 0, 0);
2709 else
2710 #endif
2711 #ifdef HAVE_cmpstrhi
2712 if (HAVE_cmpstrhi
2713 && GET_CODE (size) == CONST_INT
2714 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2716 enum machine_mode result_mode
2717 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2718 rtx result = gen_reg_rtx (result_mode);
2719 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2720 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2721 result_mode, 0, 0);
2723 else
2724 #endif
2725 #ifdef HAVE_cmpstrsi
2726 if (HAVE_cmpstrsi)
2728 enum machine_mode result_mode
2729 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2730 rtx result = gen_reg_rtx (result_mode);
2731 size = protect_from_queue (size, 0);
2732 emit_insn (gen_cmpstrsi (result, x, y,
2733 convert_to_mode (SImode, size, 1),
2734 GEN_INT (align)));
2735 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2736 result_mode, 0, 0);
2738 else
2739 #endif
2741 #ifdef TARGET_MEM_FUNCTIONS
2742 emit_library_call (memcmp_libfunc, 0,
2743 TYPE_MODE (integer_type_node), 3,
2744 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2745 size, Pmode);
2746 #else
2747 emit_library_call (bcmp_libfunc, 0,
2748 TYPE_MODE (integer_type_node), 3,
2749 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2750 size, Pmode);
2751 #endif
2752 emit_cmp_insn (hard_libcall_value (TYPE_MODE (integer_type_node)),
2753 const0_rtx, comparison, NULL_RTX,
2754 TYPE_MODE (integer_type_node), 0, 0);
2756 return;
2759 /* Handle some compares against zero. */
2761 if (y == CONST0_RTX (mode)
2762 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2764 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2766 emit_queue ();
2767 x = protect_from_queue (x, 0);
2768 y = protect_from_queue (y, 0);
2770 /* Now, if insn does accept these operands, put them into pseudos. */
2771 if (! (*insn_operand_predicate[icode][0])
2772 (x, insn_operand_mode[icode][0]))
2773 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2775 emit_insn (GEN_FCN (icode) (x));
2776 return;
2779 /* Handle compares for which there is a directly suitable insn. */
2781 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2783 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2785 emit_queue ();
2786 x = protect_from_queue (x, 0);
2787 y = protect_from_queue (y, 0);
2789 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2790 if (! (*insn_operand_predicate[icode][0])
2791 (x, insn_operand_mode[icode][0]))
2792 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2794 if (! (*insn_operand_predicate[icode][1])
2795 (y, insn_operand_mode[icode][1]))
2796 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2798 emit_insn (GEN_FCN (icode) (x, y));
2799 return;
2802 /* Try widening if we can find a direct insn that way. */
2804 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2806 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2807 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2809 if (cmp_optab->handlers[(int) wider_mode].insn_code
2810 != CODE_FOR_nothing)
2812 x = protect_from_queue (x, 0);
2813 y = protect_from_queue (y, 0);
2814 x = convert_modes (wider_mode, mode, x, unsignedp);
2815 y = convert_modes (wider_mode, mode, y, unsignedp);
2816 emit_cmp_insn (x, y, comparison, NULL_RTX,
2817 wider_mode, unsignedp, align);
2818 return;
2823 /* Handle a lib call just for the mode we are using. */
2825 if (cmp_optab->handlers[(int) mode].libfunc
2826 && class != MODE_FLOAT)
2828 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2829 /* If we want unsigned, and this mode has a distinct unsigned
2830 comparison routine, use that. */
2831 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2832 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2834 emit_library_call (libfunc, 1,
2835 word_mode, 2, x, mode, y, mode);
2837 /* Integer comparison returns a result that must be compared against 1,
2838 so that even if we do an unsigned compare afterward,
2839 there is still a value that can represent the result "less than". */
2841 emit_cmp_insn (hard_libcall_value (word_mode), const1_rtx,
2842 comparison, NULL_RTX, word_mode, unsignedp, 0);
2843 return;
2846 if (class == MODE_FLOAT)
2847 emit_float_lib_cmp (x, y, comparison);
2849 else
2850 abort ();
2853 /* Nonzero if a compare of mode MODE can be done straightforwardly
2854 (without splitting it into pieces). */
2857 can_compare_p (mode)
2858 enum machine_mode mode;
2862 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2863 return 1;
2864 mode = GET_MODE_WIDER_MODE (mode);
2865 } while (mode != VOIDmode);
2867 return 0;
2870 /* Emit a library call comparison between floating point X and Y.
2871 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2873 void
2874 emit_float_lib_cmp (x, y, comparison)
2875 rtx x, y;
2876 enum rtx_code comparison;
2878 enum machine_mode mode = GET_MODE (x);
2879 rtx libfunc = 0;
2881 if (mode == HFmode)
2882 switch (comparison)
2884 case EQ:
2885 libfunc = eqhf2_libfunc;
2886 break;
2888 case NE:
2889 libfunc = nehf2_libfunc;
2890 break;
2892 case GT:
2893 libfunc = gthf2_libfunc;
2894 break;
2896 case GE:
2897 libfunc = gehf2_libfunc;
2898 break;
2900 case LT:
2901 libfunc = lthf2_libfunc;
2902 break;
2904 case LE:
2905 libfunc = lehf2_libfunc;
2906 break;
2908 else if (mode == SFmode)
2909 switch (comparison)
2911 case EQ:
2912 libfunc = eqsf2_libfunc;
2913 break;
2915 case NE:
2916 libfunc = nesf2_libfunc;
2917 break;
2919 case GT:
2920 libfunc = gtsf2_libfunc;
2921 break;
2923 case GE:
2924 libfunc = gesf2_libfunc;
2925 break;
2927 case LT:
2928 libfunc = ltsf2_libfunc;
2929 break;
2931 case LE:
2932 libfunc = lesf2_libfunc;
2933 break;
2935 else if (mode == DFmode)
2936 switch (comparison)
2938 case EQ:
2939 libfunc = eqdf2_libfunc;
2940 break;
2942 case NE:
2943 libfunc = nedf2_libfunc;
2944 break;
2946 case GT:
2947 libfunc = gtdf2_libfunc;
2948 break;
2950 case GE:
2951 libfunc = gedf2_libfunc;
2952 break;
2954 case LT:
2955 libfunc = ltdf2_libfunc;
2956 break;
2958 case LE:
2959 libfunc = ledf2_libfunc;
2960 break;
2962 else if (mode == XFmode)
2963 switch (comparison)
2965 case EQ:
2966 libfunc = eqxf2_libfunc;
2967 break;
2969 case NE:
2970 libfunc = nexf2_libfunc;
2971 break;
2973 case GT:
2974 libfunc = gtxf2_libfunc;
2975 break;
2977 case GE:
2978 libfunc = gexf2_libfunc;
2979 break;
2981 case LT:
2982 libfunc = ltxf2_libfunc;
2983 break;
2985 case LE:
2986 libfunc = lexf2_libfunc;
2987 break;
2989 else if (mode == TFmode)
2990 switch (comparison)
2992 case EQ:
2993 libfunc = eqtf2_libfunc;
2994 break;
2996 case NE:
2997 libfunc = netf2_libfunc;
2998 break;
3000 case GT:
3001 libfunc = gttf2_libfunc;
3002 break;
3004 case GE:
3005 libfunc = getf2_libfunc;
3006 break;
3008 case LT:
3009 libfunc = lttf2_libfunc;
3010 break;
3012 case LE:
3013 libfunc = letf2_libfunc;
3014 break;
3016 else
3018 enum machine_mode wider_mode;
3020 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3021 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3023 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3024 != CODE_FOR_nothing)
3025 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3027 x = protect_from_queue (x, 0);
3028 y = protect_from_queue (y, 0);
3029 x = convert_to_mode (wider_mode, x, 0);
3030 y = convert_to_mode (wider_mode, y, 0);
3031 emit_float_lib_cmp (x, y, comparison);
3032 return;
3035 abort ();
3038 if (libfunc == 0)
3039 abort ();
3041 emit_library_call (libfunc, 1,
3042 word_mode, 2, x, mode, y, mode);
3044 emit_cmp_insn (hard_libcall_value (word_mode), const0_rtx, comparison,
3045 NULL_RTX, word_mode, 0, 0);
3048 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3050 void
3051 emit_indirect_jump (loc)
3052 rtx loc;
3054 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3055 (loc, Pmode)))
3056 loc = copy_to_mode_reg (Pmode, loc);
3058 emit_jump_insn (gen_indirect_jump (loc));
3059 emit_barrier ();
3062 #ifdef HAVE_conditional_move
3064 /* Emit a conditional move instruction if the machine supports one for that
3065 condition and machine mode.
3067 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3068 the mode to use should they be constants. If it is VOIDmode, they cannot
3069 both be constants.
3071 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3072 should be stored there. MODE is the mode to use should they be constants.
3073 If it is VOIDmode, they cannot both be constants.
3075 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3076 is not supported. */
3079 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3080 unsignedp)
3081 rtx target;
3082 enum rtx_code code;
3083 rtx op0, op1;
3084 enum machine_mode cmode;
3085 rtx op2, op3;
3086 enum machine_mode mode;
3087 int unsignedp;
3089 rtx tem, subtarget, comparison, insn;
3090 enum insn_code icode;
3092 /* If one operand is constant, make it the second one. Only do this
3093 if the other operand is not constant as well. */
3095 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3096 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3098 tem = op0;
3099 op0 = op1;
3100 op1 = tem;
3101 code = swap_condition (code);
3104 if (cmode == VOIDmode)
3105 cmode = GET_MODE (op0);
3107 if ((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3108 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3110 tem = op2;
3111 op2 = op3;
3112 op3 = tem;
3113 /* ??? This may not be appropriate (consider IEEE). Perhaps we should
3114 call can_reverse_comparison_p here and bail out if necessary.
3115 It's not clear whether we need to do this canonicalization though. */
3116 code = reverse_condition (code);
3119 if (mode == VOIDmode)
3120 mode = GET_MODE (op2);
3122 icode = movcc_gen_code[mode];
3124 if (icode == CODE_FOR_nothing)
3125 return 0;
3127 if (flag_force_mem)
3129 op2 = force_not_mem (op2);
3130 op3 = force_not_mem (op3);
3133 if (target)
3134 target = protect_from_queue (target, 1);
3135 else
3136 target = gen_reg_rtx (mode);
3138 subtarget = target;
3140 emit_queue ();
3142 op2 = protect_from_queue (op2, 0);
3143 op3 = protect_from_queue (op3, 0);
3145 /* If the insn doesn't accept these operands, put them in pseudos. */
3147 if (! (*insn_operand_predicate[icode][0])
3148 (subtarget, insn_operand_mode[icode][0]))
3149 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3151 if (! (*insn_operand_predicate[icode][2])
3152 (op2, insn_operand_mode[icode][2]))
3153 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3155 if (! (*insn_operand_predicate[icode][3])
3156 (op3, insn_operand_mode[icode][3]))
3157 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3159 /* Everything should now be in the suitable form, so emit the compare insn
3160 and then the conditional move. */
3162 comparison
3163 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3165 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3166 if (GET_CODE (comparison) != code)
3167 /* This shouldn't happen. */
3168 abort ();
3170 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3172 /* If that failed, then give up. */
3173 if (insn == 0)
3174 return 0;
3176 emit_insn (insn);
3178 if (subtarget != target)
3179 convert_move (target, subtarget, 0);
3181 return target;
3184 /* Return non-zero if a conditional move of mode MODE is supported.
3186 This function is for combine so it can tell whether an insn that looks
3187 like a conditional move is actually supported by the hardware. If we
3188 guess wrong we lose a bit on optimization, but that's it. */
3189 /* ??? sparc64 supports conditionally moving integers values based on fp
3190 comparisons, and vice versa. How do we handle them? */
3193 can_conditionally_move_p (mode)
3194 enum machine_mode mode;
3196 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3197 return 1;
3199 return 0;
3202 #endif /* HAVE_conditional_move */
3204 /* These three functions generate an insn body and return it
3205 rather than emitting the insn.
3207 They do not protect from queued increments,
3208 because they may be used 1) in protect_from_queue itself
3209 and 2) in other passes where there is no queue. */
3211 /* Generate and return an insn body to add Y to X. */
3214 gen_add2_insn (x, y)
3215 rtx x, y;
3217 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3219 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3220 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3221 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3222 abort ();
3224 return (GEN_FCN (icode) (x, x, y));
3228 have_add2_insn (mode)
3229 enum machine_mode mode;
3231 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3234 /* Generate and return an insn body to subtract Y from X. */
3237 gen_sub2_insn (x, y)
3238 rtx x, y;
3240 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3242 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3243 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3244 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3245 abort ();
3247 return (GEN_FCN (icode) (x, x, y));
3251 have_sub2_insn (mode)
3252 enum machine_mode mode;
3254 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3257 /* Generate the body of an instruction to copy Y into X.
3258 It may be a SEQUENCE, if one insn isn't enough. */
3261 gen_move_insn (x, y)
3262 rtx x, y;
3264 register enum machine_mode mode = GET_MODE (x);
3265 enum insn_code insn_code;
3266 rtx seq;
3268 if (mode == VOIDmode)
3269 mode = GET_MODE (y);
3271 insn_code = mov_optab->handlers[(int) mode].insn_code;
3273 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3274 find a mode to do it in. If we have a movcc, use it. Otherwise,
3275 find the MODE_INT mode of the same width. */
3277 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3279 enum machine_mode tmode = VOIDmode;
3280 rtx x1 = x, y1 = y;
3282 if (mode != CCmode
3283 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3284 tmode = CCmode;
3285 else
3286 for (tmode = QImode; tmode != VOIDmode;
3287 tmode = GET_MODE_WIDER_MODE (tmode))
3288 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3289 break;
3291 if (tmode == VOIDmode)
3292 abort ();
3294 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3295 may call change_address which is not appropriate if we were
3296 called when a reload was in progress. We don't have to worry
3297 about changing the address since the size in bytes is supposed to
3298 be the same. Copy the MEM to change the mode and move any
3299 substitutions from the old MEM to the new one. */
3301 if (reload_in_progress)
3303 x = gen_lowpart_common (tmode, x1);
3304 if (x == 0 && GET_CODE (x1) == MEM)
3306 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3307 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3308 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3309 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3310 copy_replacements (x1, x);
3313 y = gen_lowpart_common (tmode, y1);
3314 if (y == 0 && GET_CODE (y1) == MEM)
3316 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3317 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3318 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3319 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3320 copy_replacements (y1, y);
3323 else
3325 x = gen_lowpart (tmode, x);
3326 y = gen_lowpart (tmode, y);
3329 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3330 return (GEN_FCN (insn_code) (x, y));
3333 start_sequence ();
3334 emit_move_insn_1 (x, y);
3335 seq = gen_sequence ();
3336 end_sequence ();
3337 return seq;
3340 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3341 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3342 no such operation exists, CODE_FOR_nothing will be returned. */
3344 enum insn_code
3345 can_extend_p (to_mode, from_mode, unsignedp)
3346 enum machine_mode to_mode, from_mode;
3347 int unsignedp;
3349 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3352 /* Generate the body of an insn to extend Y (with mode MFROM)
3353 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3356 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3357 rtx x, y;
3358 enum machine_mode mto, mfrom;
3359 int unsignedp;
3361 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3364 /* can_fix_p and can_float_p say whether the target machine
3365 can directly convert a given fixed point type to
3366 a given floating point type, or vice versa.
3367 The returned value is the CODE_FOR_... value to use,
3368 or CODE_FOR_nothing if these modes cannot be directly converted.
3370 *TRUNCP_PTR is set to 1 if it is necessary to output
3371 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3373 static enum insn_code
3374 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3375 enum machine_mode fltmode, fixmode;
3376 int unsignedp;
3377 int *truncp_ptr;
3379 *truncp_ptr = 0;
3380 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3381 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3383 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3385 *truncp_ptr = 1;
3386 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3388 return CODE_FOR_nothing;
3391 static enum insn_code
3392 can_float_p (fltmode, fixmode, unsignedp)
3393 enum machine_mode fixmode, fltmode;
3394 int unsignedp;
3396 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3399 /* Generate code to convert FROM to floating point
3400 and store in TO. FROM must be fixed point and not VOIDmode.
3401 UNSIGNEDP nonzero means regard FROM as unsigned.
3402 Normally this is done by correcting the final value
3403 if it is negative. */
3405 void
3406 expand_float (to, from, unsignedp)
3407 rtx to, from;
3408 int unsignedp;
3410 enum insn_code icode;
3411 register rtx target = to;
3412 enum machine_mode fmode, imode;
3414 /* Crash now, because we won't be able to decide which mode to use. */
3415 if (GET_MODE (from) == VOIDmode)
3416 abort ();
3418 /* Look for an insn to do the conversion. Do it in the specified
3419 modes if possible; otherwise convert either input, output or both to
3420 wider mode. If the integer mode is wider than the mode of FROM,
3421 we can do the conversion signed even if the input is unsigned. */
3423 for (imode = GET_MODE (from); imode != VOIDmode;
3424 imode = GET_MODE_WIDER_MODE (imode))
3425 for (fmode = GET_MODE (to); fmode != VOIDmode;
3426 fmode = GET_MODE_WIDER_MODE (fmode))
3428 int doing_unsigned = unsignedp;
3430 icode = can_float_p (fmode, imode, unsignedp);
3431 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3432 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3434 if (icode != CODE_FOR_nothing)
3436 to = protect_from_queue (to, 1);
3437 from = protect_from_queue (from, 0);
3439 if (imode != GET_MODE (from))
3440 from = convert_to_mode (imode, from, unsignedp);
3442 if (fmode != GET_MODE (to))
3443 target = gen_reg_rtx (fmode);
3445 emit_unop_insn (icode, target, from,
3446 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3448 if (target != to)
3449 convert_move (to, target, 0);
3450 return;
3454 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3456 /* Unsigned integer, and no way to convert directly.
3457 Convert as signed, then conditionally adjust the result. */
3458 if (unsignedp)
3460 rtx label = gen_label_rtx ();
3461 rtx temp;
3462 REAL_VALUE_TYPE offset;
3464 emit_queue ();
3466 to = protect_from_queue (to, 1);
3467 from = protect_from_queue (from, 0);
3469 if (flag_force_mem)
3470 from = force_not_mem (from);
3472 /* Look for a usable floating mode FMODE wider than the source and at
3473 least as wide as the target. Using FMODE will avoid rounding woes
3474 with unsigned values greater than the signed maximum value. */
3476 for (fmode = GET_MODE (to); fmode != VOIDmode;
3477 fmode = GET_MODE_WIDER_MODE (fmode))
3478 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3479 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3480 break;
3482 if (fmode == VOIDmode)
3484 /* There is no such mode. Pretend the target is wide enough. */
3485 fmode = GET_MODE (to);
3487 /* Avoid double-rounding when TO is narrower than FROM. */
3488 if ((significand_size (fmode) + 1)
3489 < GET_MODE_BITSIZE (GET_MODE (from)))
3491 rtx temp1;
3492 rtx neglabel = gen_label_rtx ();
3494 /* Don't use TARGET if it isn't a register, is a hard register,
3495 or is the wrong mode. */
3496 if (GET_CODE (target) != REG
3497 || REGNO (target) < FIRST_PSEUDO_REGISTER
3498 || GET_MODE (target) != fmode)
3499 target = gen_reg_rtx (fmode);
3501 imode = GET_MODE (from);
3502 do_pending_stack_adjust ();
3504 /* Test whether the sign bit is set. */
3505 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3506 emit_jump_insn (gen_blt (neglabel));
3508 /* The sign bit is not set. Convert as signed. */
3509 expand_float (target, from, 0);
3510 emit_jump_insn (gen_jump (label));
3512 /* The sign bit is set.
3513 Convert to a usable (positive signed) value by shifting right
3514 one bit, while remembering if a nonzero bit was shifted
3515 out; i.e., compute (from & 1) | (from >> 1). */
3517 emit_label (neglabel);
3518 temp = expand_binop (imode, and_optab, from, const1_rtx,
3519 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3520 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3521 NULL_RTX, 1);
3522 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3523 OPTAB_LIB_WIDEN);
3524 expand_float (target, temp, 0);
3526 /* Multiply by 2 to undo the shift above. */
3527 temp = expand_binop (fmode, add_optab, target, target,
3528 target, 0, OPTAB_LIB_WIDEN);
3529 if (temp != target)
3530 emit_move_insn (target, temp);
3532 do_pending_stack_adjust ();
3533 emit_label (label);
3534 goto done;
3538 /* If we are about to do some arithmetic to correct for an
3539 unsigned operand, do it in a pseudo-register. */
3541 if (GET_MODE (to) != fmode
3542 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3543 target = gen_reg_rtx (fmode);
3545 /* Convert as signed integer to floating. */
3546 expand_float (target, from, 0);
3548 /* If FROM is negative (and therefore TO is negative),
3549 correct its value by 2**bitwidth. */
3551 do_pending_stack_adjust ();
3552 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3553 emit_jump_insn (gen_bge (label));
3555 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3556 Rather than setting up a dconst_dot_5, let's hope SCO
3557 fixes the bug. */
3558 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3559 temp = expand_binop (fmode, add_optab, target,
3560 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3561 target, 0, OPTAB_LIB_WIDEN);
3562 if (temp != target)
3563 emit_move_insn (target, temp);
3565 do_pending_stack_adjust ();
3566 emit_label (label);
3567 goto done;
3569 #endif
3571 /* No hardware instruction available; call a library routine to convert from
3572 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3574 rtx libfcn;
3575 rtx insns;
3576 rtx value;
3578 to = protect_from_queue (to, 1);
3579 from = protect_from_queue (from, 0);
3581 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3582 from = convert_to_mode (SImode, from, unsignedp);
3584 if (flag_force_mem)
3585 from = force_not_mem (from);
3587 if (GET_MODE (to) == SFmode)
3589 if (GET_MODE (from) == SImode)
3590 libfcn = floatsisf_libfunc;
3591 else if (GET_MODE (from) == DImode)
3592 libfcn = floatdisf_libfunc;
3593 else if (GET_MODE (from) == TImode)
3594 libfcn = floattisf_libfunc;
3595 else
3596 abort ();
3598 else if (GET_MODE (to) == DFmode)
3600 if (GET_MODE (from) == SImode)
3601 libfcn = floatsidf_libfunc;
3602 else if (GET_MODE (from) == DImode)
3603 libfcn = floatdidf_libfunc;
3604 else if (GET_MODE (from) == TImode)
3605 libfcn = floattidf_libfunc;
3606 else
3607 abort ();
3609 else if (GET_MODE (to) == XFmode)
3611 if (GET_MODE (from) == SImode)
3612 libfcn = floatsixf_libfunc;
3613 else if (GET_MODE (from) == DImode)
3614 libfcn = floatdixf_libfunc;
3615 else if (GET_MODE (from) == TImode)
3616 libfcn = floattixf_libfunc;
3617 else
3618 abort ();
3620 else if (GET_MODE (to) == TFmode)
3622 if (GET_MODE (from) == SImode)
3623 libfcn = floatsitf_libfunc;
3624 else if (GET_MODE (from) == DImode)
3625 libfcn = floatditf_libfunc;
3626 else if (GET_MODE (from) == TImode)
3627 libfcn = floattitf_libfunc;
3628 else
3629 abort ();
3631 else
3632 abort ();
3634 start_sequence ();
3636 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3637 GET_MODE (to),
3638 1, from, GET_MODE (from));
3639 insns = get_insns ();
3640 end_sequence ();
3642 emit_libcall_block (insns, target, value,
3643 gen_rtx (FLOAT, GET_MODE (to), from));
3646 done:
3648 /* Copy result to requested destination
3649 if we have been computing in a temp location. */
3651 if (target != to)
3653 if (GET_MODE (target) == GET_MODE (to))
3654 emit_move_insn (to, target);
3655 else
3656 convert_move (to, target, 0);
3660 /* expand_fix: generate code to convert FROM to fixed point
3661 and store in TO. FROM must be floating point. */
3663 static rtx
3664 ftruncify (x)
3665 rtx x;
3667 rtx temp = gen_reg_rtx (GET_MODE (x));
3668 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3671 void
3672 expand_fix (to, from, unsignedp)
3673 register rtx to, from;
3674 int unsignedp;
3676 enum insn_code icode;
3677 register rtx target = to;
3678 enum machine_mode fmode, imode;
3679 int must_trunc = 0;
3680 rtx libfcn = 0;
3682 /* We first try to find a pair of modes, one real and one integer, at
3683 least as wide as FROM and TO, respectively, in which we can open-code
3684 this conversion. If the integer mode is wider than the mode of TO,
3685 we can do the conversion either signed or unsigned. */
3687 for (imode = GET_MODE (to); imode != VOIDmode;
3688 imode = GET_MODE_WIDER_MODE (imode))
3689 for (fmode = GET_MODE (from); fmode != VOIDmode;
3690 fmode = GET_MODE_WIDER_MODE (fmode))
3692 int doing_unsigned = unsignedp;
3694 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3695 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3696 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3698 if (icode != CODE_FOR_nothing)
3700 to = protect_from_queue (to, 1);
3701 from = protect_from_queue (from, 0);
3703 if (fmode != GET_MODE (from))
3704 from = convert_to_mode (fmode, from, 0);
3706 if (must_trunc)
3707 from = ftruncify (from);
3709 if (imode != GET_MODE (to))
3710 target = gen_reg_rtx (imode);
3712 emit_unop_insn (icode, target, from,
3713 doing_unsigned ? UNSIGNED_FIX : FIX);
3714 if (target != to)
3715 convert_move (to, target, unsignedp);
3716 return;
3720 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3721 /* For an unsigned conversion, there is one more way to do it.
3722 If we have a signed conversion, we generate code that compares
3723 the real value to the largest representable positive number. If if
3724 is smaller, the conversion is done normally. Otherwise, subtract
3725 one plus the highest signed number, convert, and add it back.
3727 We only need to check all real modes, since we know we didn't find
3728 anything with a wider integer mode. */
3730 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3731 for (fmode = GET_MODE (from); fmode != VOIDmode;
3732 fmode = GET_MODE_WIDER_MODE (fmode))
3733 /* Make sure we won't lose significant bits doing this. */
3734 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3735 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3736 &must_trunc))
3738 int bitsize;
3739 REAL_VALUE_TYPE offset;
3740 rtx limit, lab1, lab2, insn;
3742 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3743 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3744 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3745 lab1 = gen_label_rtx ();
3746 lab2 = gen_label_rtx ();
3748 emit_queue ();
3749 to = protect_from_queue (to, 1);
3750 from = protect_from_queue (from, 0);
3752 if (flag_force_mem)
3753 from = force_not_mem (from);
3755 if (fmode != GET_MODE (from))
3756 from = convert_to_mode (fmode, from, 0);
3758 /* See if we need to do the subtraction. */
3759 do_pending_stack_adjust ();
3760 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3761 emit_jump_insn (gen_bge (lab1));
3763 /* If not, do the signed "fix" and branch around fixup code. */
3764 expand_fix (to, from, 0);
3765 emit_jump_insn (gen_jump (lab2));
3766 emit_barrier ();
3768 /* Otherwise, subtract 2**(N-1), convert to signed number,
3769 then add 2**(N-1). Do the addition using XOR since this
3770 will often generate better code. */
3771 emit_label (lab1);
3772 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3773 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3774 expand_fix (to, target, 0);
3775 target = expand_binop (GET_MODE (to), xor_optab, to,
3776 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3777 to, 1, OPTAB_LIB_WIDEN);
3779 if (target != to)
3780 emit_move_insn (to, target);
3782 emit_label (lab2);
3784 /* Make a place for a REG_NOTE and add it. */
3785 insn = emit_move_insn (to, to);
3786 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3787 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3788 copy_rtx (from)),
3789 REG_NOTES (insn));
3791 return;
3793 #endif
3795 /* We can't do it with an insn, so use a library call. But first ensure
3796 that the mode of TO is at least as wide as SImode, since those are the
3797 only library calls we know about. */
3799 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3801 target = gen_reg_rtx (SImode);
3803 expand_fix (target, from, unsignedp);
3805 else if (GET_MODE (from) == SFmode)
3807 if (GET_MODE (to) == SImode)
3808 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3809 else if (GET_MODE (to) == DImode)
3810 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3811 else if (GET_MODE (to) == TImode)
3812 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3813 else
3814 abort ();
3816 else if (GET_MODE (from) == DFmode)
3818 if (GET_MODE (to) == SImode)
3819 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3820 else if (GET_MODE (to) == DImode)
3821 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3822 else if (GET_MODE (to) == TImode)
3823 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3824 else
3825 abort ();
3827 else if (GET_MODE (from) == XFmode)
3829 if (GET_MODE (to) == SImode)
3830 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3831 else if (GET_MODE (to) == DImode)
3832 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3833 else if (GET_MODE (to) == TImode)
3834 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3835 else
3836 abort ();
3838 else if (GET_MODE (from) == TFmode)
3840 if (GET_MODE (to) == SImode)
3841 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3842 else if (GET_MODE (to) == DImode)
3843 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3844 else if (GET_MODE (to) == TImode)
3845 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3846 else
3847 abort ();
3849 else
3850 abort ();
3852 if (libfcn)
3854 rtx insns;
3855 rtx value;
3857 to = protect_from_queue (to, 1);
3858 from = protect_from_queue (from, 0);
3860 if (flag_force_mem)
3861 from = force_not_mem (from);
3863 start_sequence ();
3865 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3867 1, from, GET_MODE (from));
3868 insns = get_insns ();
3869 end_sequence ();
3871 emit_libcall_block (insns, target, value,
3872 gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3873 GET_MODE (to), from));
3876 if (GET_MODE (to) == GET_MODE (target))
3877 emit_move_insn (to, target);
3878 else
3879 convert_move (to, target, 0);
3882 static optab
3883 init_optab (code)
3884 enum rtx_code code;
3886 int i;
3887 optab op = (optab) xmalloc (sizeof (struct optab));
3888 op->code = code;
3889 for (i = 0; i < NUM_MACHINE_MODES; i++)
3891 op->handlers[i].insn_code = CODE_FOR_nothing;
3892 op->handlers[i].libfunc = 0;
3895 if (code != UNKNOWN)
3896 code_to_optab[(int) code] = op;
3898 return op;
3901 /* Initialize the libfunc fields of an entire group of entries in some
3902 optab. Each entry is set equal to a string consisting of a leading
3903 pair of underscores followed by a generic operation name followed by
3904 a mode name (downshifted to lower case) followed by a single character
3905 representing the number of operands for the given operation (which is
3906 usually one of the characters '2', '3', or '4').
3908 OPTABLE is the table in which libfunc fields are to be initialized.
3909 FIRST_MODE is the first machine mode index in the given optab to
3910 initialize.
3911 LAST_MODE is the last machine mode index in the given optab to
3912 initialize.
3913 OPNAME is the generic (string) name of the operation.
3914 SUFFIX is the character which specifies the number of operands for
3915 the given generic operation.
3918 static void
3919 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3920 register optab optable;
3921 register int first_mode;
3922 register int last_mode;
3923 register char *opname;
3924 register char suffix;
3926 register int mode;
3927 register unsigned opname_len = strlen (opname);
3929 for (mode = first_mode; (int) mode <= (int) last_mode;
3930 mode = (enum machine_mode) ((int) mode + 1))
3932 register char *mname = mode_name[(int) mode];
3933 register unsigned mname_len = strlen (mname);
3934 register char *libfunc_name
3935 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3936 register char *p;
3937 register char *q;
3939 p = libfunc_name;
3940 *p++ = '_';
3941 *p++ = '_';
3942 for (q = opname; *q; )
3943 *p++ = *q++;
3944 for (q = mname; *q; q++)
3945 *p++ = tolower (*q);
3946 *p++ = suffix;
3947 *p++ = '\0';
3948 optable->handlers[(int) mode].libfunc
3949 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
3953 /* Initialize the libfunc fields of an entire group of entries in some
3954 optab which correspond to all integer mode operations. The parameters
3955 have the same meaning as similarly named ones for the `init_libfuncs'
3956 routine. (See above). */
3958 static void
3959 init_integral_libfuncs (optable, opname, suffix)
3960 register optab optable;
3961 register char *opname;
3962 register char suffix;
3964 init_libfuncs (optable, SImode, TImode, opname, suffix);
3967 /* Initialize the libfunc fields of an entire group of entries in some
3968 optab which correspond to all real mode operations. The parameters
3969 have the same meaning as similarly named ones for the `init_libfuncs'
3970 routine. (See above). */
3972 static void
3973 init_floating_libfuncs (optable, opname, suffix)
3974 register optab optable;
3975 register char *opname;
3976 register char suffix;
3978 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
3981 /* Initialize the libfunc fields of an entire group of entries in some
3982 optab which correspond to all complex floating modes. The parameters
3983 have the same meaning as similarly named ones for the `init_libfuncs'
3984 routine. (See above). */
3986 static void
3987 init_complex_libfuncs (optable, opname, suffix)
3988 register optab optable;
3989 register char *opname;
3990 register char suffix;
3992 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
3995 /* Call this once to initialize the contents of the optabs
3996 appropriately for the current target machine. */
3998 void
3999 init_optabs ()
4001 int i, j;
4002 enum insn_code *p;
4004 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4006 for (p = fixtab[0][0];
4007 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4008 p++)
4009 *p = CODE_FOR_nothing;
4011 for (p = fixtrunctab[0][0];
4012 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4013 p++)
4014 *p = CODE_FOR_nothing;
4016 for (p = floattab[0][0];
4017 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4018 p++)
4019 *p = CODE_FOR_nothing;
4021 for (p = extendtab[0][0];
4022 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4023 p++)
4024 *p = CODE_FOR_nothing;
4026 for (i = 0; i < NUM_RTX_CODE; i++)
4027 setcc_gen_code[i] = CODE_FOR_nothing;
4029 #ifdef HAVE_conditional_move
4030 for (i = 0; i < NUM_MACHINE_MODES; i++)
4031 movcc_gen_code[i] = CODE_FOR_nothing;
4032 #endif
4034 add_optab = init_optab (PLUS);
4035 sub_optab = init_optab (MINUS);
4036 smul_optab = init_optab (MULT);
4037 smul_highpart_optab = init_optab (UNKNOWN);
4038 umul_highpart_optab = init_optab (UNKNOWN);
4039 smul_widen_optab = init_optab (UNKNOWN);
4040 umul_widen_optab = init_optab (UNKNOWN);
4041 sdiv_optab = init_optab (DIV);
4042 sdivmod_optab = init_optab (UNKNOWN);
4043 udiv_optab = init_optab (UDIV);
4044 udivmod_optab = init_optab (UNKNOWN);
4045 smod_optab = init_optab (MOD);
4046 umod_optab = init_optab (UMOD);
4047 flodiv_optab = init_optab (DIV);
4048 ftrunc_optab = init_optab (UNKNOWN);
4049 and_optab = init_optab (AND);
4050 ior_optab = init_optab (IOR);
4051 xor_optab = init_optab (XOR);
4052 ashl_optab = init_optab (ASHIFT);
4053 ashr_optab = init_optab (ASHIFTRT);
4054 lshr_optab = init_optab (LSHIFTRT);
4055 rotl_optab = init_optab (ROTATE);
4056 rotr_optab = init_optab (ROTATERT);
4057 smin_optab = init_optab (SMIN);
4058 smax_optab = init_optab (SMAX);
4059 umin_optab = init_optab (UMIN);
4060 umax_optab = init_optab (UMAX);
4061 mov_optab = init_optab (UNKNOWN);
4062 movstrict_optab = init_optab (UNKNOWN);
4063 cmp_optab = init_optab (UNKNOWN);
4064 ucmp_optab = init_optab (UNKNOWN);
4065 tst_optab = init_optab (UNKNOWN);
4066 neg_optab = init_optab (NEG);
4067 abs_optab = init_optab (ABS);
4068 one_cmpl_optab = init_optab (NOT);
4069 ffs_optab = init_optab (FFS);
4070 sqrt_optab = init_optab (SQRT);
4071 sin_optab = init_optab (UNKNOWN);
4072 cos_optab = init_optab (UNKNOWN);
4073 strlen_optab = init_optab (UNKNOWN);
4075 for (i = 0; i < NUM_MACHINE_MODES; i++)
4077 movstr_optab[i] = CODE_FOR_nothing;
4079 #ifdef HAVE_SECONDARY_RELOADS
4080 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4081 #endif
4084 /* Fill in the optabs with the insns we support. */
4085 init_all_optabs ();
4087 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4088 /* This flag says the same insns that convert to a signed fixnum
4089 also convert validly to an unsigned one. */
4090 for (i = 0; i < NUM_MACHINE_MODES; i++)
4091 for (j = 0; j < NUM_MACHINE_MODES; j++)
4092 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4093 #endif
4095 #ifdef EXTRA_CC_MODES
4096 init_mov_optab ();
4097 #endif
4099 /* Initialize the optabs with the names of the library functions. */
4100 init_integral_libfuncs (add_optab, "add", '3');
4101 init_floating_libfuncs (add_optab, "add", '3');
4102 init_integral_libfuncs (sub_optab, "sub", '3');
4103 init_floating_libfuncs (sub_optab, "sub", '3');
4104 init_integral_libfuncs (smul_optab, "mul", '3');
4105 init_floating_libfuncs (smul_optab, "mul", '3');
4106 init_integral_libfuncs (sdiv_optab, "div", '3');
4107 init_integral_libfuncs (udiv_optab, "udiv", '3');
4108 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4109 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4110 init_integral_libfuncs (smod_optab, "mod", '3');
4111 init_integral_libfuncs (umod_optab, "umod", '3');
4112 init_floating_libfuncs (flodiv_optab, "div", '3');
4113 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4114 init_integral_libfuncs (and_optab, "and", '3');
4115 init_integral_libfuncs (ior_optab, "ior", '3');
4116 init_integral_libfuncs (xor_optab, "xor", '3');
4117 init_integral_libfuncs (ashl_optab, "ashl", '3');
4118 init_integral_libfuncs (ashr_optab, "ashr", '3');
4119 init_integral_libfuncs (lshr_optab, "lshr", '3');
4120 init_integral_libfuncs (smin_optab, "min", '3');
4121 init_floating_libfuncs (smin_optab, "min", '3');
4122 init_integral_libfuncs (smax_optab, "max", '3');
4123 init_floating_libfuncs (smax_optab, "max", '3');
4124 init_integral_libfuncs (umin_optab, "umin", '3');
4125 init_integral_libfuncs (umax_optab, "umax", '3');
4126 init_integral_libfuncs (neg_optab, "neg", '2');
4127 init_floating_libfuncs (neg_optab, "neg", '2');
4128 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4129 init_integral_libfuncs (ffs_optab, "ffs", '2');
4131 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4132 init_integral_libfuncs (cmp_optab, "cmp", '2');
4133 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4134 init_floating_libfuncs (cmp_optab, "cmp", '2');
4136 #ifdef MULSI3_LIBCALL
4137 smul_optab->handlers[(int) SImode].libfunc
4138 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4139 #endif
4140 #ifdef MULDI3_LIBCALL
4141 smul_optab->handlers[(int) DImode].libfunc
4142 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4143 #endif
4144 #ifdef MULTI3_LIBCALL
4145 smul_optab->handlers[(int) TImode].libfunc
4146 = gen_rtx (SYMBOL_REF, Pmode, MULTI3_LIBCALL);
4147 #endif
4149 #ifdef DIVSI3_LIBCALL
4150 sdiv_optab->handlers[(int) SImode].libfunc
4151 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4152 #endif
4153 #ifdef DIVDI3_LIBCALL
4154 sdiv_optab->handlers[(int) DImode].libfunc
4155 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4156 #endif
4157 #ifdef DIVTI3_LIBCALL
4158 sdiv_optab->handlers[(int) TImode].libfunc
4159 = gen_rtx (SYMBOL_REF, Pmode, DIVTI3_LIBCALL);
4160 #endif
4162 #ifdef UDIVSI3_LIBCALL
4163 udiv_optab->handlers[(int) SImode].libfunc
4164 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4165 #endif
4166 #ifdef UDIVDI3_LIBCALL
4167 udiv_optab->handlers[(int) DImode].libfunc
4168 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4169 #endif
4170 #ifdef UDIVTI3_LIBCALL
4171 udiv_optab->handlers[(int) TImode].libfunc
4172 = gen_rtx (SYMBOL_REF, Pmode, UDIVTI3_LIBCALL);
4173 #endif
4176 #ifdef MODSI3_LIBCALL
4177 smod_optab->handlers[(int) SImode].libfunc
4178 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4179 #endif
4180 #ifdef MODDI3_LIBCALL
4181 smod_optab->handlers[(int) DImode].libfunc
4182 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4183 #endif
4184 #ifdef MODTI3_LIBCALL
4185 smod_optab->handlers[(int) TImode].libfunc
4186 = gen_rtx (SYMBOL_REF, Pmode, MODTI3_LIBCALL);
4187 #endif
4190 #ifdef UMODSI3_LIBCALL
4191 umod_optab->handlers[(int) SImode].libfunc
4192 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4193 #endif
4194 #ifdef UMODDI3_LIBCALL
4195 umod_optab->handlers[(int) DImode].libfunc
4196 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4197 #endif
4198 #ifdef UMODTI3_LIBCALL
4199 umod_optab->handlers[(int) TImode].libfunc
4200 = gen_rtx (SYMBOL_REF, Pmode, UMODTI3_LIBCALL);
4201 #endif
4203 /* Define library calls for quad FP instructions */
4204 #ifdef ADDTF3_LIBCALL
4205 add_optab->handlers[(int) TFmode].libfunc
4206 = gen_rtx (SYMBOL_REF, Pmode, ADDTF3_LIBCALL);
4207 #endif
4208 #ifdef SUBTF3_LIBCALL
4209 sub_optab->handlers[(int) TFmode].libfunc
4210 = gen_rtx (SYMBOL_REF, Pmode, SUBTF3_LIBCALL);
4211 #endif
4212 #ifdef MULTF3_LIBCALL
4213 smul_optab->handlers[(int) TFmode].libfunc
4214 = gen_rtx (SYMBOL_REF, Pmode, MULTF3_LIBCALL);
4215 #endif
4216 #ifdef DIVTF3_LIBCALL
4217 flodiv_optab->handlers[(int) TFmode].libfunc
4218 = gen_rtx (SYMBOL_REF, Pmode, DIVTF3_LIBCALL);
4219 #endif
4220 #ifdef SQRTTF2_LIBCALL
4221 sqrt_optab->handlers[(int) TFmode].libfunc
4222 = gen_rtx (SYMBOL_REF, Pmode, SQRTTF2_LIBCALL);
4223 #endif
4225 /* Use cabs for DC complex abs, since systems generally have cabs.
4226 Don't define any libcall for SCmode, so that cabs will be used. */
4227 abs_optab->handlers[(int) DCmode].libfunc
4228 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4230 /* The ffs function operates on `int'. */
4231 #ifndef INT_TYPE_SIZE
4232 #define INT_TYPE_SIZE BITS_PER_WORD
4233 #endif
4234 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4235 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4237 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4238 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4239 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4240 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4241 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4243 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4244 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4245 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4246 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4247 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4249 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4250 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4251 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4252 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4253 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4254 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4256 eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4257 nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4258 gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4259 gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4260 lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4261 lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4263 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4264 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4265 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4266 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4267 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4268 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4270 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4271 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4272 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4273 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4274 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4275 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4277 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4278 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4279 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4280 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4281 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4282 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4284 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4285 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4286 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4287 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4288 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4289 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4291 /* Define library calls for quad FP instructions */
4292 #ifdef EQTF2_LIBCALL
4293 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EQTF2_LIBCALL);
4294 #endif
4295 #ifdef NETF2_LIBCALL
4296 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, NETF2_LIBCALL);
4297 #endif
4298 #ifdef GTTF2_LIBCALL
4299 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GTTF2_LIBCALL);
4300 #endif
4301 #ifdef GETF2_LIBCALL
4302 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, GETF2_LIBCALL);
4303 #endif
4304 #ifdef LTTF2_LIBCALL
4305 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LTTF2_LIBCALL);
4306 #endif
4307 #ifdef LETF2_LIBCALL
4308 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, LETF2_LIBCALL);
4309 #endif
4311 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4312 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4313 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4315 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4316 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4317 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4319 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4320 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4321 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4323 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4324 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4325 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4327 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4328 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4329 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4331 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4332 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4333 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4335 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4336 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4337 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4339 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4340 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4341 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4343 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4344 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4345 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4347 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4348 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4349 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4351 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4352 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4353 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4355 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4356 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4357 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4359 /* Define library calls for quad FP instructions */
4360 #ifdef TRUNCTFSF2_LIBCALL
4361 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFSF2_LIBCALL);
4362 #endif
4363 #ifdef TRUNCTFDF2_LIBCALL
4364 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, TRUNCTFDF2_LIBCALL);
4365 #endif
4366 #ifdef EXTENDSFTF2_LIBCALL
4367 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDSFTF2_LIBCALL);
4368 #endif
4369 #ifdef EXTENDDFTF2_LIBCALL
4370 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, EXTENDDFTF2_LIBCALL);
4371 #endif
4372 #ifdef FLOATSITF2_LIBCALL
4373 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, FLOATSITF2_LIBCALL);
4374 #endif
4375 #ifdef FIX_TRUNCTFSI2_LIBCALL
4376 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIX_TRUNCTFSI2_LIBCALL);
4377 #endif
4378 #ifdef FIXUNS_TRUNCTFSI2_LIBCALL
4379 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, FIXUNS_TRUNCTFSI2_LIBCALL);
4380 #endif
4382 #ifdef INIT_TARGET_OPTABS
4383 /* Allow the target to add more libcalls or rename some, etc. */
4384 INIT_TARGET_OPTABS;
4385 #endif
4388 #ifdef BROKEN_LDEXP
4390 /* SCO 3.2 apparently has a broken ldexp. */
4392 double
4393 ldexp(x,n)
4394 double x;
4395 int n;
4397 if (n > 0)
4398 while (n--)
4399 x *= 2;
4401 return x;
4403 #endif /* BROKEN_LDEXP */