[official-gcc.git] / gcc / optabs.c
blobc00562fbf88e4f22d791f1efd263a90055e0debb
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92-97, 1998 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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "rtl.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "insn-flags.h"
28 #include "insn-codes.h"
29 #include "expr.h"
30 #include "insn-config.h"
31 #include "recog.h"
32 #include "reload.h"
34 /* Each optab contains info on how this target machine
35 can perform a particular operation
36 for all sizes and kinds of operands.
38 The operation to be performed is often specified
39 by passing one of these optabs as an argument.
41 See expr.h for documentation of these optabs. */
43 optab add_optab;
44 optab sub_optab;
45 optab smul_optab;
46 optab smul_highpart_optab;
47 optab umul_highpart_optab;
48 optab smul_widen_optab;
49 optab umul_widen_optab;
50 optab sdiv_optab;
51 optab sdivmod_optab;
52 optab udiv_optab;
53 optab udivmod_optab;
54 optab smod_optab;
55 optab umod_optab;
56 optab flodiv_optab;
57 optab ftrunc_optab;
58 optab and_optab;
59 optab ior_optab;
60 optab xor_optab;
61 optab ashl_optab;
62 optab lshr_optab;
63 optab ashr_optab;
64 optab rotl_optab;
65 optab rotr_optab;
66 optab smin_optab;
67 optab smax_optab;
68 optab umin_optab;
69 optab umax_optab;
71 optab mov_optab;
72 optab movstrict_optab;
74 optab neg_optab;
75 optab abs_optab;
76 optab one_cmpl_optab;
77 optab ffs_optab;
78 optab sqrt_optab;
79 optab sin_optab;
80 optab cos_optab;
82 optab cmp_optab;
83 optab ucmp_optab; /* Used only for libcalls for unsigned comparisons. */
84 optab tst_optab;
86 optab strlen_optab;
88 /* Tables of patterns for extending one integer mode to another. */
89 enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2];
91 /* Tables of patterns for converting between fixed and floating point. */
92 enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
93 enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
94 enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2];
96 /* Contains the optab used for each rtx code. */
97 optab code_to_optab[NUM_RTX_CODE + 1];
99 /* SYMBOL_REF rtx's for the library functions that are called
100 implicitly and not via optabs. */
102 rtx extendsfdf2_libfunc;
103 rtx extendsfxf2_libfunc;
104 rtx extendsftf2_libfunc;
105 rtx extenddfxf2_libfunc;
106 rtx extenddftf2_libfunc;
108 rtx truncdfsf2_libfunc;
109 rtx truncxfsf2_libfunc;
110 rtx trunctfsf2_libfunc;
111 rtx truncxfdf2_libfunc;
112 rtx trunctfdf2_libfunc;
114 rtx memcpy_libfunc;
115 rtx bcopy_libfunc;
116 rtx memcmp_libfunc;
117 rtx bcmp_libfunc;
118 rtx memset_libfunc;
119 rtx bzero_libfunc;
121 rtx throw_libfunc;
122 rtx sjthrow_libfunc;
123 rtx sjpopnthrow_libfunc;
124 rtx terminate_libfunc;
125 rtx setjmp_libfunc;
126 rtx longjmp_libfunc;
128 rtx eqhf2_libfunc;
129 rtx nehf2_libfunc;
130 rtx gthf2_libfunc;
131 rtx gehf2_libfunc;
132 rtx lthf2_libfunc;
133 rtx lehf2_libfunc;
135 rtx eqsf2_libfunc;
136 rtx nesf2_libfunc;
137 rtx gtsf2_libfunc;
138 rtx gesf2_libfunc;
139 rtx ltsf2_libfunc;
140 rtx lesf2_libfunc;
142 rtx eqdf2_libfunc;
143 rtx nedf2_libfunc;
144 rtx gtdf2_libfunc;
145 rtx gedf2_libfunc;
146 rtx ltdf2_libfunc;
147 rtx ledf2_libfunc;
149 rtx eqxf2_libfunc;
150 rtx nexf2_libfunc;
151 rtx gtxf2_libfunc;
152 rtx gexf2_libfunc;
153 rtx ltxf2_libfunc;
154 rtx lexf2_libfunc;
156 rtx eqtf2_libfunc;
157 rtx netf2_libfunc;
158 rtx gttf2_libfunc;
159 rtx getf2_libfunc;
160 rtx lttf2_libfunc;
161 rtx letf2_libfunc;
163 rtx floatsisf_libfunc;
164 rtx floatdisf_libfunc;
165 rtx floattisf_libfunc;
167 rtx floatsidf_libfunc;
168 rtx floatdidf_libfunc;
169 rtx floattidf_libfunc;
171 rtx floatsixf_libfunc;
172 rtx floatdixf_libfunc;
173 rtx floattixf_libfunc;
175 rtx floatsitf_libfunc;
176 rtx floatditf_libfunc;
177 rtx floattitf_libfunc;
179 rtx fixsfsi_libfunc;
180 rtx fixsfdi_libfunc;
181 rtx fixsfti_libfunc;
183 rtx fixdfsi_libfunc;
184 rtx fixdfdi_libfunc;
185 rtx fixdfti_libfunc;
187 rtx fixxfsi_libfunc;
188 rtx fixxfdi_libfunc;
189 rtx fixxfti_libfunc;
191 rtx fixtfsi_libfunc;
192 rtx fixtfdi_libfunc;
193 rtx fixtfti_libfunc;
195 rtx fixunssfsi_libfunc;
196 rtx fixunssfdi_libfunc;
197 rtx fixunssfti_libfunc;
199 rtx fixunsdfsi_libfunc;
200 rtx fixunsdfdi_libfunc;
201 rtx fixunsdfti_libfunc;
203 rtx fixunsxfsi_libfunc;
204 rtx fixunsxfdi_libfunc;
205 rtx fixunsxfti_libfunc;
207 rtx fixunstfsi_libfunc;
208 rtx fixunstfdi_libfunc;
209 rtx fixunstfti_libfunc;
211 rtx chkr_check_addr_libfunc;
212 rtx chkr_set_right_libfunc;
213 rtx chkr_copy_bitmap_libfunc;
214 rtx chkr_check_exec_libfunc;
215 rtx chkr_check_str_libfunc;
217 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
218 gives the gen_function to make a branch to test that condition. */
220 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
222 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
223 gives the insn code to make a store-condition insn
224 to test that condition. */
226 enum insn_code setcc_gen_code[NUM_RTX_CODE];
228 #ifdef HAVE_conditional_move
229 /* Indexed by the machine mode, gives the insn code to make a conditional
230 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
231 setcc_gen_code to cut down on the number of named patterns. Consider a day
232 when a lot more rtx codes are conditional (eg: for the ARM). */
234 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
235 #endif
237 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
238 static rtx widen_operand PROTO((rtx, enum machine_mode,
239 enum machine_mode, int, int));
240 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
241 int, int *));
242 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
243 int));
244 static rtx ftruncify PROTO((rtx));
245 static optab init_optab PROTO((enum rtx_code));
246 static void init_libfuncs PROTO((optab, int, int, char *, int));
247 static void init_integral_libfuncs PROTO((optab, char *, int));
248 static void init_floating_libfuncs PROTO((optab, char *, int));
250 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
251 the result of operation CODE applied to OP0 (and OP1 if it is a binary
252 operation).
254 If the last insn does not set TARGET, don't do anything, but return 1.
256 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
257 don't add the REG_EQUAL note but return 0. Our caller can then try
258 again, ensuring that TARGET is not one of the operands. */
260 static int
261 add_equal_note (seq, target, code, op0, op1)
262 rtx seq;
263 rtx target;
264 enum rtx_code code;
265 rtx op0, op1;
267 rtx set;
268 int i;
269 rtx note;
271 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
272 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
273 || GET_CODE (seq) != SEQUENCE
274 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
275 || GET_CODE (target) == ZERO_EXTRACT
276 || (! rtx_equal_p (SET_DEST (set), target)
277 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
278 SUBREG. */
279 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
280 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
281 target))))
282 return 1;
284 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
285 besides the last insn. */
286 if (reg_overlap_mentioned_p (target, op0)
287 || (op1 && reg_overlap_mentioned_p (target, op1)))
288 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
289 if (reg_set_p (target, XVECEXP (seq, 0, i)))
290 return 0;
292 if (GET_RTX_CLASS (code) == '1')
293 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
294 else
295 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
297 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
298 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
299 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
301 return 1;
304 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
305 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
306 not actually do a sign-extend or zero-extend, but can leave the
307 higher-order bits of the result rtx undefined, for example, in the case
308 of logical operations, but not right shifts. */
310 static rtx
311 widen_operand (op, mode, oldmode, unsignedp, no_extend)
312 rtx op;
313 enum machine_mode mode, oldmode;
314 int unsignedp;
315 int no_extend;
317 rtx result;
319 /* If we must extend do so. If OP is either a constant or a SUBREG
320 for a promoted object, also extend since it will be more efficient to
321 do so. */
322 if (! no_extend
323 || GET_MODE (op) == VOIDmode
324 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
325 return convert_modes (mode, oldmode, op, unsignedp);
327 /* If MODE is no wider than a single word, we return a paradoxical
328 SUBREG. */
329 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
330 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
332 /* Otherwise, get an object of MODE, clobber it, and set the low-order
333 part to OP. */
335 result = gen_reg_rtx (mode);
336 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
337 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
338 return result;
341 /* Generate code to perform an operation specified by BINOPTAB
342 on operands OP0 and OP1, with result having machine-mode MODE.
344 UNSIGNEDP is for the case where we have to widen the operands
345 to perform the operation. It says to use zero-extension.
347 If TARGET is nonzero, the value
348 is generated there, if it is convenient to do so.
349 In all cases an rtx is returned for the locus of the value;
350 this may or may not be TARGET. */
353 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
354 enum machine_mode mode;
355 optab binoptab;
356 rtx op0, op1;
357 rtx target;
358 int unsignedp;
359 enum optab_methods methods;
361 enum optab_methods next_methods
362 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
363 ? OPTAB_WIDEN : methods);
364 enum mode_class class;
365 enum machine_mode wider_mode;
366 register rtx temp;
367 int commutative_op = 0;
368 int shift_op = (binoptab->code == ASHIFT
369 || binoptab->code == ASHIFTRT
370 || binoptab->code == LSHIFTRT
371 || binoptab->code == ROTATE
372 || binoptab->code == ROTATERT);
373 rtx entry_last = get_last_insn ();
374 rtx last;
376 class = GET_MODE_CLASS (mode);
378 op0 = protect_from_queue (op0, 0);
379 op1 = protect_from_queue (op1, 0);
380 if (target)
381 target = protect_from_queue (target, 1);
383 if (flag_force_mem)
385 op0 = force_not_mem (op0);
386 op1 = force_not_mem (op1);
389 /* If subtracting an integer constant, convert this into an addition of
390 the negated constant. */
392 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
394 op1 = negate_rtx (mode, op1);
395 binoptab = add_optab;
398 /* If we are inside an appropriately-short loop and one operand is an
399 expensive constant, force it into a register. */
400 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
401 && rtx_cost (op0, binoptab->code) > 2)
402 op0 = force_reg (mode, op0);
404 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
405 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
406 op1 = force_reg (mode, op1);
408 /* Record where to delete back to if we backtrack. */
409 last = get_last_insn ();
411 /* If operation is commutative,
412 try to make the first operand a register.
413 Even better, try to make it the same as the target.
414 Also try to make the last operand a constant. */
415 if (GET_RTX_CLASS (binoptab->code) == 'c'
416 || binoptab == smul_widen_optab
417 || binoptab == umul_widen_optab
418 || binoptab == smul_highpart_optab
419 || binoptab == umul_highpart_optab)
421 commutative_op = 1;
423 if (((target == 0 || GET_CODE (target) == REG)
424 ? ((GET_CODE (op1) == REG
425 && GET_CODE (op0) != REG)
426 || target == op1)
427 : rtx_equal_p (op1, target))
428 || GET_CODE (op0) == CONST_INT)
430 temp = op1;
431 op1 = op0;
432 op0 = temp;
436 /* If we can do it with a three-operand insn, do so. */
438 if (methods != OPTAB_MUST_WIDEN
439 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
441 int icode = (int) binoptab->handlers[(int) mode].insn_code;
442 enum machine_mode mode0 = insn_operand_mode[icode][1];
443 enum machine_mode mode1 = insn_operand_mode[icode][2];
444 rtx pat;
445 rtx xop0 = op0, xop1 = op1;
447 if (target)
448 temp = target;
449 else
450 temp = gen_reg_rtx (mode);
452 /* If it is a commutative operator and the modes would match
453 if we would swap the operands, we can save the conversions. */
454 if (commutative_op)
456 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
457 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
459 register rtx tmp;
461 tmp = op0; op0 = op1; op1 = tmp;
462 tmp = xop0; xop0 = xop1; xop1 = tmp;
466 /* In case the insn wants input operands in modes different from
467 the result, convert the operands. */
469 if (GET_MODE (op0) != VOIDmode
470 && GET_MODE (op0) != mode0
471 && mode0 != VOIDmode)
472 xop0 = convert_to_mode (mode0, xop0, unsignedp);
474 if (GET_MODE (xop1) != VOIDmode
475 && GET_MODE (xop1) != mode1
476 && mode1 != VOIDmode)
477 xop1 = convert_to_mode (mode1, xop1, unsignedp);
479 /* Now, if insn's predicates don't allow our operands, put them into
480 pseudo regs. */
482 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
483 && mode0 != VOIDmode)
484 xop0 = copy_to_mode_reg (mode0, xop0);
486 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
487 && mode1 != VOIDmode)
488 xop1 = copy_to_mode_reg (mode1, xop1);
490 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
491 temp = gen_reg_rtx (mode);
493 pat = GEN_FCN (icode) (temp, xop0, xop1);
494 if (pat)
496 /* If PAT is a multi-insn sequence, try to add an appropriate
497 REG_EQUAL note to it. If we can't because TEMP conflicts with an
498 operand, call ourselves again, this time without a target. */
499 if (GET_CODE (pat) == SEQUENCE
500 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
502 delete_insns_since (last);
503 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
504 unsignedp, methods);
507 emit_insn (pat);
508 return temp;
510 else
511 delete_insns_since (last);
514 /* If this is a multiply, see if we can do a widening operation that
515 takes operands of this mode and makes a wider mode. */
517 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
518 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
519 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
520 != CODE_FOR_nothing))
522 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
523 unsignedp ? umul_widen_optab : smul_widen_optab,
524 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
526 if (temp != 0)
528 if (GET_MODE_CLASS (mode) == MODE_INT)
529 return gen_lowpart (mode, temp);
530 else
531 return convert_to_mode (mode, temp, unsignedp);
535 /* Look for a wider mode of the same class for which we think we
536 can open-code the operation. Check for a widening multiply at the
537 wider mode as well. */
539 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
540 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
541 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
542 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
544 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
545 || (binoptab == smul_optab
546 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
547 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
548 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
549 != CODE_FOR_nothing)))
551 rtx xop0 = op0, xop1 = op1;
552 int no_extend = 0;
554 /* For certain integer operations, we need not actually extend
555 the narrow operands, as long as we will truncate
556 the results to the same narrowness. */
558 if ((binoptab == ior_optab || binoptab == and_optab
559 || binoptab == xor_optab
560 || binoptab == add_optab || binoptab == sub_optab
561 || binoptab == smul_optab || binoptab == ashl_optab)
562 && class == MODE_INT)
563 no_extend = 1;
565 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
567 /* The second operand of a shift must always be extended. */
568 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
569 no_extend && binoptab != ashl_optab);
571 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
572 unsignedp, OPTAB_DIRECT);
573 if (temp)
575 if (class != MODE_INT)
577 if (target == 0)
578 target = gen_reg_rtx (mode);
579 convert_move (target, temp, 0);
580 return target;
582 else
583 return gen_lowpart (mode, temp);
585 else
586 delete_insns_since (last);
590 /* These can be done a word at a time. */
591 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
592 && class == MODE_INT
593 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
594 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
596 int i;
597 rtx insns;
598 rtx equiv_value;
600 /* If TARGET is the same as one of the operands, the REG_EQUAL note
601 won't be accurate, so use a new target. */
602 if (target == 0 || target == op0 || target == op1)
603 target = gen_reg_rtx (mode);
605 start_sequence ();
607 /* Do the actual arithmetic. */
608 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
610 rtx target_piece = operand_subword (target, i, 1, mode);
611 rtx x = expand_binop (word_mode, binoptab,
612 operand_subword_force (op0, i, mode),
613 operand_subword_force (op1, i, mode),
614 target_piece, unsignedp, next_methods);
616 if (x == 0)
617 break;
619 if (target_piece != x)
620 emit_move_insn (target_piece, x);
623 insns = get_insns ();
624 end_sequence ();
626 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
628 if (binoptab->code != UNKNOWN)
629 equiv_value
630 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
631 else
632 equiv_value = 0;
634 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
635 return target;
639 /* Synthesize double word shifts from single word shifts. */
640 if ((binoptab == lshr_optab || binoptab == ashl_optab
641 || binoptab == ashr_optab)
642 && class == MODE_INT
643 && GET_CODE (op1) == CONST_INT
644 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
645 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
646 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
647 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
649 rtx insns, inter, equiv_value;
650 rtx into_target, outof_target;
651 rtx into_input, outof_input;
652 int shift_count, left_shift, outof_word;
654 /* If TARGET is the same as one of the operands, the REG_EQUAL note
655 won't be accurate, so use a new target. */
656 if (target == 0 || target == op0 || target == op1)
657 target = gen_reg_rtx (mode);
659 start_sequence ();
661 shift_count = INTVAL (op1);
663 /* OUTOF_* is the word we are shifting bits away from, and
664 INTO_* is the word that we are shifting bits towards, thus
665 they differ depending on the direction of the shift and
666 WORDS_BIG_ENDIAN. */
668 left_shift = binoptab == ashl_optab;
669 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
671 outof_target = operand_subword (target, outof_word, 1, mode);
672 into_target = operand_subword (target, 1 - outof_word, 1, mode);
674 outof_input = operand_subword_force (op0, outof_word, mode);
675 into_input = operand_subword_force (op0, 1 - outof_word, mode);
677 if (shift_count >= BITS_PER_WORD)
679 inter = expand_binop (word_mode, binoptab,
680 outof_input,
681 GEN_INT (shift_count - BITS_PER_WORD),
682 into_target, unsignedp, next_methods);
684 if (inter != 0 && inter != into_target)
685 emit_move_insn (into_target, inter);
687 /* For a signed right shift, we must fill the word we are shifting
688 out of with copies of the sign bit. Otherwise it is zeroed. */
689 if (inter != 0 && binoptab != ashr_optab)
690 inter = CONST0_RTX (word_mode);
691 else if (inter != 0)
692 inter = expand_binop (word_mode, binoptab,
693 outof_input,
694 GEN_INT (BITS_PER_WORD - 1),
695 outof_target, unsignedp, next_methods);
697 if (inter != 0 && inter != outof_target)
698 emit_move_insn (outof_target, inter);
700 else
702 rtx carries;
703 optab reverse_unsigned_shift, unsigned_shift;
705 /* For a shift of less then BITS_PER_WORD, to compute the carry,
706 we must do a logical shift in the opposite direction of the
707 desired shift. */
709 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
711 /* For a shift of less than BITS_PER_WORD, to compute the word
712 shifted towards, we need to unsigned shift the orig value of
713 that word. */
715 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
717 carries = expand_binop (word_mode, reverse_unsigned_shift,
718 outof_input,
719 GEN_INT (BITS_PER_WORD - shift_count),
720 0, unsignedp, next_methods);
722 if (carries == 0)
723 inter = 0;
724 else
725 inter = expand_binop (word_mode, unsigned_shift, into_input,
726 op1, 0, unsignedp, next_methods);
728 if (inter != 0)
729 inter = expand_binop (word_mode, ior_optab, carries, inter,
730 into_target, unsignedp, next_methods);
732 if (inter != 0 && inter != into_target)
733 emit_move_insn (into_target, inter);
735 if (inter != 0)
736 inter = expand_binop (word_mode, binoptab, outof_input,
737 op1, outof_target, unsignedp, next_methods);
739 if (inter != 0 && inter != outof_target)
740 emit_move_insn (outof_target, inter);
743 insns = get_insns ();
744 end_sequence ();
746 if (inter != 0)
748 if (binoptab->code != UNKNOWN)
749 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
750 else
751 equiv_value = 0;
753 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
754 return target;
758 /* Synthesize double word rotates from single word shifts. */
759 if ((binoptab == rotl_optab || binoptab == rotr_optab)
760 && class == MODE_INT
761 && GET_CODE (op1) == CONST_INT
762 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
763 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
764 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
766 rtx insns, equiv_value;
767 rtx into_target, outof_target;
768 rtx into_input, outof_input;
769 rtx inter;
770 int shift_count, left_shift, outof_word;
772 /* If TARGET is the same as one of the operands, the REG_EQUAL note
773 won't be accurate, so use a new target. */
774 if (target == 0 || target == op0 || target == op1)
775 target = gen_reg_rtx (mode);
777 start_sequence ();
779 shift_count = INTVAL (op1);
781 /* OUTOF_* is the word we are shifting bits away from, and
782 INTO_* is the word that we are shifting bits towards, thus
783 they differ depending on the direction of the shift and
784 WORDS_BIG_ENDIAN. */
786 left_shift = (binoptab == rotl_optab);
787 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
789 outof_target = operand_subword (target, outof_word, 1, mode);
790 into_target = operand_subword (target, 1 - outof_word, 1, mode);
792 outof_input = operand_subword_force (op0, outof_word, mode);
793 into_input = operand_subword_force (op0, 1 - outof_word, mode);
795 if (shift_count == BITS_PER_WORD)
797 /* This is just a word swap. */
798 emit_move_insn (outof_target, into_input);
799 emit_move_insn (into_target, outof_input);
800 inter = const0_rtx;
802 else
804 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
805 rtx first_shift_count, second_shift_count;
806 optab reverse_unsigned_shift, unsigned_shift;
808 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
809 ? lshr_optab : ashl_optab);
811 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
812 ? ashl_optab : lshr_optab);
814 if (shift_count > BITS_PER_WORD)
816 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
817 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
819 else
821 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
822 second_shift_count = GEN_INT (shift_count);
825 into_temp1 = expand_binop (word_mode, unsigned_shift,
826 outof_input, first_shift_count,
827 NULL_RTX, unsignedp, next_methods);
828 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
829 into_input, second_shift_count,
830 into_target, unsignedp, next_methods);
832 if (into_temp1 != 0 && into_temp2 != 0)
833 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
834 into_target, unsignedp, next_methods);
835 else
836 inter = 0;
838 if (inter != 0 && inter != into_target)
839 emit_move_insn (into_target, inter);
841 outof_temp1 = expand_binop (word_mode, unsigned_shift,
842 into_input, first_shift_count,
843 NULL_RTX, unsignedp, next_methods);
844 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
845 outof_input, second_shift_count,
846 outof_target, unsignedp, next_methods);
848 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
849 inter = expand_binop (word_mode, ior_optab,
850 outof_temp1, outof_temp2,
851 outof_target, unsignedp, next_methods);
853 if (inter != 0 && inter != outof_target)
854 emit_move_insn (outof_target, inter);
857 insns = get_insns ();
858 end_sequence ();
860 if (inter != 0)
862 if (binoptab->code != UNKNOWN)
863 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
864 else
865 equiv_value = 0;
867 /* We can't make this a no conflict block if this is a word swap,
868 because the word swap case fails if the input and output values
869 are in the same register. */
870 if (shift_count != BITS_PER_WORD)
871 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
872 else
873 emit_insns (insns);
876 return target;
880 /* These can be done a word at a time by propagating carries. */
881 if ((binoptab == add_optab || binoptab == sub_optab)
882 && class == MODE_INT
883 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
884 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
886 int i;
887 rtx carry_tmp = gen_reg_rtx (word_mode);
888 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
889 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
890 rtx carry_in, carry_out;
891 rtx xop0, xop1;
893 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
894 value is one of those, use it. Otherwise, use 1 since it is the
895 one easiest to get. */
896 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
897 int normalizep = STORE_FLAG_VALUE;
898 #else
899 int normalizep = 1;
900 #endif
902 /* Prepare the operands. */
903 xop0 = force_reg (mode, op0);
904 xop1 = force_reg (mode, op1);
906 if (target == 0 || GET_CODE (target) != REG
907 || target == xop0 || target == xop1)
908 target = gen_reg_rtx (mode);
910 /* Indicate for flow that the entire target reg is being set. */
911 if (GET_CODE (target) == REG)
912 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
914 /* Do the actual arithmetic. */
915 for (i = 0; i < nwords; i++)
917 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
918 rtx target_piece = operand_subword (target, index, 1, mode);
919 rtx op0_piece = operand_subword_force (xop0, index, mode);
920 rtx op1_piece = operand_subword_force (xop1, index, mode);
921 rtx x;
923 /* Main add/subtract of the input operands. */
924 x = expand_binop (word_mode, binoptab,
925 op0_piece, op1_piece,
926 target_piece, unsignedp, next_methods);
927 if (x == 0)
928 break;
930 if (i + 1 < nwords)
932 /* Store carry from main add/subtract. */
933 carry_out = gen_reg_rtx (word_mode);
934 carry_out = emit_store_flag_force (carry_out,
935 (binoptab == add_optab
936 ? LTU : GTU),
937 x, op0_piece,
938 word_mode, 1, normalizep);
941 if (i > 0)
943 /* Add/subtract previous carry to main result. */
944 x = expand_binop (word_mode,
945 normalizep == 1 ? binoptab : otheroptab,
946 x, carry_in,
947 target_piece, 1, next_methods);
948 if (x == 0)
949 break;
950 else if (target_piece != x)
951 emit_move_insn (target_piece, x);
953 if (i + 1 < nwords)
955 /* THIS CODE HAS NOT BEEN TESTED. */
956 /* Get out carry from adding/subtracting carry in. */
957 carry_tmp = emit_store_flag_force (carry_tmp,
958 binoptab == add_optab
959 ? LTU : GTU,
960 x, carry_in,
961 word_mode, 1, normalizep);
963 /* Logical-ior the two poss. carry together. */
964 carry_out = expand_binop (word_mode, ior_optab,
965 carry_out, carry_tmp,
966 carry_out, 0, next_methods);
967 if (carry_out == 0)
968 break;
972 carry_in = carry_out;
975 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
977 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
979 rtx temp = emit_move_insn (target, target);
981 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
982 gen_rtx (binoptab->code, mode,
983 copy_rtx (xop0),
984 copy_rtx (xop1)),
985 REG_NOTES (temp));
987 return target;
989 else
990 delete_insns_since (last);
993 /* If we want to multiply two two-word values and have normal and widening
994 multiplies of single-word values, we can do this with three smaller
995 multiplications. Note that we do not make a REG_NO_CONFLICT block here
996 because we are not operating on one word at a time.
998 The multiplication proceeds as follows:
999 _______________________
1000 [__op0_high_|__op0_low__]
1001 _______________________
1002 * [__op1_high_|__op1_low__]
1003 _______________________________________________
1004 _______________________
1005 (1) [__op0_low__*__op1_low__]
1006 _______________________
1007 (2a) [__op0_low__*__op1_high_]
1008 _______________________
1009 (2b) [__op0_high_*__op1_low__]
1010 _______________________
1011 (3) [__op0_high_*__op1_high_]
1014 This gives a 4-word result. Since we are only interested in the
1015 lower 2 words, partial result (3) and the upper words of (2a) and
1016 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1017 calculated using non-widening multiplication.
1019 (1), however, needs to be calculated with an unsigned widening
1020 multiplication. If this operation is not directly supported we
1021 try using a signed widening multiplication and adjust the result.
1022 This adjustment works as follows:
1024 If both operands are positive then no adjustment is needed.
1026 If the operands have different signs, for example op0_low < 0 and
1027 op1_low >= 0, the instruction treats the most significant bit of
1028 op0_low as a sign bit instead of a bit with significance
1029 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1030 with 2**BITS_PER_WORD - op0_low, and two's complements the
1031 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1032 the result.
1034 Similarly, if both operands are negative, we need to add
1035 (op0_low + op1_low) * 2**BITS_PER_WORD.
1037 We use a trick to adjust quickly. We logically shift op0_low right
1038 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1039 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1040 logical shift exists, we do an arithmetic right shift and subtract
1041 the 0 or -1. */
1043 if (binoptab == smul_optab
1044 && class == MODE_INT
1045 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1046 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1047 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1048 && ((umul_widen_optab->handlers[(int) mode].insn_code
1049 != CODE_FOR_nothing)
1050 || (smul_widen_optab->handlers[(int) mode].insn_code
1051 != CODE_FOR_nothing)))
1053 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1054 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1055 rtx op0_high = operand_subword_force (op0, high, mode);
1056 rtx op0_low = operand_subword_force (op0, low, mode);
1057 rtx op1_high = operand_subword_force (op1, high, mode);
1058 rtx op1_low = operand_subword_force (op1, low, mode);
1059 rtx product = 0;
1060 rtx op0_xhigh;
1061 rtx op1_xhigh;
1063 /* If the target is the same as one of the inputs, don't use it. This
1064 prevents problems with the REG_EQUAL note. */
1065 if (target == op0 || target == op1
1066 || (target != 0 && GET_CODE (target) != REG))
1067 target = 0;
1069 /* Multiply the two lower words to get a double-word product.
1070 If unsigned widening multiplication is available, use that;
1071 otherwise use the signed form and compensate. */
1073 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1075 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1076 target, 1, OPTAB_DIRECT);
1078 /* If we didn't succeed, delete everything we did so far. */
1079 if (product == 0)
1080 delete_insns_since (last);
1081 else
1082 op0_xhigh = op0_high, op1_xhigh = op1_high;
1085 if (product == 0
1086 && smul_widen_optab->handlers[(int) mode].insn_code
1087 != CODE_FOR_nothing)
1089 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1090 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1091 target, 1, OPTAB_DIRECT);
1092 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1093 NULL_RTX, 1, next_methods);
1094 if (op0_xhigh)
1095 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1096 op0_xhigh, op0_xhigh, 0, next_methods);
1097 else
1099 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1100 NULL_RTX, 0, next_methods);
1101 if (op0_xhigh)
1102 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1103 op0_xhigh, op0_xhigh, 0,
1104 next_methods);
1107 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1108 NULL_RTX, 1, next_methods);
1109 if (op1_xhigh)
1110 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1111 op1_xhigh, op1_xhigh, 0, next_methods);
1112 else
1114 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1115 NULL_RTX, 0, next_methods);
1116 if (op1_xhigh)
1117 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1118 op1_xhigh, op1_xhigh, 0,
1119 next_methods);
1123 /* If we have been able to directly compute the product of the
1124 low-order words of the operands and perform any required adjustments
1125 of the operands, we proceed by trying two more multiplications
1126 and then computing the appropriate sum.
1128 We have checked above that the required addition is provided.
1129 Full-word addition will normally always succeed, especially if
1130 it is provided at all, so we don't worry about its failure. The
1131 multiplication may well fail, however, so we do handle that. */
1133 if (product && op0_xhigh && op1_xhigh)
1135 rtx product_high = operand_subword (product, high, 1, mode);
1136 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1137 NULL_RTX, 0, OPTAB_DIRECT);
1139 if (temp != 0)
1140 temp = expand_binop (word_mode, add_optab, temp, product_high,
1141 product_high, 0, next_methods);
1143 if (temp != 0 && temp != product_high)
1144 emit_move_insn (product_high, temp);
1146 if (temp != 0)
1147 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1148 NULL_RTX, 0, OPTAB_DIRECT);
1150 if (temp != 0)
1151 temp = expand_binop (word_mode, add_optab, temp,
1152 product_high, product_high,
1153 0, next_methods);
1155 if (temp != 0 && temp != product_high)
1156 emit_move_insn (product_high, temp);
1158 if (temp != 0)
1160 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1162 temp = emit_move_insn (product, product);
1163 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1164 gen_rtx (MULT, mode,
1165 copy_rtx (op0),
1166 copy_rtx (op1)),
1167 REG_NOTES (temp));
1169 return product;
1173 /* If we get here, we couldn't do it for some reason even though we
1174 originally thought we could. Delete anything we've emitted in
1175 trying to do it. */
1177 delete_insns_since (last);
1180 /* We need to open-code the complex type operations: '+, -, * and /' */
1182 /* At this point we allow operations between two similar complex
1183 numbers, and also if one of the operands is not a complex number
1184 but rather of MODE_FLOAT or MODE_INT. However, the caller
1185 must make sure that the MODE of the non-complex operand matches
1186 the SUBMODE of the complex operand. */
1188 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1190 rtx real0 = 0, imag0 = 0;
1191 rtx real1 = 0, imag1 = 0;
1192 rtx realr, imagr, res;
1193 rtx seq;
1194 rtx equiv_value;
1195 int ok = 0;
1197 /* Find the correct mode for the real and imaginary parts */
1198 enum machine_mode submode
1199 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1200 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1203 if (submode == BLKmode)
1204 abort ();
1206 if (! target)
1207 target = gen_reg_rtx (mode);
1209 start_sequence ();
1211 realr = gen_realpart (submode, target);
1212 imagr = gen_imagpart (submode, target);
1214 if (GET_MODE (op0) == mode)
1216 real0 = gen_realpart (submode, op0);
1217 imag0 = gen_imagpart (submode, op0);
1219 else
1220 real0 = op0;
1222 if (GET_MODE (op1) == mode)
1224 real1 = gen_realpart (submode, op1);
1225 imag1 = gen_imagpart (submode, op1);
1227 else
1228 real1 = op1;
1230 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1231 abort ();
1233 switch (binoptab->code)
1235 case PLUS:
1236 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1237 case MINUS:
1238 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1239 res = expand_binop (submode, binoptab, real0, real1,
1240 realr, unsignedp, methods);
1242 if (res == 0)
1243 break;
1244 else if (res != realr)
1245 emit_move_insn (realr, res);
1247 if (imag0 && imag1)
1248 res = expand_binop (submode, binoptab, imag0, imag1,
1249 imagr, unsignedp, methods);
1250 else if (imag0)
1251 res = imag0;
1252 else if (binoptab->code == MINUS)
1253 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1254 else
1255 res = imag1;
1257 if (res == 0)
1258 break;
1259 else if (res != imagr)
1260 emit_move_insn (imagr, res);
1262 ok = 1;
1263 break;
1265 case MULT:
1266 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1268 if (imag0 && imag1)
1270 rtx temp1, temp2;
1272 /* Don't fetch these from memory more than once. */
1273 real0 = force_reg (submode, real0);
1274 real1 = force_reg (submode, real1);
1275 imag0 = force_reg (submode, imag0);
1276 imag1 = force_reg (submode, imag1);
1278 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1279 unsignedp, methods);
1281 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1282 unsignedp, methods);
1284 if (temp1 == 0 || temp2 == 0)
1285 break;
1287 res = expand_binop (submode, sub_optab, temp1, temp2,
1288 realr, unsignedp, methods);
1290 if (res == 0)
1291 break;
1292 else if (res != realr)
1293 emit_move_insn (realr, res);
1295 temp1 = expand_binop (submode, binoptab, real0, imag1,
1296 NULL_RTX, unsignedp, methods);
1298 temp2 = expand_binop (submode, binoptab, real1, imag0,
1299 NULL_RTX, unsignedp, methods);
1301 if (temp1 == 0 || temp2 == 0)
1302 break;
1304 res = expand_binop (submode, add_optab, temp1, temp2,
1305 imagr, unsignedp, methods);
1307 if (res == 0)
1308 break;
1309 else if (res != imagr)
1310 emit_move_insn (imagr, res);
1312 ok = 1;
1314 else
1316 /* Don't fetch these from memory more than once. */
1317 real0 = force_reg (submode, real0);
1318 real1 = force_reg (submode, real1);
1320 res = expand_binop (submode, binoptab, real0, real1,
1321 realr, unsignedp, methods);
1322 if (res == 0)
1323 break;
1324 else if (res != realr)
1325 emit_move_insn (realr, res);
1327 if (imag0 != 0)
1328 res = expand_binop (submode, binoptab,
1329 real1, imag0, imagr, unsignedp, methods);
1330 else
1331 res = expand_binop (submode, binoptab,
1332 real0, imag1, imagr, unsignedp, methods);
1334 if (res == 0)
1335 break;
1336 else if (res != imagr)
1337 emit_move_insn (imagr, res);
1339 ok = 1;
1341 break;
1343 case DIV:
1344 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1346 if (imag1 == 0)
1348 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1350 /* Don't fetch these from memory more than once. */
1351 real1 = force_reg (submode, real1);
1353 /* Simply divide the real and imaginary parts by `c' */
1354 if (class == MODE_COMPLEX_FLOAT)
1355 res = expand_binop (submode, binoptab, real0, real1,
1356 realr, unsignedp, methods);
1357 else
1358 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1359 real0, real1, realr, unsignedp);
1361 if (res == 0)
1362 break;
1363 else if (res != realr)
1364 emit_move_insn (realr, res);
1366 if (class == MODE_COMPLEX_FLOAT)
1367 res = expand_binop (submode, binoptab, imag0, real1,
1368 imagr, unsignedp, methods);
1369 else
1370 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1371 imag0, real1, imagr, unsignedp);
1373 if (res == 0)
1374 break;
1375 else if (res != imagr)
1376 emit_move_insn (imagr, res);
1378 ok = 1;
1380 else
1382 /* Divisor is of complex type:
1383 X/(a+ib) */
1384 rtx divisor;
1385 rtx real_t, imag_t;
1386 rtx temp1, temp2;
1388 /* Don't fetch these from memory more than once. */
1389 real0 = force_reg (submode, real0);
1390 real1 = force_reg (submode, real1);
1392 if (imag0 != 0)
1393 imag0 = force_reg (submode, imag0);
1395 imag1 = force_reg (submode, imag1);
1397 /* Divisor: c*c + d*d */
1398 temp1 = expand_binop (submode, smul_optab, real1, real1,
1399 NULL_RTX, unsignedp, methods);
1401 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1402 NULL_RTX, unsignedp, methods);
1404 if (temp1 == 0 || temp2 == 0)
1405 break;
1407 divisor = expand_binop (submode, add_optab, temp1, temp2,
1408 NULL_RTX, unsignedp, methods);
1409 if (divisor == 0)
1410 break;
1412 if (imag0 == 0)
1414 /* ((a)(c-id))/divisor */
1415 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1417 /* Calculate the dividend */
1418 real_t = expand_binop (submode, smul_optab, real0, real1,
1419 NULL_RTX, unsignedp, methods);
1421 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1422 NULL_RTX, unsignedp, methods);
1424 if (real_t == 0 || imag_t == 0)
1425 break;
1427 imag_t = expand_unop (submode, neg_optab, imag_t,
1428 NULL_RTX, unsignedp);
1430 else
1432 /* ((a+ib)(c-id))/divider */
1433 /* Calculate the dividend */
1434 temp1 = expand_binop (submode, smul_optab, real0, real1,
1435 NULL_RTX, unsignedp, methods);
1437 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1438 NULL_RTX, unsignedp, methods);
1440 if (temp1 == 0 || temp2 == 0)
1441 break;
1443 real_t = expand_binop (submode, add_optab, temp1, temp2,
1444 NULL_RTX, unsignedp, methods);
1446 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1447 NULL_RTX, unsignedp, methods);
1449 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1450 NULL_RTX, unsignedp, methods);
1452 if (temp1 == 0 || temp2 == 0)
1453 break;
1455 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1456 NULL_RTX, unsignedp, methods);
1458 if (real_t == 0 || imag_t == 0)
1459 break;
1462 if (class == MODE_COMPLEX_FLOAT)
1463 res = expand_binop (submode, binoptab, real_t, divisor,
1464 realr, unsignedp, methods);
1465 else
1466 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1467 real_t, divisor, realr, unsignedp);
1469 if (res == 0)
1470 break;
1471 else if (res != realr)
1472 emit_move_insn (realr, res);
1474 if (class == MODE_COMPLEX_FLOAT)
1475 res = expand_binop (submode, binoptab, imag_t, divisor,
1476 imagr, unsignedp, methods);
1477 else
1478 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1479 imag_t, divisor, imagr, unsignedp);
1481 if (res == 0)
1482 break;
1483 else if (res != imagr)
1484 emit_move_insn (imagr, res);
1486 ok = 1;
1488 break;
1490 default:
1491 abort ();
1494 seq = get_insns ();
1495 end_sequence ();
1497 if (ok)
1499 if (binoptab->code != UNKNOWN)
1500 equiv_value
1501 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1502 else
1503 equiv_value = 0;
1505 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1507 return target;
1511 /* It can't be open-coded in this mode.
1512 Use a library call if one is available and caller says that's ok. */
1514 if (binoptab->handlers[(int) mode].libfunc
1515 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1517 rtx insns;
1518 rtx op1x = op1;
1519 enum machine_mode op1_mode = mode;
1520 rtx value;
1522 start_sequence ();
1524 if (shift_op)
1526 op1_mode = word_mode;
1527 /* Specify unsigned here,
1528 since negative shift counts are meaningless. */
1529 op1x = convert_to_mode (word_mode, op1, 1);
1532 if (GET_MODE (op0) != VOIDmode
1533 && GET_MODE (op0) != mode)
1534 op0 = convert_to_mode (mode, op0, unsignedp);
1536 /* Pass 1 for NO_QUEUE so we don't lose any increments
1537 if the libcall is cse'd or moved. */
1538 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1539 NULL_RTX, 1, mode, 2,
1540 op0, mode, op1x, op1_mode);
1542 insns = get_insns ();
1543 end_sequence ();
1545 target = gen_reg_rtx (mode);
1546 emit_libcall_block (insns, target, value,
1547 gen_rtx (binoptab->code, mode, op0, op1));
1549 return target;
1552 delete_insns_since (last);
1554 /* It can't be done in this mode. Can we do it in a wider mode? */
1556 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1557 || methods == OPTAB_MUST_WIDEN))
1559 /* Caller says, don't even try. */
1560 delete_insns_since (entry_last);
1561 return 0;
1564 /* Compute the value of METHODS to pass to recursive calls.
1565 Don't allow widening to be tried recursively. */
1567 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1569 /* Look for a wider mode of the same class for which it appears we can do
1570 the operation. */
1572 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1574 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1575 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1577 if ((binoptab->handlers[(int) wider_mode].insn_code
1578 != CODE_FOR_nothing)
1579 || (methods == OPTAB_LIB
1580 && binoptab->handlers[(int) wider_mode].libfunc))
1582 rtx xop0 = op0, xop1 = op1;
1583 int no_extend = 0;
1585 /* For certain integer operations, we need not actually extend
1586 the narrow operands, as long as we will truncate
1587 the results to the same narrowness. */
1589 if ((binoptab == ior_optab || binoptab == and_optab
1590 || binoptab == xor_optab
1591 || binoptab == add_optab || binoptab == sub_optab
1592 || binoptab == smul_optab || binoptab == ashl_optab)
1593 && class == MODE_INT)
1594 no_extend = 1;
1596 xop0 = widen_operand (xop0, wider_mode, mode,
1597 unsignedp, no_extend);
1599 /* The second operand of a shift must always be extended. */
1600 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1601 no_extend && binoptab != ashl_optab);
1603 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1604 unsignedp, methods);
1605 if (temp)
1607 if (class != MODE_INT)
1609 if (target == 0)
1610 target = gen_reg_rtx (mode);
1611 convert_move (target, temp, 0);
1612 return target;
1614 else
1615 return gen_lowpart (mode, temp);
1617 else
1618 delete_insns_since (last);
1623 delete_insns_since (entry_last);
1624 return 0;
1627 /* Expand a binary operator which has both signed and unsigned forms.
1628 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1629 signed operations.
1631 If we widen unsigned operands, we may use a signed wider operation instead
1632 of an unsigned wider operation, since the result would be the same. */
1635 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1636 enum machine_mode mode;
1637 optab uoptab, soptab;
1638 rtx op0, op1, target;
1639 int unsignedp;
1640 enum optab_methods methods;
1642 register rtx temp;
1643 optab direct_optab = unsignedp ? uoptab : soptab;
1644 struct optab wide_soptab;
1646 /* Do it without widening, if possible. */
1647 temp = expand_binop (mode, direct_optab, op0, op1, target,
1648 unsignedp, OPTAB_DIRECT);
1649 if (temp || methods == OPTAB_DIRECT)
1650 return temp;
1652 /* Try widening to a signed int. Make a fake signed optab that
1653 hides any signed insn for direct use. */
1654 wide_soptab = *soptab;
1655 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1656 wide_soptab.handlers[(int) mode].libfunc = 0;
1658 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1659 unsignedp, OPTAB_WIDEN);
1661 /* For unsigned operands, try widening to an unsigned int. */
1662 if (temp == 0 && unsignedp)
1663 temp = expand_binop (mode, uoptab, op0, op1, target,
1664 unsignedp, OPTAB_WIDEN);
1665 if (temp || methods == OPTAB_WIDEN)
1666 return temp;
1668 /* Use the right width lib call if that exists. */
1669 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1670 if (temp || methods == OPTAB_LIB)
1671 return temp;
1673 /* Must widen and use a lib call, use either signed or unsigned. */
1674 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1675 unsignedp, methods);
1676 if (temp != 0)
1677 return temp;
1678 if (unsignedp)
1679 return expand_binop (mode, uoptab, op0, op1, target,
1680 unsignedp, methods);
1681 return 0;
1684 /* Generate code to perform an operation specified by BINOPTAB
1685 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1686 We assume that the order of the operands for the instruction
1687 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1688 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1690 Either TARG0 or TARG1 may be zero, but what that means is that
1691 the result is not actually wanted. We will generate it into
1692 a dummy pseudo-reg and discard it. They may not both be zero.
1694 Returns 1 if this operation can be performed; 0 if not. */
1697 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1698 optab binoptab;
1699 rtx op0, op1;
1700 rtx targ0, targ1;
1701 int unsignedp;
1703 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1704 enum mode_class class;
1705 enum machine_mode wider_mode;
1706 rtx entry_last = get_last_insn ();
1707 rtx last;
1709 class = GET_MODE_CLASS (mode);
1711 op0 = protect_from_queue (op0, 0);
1712 op1 = protect_from_queue (op1, 0);
1714 if (flag_force_mem)
1716 op0 = force_not_mem (op0);
1717 op1 = force_not_mem (op1);
1720 /* If we are inside an appropriately-short loop and one operand is an
1721 expensive constant, force it into a register. */
1722 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1723 && rtx_cost (op0, binoptab->code) > 2)
1724 op0 = force_reg (mode, op0);
1726 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1727 && rtx_cost (op1, binoptab->code) > 2)
1728 op1 = force_reg (mode, op1);
1730 if (targ0)
1731 targ0 = protect_from_queue (targ0, 1);
1732 else
1733 targ0 = gen_reg_rtx (mode);
1734 if (targ1)
1735 targ1 = protect_from_queue (targ1, 1);
1736 else
1737 targ1 = gen_reg_rtx (mode);
1739 /* Record where to go back to if we fail. */
1740 last = get_last_insn ();
1742 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1744 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1745 enum machine_mode mode0 = insn_operand_mode[icode][1];
1746 enum machine_mode mode1 = insn_operand_mode[icode][2];
1747 rtx pat;
1748 rtx xop0 = op0, xop1 = op1;
1750 /* In case this insn wants input operands in modes different from the
1751 result, convert the operands. */
1752 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1753 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1755 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1756 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1758 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1759 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1760 xop0 = copy_to_mode_reg (mode0, xop0);
1762 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1763 xop1 = copy_to_mode_reg (mode1, xop1);
1765 /* We could handle this, but we should always be called with a pseudo
1766 for our targets and all insns should take them as outputs. */
1767 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1768 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1769 abort ();
1771 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1772 if (pat)
1774 emit_insn (pat);
1775 return 1;
1777 else
1778 delete_insns_since (last);
1781 /* It can't be done in this mode. Can we do it in a wider mode? */
1783 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1785 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1786 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1788 if (binoptab->handlers[(int) wider_mode].insn_code
1789 != CODE_FOR_nothing)
1791 register rtx t0 = gen_reg_rtx (wider_mode);
1792 register rtx t1 = gen_reg_rtx (wider_mode);
1794 if (expand_twoval_binop (binoptab,
1795 convert_modes (wider_mode, mode, op0,
1796 unsignedp),
1797 convert_modes (wider_mode, mode, op1,
1798 unsignedp),
1799 t0, t1, unsignedp))
1801 convert_move (targ0, t0, unsignedp);
1802 convert_move (targ1, t1, unsignedp);
1803 return 1;
1805 else
1806 delete_insns_since (last);
1811 delete_insns_since (entry_last);
1812 return 0;
1815 /* Generate code to perform an operation specified by UNOPTAB
1816 on operand OP0, with result having machine-mode MODE.
1818 UNSIGNEDP is for the case where we have to widen the operands
1819 to perform the operation. It says to use zero-extension.
1821 If TARGET is nonzero, the value
1822 is generated there, if it is convenient to do so.
1823 In all cases an rtx is returned for the locus of the value;
1824 this may or may not be TARGET. */
1827 expand_unop (mode, unoptab, op0, target, unsignedp)
1828 enum machine_mode mode;
1829 optab unoptab;
1830 rtx op0;
1831 rtx target;
1832 int unsignedp;
1834 enum mode_class class;
1835 enum machine_mode wider_mode;
1836 register rtx temp;
1837 rtx last = get_last_insn ();
1838 rtx pat;
1840 class = GET_MODE_CLASS (mode);
1842 op0 = protect_from_queue (op0, 0);
1844 if (flag_force_mem)
1846 op0 = force_not_mem (op0);
1849 if (target)
1850 target = protect_from_queue (target, 1);
1852 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1854 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1855 enum machine_mode mode0 = insn_operand_mode[icode][1];
1856 rtx xop0 = op0;
1858 if (target)
1859 temp = target;
1860 else
1861 temp = gen_reg_rtx (mode);
1863 if (GET_MODE (xop0) != VOIDmode
1864 && GET_MODE (xop0) != mode0)
1865 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1867 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1869 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1870 xop0 = copy_to_mode_reg (mode0, xop0);
1872 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1873 temp = gen_reg_rtx (mode);
1875 pat = GEN_FCN (icode) (temp, xop0);
1876 if (pat)
1878 if (GET_CODE (pat) == SEQUENCE
1879 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1881 delete_insns_since (last);
1882 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1885 emit_insn (pat);
1887 return temp;
1889 else
1890 delete_insns_since (last);
1893 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1895 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1896 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1897 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1899 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1901 rtx xop0 = op0;
1903 /* For certain operations, we need not actually extend
1904 the narrow operand, as long as we will truncate the
1905 results to the same narrowness. */
1907 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1908 (unoptab == neg_optab
1909 || unoptab == one_cmpl_optab)
1910 && class == MODE_INT);
1912 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1913 unsignedp);
1915 if (temp)
1917 if (class != MODE_INT)
1919 if (target == 0)
1920 target = gen_reg_rtx (mode);
1921 convert_move (target, temp, 0);
1922 return target;
1924 else
1925 return gen_lowpart (mode, temp);
1927 else
1928 delete_insns_since (last);
1932 /* These can be done a word at a time. */
1933 if (unoptab == one_cmpl_optab
1934 && class == MODE_INT
1935 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1936 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1938 int i;
1939 rtx insns;
1941 if (target == 0 || target == op0)
1942 target = gen_reg_rtx (mode);
1944 start_sequence ();
1946 /* Do the actual arithmetic. */
1947 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1949 rtx target_piece = operand_subword (target, i, 1, mode);
1950 rtx x = expand_unop (word_mode, unoptab,
1951 operand_subword_force (op0, i, mode),
1952 target_piece, unsignedp);
1953 if (target_piece != x)
1954 emit_move_insn (target_piece, x);
1957 insns = get_insns ();
1958 end_sequence ();
1960 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1961 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1962 return target;
1965 /* Open-code the complex negation operation. */
1966 else if (unoptab == neg_optab
1967 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1969 rtx target_piece;
1970 rtx x;
1971 rtx seq;
1973 /* Find the correct mode for the real and imaginary parts */
1974 enum machine_mode submode
1975 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1976 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1979 if (submode == BLKmode)
1980 abort ();
1982 if (target == 0)
1983 target = gen_reg_rtx (mode);
1985 start_sequence ();
1987 target_piece = gen_imagpart (submode, target);
1988 x = expand_unop (submode, unoptab,
1989 gen_imagpart (submode, op0),
1990 target_piece, unsignedp);
1991 if (target_piece != x)
1992 emit_move_insn (target_piece, x);
1994 target_piece = gen_realpart (submode, target);
1995 x = expand_unop (submode, unoptab,
1996 gen_realpart (submode, op0),
1997 target_piece, unsignedp);
1998 if (target_piece != x)
1999 emit_move_insn (target_piece, x);
2001 seq = get_insns ();
2002 end_sequence ();
2004 emit_no_conflict_block (seq, target, op0, 0,
2005 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
2006 return target;
2009 /* Now try a library call in this mode. */
2010 if (unoptab->handlers[(int) mode].libfunc)
2012 rtx insns;
2013 rtx value;
2015 start_sequence ();
2017 /* Pass 1 for NO_QUEUE so we don't lose any increments
2018 if the libcall is cse'd or moved. */
2019 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2020 NULL_RTX, 1, mode, 1, op0, mode);
2021 insns = get_insns ();
2022 end_sequence ();
2024 target = gen_reg_rtx (mode);
2025 emit_libcall_block (insns, target, value,
2026 gen_rtx (unoptab->code, mode, op0));
2028 return target;
2031 /* It can't be done in this mode. Can we do it in a wider mode? */
2033 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2035 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2036 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2038 if ((unoptab->handlers[(int) wider_mode].insn_code
2039 != CODE_FOR_nothing)
2040 || unoptab->handlers[(int) wider_mode].libfunc)
2042 rtx xop0 = op0;
2044 /* For certain operations, we need not actually extend
2045 the narrow operand, as long as we will truncate the
2046 results to the same narrowness. */
2048 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2049 (unoptab == neg_optab
2050 || unoptab == one_cmpl_optab)
2051 && class == MODE_INT);
2053 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2054 unsignedp);
2056 if (temp)
2058 if (class != MODE_INT)
2060 if (target == 0)
2061 target = gen_reg_rtx (mode);
2062 convert_move (target, temp, 0);
2063 return target;
2065 else
2066 return gen_lowpart (mode, temp);
2068 else
2069 delete_insns_since (last);
2074 /* If there is no negate operation, try doing a subtract from zero.
2075 The US Software GOFAST library needs this. */
2076 if (unoptab == neg_optab)
2078 rtx temp;
2079 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2080 target, unsignedp, OPTAB_LIB_WIDEN);
2081 if (temp)
2082 return temp;
2085 return 0;
2088 /* Emit code to compute the absolute value of OP0, with result to
2089 TARGET if convenient. (TARGET may be 0.) The return value says
2090 where the result actually is to be found.
2092 MODE is the mode of the operand; the mode of the result is
2093 different but can be deduced from MODE.
2095 UNSIGNEDP is relevant if extension is needed. */
2098 expand_abs (mode, op0, target, unsignedp, safe)
2099 enum machine_mode mode;
2100 rtx op0;
2101 rtx target;
2102 int unsignedp;
2103 int safe;
2105 rtx temp, op1;
2107 /* First try to do it with a special abs instruction. */
2108 temp = expand_unop (mode, abs_optab, op0, target, 0);
2109 if (temp != 0)
2110 return temp;
2112 /* If this machine has expensive jumps, we can do integer absolute
2113 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2114 where W is the width of MODE. */
2116 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2118 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2119 size_int (GET_MODE_BITSIZE (mode) - 1),
2120 NULL_RTX, 0);
2122 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2123 OPTAB_LIB_WIDEN);
2124 if (temp != 0)
2125 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2126 OPTAB_LIB_WIDEN);
2128 if (temp != 0)
2129 return temp;
2132 /* If that does not win, use conditional jump and negate. */
2134 /* It is safe to use the target if it is the same
2135 as the source if this is also a pseudo register */
2136 if (op0 == target && GET_CODE (op0) == REG
2137 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2138 safe = 1;
2140 op1 = gen_label_rtx ();
2141 if (target == 0 || ! safe
2142 || GET_MODE (target) != mode
2143 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2144 || (GET_CODE (target) == REG
2145 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2146 target = gen_reg_rtx (mode);
2148 emit_move_insn (target, op0);
2149 NO_DEFER_POP;
2151 /* If this mode is an integer too wide to compare properly,
2152 compare word by word. Rely on CSE to optimize constant cases. */
2153 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2154 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2155 NULL_RTX, op1);
2156 else
2158 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2159 NULL_RTX, 0);
2160 if (temp == const1_rtx)
2161 return target;
2162 else if (temp != const0_rtx)
2164 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2165 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2166 else
2167 abort ();
2171 op0 = expand_unop (mode, neg_optab, target, target, 0);
2172 if (op0 != target)
2173 emit_move_insn (target, op0);
2174 emit_label (op1);
2175 OK_DEFER_POP;
2176 return target;
2179 /* Emit code to compute the absolute value of OP0, with result to
2180 TARGET if convenient. (TARGET may be 0.) The return value says
2181 where the result actually is to be found.
2183 MODE is the mode of the operand; the mode of the result is
2184 different but can be deduced from MODE.
2186 UNSIGNEDP is relevant for complex integer modes. */
2189 expand_complex_abs (mode, op0, target, unsignedp)
2190 enum machine_mode mode;
2191 rtx op0;
2192 rtx target;
2193 int unsignedp;
2195 enum mode_class class = GET_MODE_CLASS (mode);
2196 enum machine_mode wider_mode;
2197 register rtx temp;
2198 rtx entry_last = get_last_insn ();
2199 rtx last;
2200 rtx pat;
2202 /* Find the correct mode for the real and imaginary parts. */
2203 enum machine_mode submode
2204 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2205 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2208 if (submode == BLKmode)
2209 abort ();
2211 op0 = protect_from_queue (op0, 0);
2213 if (flag_force_mem)
2215 op0 = force_not_mem (op0);
2218 last = get_last_insn ();
2220 if (target)
2221 target = protect_from_queue (target, 1);
2223 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2225 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2226 enum machine_mode mode0 = insn_operand_mode[icode][1];
2227 rtx xop0 = op0;
2229 if (target)
2230 temp = target;
2231 else
2232 temp = gen_reg_rtx (submode);
2234 if (GET_MODE (xop0) != VOIDmode
2235 && GET_MODE (xop0) != mode0)
2236 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2238 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2240 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2241 xop0 = copy_to_mode_reg (mode0, xop0);
2243 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2244 temp = gen_reg_rtx (submode);
2246 pat = GEN_FCN (icode) (temp, xop0);
2247 if (pat)
2249 if (GET_CODE (pat) == SEQUENCE
2250 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2252 delete_insns_since (last);
2253 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2256 emit_insn (pat);
2258 return temp;
2260 else
2261 delete_insns_since (last);
2264 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2266 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2267 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2269 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2271 rtx xop0 = op0;
2273 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2274 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2276 if (temp)
2278 if (class != MODE_COMPLEX_INT)
2280 if (target == 0)
2281 target = gen_reg_rtx (submode);
2282 convert_move (target, temp, 0);
2283 return target;
2285 else
2286 return gen_lowpart (submode, temp);
2288 else
2289 delete_insns_since (last);
2293 /* Open-code the complex absolute-value operation
2294 if we can open-code sqrt. Otherwise it's not worth while. */
2295 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2297 rtx real, imag, total;
2299 real = gen_realpart (submode, op0);
2300 imag = gen_imagpart (submode, op0);
2302 /* Square both parts. */
2303 real = expand_mult (submode, real, real, NULL_RTX, 0);
2304 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2306 /* Sum the parts. */
2307 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2308 0, OPTAB_LIB_WIDEN);
2310 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2311 target = expand_unop (submode, sqrt_optab, total, target, 0);
2312 if (target == 0)
2313 delete_insns_since (last);
2314 else
2315 return target;
2318 /* Now try a library call in this mode. */
2319 if (abs_optab->handlers[(int) mode].libfunc)
2321 rtx insns;
2322 rtx value;
2324 start_sequence ();
2326 /* Pass 1 for NO_QUEUE so we don't lose any increments
2327 if the libcall is cse'd or moved. */
2328 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2329 NULL_RTX, 1, submode, 1, op0, mode);
2330 insns = get_insns ();
2331 end_sequence ();
2333 target = gen_reg_rtx (submode);
2334 emit_libcall_block (insns, target, value,
2335 gen_rtx (abs_optab->code, mode, op0));
2337 return target;
2340 /* It can't be done in this mode. Can we do it in a wider mode? */
2342 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2343 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2345 if ((abs_optab->handlers[(int) wider_mode].insn_code
2346 != CODE_FOR_nothing)
2347 || abs_optab->handlers[(int) wider_mode].libfunc)
2349 rtx xop0 = op0;
2351 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2353 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2355 if (temp)
2357 if (class != MODE_COMPLEX_INT)
2359 if (target == 0)
2360 target = gen_reg_rtx (submode);
2361 convert_move (target, temp, 0);
2362 return target;
2364 else
2365 return gen_lowpart (submode, temp);
2367 else
2368 delete_insns_since (last);
2372 delete_insns_since (entry_last);
2373 return 0;
2376 /* Generate an instruction whose insn-code is INSN_CODE,
2377 with two operands: an output TARGET and an input OP0.
2378 TARGET *must* be nonzero, and the output is always stored there.
2379 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2380 the value that is stored into TARGET. */
2382 void
2383 emit_unop_insn (icode, target, op0, code)
2384 int icode;
2385 rtx target;
2386 rtx op0;
2387 enum rtx_code code;
2389 register rtx temp;
2390 enum machine_mode mode0 = insn_operand_mode[icode][1];
2391 rtx pat;
2393 temp = target = protect_from_queue (target, 1);
2395 op0 = protect_from_queue (op0, 0);
2397 /* Sign and zero extension from memory is often done specially on
2398 RISC machines, so forcing into a register here can pessimize
2399 code. */
2400 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2401 op0 = force_not_mem (op0);
2403 /* Now, if insn does not accept our operands, put them into pseudos. */
2405 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2406 op0 = copy_to_mode_reg (mode0, op0);
2408 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2409 || (flag_force_mem && GET_CODE (temp) == MEM))
2410 temp = gen_reg_rtx (GET_MODE (temp));
2412 pat = GEN_FCN (icode) (temp, op0);
2414 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2415 add_equal_note (pat, temp, code, op0, NULL_RTX);
2417 emit_insn (pat);
2419 if (temp != target)
2420 emit_move_insn (target, temp);
2423 /* Emit code to perform a series of operations on a multi-word quantity, one
2424 word at a time.
2426 Such a block is preceded by a CLOBBER of the output, consists of multiple
2427 insns, each setting one word of the output, and followed by a SET copying
2428 the output to itself.
2430 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2431 note indicating that it doesn't conflict with the (also multi-word)
2432 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2433 notes.
2435 INSNS is a block of code generated to perform the operation, not including
2436 the CLOBBER and final copy. All insns that compute intermediate values
2437 are first emitted, followed by the block as described above.
2439 TARGET, OP0, and OP1 are the output and inputs of the operations,
2440 respectively. OP1 may be zero for a unary operation.
2442 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2443 on the last insn.
2445 If TARGET is not a register, INSNS is simply emitted with no special
2446 processing. Likewise if anything in INSNS is not an INSN or if
2447 there is a libcall block inside INSNS.
2449 The final insn emitted is returned. */
2452 emit_no_conflict_block (insns, target, op0, op1, equiv)
2453 rtx insns;
2454 rtx target;
2455 rtx op0, op1;
2456 rtx equiv;
2458 rtx prev, next, first, last, insn;
2460 if (GET_CODE (target) != REG || reload_in_progress)
2461 return emit_insns (insns);
2462 else
2463 for (insn = insns; insn; insn = NEXT_INSN (insn))
2464 if (GET_CODE (insn) != INSN
2465 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2466 return emit_insns (insns);
2468 /* First emit all insns that do not store into words of the output and remove
2469 these from the list. */
2470 for (insn = insns; insn; insn = next)
2472 rtx set = 0;
2473 int i;
2475 next = NEXT_INSN (insn);
2477 if (GET_CODE (PATTERN (insn)) == SET)
2478 set = PATTERN (insn);
2479 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2481 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2482 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2484 set = XVECEXP (PATTERN (insn), 0, i);
2485 break;
2489 if (set == 0)
2490 abort ();
2492 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2494 if (PREV_INSN (insn))
2495 NEXT_INSN (PREV_INSN (insn)) = next;
2496 else
2497 insns = next;
2499 if (next)
2500 PREV_INSN (next) = PREV_INSN (insn);
2502 add_insn (insn);
2506 prev = get_last_insn ();
2508 /* Now write the CLOBBER of the output, followed by the setting of each
2509 of the words, followed by the final copy. */
2510 if (target != op0 && target != op1)
2511 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2513 for (insn = insns; insn; insn = next)
2515 next = NEXT_INSN (insn);
2516 add_insn (insn);
2518 if (op1 && GET_CODE (op1) == REG)
2519 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2520 REG_NOTES (insn));
2522 if (op0 && GET_CODE (op0) == REG)
2523 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2524 REG_NOTES (insn));
2527 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2528 != CODE_FOR_nothing)
2530 last = emit_move_insn (target, target);
2531 if (equiv)
2532 REG_NOTES (last)
2533 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2535 else
2536 last = get_last_insn ();
2538 if (prev == 0)
2539 first = get_insns ();
2540 else
2541 first = NEXT_INSN (prev);
2543 /* Encapsulate the block so it gets manipulated as a unit. */
2544 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2545 REG_NOTES (first));
2546 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2548 return last;
2551 /* Emit code to make a call to a constant function or a library call.
2553 INSNS is a list containing all insns emitted in the call.
2554 These insns leave the result in RESULT. Our block is to copy RESULT
2555 to TARGET, which is logically equivalent to EQUIV.
2557 We first emit any insns that set a pseudo on the assumption that these are
2558 loading constants into registers; doing so allows them to be safely cse'ed
2559 between blocks. Then we emit all the other insns in the block, followed by
2560 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2561 note with an operand of EQUIV.
2563 Moving assignments to pseudos outside of the block is done to improve
2564 the generated code, but is not required to generate correct code,
2565 hence being unable to move an assignment is not grounds for not making
2566 a libcall block. There are two reasons why it is safe to leave these
2567 insns inside the block: First, we know that these pseudos cannot be
2568 used in generated RTL outside the block since they are created for
2569 temporary purposes within the block. Second, CSE will not record the
2570 values of anything set inside a libcall block, so we know they must
2571 be dead at the end of the block.
2573 Except for the first group of insns (the ones setting pseudos), the
2574 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2576 void
2577 emit_libcall_block (insns, target, result, equiv)
2578 rtx insns;
2579 rtx target;
2580 rtx result;
2581 rtx equiv;
2583 rtx prev, next, first, last, insn;
2585 /* First emit all insns that set pseudos. Remove them from the list as
2586 we go. Avoid insns that set pseudos which were referenced in previous
2587 insns. These can be generated by move_by_pieces, for example,
2588 to update an address. Similarly, avoid insns that reference things
2589 set in previous insns. */
2591 for (insn = insns; insn; insn = next)
2593 rtx set = single_set (insn);
2595 next = NEXT_INSN (insn);
2597 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2598 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2599 && (insn == insns
2600 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2601 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2602 && ! modified_in_p (SET_SRC (set), insns)
2603 && ! modified_between_p (SET_SRC (set), insns, insn))))
2605 if (PREV_INSN (insn))
2606 NEXT_INSN (PREV_INSN (insn)) = next;
2607 else
2608 insns = next;
2610 if (next)
2611 PREV_INSN (next) = PREV_INSN (insn);
2613 add_insn (insn);
2617 prev = get_last_insn ();
2619 /* Write the remaining insns followed by the final copy. */
2621 for (insn = insns; insn; insn = next)
2623 next = NEXT_INSN (insn);
2625 add_insn (insn);
2628 last = emit_move_insn (target, result);
2629 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2630 != CODE_FOR_nothing)
2631 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2632 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2634 if (prev == 0)
2635 first = get_insns ();
2636 else
2637 first = NEXT_INSN (prev);
2639 /* Encapsulate the block so it gets manipulated as a unit. */
2640 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2641 REG_NOTES (first));
2642 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2645 /* Generate code to store zero in X. */
2647 void
2648 emit_clr_insn (x)
2649 rtx x;
2651 emit_move_insn (x, const0_rtx);
2654 /* Generate code to store 1 in X
2655 assuming it contains zero beforehand. */
2657 void
2658 emit_0_to_1_insn (x)
2659 rtx x;
2661 emit_move_insn (x, const1_rtx);
2664 /* Generate code to compare X with Y
2665 so that the condition codes are set.
2667 MODE is the mode of the inputs (in case they are const_int).
2668 UNSIGNEDP nonzero says that X and Y are unsigned;
2669 this matters if they need to be widened.
2671 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2672 and ALIGN specifies the known shared alignment of X and Y.
2674 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2675 It is ignored for fixed-point and block comparisons;
2676 it is used only for floating-point comparisons. */
2678 void
2679 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2680 rtx x, y;
2681 enum rtx_code comparison;
2682 rtx size;
2683 enum machine_mode mode;
2684 int unsignedp;
2685 int align;
2687 enum mode_class class;
2688 enum machine_mode wider_mode;
2690 class = GET_MODE_CLASS (mode);
2692 /* They could both be VOIDmode if both args are immediate constants,
2693 but we should fold that at an earlier stage.
2694 With no special code here, this will call abort,
2695 reminding the programmer to implement such folding. */
2697 if (mode != BLKmode && flag_force_mem)
2699 x = force_not_mem (x);
2700 y = force_not_mem (y);
2703 /* If we are inside an appropriately-short loop and one operand is an
2704 expensive constant, force it into a register. */
2705 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2706 x = force_reg (mode, x);
2708 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2709 y = force_reg (mode, y);
2711 /* Don't let both operands fail to indicate the mode. */
2712 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2713 x = force_reg (mode, x);
2715 /* Handle all BLKmode compares. */
2717 if (mode == BLKmode)
2719 emit_queue ();
2720 x = protect_from_queue (x, 0);
2721 y = protect_from_queue (y, 0);
2723 if (size == 0)
2724 abort ();
2725 #ifdef HAVE_cmpstrqi
2726 if (HAVE_cmpstrqi
2727 && GET_CODE (size) == CONST_INT
2728 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2730 enum machine_mode result_mode
2731 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2732 rtx result = gen_reg_rtx (result_mode);
2733 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2734 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2735 result_mode, 0, 0);
2737 else
2738 #endif
2739 #ifdef HAVE_cmpstrhi
2740 if (HAVE_cmpstrhi
2741 && GET_CODE (size) == CONST_INT
2742 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2744 enum machine_mode result_mode
2745 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2746 rtx result = gen_reg_rtx (result_mode);
2747 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2748 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2749 result_mode, 0, 0);
2751 else
2752 #endif
2753 #ifdef HAVE_cmpstrsi
2754 if (HAVE_cmpstrsi)
2756 enum machine_mode result_mode
2757 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2758 rtx result = gen_reg_rtx (result_mode);
2759 size = protect_from_queue (size, 0);
2760 emit_insn (gen_cmpstrsi (result, x, y,
2761 convert_to_mode (SImode, size, 1),
2762 GEN_INT (align)));
2763 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2764 result_mode, 0, 0);
2766 else
2767 #endif
2769 rtx result;
2771 #ifdef TARGET_MEM_FUNCTIONS
2772 emit_library_call (memcmp_libfunc, 0,
2773 TYPE_MODE (integer_type_node), 3,
2774 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2775 convert_to_mode (TYPE_MODE (sizetype), size,
2776 TREE_UNSIGNED (sizetype)),
2777 TYPE_MODE (sizetype));
2778 #else
2779 emit_library_call (bcmp_libfunc, 0,
2780 TYPE_MODE (integer_type_node), 3,
2781 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2782 convert_to_mode (TYPE_MODE (integer_type_node),
2783 size,
2784 TREE_UNSIGNED (integer_type_node)),
2785 TYPE_MODE (integer_type_node));
2786 #endif
2788 /* Immediately move the result of the libcall into a pseudo
2789 register so reload doesn't clobber the value if it needs
2790 the return register for a spill reg. */
2791 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
2792 emit_move_insn (result,
2793 hard_libcall_value (TYPE_MODE (integer_type_node)));
2794 emit_cmp_insn (result,
2795 const0_rtx, comparison, NULL_RTX,
2796 TYPE_MODE (integer_type_node), 0, 0);
2798 return;
2801 /* Handle some compares against zero. */
2803 if (y == CONST0_RTX (mode)
2804 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2806 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2808 emit_queue ();
2809 x = protect_from_queue (x, 0);
2810 y = protect_from_queue (y, 0);
2812 /* Now, if insn does accept these operands, put them into pseudos. */
2813 if (! (*insn_operand_predicate[icode][0])
2814 (x, insn_operand_mode[icode][0]))
2815 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2817 emit_insn (GEN_FCN (icode) (x));
2818 return;
2821 /* Handle compares for which there is a directly suitable insn. */
2823 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2825 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2827 emit_queue ();
2828 x = protect_from_queue (x, 0);
2829 y = protect_from_queue (y, 0);
2831 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2832 if (! (*insn_operand_predicate[icode][0])
2833 (x, insn_operand_mode[icode][0]))
2834 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2836 if (! (*insn_operand_predicate[icode][1])
2837 (y, insn_operand_mode[icode][1]))
2838 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2840 emit_insn (GEN_FCN (icode) (x, y));
2841 return;
2844 /* Try widening if we can find a direct insn that way. */
2846 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2848 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2849 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2851 if (cmp_optab->handlers[(int) wider_mode].insn_code
2852 != CODE_FOR_nothing)
2854 x = protect_from_queue (x, 0);
2855 y = protect_from_queue (y, 0);
2856 x = convert_modes (wider_mode, mode, x, unsignedp);
2857 y = convert_modes (wider_mode, mode, y, unsignedp);
2858 emit_cmp_insn (x, y, comparison, NULL_RTX,
2859 wider_mode, unsignedp, align);
2860 return;
2865 /* Handle a lib call just for the mode we are using. */
2867 if (cmp_optab->handlers[(int) mode].libfunc
2868 && class != MODE_FLOAT)
2870 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2871 rtx result;
2873 /* If we want unsigned, and this mode has a distinct unsigned
2874 comparison routine, use that. */
2875 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2876 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2878 emit_library_call (libfunc, 1,
2879 word_mode, 2, x, mode, y, mode);
2881 /* Immediately move the result of the libcall into a pseudo
2882 register so reload doesn't clobber the value if it needs
2883 the return register for a spill reg. */
2884 result = gen_reg_rtx (word_mode);
2885 emit_move_insn (result, hard_libcall_value (word_mode));
2887 /* Integer comparison returns a result that must be compared against 1,
2888 so that even if we do an unsigned compare afterward,
2889 there is still a value that can represent the result "less than". */
2890 emit_cmp_insn (result, const1_rtx,
2891 comparison, NULL_RTX, word_mode, unsignedp, 0);
2892 return;
2895 if (class == MODE_FLOAT)
2896 emit_float_lib_cmp (x, y, comparison);
2898 else
2899 abort ();
2902 /* Nonzero if a compare of mode MODE can be done straightforwardly
2903 (without splitting it into pieces). */
2906 can_compare_p (mode)
2907 enum machine_mode mode;
2911 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2912 return 1;
2913 mode = GET_MODE_WIDER_MODE (mode);
2914 } while (mode != VOIDmode);
2916 return 0;
2919 /* Emit a library call comparison between floating point X and Y.
2920 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2922 void
2923 emit_float_lib_cmp (x, y, comparison)
2924 rtx x, y;
2925 enum rtx_code comparison;
2927 enum machine_mode mode = GET_MODE (x);
2928 rtx libfunc = 0;
2929 rtx result;
2931 if (mode == HFmode)
2932 switch (comparison)
2934 case EQ:
2935 libfunc = eqhf2_libfunc;
2936 break;
2938 case NE:
2939 libfunc = nehf2_libfunc;
2940 break;
2942 case GT:
2943 libfunc = gthf2_libfunc;
2944 break;
2946 case GE:
2947 libfunc = gehf2_libfunc;
2948 break;
2950 case LT:
2951 libfunc = lthf2_libfunc;
2952 break;
2954 case LE:
2955 libfunc = lehf2_libfunc;
2956 break;
2958 default:
2959 break;
2961 else if (mode == SFmode)
2962 switch (comparison)
2964 case EQ:
2965 libfunc = eqsf2_libfunc;
2966 break;
2968 case NE:
2969 libfunc = nesf2_libfunc;
2970 break;
2972 case GT:
2973 libfunc = gtsf2_libfunc;
2974 break;
2976 case GE:
2977 libfunc = gesf2_libfunc;
2978 break;
2980 case LT:
2981 libfunc = ltsf2_libfunc;
2982 break;
2984 case LE:
2985 libfunc = lesf2_libfunc;
2986 break;
2988 default:
2989 break;
2991 else if (mode == DFmode)
2992 switch (comparison)
2994 case EQ:
2995 libfunc = eqdf2_libfunc;
2996 break;
2998 case NE:
2999 libfunc = nedf2_libfunc;
3000 break;
3002 case GT:
3003 libfunc = gtdf2_libfunc;
3004 break;
3006 case GE:
3007 libfunc = gedf2_libfunc;
3008 break;
3010 case LT:
3011 libfunc = ltdf2_libfunc;
3012 break;
3014 case LE:
3015 libfunc = ledf2_libfunc;
3016 break;
3018 default:
3019 break;
3021 else if (mode == XFmode)
3022 switch (comparison)
3024 case EQ:
3025 libfunc = eqxf2_libfunc;
3026 break;
3028 case NE:
3029 libfunc = nexf2_libfunc;
3030 break;
3032 case GT:
3033 libfunc = gtxf2_libfunc;
3034 break;
3036 case GE:
3037 libfunc = gexf2_libfunc;
3038 break;
3040 case LT:
3041 libfunc = ltxf2_libfunc;
3042 break;
3044 case LE:
3045 libfunc = lexf2_libfunc;
3046 break;
3048 default:
3049 break;
3051 else if (mode == TFmode)
3052 switch (comparison)
3054 case EQ:
3055 libfunc = eqtf2_libfunc;
3056 break;
3058 case NE:
3059 libfunc = netf2_libfunc;
3060 break;
3062 case GT:
3063 libfunc = gttf2_libfunc;
3064 break;
3066 case GE:
3067 libfunc = getf2_libfunc;
3068 break;
3070 case LT:
3071 libfunc = lttf2_libfunc;
3072 break;
3074 case LE:
3075 libfunc = letf2_libfunc;
3076 break;
3078 default:
3079 break;
3081 else
3083 enum machine_mode wider_mode;
3085 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3086 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3088 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3089 != CODE_FOR_nothing)
3090 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3092 x = protect_from_queue (x, 0);
3093 y = protect_from_queue (y, 0);
3094 x = convert_to_mode (wider_mode, x, 0);
3095 y = convert_to_mode (wider_mode, y, 0);
3096 emit_float_lib_cmp (x, y, comparison);
3097 return;
3100 abort ();
3103 if (libfunc == 0)
3104 abort ();
3106 emit_library_call (libfunc, 1,
3107 word_mode, 2, x, mode, y, mode);
3109 /* Immediately move the result of the libcall into a pseudo
3110 register so reload doesn't clobber the value if it needs
3111 the return register for a spill reg. */
3112 result = gen_reg_rtx (word_mode);
3113 emit_move_insn (result, hard_libcall_value (word_mode));
3115 emit_cmp_insn (result, const0_rtx, comparison,
3116 NULL_RTX, word_mode, 0, 0);
3119 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3121 void
3122 emit_indirect_jump (loc)
3123 rtx loc;
3125 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3126 (loc, Pmode)))
3127 loc = copy_to_mode_reg (Pmode, loc);
3129 emit_jump_insn (gen_indirect_jump (loc));
3130 emit_barrier ();
3133 #ifdef HAVE_conditional_move
3135 /* Emit a conditional move instruction if the machine supports one for that
3136 condition and machine mode.
3138 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3139 the mode to use should they be constants. If it is VOIDmode, they cannot
3140 both be constants.
3142 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3143 should be stored there. MODE is the mode to use should they be constants.
3144 If it is VOIDmode, they cannot both be constants.
3146 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3147 is not supported. */
3150 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3151 unsignedp)
3152 rtx target;
3153 enum rtx_code code;
3154 rtx op0, op1;
3155 enum machine_mode cmode;
3156 rtx op2, op3;
3157 enum machine_mode mode;
3158 int unsignedp;
3160 rtx tem, subtarget, comparison, insn;
3161 enum insn_code icode;
3163 /* If one operand is constant, make it the second one. Only do this
3164 if the other operand is not constant as well. */
3166 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3167 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3169 tem = op0;
3170 op0 = op1;
3171 op1 = tem;
3172 code = swap_condition (code);
3175 if (cmode == VOIDmode)
3176 cmode = GET_MODE (op0);
3178 if (((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3179 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3180 && (GET_MODE_CLASS (GET_MODE (op1)) != MODE_FLOAT
3181 || TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT || flag_fast_math))
3183 tem = op2;
3184 op2 = op3;
3185 op3 = tem;
3186 code = reverse_condition (code);
3189 if (mode == VOIDmode)
3190 mode = GET_MODE (op2);
3192 icode = movcc_gen_code[mode];
3194 if (icode == CODE_FOR_nothing)
3195 return 0;
3197 if (flag_force_mem)
3199 op2 = force_not_mem (op2);
3200 op3 = force_not_mem (op3);
3203 if (target)
3204 target = protect_from_queue (target, 1);
3205 else
3206 target = gen_reg_rtx (mode);
3208 subtarget = target;
3210 emit_queue ();
3212 op2 = protect_from_queue (op2, 0);
3213 op3 = protect_from_queue (op3, 0);
3215 /* If the insn doesn't accept these operands, put them in pseudos. */
3217 if (! (*insn_operand_predicate[icode][0])
3218 (subtarget, insn_operand_mode[icode][0]))
3219 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3221 if (! (*insn_operand_predicate[icode][2])
3222 (op2, insn_operand_mode[icode][2]))
3223 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3225 if (! (*insn_operand_predicate[icode][3])
3226 (op3, insn_operand_mode[icode][3]))
3227 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3229 /* Everything should now be in the suitable form, so emit the compare insn
3230 and then the conditional move. */
3232 comparison
3233 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3235 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3236 if (GET_CODE (comparison) != code)
3237 /* This shouldn't happen. */
3238 abort ();
3240 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3242 /* If that failed, then give up. */
3243 if (insn == 0)
3244 return 0;
3246 emit_insn (insn);
3248 if (subtarget != target)
3249 convert_move (target, subtarget, 0);
3251 return target;
3254 /* Return non-zero if a conditional move of mode MODE is supported.
3256 This function is for combine so it can tell whether an insn that looks
3257 like a conditional move is actually supported by the hardware. If we
3258 guess wrong we lose a bit on optimization, but that's it. */
3259 /* ??? sparc64 supports conditionally moving integers values based on fp
3260 comparisons, and vice versa. How do we handle them? */
3263 can_conditionally_move_p (mode)
3264 enum machine_mode mode;
3266 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3267 return 1;
3269 return 0;
3272 #endif /* HAVE_conditional_move */
3274 /* These three functions generate an insn body and return it
3275 rather than emitting the insn.
3277 They do not protect from queued increments,
3278 because they may be used 1) in protect_from_queue itself
3279 and 2) in other passes where there is no queue. */
3281 /* Generate and return an insn body to add Y to X. */
3284 gen_add2_insn (x, y)
3285 rtx x, y;
3287 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3289 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3290 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3291 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3292 abort ();
3294 return (GEN_FCN (icode) (x, x, y));
3298 have_add2_insn (mode)
3299 enum machine_mode mode;
3301 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3304 /* Generate and return an insn body to subtract Y from X. */
3307 gen_sub2_insn (x, y)
3308 rtx x, y;
3310 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3312 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3313 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3314 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3315 abort ();
3317 return (GEN_FCN (icode) (x, x, y));
3321 have_sub2_insn (mode)
3322 enum machine_mode mode;
3324 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3327 /* Generate the body of an instruction to copy Y into X.
3328 It may be a SEQUENCE, if one insn isn't enough. */
3331 gen_move_insn (x, y)
3332 rtx x, y;
3334 register enum machine_mode mode = GET_MODE (x);
3335 enum insn_code insn_code;
3336 rtx seq;
3338 if (mode == VOIDmode)
3339 mode = GET_MODE (y);
3341 insn_code = mov_optab->handlers[(int) mode].insn_code;
3343 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3344 find a mode to do it in. If we have a movcc, use it. Otherwise,
3345 find the MODE_INT mode of the same width. */
3347 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3349 enum machine_mode tmode = VOIDmode;
3350 rtx x1 = x, y1 = y;
3352 if (mode != CCmode
3353 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3354 tmode = CCmode;
3355 else
3356 for (tmode = QImode; tmode != VOIDmode;
3357 tmode = GET_MODE_WIDER_MODE (tmode))
3358 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3359 break;
3361 if (tmode == VOIDmode)
3362 abort ();
3364 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3365 may call change_address which is not appropriate if we were
3366 called when a reload was in progress. We don't have to worry
3367 about changing the address since the size in bytes is supposed to
3368 be the same. Copy the MEM to change the mode and move any
3369 substitutions from the old MEM to the new one. */
3371 if (reload_in_progress)
3373 x = gen_lowpart_common (tmode, x1);
3374 if (x == 0 && GET_CODE (x1) == MEM)
3376 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3377 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3378 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3379 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3380 copy_replacements (x1, x);
3383 y = gen_lowpart_common (tmode, y1);
3384 if (y == 0 && GET_CODE (y1) == MEM)
3386 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3387 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3388 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3389 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3390 copy_replacements (y1, y);
3393 else
3395 x = gen_lowpart (tmode, x);
3396 y = gen_lowpart (tmode, y);
3399 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3400 return (GEN_FCN (insn_code) (x, y));
3403 start_sequence ();
3404 emit_move_insn_1 (x, y);
3405 seq = gen_sequence ();
3406 end_sequence ();
3407 return seq;
3410 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3411 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3412 no such operation exists, CODE_FOR_nothing will be returned. */
3414 enum insn_code
3415 can_extend_p (to_mode, from_mode, unsignedp)
3416 enum machine_mode to_mode, from_mode;
3417 int unsignedp;
3419 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3422 /* Generate the body of an insn to extend Y (with mode MFROM)
3423 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3426 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3427 rtx x, y;
3428 enum machine_mode mto, mfrom;
3429 int unsignedp;
3431 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3434 /* can_fix_p and can_float_p say whether the target machine
3435 can directly convert a given fixed point type to
3436 a given floating point type, or vice versa.
3437 The returned value is the CODE_FOR_... value to use,
3438 or CODE_FOR_nothing if these modes cannot be directly converted.
3440 *TRUNCP_PTR is set to 1 if it is necessary to output
3441 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3443 static enum insn_code
3444 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3445 enum machine_mode fltmode, fixmode;
3446 int unsignedp;
3447 int *truncp_ptr;
3449 *truncp_ptr = 0;
3450 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3451 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3453 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3455 *truncp_ptr = 1;
3456 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3458 return CODE_FOR_nothing;
3461 static enum insn_code
3462 can_float_p (fltmode, fixmode, unsignedp)
3463 enum machine_mode fixmode, fltmode;
3464 int unsignedp;
3466 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3469 /* Generate code to convert FROM to floating point
3470 and store in TO. FROM must be fixed point and not VOIDmode.
3471 UNSIGNEDP nonzero means regard FROM as unsigned.
3472 Normally this is done by correcting the final value
3473 if it is negative. */
3475 void
3476 expand_float (to, from, unsignedp)
3477 rtx to, from;
3478 int unsignedp;
3480 enum insn_code icode;
3481 register rtx target = to;
3482 enum machine_mode fmode, imode;
3484 /* Crash now, because we won't be able to decide which mode to use. */
3485 if (GET_MODE (from) == VOIDmode)
3486 abort ();
3488 /* Look for an insn to do the conversion. Do it in the specified
3489 modes if possible; otherwise convert either input, output or both to
3490 wider mode. If the integer mode is wider than the mode of FROM,
3491 we can do the conversion signed even if the input is unsigned. */
3493 for (imode = GET_MODE (from); imode != VOIDmode;
3494 imode = GET_MODE_WIDER_MODE (imode))
3495 for (fmode = GET_MODE (to); fmode != VOIDmode;
3496 fmode = GET_MODE_WIDER_MODE (fmode))
3498 int doing_unsigned = unsignedp;
3500 icode = can_float_p (fmode, imode, unsignedp);
3501 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3502 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3504 if (icode != CODE_FOR_nothing)
3506 to = protect_from_queue (to, 1);
3507 from = protect_from_queue (from, 0);
3509 if (imode != GET_MODE (from))
3510 from = convert_to_mode (imode, from, unsignedp);
3512 if (fmode != GET_MODE (to))
3513 target = gen_reg_rtx (fmode);
3515 emit_unop_insn (icode, target, from,
3516 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3518 if (target != to)
3519 convert_move (to, target, 0);
3520 return;
3524 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3526 /* Unsigned integer, and no way to convert directly.
3527 Convert as signed, then conditionally adjust the result. */
3528 if (unsignedp)
3530 rtx label = gen_label_rtx ();
3531 rtx temp;
3532 REAL_VALUE_TYPE offset;
3534 emit_queue ();
3536 to = protect_from_queue (to, 1);
3537 from = protect_from_queue (from, 0);
3539 if (flag_force_mem)
3540 from = force_not_mem (from);
3542 /* Look for a usable floating mode FMODE wider than the source and at
3543 least as wide as the target. Using FMODE will avoid rounding woes
3544 with unsigned values greater than the signed maximum value. */
3546 for (fmode = GET_MODE (to); fmode != VOIDmode;
3547 fmode = GET_MODE_WIDER_MODE (fmode))
3548 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3549 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3550 break;
3552 if (fmode == VOIDmode)
3554 /* There is no such mode. Pretend the target is wide enough. */
3555 fmode = GET_MODE (to);
3557 /* Avoid double-rounding when TO is narrower than FROM. */
3558 if ((significand_size (fmode) + 1)
3559 < GET_MODE_BITSIZE (GET_MODE (from)))
3561 rtx temp1;
3562 rtx neglabel = gen_label_rtx ();
3564 /* Don't use TARGET if it isn't a register, is a hard register,
3565 or is the wrong mode. */
3566 if (GET_CODE (target) != REG
3567 || REGNO (target) < FIRST_PSEUDO_REGISTER
3568 || GET_MODE (target) != fmode)
3569 target = gen_reg_rtx (fmode);
3571 imode = GET_MODE (from);
3572 do_pending_stack_adjust ();
3574 /* Test whether the sign bit is set. */
3575 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3576 emit_jump_insn (gen_blt (neglabel));
3578 /* The sign bit is not set. Convert as signed. */
3579 expand_float (target, from, 0);
3580 emit_jump_insn (gen_jump (label));
3581 emit_barrier ();
3583 /* The sign bit is set.
3584 Convert to a usable (positive signed) value by shifting right
3585 one bit, while remembering if a nonzero bit was shifted
3586 out; i.e., compute (from & 1) | (from >> 1). */
3588 emit_label (neglabel);
3589 temp = expand_binop (imode, and_optab, from, const1_rtx,
3590 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3591 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3592 NULL_RTX, 1);
3593 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3594 OPTAB_LIB_WIDEN);
3595 expand_float (target, temp, 0);
3597 /* Multiply by 2 to undo the shift above. */
3598 temp = expand_binop (fmode, add_optab, target, target,
3599 target, 0, OPTAB_LIB_WIDEN);
3600 if (temp != target)
3601 emit_move_insn (target, temp);
3603 do_pending_stack_adjust ();
3604 emit_label (label);
3605 goto done;
3609 /* If we are about to do some arithmetic to correct for an
3610 unsigned operand, do it in a pseudo-register. */
3612 if (GET_MODE (to) != fmode
3613 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3614 target = gen_reg_rtx (fmode);
3616 /* Convert as signed integer to floating. */
3617 expand_float (target, from, 0);
3619 /* If FROM is negative (and therefore TO is negative),
3620 correct its value by 2**bitwidth. */
3622 do_pending_stack_adjust ();
3623 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3624 emit_jump_insn (gen_bge (label));
3626 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3627 Rather than setting up a dconst_dot_5, let's hope SCO
3628 fixes the bug. */
3629 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3630 temp = expand_binop (fmode, add_optab, target,
3631 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3632 target, 0, OPTAB_LIB_WIDEN);
3633 if (temp != target)
3634 emit_move_insn (target, temp);
3636 do_pending_stack_adjust ();
3637 emit_label (label);
3638 goto done;
3640 #endif
3642 /* No hardware instruction available; call a library routine to convert from
3643 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3645 rtx libfcn;
3646 rtx insns;
3647 rtx value;
3649 to = protect_from_queue (to, 1);
3650 from = protect_from_queue (from, 0);
3652 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3653 from = convert_to_mode (SImode, from, unsignedp);
3655 if (flag_force_mem)
3656 from = force_not_mem (from);
3658 if (GET_MODE (to) == SFmode)
3660 if (GET_MODE (from) == SImode)
3661 libfcn = floatsisf_libfunc;
3662 else if (GET_MODE (from) == DImode)
3663 libfcn = floatdisf_libfunc;
3664 else if (GET_MODE (from) == TImode)
3665 libfcn = floattisf_libfunc;
3666 else
3667 abort ();
3669 else if (GET_MODE (to) == DFmode)
3671 if (GET_MODE (from) == SImode)
3672 libfcn = floatsidf_libfunc;
3673 else if (GET_MODE (from) == DImode)
3674 libfcn = floatdidf_libfunc;
3675 else if (GET_MODE (from) == TImode)
3676 libfcn = floattidf_libfunc;
3677 else
3678 abort ();
3680 else if (GET_MODE (to) == XFmode)
3682 if (GET_MODE (from) == SImode)
3683 libfcn = floatsixf_libfunc;
3684 else if (GET_MODE (from) == DImode)
3685 libfcn = floatdixf_libfunc;
3686 else if (GET_MODE (from) == TImode)
3687 libfcn = floattixf_libfunc;
3688 else
3689 abort ();
3691 else if (GET_MODE (to) == TFmode)
3693 if (GET_MODE (from) == SImode)
3694 libfcn = floatsitf_libfunc;
3695 else if (GET_MODE (from) == DImode)
3696 libfcn = floatditf_libfunc;
3697 else if (GET_MODE (from) == TImode)
3698 libfcn = floattitf_libfunc;
3699 else
3700 abort ();
3702 else
3703 abort ();
3705 start_sequence ();
3707 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3708 GET_MODE (to),
3709 1, from, GET_MODE (from));
3710 insns = get_insns ();
3711 end_sequence ();
3713 emit_libcall_block (insns, target, value,
3714 gen_rtx (FLOAT, GET_MODE (to), from));
3717 done:
3719 /* Copy result to requested destination
3720 if we have been computing in a temp location. */
3722 if (target != to)
3724 if (GET_MODE (target) == GET_MODE (to))
3725 emit_move_insn (to, target);
3726 else
3727 convert_move (to, target, 0);
3731 /* expand_fix: generate code to convert FROM to fixed point
3732 and store in TO. FROM must be floating point. */
3734 static rtx
3735 ftruncify (x)
3736 rtx x;
3738 rtx temp = gen_reg_rtx (GET_MODE (x));
3739 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3742 void
3743 expand_fix (to, from, unsignedp)
3744 register rtx to, from;
3745 int unsignedp;
3747 enum insn_code icode;
3748 register rtx target = to;
3749 enum machine_mode fmode, imode;
3750 int must_trunc = 0;
3751 rtx libfcn = 0;
3753 /* We first try to find a pair of modes, one real and one integer, at
3754 least as wide as FROM and TO, respectively, in which we can open-code
3755 this conversion. If the integer mode is wider than the mode of TO,
3756 we can do the conversion either signed or unsigned. */
3758 for (imode = GET_MODE (to); imode != VOIDmode;
3759 imode = GET_MODE_WIDER_MODE (imode))
3760 for (fmode = GET_MODE (from); fmode != VOIDmode;
3761 fmode = GET_MODE_WIDER_MODE (fmode))
3763 int doing_unsigned = unsignedp;
3765 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3766 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3767 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3769 if (icode != CODE_FOR_nothing)
3771 to = protect_from_queue (to, 1);
3772 from = protect_from_queue (from, 0);
3774 if (fmode != GET_MODE (from))
3775 from = convert_to_mode (fmode, from, 0);
3777 if (must_trunc)
3778 from = ftruncify (from);
3780 if (imode != GET_MODE (to))
3781 target = gen_reg_rtx (imode);
3783 emit_unop_insn (icode, target, from,
3784 doing_unsigned ? UNSIGNED_FIX : FIX);
3785 if (target != to)
3786 convert_move (to, target, unsignedp);
3787 return;
3791 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3792 /* For an unsigned conversion, there is one more way to do it.
3793 If we have a signed conversion, we generate code that compares
3794 the real value to the largest representable positive number. If if
3795 is smaller, the conversion is done normally. Otherwise, subtract
3796 one plus the highest signed number, convert, and add it back.
3798 We only need to check all real modes, since we know we didn't find
3799 anything with a wider integer mode. */
3801 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3802 for (fmode = GET_MODE (from); fmode != VOIDmode;
3803 fmode = GET_MODE_WIDER_MODE (fmode))
3804 /* Make sure we won't lose significant bits doing this. */
3805 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3806 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3807 &must_trunc))
3809 int bitsize;
3810 REAL_VALUE_TYPE offset;
3811 rtx limit, lab1, lab2, insn;
3813 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3814 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3815 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3816 lab1 = gen_label_rtx ();
3817 lab2 = gen_label_rtx ();
3819 emit_queue ();
3820 to = protect_from_queue (to, 1);
3821 from = protect_from_queue (from, 0);
3823 if (flag_force_mem)
3824 from = force_not_mem (from);
3826 if (fmode != GET_MODE (from))
3827 from = convert_to_mode (fmode, from, 0);
3829 /* See if we need to do the subtraction. */
3830 do_pending_stack_adjust ();
3831 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3832 emit_jump_insn (gen_bge (lab1));
3834 /* If not, do the signed "fix" and branch around fixup code. */
3835 expand_fix (to, from, 0);
3836 emit_jump_insn (gen_jump (lab2));
3837 emit_barrier ();
3839 /* Otherwise, subtract 2**(N-1), convert to signed number,
3840 then add 2**(N-1). Do the addition using XOR since this
3841 will often generate better code. */
3842 emit_label (lab1);
3843 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3844 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3845 expand_fix (to, target, 0);
3846 target = expand_binop (GET_MODE (to), xor_optab, to,
3847 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3848 to, 1, OPTAB_LIB_WIDEN);
3850 if (target != to)
3851 emit_move_insn (to, target);
3853 emit_label (lab2);
3855 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
3856 != CODE_FOR_nothing)
3858 /* Make a place for a REG_NOTE and add it. */
3859 insn = emit_move_insn (to, to);
3860 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3861 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3862 copy_rtx (from)),
3863 REG_NOTES (insn));
3865 return;
3867 #endif
3869 /* We can't do it with an insn, so use a library call. But first ensure
3870 that the mode of TO is at least as wide as SImode, since those are the
3871 only library calls we know about. */
3873 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3875 target = gen_reg_rtx (SImode);
3877 expand_fix (target, from, unsignedp);
3879 else if (GET_MODE (from) == SFmode)
3881 if (GET_MODE (to) == SImode)
3882 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3883 else if (GET_MODE (to) == DImode)
3884 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3885 else if (GET_MODE (to) == TImode)
3886 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3887 else
3888 abort ();
3890 else if (GET_MODE (from) == DFmode)
3892 if (GET_MODE (to) == SImode)
3893 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3894 else if (GET_MODE (to) == DImode)
3895 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3896 else if (GET_MODE (to) == TImode)
3897 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3898 else
3899 abort ();
3901 else if (GET_MODE (from) == XFmode)
3903 if (GET_MODE (to) == SImode)
3904 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3905 else if (GET_MODE (to) == DImode)
3906 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3907 else if (GET_MODE (to) == TImode)
3908 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3909 else
3910 abort ();
3912 else if (GET_MODE (from) == TFmode)
3914 if (GET_MODE (to) == SImode)
3915 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3916 else if (GET_MODE (to) == DImode)
3917 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3918 else if (GET_MODE (to) == TImode)
3919 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3920 else
3921 abort ();
3923 else
3924 abort ();
3926 if (libfcn)
3928 rtx insns;
3929 rtx value;
3931 to = protect_from_queue (to, 1);
3932 from = protect_from_queue (from, 0);
3934 if (flag_force_mem)
3935 from = force_not_mem (from);
3937 start_sequence ();
3939 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3941 1, from, GET_MODE (from));
3942 insns = get_insns ();
3943 end_sequence ();
3945 emit_libcall_block (insns, target, value,
3946 gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3947 GET_MODE (to), from));
3950 if (target != to)
3952 if (GET_MODE (to) == GET_MODE (target))
3953 emit_move_insn (to, target);
3954 else
3955 convert_move (to, target, 0);
3959 static optab
3960 init_optab (code)
3961 enum rtx_code code;
3963 int i;
3964 optab op = (optab) xmalloc (sizeof (struct optab));
3965 op->code = code;
3966 for (i = 0; i < NUM_MACHINE_MODES; i++)
3968 op->handlers[i].insn_code = CODE_FOR_nothing;
3969 op->handlers[i].libfunc = 0;
3972 if (code != UNKNOWN)
3973 code_to_optab[(int) code] = op;
3975 return op;
3978 /* Initialize the libfunc fields of an entire group of entries in some
3979 optab. Each entry is set equal to a string consisting of a leading
3980 pair of underscores followed by a generic operation name followed by
3981 a mode name (downshifted to lower case) followed by a single character
3982 representing the number of operands for the given operation (which is
3983 usually one of the characters '2', '3', or '4').
3985 OPTABLE is the table in which libfunc fields are to be initialized.
3986 FIRST_MODE is the first machine mode index in the given optab to
3987 initialize.
3988 LAST_MODE is the last machine mode index in the given optab to
3989 initialize.
3990 OPNAME is the generic (string) name of the operation.
3991 SUFFIX is the character which specifies the number of operands for
3992 the given generic operation.
3995 static void
3996 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3997 register optab optable;
3998 register int first_mode;
3999 register int last_mode;
4000 register char *opname;
4001 register int suffix;
4003 register int mode;
4004 register unsigned opname_len = strlen (opname);
4006 for (mode = first_mode; (int) mode <= (int) last_mode;
4007 mode = (enum machine_mode) ((int) mode + 1))
4009 register char *mname = mode_name[(int) mode];
4010 register unsigned mname_len = strlen (mname);
4011 register char *libfunc_name
4012 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4013 register char *p;
4014 register char *q;
4016 p = libfunc_name;
4017 *p++ = '_';
4018 *p++ = '_';
4019 for (q = opname; *q; )
4020 *p++ = *q++;
4021 for (q = mname; *q; q++)
4022 *p++ = tolower (*q);
4023 *p++ = suffix;
4024 *p++ = '\0';
4025 optable->handlers[(int) mode].libfunc
4026 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
4030 /* Initialize the libfunc fields of an entire group of entries in some
4031 optab which correspond to all integer mode operations. The parameters
4032 have the same meaning as similarly named ones for the `init_libfuncs'
4033 routine. (See above). */
4035 static void
4036 init_integral_libfuncs (optable, opname, suffix)
4037 register optab optable;
4038 register char *opname;
4039 register int suffix;
4041 init_libfuncs (optable, SImode, TImode, opname, suffix);
4044 /* Initialize the libfunc fields of an entire group of entries in some
4045 optab which correspond to all real mode operations. The parameters
4046 have the same meaning as similarly named ones for the `init_libfuncs'
4047 routine. (See above). */
4049 static void
4050 init_floating_libfuncs (optable, opname, suffix)
4051 register optab optable;
4052 register char *opname;
4053 register int suffix;
4055 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4059 /* Call this once to initialize the contents of the optabs
4060 appropriately for the current target machine. */
4062 void
4063 init_optabs ()
4065 int i;
4066 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4067 int j;
4068 #endif
4070 enum insn_code *p;
4072 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4074 for (p = fixtab[0][0];
4075 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4076 p++)
4077 *p = CODE_FOR_nothing;
4079 for (p = fixtrunctab[0][0];
4080 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4081 p++)
4082 *p = CODE_FOR_nothing;
4084 for (p = floattab[0][0];
4085 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4086 p++)
4087 *p = CODE_FOR_nothing;
4089 for (p = extendtab[0][0];
4090 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4091 p++)
4092 *p = CODE_FOR_nothing;
4094 for (i = 0; i < NUM_RTX_CODE; i++)
4095 setcc_gen_code[i] = CODE_FOR_nothing;
4097 #ifdef HAVE_conditional_move
4098 for (i = 0; i < NUM_MACHINE_MODES; i++)
4099 movcc_gen_code[i] = CODE_FOR_nothing;
4100 #endif
4102 add_optab = init_optab (PLUS);
4103 sub_optab = init_optab (MINUS);
4104 smul_optab = init_optab (MULT);
4105 smul_highpart_optab = init_optab (UNKNOWN);
4106 umul_highpart_optab = init_optab (UNKNOWN);
4107 smul_widen_optab = init_optab (UNKNOWN);
4108 umul_widen_optab = init_optab (UNKNOWN);
4109 sdiv_optab = init_optab (DIV);
4110 sdivmod_optab = init_optab (UNKNOWN);
4111 udiv_optab = init_optab (UDIV);
4112 udivmod_optab = init_optab (UNKNOWN);
4113 smod_optab = init_optab (MOD);
4114 umod_optab = init_optab (UMOD);
4115 flodiv_optab = init_optab (DIV);
4116 ftrunc_optab = init_optab (UNKNOWN);
4117 and_optab = init_optab (AND);
4118 ior_optab = init_optab (IOR);
4119 xor_optab = init_optab (XOR);
4120 ashl_optab = init_optab (ASHIFT);
4121 ashr_optab = init_optab (ASHIFTRT);
4122 lshr_optab = init_optab (LSHIFTRT);
4123 rotl_optab = init_optab (ROTATE);
4124 rotr_optab = init_optab (ROTATERT);
4125 smin_optab = init_optab (SMIN);
4126 smax_optab = init_optab (SMAX);
4127 umin_optab = init_optab (UMIN);
4128 umax_optab = init_optab (UMAX);
4129 mov_optab = init_optab (UNKNOWN);
4130 movstrict_optab = init_optab (UNKNOWN);
4131 cmp_optab = init_optab (UNKNOWN);
4132 ucmp_optab = init_optab (UNKNOWN);
4133 tst_optab = init_optab (UNKNOWN);
4134 neg_optab = init_optab (NEG);
4135 abs_optab = init_optab (ABS);
4136 one_cmpl_optab = init_optab (NOT);
4137 ffs_optab = init_optab (FFS);
4138 sqrt_optab = init_optab (SQRT);
4139 sin_optab = init_optab (UNKNOWN);
4140 cos_optab = init_optab (UNKNOWN);
4141 strlen_optab = init_optab (UNKNOWN);
4143 for (i = 0; i < NUM_MACHINE_MODES; i++)
4145 movstr_optab[i] = CODE_FOR_nothing;
4146 clrstr_optab[i] = CODE_FOR_nothing;
4148 #ifdef HAVE_SECONDARY_RELOADS
4149 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4150 #endif
4153 /* Fill in the optabs with the insns we support. */
4154 init_all_optabs ();
4156 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4157 /* This flag says the same insns that convert to a signed fixnum
4158 also convert validly to an unsigned one. */
4159 for (i = 0; i < NUM_MACHINE_MODES; i++)
4160 for (j = 0; j < NUM_MACHINE_MODES; j++)
4161 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4162 #endif
4164 #ifdef EXTRA_CC_MODES
4165 init_mov_optab ();
4166 #endif
4168 /* Initialize the optabs with the names of the library functions. */
4169 init_integral_libfuncs (add_optab, "add", '3');
4170 init_floating_libfuncs (add_optab, "add", '3');
4171 init_integral_libfuncs (sub_optab, "sub", '3');
4172 init_floating_libfuncs (sub_optab, "sub", '3');
4173 init_integral_libfuncs (smul_optab, "mul", '3');
4174 init_floating_libfuncs (smul_optab, "mul", '3');
4175 init_integral_libfuncs (sdiv_optab, "div", '3');
4176 init_integral_libfuncs (udiv_optab, "udiv", '3');
4177 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4178 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4179 init_integral_libfuncs (smod_optab, "mod", '3');
4180 init_integral_libfuncs (umod_optab, "umod", '3');
4181 init_floating_libfuncs (flodiv_optab, "div", '3');
4182 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4183 init_integral_libfuncs (and_optab, "and", '3');
4184 init_integral_libfuncs (ior_optab, "ior", '3');
4185 init_integral_libfuncs (xor_optab, "xor", '3');
4186 init_integral_libfuncs (ashl_optab, "ashl", '3');
4187 init_integral_libfuncs (ashr_optab, "ashr", '3');
4188 init_integral_libfuncs (lshr_optab, "lshr", '3');
4189 init_integral_libfuncs (smin_optab, "min", '3');
4190 init_floating_libfuncs (smin_optab, "min", '3');
4191 init_integral_libfuncs (smax_optab, "max", '3');
4192 init_floating_libfuncs (smax_optab, "max", '3');
4193 init_integral_libfuncs (umin_optab, "umin", '3');
4194 init_integral_libfuncs (umax_optab, "umax", '3');
4195 init_integral_libfuncs (neg_optab, "neg", '2');
4196 init_floating_libfuncs (neg_optab, "neg", '2');
4197 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4198 init_integral_libfuncs (ffs_optab, "ffs", '2');
4200 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4201 init_integral_libfuncs (cmp_optab, "cmp", '2');
4202 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4203 init_floating_libfuncs (cmp_optab, "cmp", '2');
4205 #ifdef MULSI3_LIBCALL
4206 smul_optab->handlers[(int) SImode].libfunc
4207 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4208 #endif
4209 #ifdef MULDI3_LIBCALL
4210 smul_optab->handlers[(int) DImode].libfunc
4211 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4212 #endif
4214 #ifdef DIVSI3_LIBCALL
4215 sdiv_optab->handlers[(int) SImode].libfunc
4216 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4217 #endif
4218 #ifdef DIVDI3_LIBCALL
4219 sdiv_optab->handlers[(int) DImode].libfunc
4220 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4221 #endif
4223 #ifdef UDIVSI3_LIBCALL
4224 udiv_optab->handlers[(int) SImode].libfunc
4225 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4226 #endif
4227 #ifdef UDIVDI3_LIBCALL
4228 udiv_optab->handlers[(int) DImode].libfunc
4229 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4230 #endif
4232 #ifdef MODSI3_LIBCALL
4233 smod_optab->handlers[(int) SImode].libfunc
4234 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4235 #endif
4236 #ifdef MODDI3_LIBCALL
4237 smod_optab->handlers[(int) DImode].libfunc
4238 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4239 #endif
4241 #ifdef UMODSI3_LIBCALL
4242 umod_optab->handlers[(int) SImode].libfunc
4243 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4244 #endif
4245 #ifdef UMODDI3_LIBCALL
4246 umod_optab->handlers[(int) DImode].libfunc
4247 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4248 #endif
4250 /* Use cabs for DC complex abs, since systems generally have cabs.
4251 Don't define any libcall for SCmode, so that cabs will be used. */
4252 abs_optab->handlers[(int) DCmode].libfunc
4253 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4255 /* The ffs function operates on `int'. */
4256 #ifndef INT_TYPE_SIZE
4257 #define INT_TYPE_SIZE BITS_PER_WORD
4258 #endif
4259 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4260 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4262 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4263 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4264 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4265 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4266 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4268 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4269 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4270 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4271 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4272 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4274 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4275 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4276 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4277 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4278 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4279 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4281 throw_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__throw");
4282 sjthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjthrow");
4283 sjpopnthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjpopnthrow");
4284 terminate_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__terminate");
4285 #ifndef DONT_USE_BUILTIN_SETJMP
4286 setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_setjmp");
4287 longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_longjmp");
4288 #else
4289 setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "setjmp");
4290 longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "longjmp");
4291 #endif
4293 eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4294 nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4295 gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4296 gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4297 lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4298 lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4300 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4301 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4302 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4303 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4304 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4305 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4307 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4308 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4309 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4310 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4311 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4312 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4314 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4315 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4316 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4317 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4318 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4319 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4321 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4322 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4323 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4324 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4325 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4326 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4328 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4329 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4330 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4332 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4333 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4334 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4336 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4337 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4338 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4340 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4341 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4342 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4344 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4345 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4346 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4348 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4349 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4350 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4352 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4353 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4354 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4356 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4357 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4358 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4360 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4361 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4362 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4364 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4365 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4366 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4368 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4369 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4370 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4372 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4373 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4374 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4376 /* For check-memory-usage. */
4377 chkr_check_addr_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_addr");
4378 chkr_set_right_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_set_right");
4379 chkr_copy_bitmap_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_copy_bitmap");
4380 chkr_check_exec_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_exec");
4381 chkr_check_str_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_str");
4383 #ifdef INIT_TARGET_OPTABS
4384 /* Allow the target to add more libcalls or rename some, etc. */
4385 INIT_TARGET_OPTABS;
4386 #endif
4389 #ifdef BROKEN_LDEXP
4391 /* SCO 3.2 apparently has a broken ldexp. */
4393 double
4394 ldexp(x,n)
4395 double x;
4396 int n;
4398 if (n > 0)
4399 while (n--)
4400 x *= 2;
4402 return x;
4404 #endif /* BROKEN_LDEXP */