* pa.md (alternate dbra pattern): Remove incorrect pattern.
[official-gcc.git] / gcc / optabs.c
blob992660d0c870e0e8b9cc9318579f78e234bb85f1
1 /* Expand the basic unary and binary arithmetic operations, for GNU compiler.
2 Copyright (C) 1987, 88, 92, 93, 94, 95, 1996 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 "rtl.h"
24 #include "tree.h"
25 #include "flags.h"
26 #include "insn-flags.h"
27 #include "insn-codes.h"
28 #include "expr.h"
29 #include "insn-config.h"
30 #include "recog.h"
31 #include "reload.h"
32 #include <ctype.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;
127 rtx get_dynamic_handler_chain_libfunc;
129 rtx eqhf2_libfunc;
130 rtx nehf2_libfunc;
131 rtx gthf2_libfunc;
132 rtx gehf2_libfunc;
133 rtx lthf2_libfunc;
134 rtx lehf2_libfunc;
136 rtx eqsf2_libfunc;
137 rtx nesf2_libfunc;
138 rtx gtsf2_libfunc;
139 rtx gesf2_libfunc;
140 rtx ltsf2_libfunc;
141 rtx lesf2_libfunc;
143 rtx eqdf2_libfunc;
144 rtx nedf2_libfunc;
145 rtx gtdf2_libfunc;
146 rtx gedf2_libfunc;
147 rtx ltdf2_libfunc;
148 rtx ledf2_libfunc;
150 rtx eqxf2_libfunc;
151 rtx nexf2_libfunc;
152 rtx gtxf2_libfunc;
153 rtx gexf2_libfunc;
154 rtx ltxf2_libfunc;
155 rtx lexf2_libfunc;
157 rtx eqtf2_libfunc;
158 rtx netf2_libfunc;
159 rtx gttf2_libfunc;
160 rtx getf2_libfunc;
161 rtx lttf2_libfunc;
162 rtx letf2_libfunc;
164 rtx floatsisf_libfunc;
165 rtx floatdisf_libfunc;
166 rtx floattisf_libfunc;
168 rtx floatsidf_libfunc;
169 rtx floatdidf_libfunc;
170 rtx floattidf_libfunc;
172 rtx floatsixf_libfunc;
173 rtx floatdixf_libfunc;
174 rtx floattixf_libfunc;
176 rtx floatsitf_libfunc;
177 rtx floatditf_libfunc;
178 rtx floattitf_libfunc;
180 rtx fixsfsi_libfunc;
181 rtx fixsfdi_libfunc;
182 rtx fixsfti_libfunc;
184 rtx fixdfsi_libfunc;
185 rtx fixdfdi_libfunc;
186 rtx fixdfti_libfunc;
188 rtx fixxfsi_libfunc;
189 rtx fixxfdi_libfunc;
190 rtx fixxfti_libfunc;
192 rtx fixtfsi_libfunc;
193 rtx fixtfdi_libfunc;
194 rtx fixtfti_libfunc;
196 rtx fixunssfsi_libfunc;
197 rtx fixunssfdi_libfunc;
198 rtx fixunssfti_libfunc;
200 rtx fixunsdfsi_libfunc;
201 rtx fixunsdfdi_libfunc;
202 rtx fixunsdfti_libfunc;
204 rtx fixunsxfsi_libfunc;
205 rtx fixunsxfdi_libfunc;
206 rtx fixunsxfti_libfunc;
208 rtx fixunstfsi_libfunc;
209 rtx fixunstfdi_libfunc;
210 rtx fixunstfti_libfunc;
212 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
213 gives the gen_function to make a branch to test that condition. */
215 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
217 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
218 gives the insn code to make a store-condition insn
219 to test that condition. */
221 enum insn_code setcc_gen_code[NUM_RTX_CODE];
223 #ifdef HAVE_conditional_move
224 /* Indexed by the machine mode, gives the insn code to make a conditional
225 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
226 setcc_gen_code to cut down on the number of named patterns. Consider a day
227 when a lot more rtx codes are conditional (eg: for the ARM). */
229 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
230 #endif
232 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
233 static rtx widen_operand PROTO((rtx, enum machine_mode,
234 enum machine_mode, int, int));
235 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
236 int, int *));
237 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
238 int));
239 static rtx ftruncify PROTO((rtx));
240 static optab init_optab PROTO((enum rtx_code));
241 static void init_libfuncs PROTO((optab, int, int, char *, int));
242 static void init_integral_libfuncs PROTO((optab, char *, int));
243 static void init_floating_libfuncs PROTO((optab, char *, int));
244 static void init_complex_libfuncs PROTO((optab, char *, int));
246 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
247 the result of operation CODE applied to OP0 (and OP1 if it is a binary
248 operation).
250 If the last insn does not set TARGET, don't do anything, but return 1.
252 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
253 don't add the REG_EQUAL note but return 0. Our caller can then try
254 again, ensuring that TARGET is not one of the operands. */
256 static int
257 add_equal_note (seq, target, code, op0, op1)
258 rtx seq;
259 rtx target;
260 enum rtx_code code;
261 rtx op0, op1;
263 rtx set;
264 int i;
265 rtx note;
267 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
268 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
269 || GET_CODE (seq) != SEQUENCE
270 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
271 || GET_CODE (target) == ZERO_EXTRACT
272 || (! rtx_equal_p (SET_DEST (set), target)
273 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
274 SUBREG. */
275 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
276 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
277 target))))
278 return 1;
280 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
281 besides the last insn. */
282 if (reg_overlap_mentioned_p (target, op0)
283 || (op1 && reg_overlap_mentioned_p (target, op1)))
284 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
285 if (reg_set_p (target, XVECEXP (seq, 0, i)))
286 return 0;
288 if (GET_RTX_CLASS (code) == '1')
289 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
290 else
291 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
293 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
294 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
295 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
297 return 1;
300 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
301 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
302 not actually do a sign-extend or zero-extend, but can leave the
303 higher-order bits of the result rtx undefined, for example, in the case
304 of logical operations, but not right shifts. */
306 static rtx
307 widen_operand (op, mode, oldmode, unsignedp, no_extend)
308 rtx op;
309 enum machine_mode mode, oldmode;
310 int unsignedp;
311 int no_extend;
313 rtx result;
315 /* If we must extend do so. If OP is either a constant or a SUBREG
316 for a promoted object, also extend since it will be more efficient to
317 do so. */
318 if (! no_extend
319 || GET_MODE (op) == VOIDmode
320 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
321 return convert_modes (mode, oldmode, op, unsignedp);
323 /* If MODE is no wider than a single word, we return a paradoxical
324 SUBREG. */
325 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
326 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
328 /* Otherwise, get an object of MODE, clobber it, and set the low-order
329 part to OP. */
331 result = gen_reg_rtx (mode);
332 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
333 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
334 return result;
337 /* Generate code to perform an operation specified by BINOPTAB
338 on operands OP0 and OP1, with result having machine-mode MODE.
340 UNSIGNEDP is for the case where we have to widen the operands
341 to perform the operation. It says to use zero-extension.
343 If TARGET is nonzero, the value
344 is generated there, if it is convenient to do so.
345 In all cases an rtx is returned for the locus of the value;
346 this may or may not be TARGET. */
349 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
350 enum machine_mode mode;
351 optab binoptab;
352 rtx op0, op1;
353 rtx target;
354 int unsignedp;
355 enum optab_methods methods;
357 enum optab_methods next_methods
358 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
359 ? OPTAB_WIDEN : methods);
360 enum mode_class class;
361 enum machine_mode wider_mode;
362 register rtx temp;
363 int commutative_op = 0;
364 int shift_op = (binoptab->code == ASHIFT
365 || binoptab->code == ASHIFTRT
366 || binoptab->code == LSHIFTRT
367 || binoptab->code == ROTATE
368 || binoptab->code == ROTATERT);
369 rtx entry_last = get_last_insn ();
370 rtx last;
372 class = GET_MODE_CLASS (mode);
374 op0 = protect_from_queue (op0, 0);
375 op1 = protect_from_queue (op1, 0);
376 if (target)
377 target = protect_from_queue (target, 1);
379 if (flag_force_mem)
381 op0 = force_not_mem (op0);
382 op1 = force_not_mem (op1);
385 /* If subtracting an integer constant, convert this into an addition of
386 the negated constant. */
388 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
390 op1 = negate_rtx (mode, op1);
391 binoptab = add_optab;
394 /* If we are inside an appropriately-short loop and one operand is an
395 expensive constant, force it into a register. */
396 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
397 && rtx_cost (op0, binoptab->code) > 2)
398 op0 = force_reg (mode, op0);
400 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
401 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
402 op1 = force_reg (mode, op1);
404 /* Record where to delete back to if we backtrack. */
405 last = get_last_insn ();
407 /* If operation is commutative,
408 try to make the first operand a register.
409 Even better, try to make it the same as the target.
410 Also try to make the last operand a constant. */
411 if (GET_RTX_CLASS (binoptab->code) == 'c'
412 || binoptab == smul_widen_optab
413 || binoptab == umul_widen_optab
414 || binoptab == smul_highpart_optab
415 || binoptab == umul_highpart_optab)
417 commutative_op = 1;
419 if (((target == 0 || GET_CODE (target) == REG)
420 ? ((GET_CODE (op1) == REG
421 && GET_CODE (op0) != REG)
422 || target == op1)
423 : rtx_equal_p (op1, target))
424 || GET_CODE (op0) == CONST_INT)
426 temp = op1;
427 op1 = op0;
428 op0 = temp;
432 /* If we can do it with a three-operand insn, do so. */
434 if (methods != OPTAB_MUST_WIDEN
435 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
437 int icode = (int) binoptab->handlers[(int) mode].insn_code;
438 enum machine_mode mode0 = insn_operand_mode[icode][1];
439 enum machine_mode mode1 = insn_operand_mode[icode][2];
440 rtx pat;
441 rtx xop0 = op0, xop1 = op1;
443 if (target)
444 temp = target;
445 else
446 temp = gen_reg_rtx (mode);
448 /* If it is a commutative operator and the modes would match
449 if we would swap the operands, we can save the conversions. */
450 if (commutative_op)
452 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
453 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
455 register rtx tmp;
457 tmp = op0; op0 = op1; op1 = tmp;
458 tmp = xop0; xop0 = xop1; xop1 = tmp;
462 /* In case the insn wants input operands in modes different from
463 the result, convert the operands. */
465 if (GET_MODE (op0) != VOIDmode
466 && GET_MODE (op0) != mode0
467 && mode0 != VOIDmode)
468 xop0 = convert_to_mode (mode0, xop0, unsignedp);
470 if (GET_MODE (xop1) != VOIDmode
471 && GET_MODE (xop1) != mode1
472 && mode1 != VOIDmode)
473 xop1 = convert_to_mode (mode1, xop1, unsignedp);
475 /* Now, if insn's predicates don't allow our operands, put them into
476 pseudo regs. */
478 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
479 && mode0 != VOIDmode)
480 xop0 = copy_to_mode_reg (mode0, xop0);
482 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
483 && mode1 != VOIDmode)
484 xop1 = copy_to_mode_reg (mode1, xop1);
486 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
487 temp = gen_reg_rtx (mode);
489 pat = GEN_FCN (icode) (temp, xop0, xop1);
490 if (pat)
492 /* If PAT is a multi-insn sequence, try to add an appropriate
493 REG_EQUAL note to it. If we can't because TEMP conflicts with an
494 operand, call ourselves again, this time without a target. */
495 if (GET_CODE (pat) == SEQUENCE
496 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
498 delete_insns_since (last);
499 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
500 unsignedp, methods);
503 emit_insn (pat);
504 return temp;
506 else
507 delete_insns_since (last);
510 /* If this is a multiply, see if we can do a widening operation that
511 takes operands of this mode and makes a wider mode. */
513 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
514 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
515 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
516 != CODE_FOR_nothing))
518 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
519 unsignedp ? umul_widen_optab : smul_widen_optab,
520 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
522 if (temp != 0)
524 if (GET_MODE_CLASS (mode) == MODE_INT)
525 return gen_lowpart (mode, temp);
526 else
527 return convert_to_mode (mode, temp, unsignedp);
531 /* Look for a wider mode of the same class for which we think we
532 can open-code the operation. Check for a widening multiply at the
533 wider mode as well. */
535 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
536 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
537 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
538 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
540 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
541 || (binoptab == smul_optab
542 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
543 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
544 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
545 != CODE_FOR_nothing)))
547 rtx xop0 = op0, xop1 = op1;
548 int no_extend = 0;
550 /* For certain integer operations, we need not actually extend
551 the narrow operands, as long as we will truncate
552 the results to the same narrowness. */
554 if ((binoptab == ior_optab || binoptab == and_optab
555 || binoptab == xor_optab
556 || binoptab == add_optab || binoptab == sub_optab
557 || binoptab == smul_optab || binoptab == ashl_optab)
558 && class == MODE_INT)
559 no_extend = 1;
561 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
563 /* The second operand of a shift must always be extended. */
564 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
565 no_extend && binoptab != ashl_optab);
567 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
568 unsignedp, OPTAB_DIRECT);
569 if (temp)
571 if (class != MODE_INT)
573 if (target == 0)
574 target = gen_reg_rtx (mode);
575 convert_move (target, temp, 0);
576 return target;
578 else
579 return gen_lowpart (mode, temp);
581 else
582 delete_insns_since (last);
586 /* These can be done a word at a time. */
587 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
588 && class == MODE_INT
589 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
590 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
592 int i;
593 rtx insns;
594 rtx equiv_value;
596 /* If TARGET is the same as one of the operands, the REG_EQUAL note
597 won't be accurate, so use a new target. */
598 if (target == 0 || target == op0 || target == op1)
599 target = gen_reg_rtx (mode);
601 start_sequence ();
603 /* Do the actual arithmetic. */
604 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
606 rtx target_piece = operand_subword (target, i, 1, mode);
607 rtx x = expand_binop (word_mode, binoptab,
608 operand_subword_force (op0, i, mode),
609 operand_subword_force (op1, i, mode),
610 target_piece, unsignedp, next_methods);
612 if (x == 0)
613 break;
615 if (target_piece != x)
616 emit_move_insn (target_piece, x);
619 insns = get_insns ();
620 end_sequence ();
622 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
624 if (binoptab->code != UNKNOWN)
625 equiv_value
626 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
627 else
628 equiv_value = 0;
630 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
631 return target;
635 /* Synthesize double word shifts from single word shifts. */
636 if ((binoptab == lshr_optab || binoptab == ashl_optab
637 || binoptab == ashr_optab)
638 && class == MODE_INT
639 && GET_CODE (op1) == CONST_INT
640 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
641 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
642 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
643 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
645 rtx insns, inter, equiv_value;
646 rtx into_target, outof_target;
647 rtx into_input, outof_input;
648 int shift_count, left_shift, outof_word;
650 /* If TARGET is the same as one of the operands, the REG_EQUAL note
651 won't be accurate, so use a new target. */
652 if (target == 0 || target == op0 || target == op1)
653 target = gen_reg_rtx (mode);
655 start_sequence ();
657 shift_count = INTVAL (op1);
659 /* OUTOF_* is the word we are shifting bits away from, and
660 INTO_* is the word that we are shifting bits towards, thus
661 they differ depending on the direction of the shift and
662 WORDS_BIG_ENDIAN. */
664 left_shift = binoptab == ashl_optab;
665 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
667 outof_target = operand_subword (target, outof_word, 1, mode);
668 into_target = operand_subword (target, 1 - outof_word, 1, mode);
670 outof_input = operand_subword_force (op0, outof_word, mode);
671 into_input = operand_subword_force (op0, 1 - outof_word, mode);
673 if (shift_count >= BITS_PER_WORD)
675 inter = expand_binop (word_mode, binoptab,
676 outof_input,
677 GEN_INT (shift_count - BITS_PER_WORD),
678 into_target, unsignedp, next_methods);
680 if (inter != 0 && inter != into_target)
681 emit_move_insn (into_target, inter);
683 /* For a signed right shift, we must fill the word we are shifting
684 out of with copies of the sign bit. Otherwise it is zeroed. */
685 if (inter != 0 && binoptab != ashr_optab)
686 inter = CONST0_RTX (word_mode);
687 else if (inter != 0)
688 inter = expand_binop (word_mode, binoptab,
689 outof_input,
690 GEN_INT (BITS_PER_WORD - 1),
691 outof_target, unsignedp, next_methods);
693 if (inter != 0 && inter != outof_target)
694 emit_move_insn (outof_target, inter);
696 else
698 rtx carries;
699 optab reverse_unsigned_shift, unsigned_shift;
701 /* For a shift of less then BITS_PER_WORD, to compute the carry,
702 we must do a logical shift in the opposite direction of the
703 desired shift. */
705 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
707 /* For a shift of less than BITS_PER_WORD, to compute the word
708 shifted towards, we need to unsigned shift the orig value of
709 that word. */
711 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
713 carries = expand_binop (word_mode, reverse_unsigned_shift,
714 outof_input,
715 GEN_INT (BITS_PER_WORD - shift_count),
716 0, unsignedp, next_methods);
718 if (carries == 0)
719 inter = 0;
720 else
721 inter = expand_binop (word_mode, unsigned_shift, into_input,
722 op1, 0, unsignedp, next_methods);
724 if (inter != 0)
725 inter = expand_binop (word_mode, ior_optab, carries, inter,
726 into_target, unsignedp, next_methods);
728 if (inter != 0 && inter != into_target)
729 emit_move_insn (into_target, inter);
731 if (inter != 0)
732 inter = expand_binop (word_mode, binoptab, outof_input,
733 op1, outof_target, unsignedp, next_methods);
735 if (inter != 0 && inter != outof_target)
736 emit_move_insn (outof_target, inter);
739 insns = get_insns ();
740 end_sequence ();
742 if (inter != 0)
744 if (binoptab->code != UNKNOWN)
745 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
746 else
747 equiv_value = 0;
749 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
750 return target;
754 /* Synthesize double word rotates from single word shifts. */
755 if ((binoptab == rotl_optab || binoptab == rotr_optab)
756 && class == MODE_INT
757 && GET_CODE (op1) == CONST_INT
758 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
759 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
760 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
762 rtx insns, equiv_value;
763 rtx into_target, outof_target;
764 rtx into_input, outof_input;
765 rtx inter;
766 int shift_count, left_shift, outof_word;
768 /* If TARGET is the same as one of the operands, the REG_EQUAL note
769 won't be accurate, so use a new target. */
770 if (target == 0 || target == op0 || target == op1)
771 target = gen_reg_rtx (mode);
773 start_sequence ();
775 shift_count = INTVAL (op1);
777 /* OUTOF_* is the word we are shifting bits away from, and
778 INTO_* is the word that we are shifting bits towards, thus
779 they differ depending on the direction of the shift and
780 WORDS_BIG_ENDIAN. */
782 left_shift = (binoptab == rotl_optab);
783 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
785 outof_target = operand_subword (target, outof_word, 1, mode);
786 into_target = operand_subword (target, 1 - outof_word, 1, mode);
788 outof_input = operand_subword_force (op0, outof_word, mode);
789 into_input = operand_subword_force (op0, 1 - outof_word, mode);
791 if (shift_count == BITS_PER_WORD)
793 /* This is just a word swap. */
794 emit_move_insn (outof_target, into_input);
795 emit_move_insn (into_target, outof_input);
796 inter = const0_rtx;
798 else
800 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
801 rtx first_shift_count, second_shift_count;
802 optab reverse_unsigned_shift, unsigned_shift;
804 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
805 ? lshr_optab : ashl_optab);
807 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
808 ? ashl_optab : lshr_optab);
810 if (shift_count > BITS_PER_WORD)
812 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
813 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
815 else
817 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
818 second_shift_count = GEN_INT (shift_count);
821 into_temp1 = expand_binop (word_mode, unsigned_shift,
822 outof_input, first_shift_count,
823 NULL_RTX, unsignedp, next_methods);
824 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
825 into_input, second_shift_count,
826 into_target, unsignedp, next_methods);
828 if (into_temp1 != 0 && into_temp2 != 0)
829 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
830 into_target, unsignedp, next_methods);
831 else
832 inter = 0;
834 if (inter != 0 && inter != into_target)
835 emit_move_insn (into_target, inter);
837 outof_temp1 = expand_binop (word_mode, unsigned_shift,
838 into_input, first_shift_count,
839 NULL_RTX, unsignedp, next_methods);
840 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
841 outof_input, second_shift_count,
842 outof_target, unsignedp, next_methods);
844 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
845 inter = expand_binop (word_mode, ior_optab,
846 outof_temp1, outof_temp2,
847 outof_target, unsignedp, next_methods);
849 if (inter != 0 && inter != outof_target)
850 emit_move_insn (outof_target, inter);
853 insns = get_insns ();
854 end_sequence ();
856 if (inter != 0)
858 if (binoptab->code != UNKNOWN)
859 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
860 else
861 equiv_value = 0;
863 /* We can't make this a no conflict block if this is a word swap,
864 because the word swap case fails if the input and output values
865 are in the same register. */
866 if (shift_count != BITS_PER_WORD)
867 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
868 else
869 emit_insns (insns);
872 return target;
876 /* These can be done a word at a time by propagating carries. */
877 if ((binoptab == add_optab || binoptab == sub_optab)
878 && class == MODE_INT
879 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
880 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
882 int i;
883 rtx carry_tmp = gen_reg_rtx (word_mode);
884 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
885 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
886 rtx carry_in, carry_out;
887 rtx xop0, xop1;
889 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
890 value is one of those, use it. Otherwise, use 1 since it is the
891 one easiest to get. */
892 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
893 int normalizep = STORE_FLAG_VALUE;
894 #else
895 int normalizep = 1;
896 #endif
898 /* Prepare the operands. */
899 xop0 = force_reg (mode, op0);
900 xop1 = force_reg (mode, op1);
902 if (target == 0 || GET_CODE (target) != REG
903 || target == xop0 || target == xop1)
904 target = gen_reg_rtx (mode);
906 /* Indicate for flow that the entire target reg is being set. */
907 if (GET_CODE (target) == REG)
908 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
910 /* Do the actual arithmetic. */
911 for (i = 0; i < nwords; i++)
913 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
914 rtx target_piece = operand_subword (target, index, 1, mode);
915 rtx op0_piece = operand_subword_force (xop0, index, mode);
916 rtx op1_piece = operand_subword_force (xop1, index, mode);
917 rtx x;
919 /* Main add/subtract of the input operands. */
920 x = expand_binop (word_mode, binoptab,
921 op0_piece, op1_piece,
922 target_piece, unsignedp, next_methods);
923 if (x == 0)
924 break;
926 if (i + 1 < nwords)
928 /* Store carry from main add/subtract. */
929 carry_out = gen_reg_rtx (word_mode);
930 carry_out = emit_store_flag_force (carry_out,
931 (binoptab == add_optab
932 ? LTU : GTU),
933 x, op0_piece,
934 word_mode, 1, normalizep);
937 if (i > 0)
939 /* Add/subtract previous carry to main result. */
940 x = expand_binop (word_mode,
941 normalizep == 1 ? binoptab : otheroptab,
942 x, carry_in,
943 target_piece, 1, next_methods);
944 if (x == 0)
945 break;
946 else if (target_piece != x)
947 emit_move_insn (target_piece, x);
949 if (i + 1 < nwords)
951 /* THIS CODE HAS NOT BEEN TESTED. */
952 /* Get out carry from adding/subtracting carry in. */
953 carry_tmp = emit_store_flag_force (carry_tmp,
954 binoptab == add_optab
955 ? LTU : GTU,
956 x, carry_in,
957 word_mode, 1, normalizep);
959 /* Logical-ior the two poss. carry together. */
960 carry_out = expand_binop (word_mode, ior_optab,
961 carry_out, carry_tmp,
962 carry_out, 0, next_methods);
963 if (carry_out == 0)
964 break;
968 carry_in = carry_out;
971 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
973 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
975 rtx temp = emit_move_insn (target, target);
977 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
978 gen_rtx (binoptab->code, mode,
979 copy_rtx (xop0),
980 copy_rtx (xop1)),
981 REG_NOTES (temp));
983 return target;
985 else
986 delete_insns_since (last);
989 /* If we want to multiply two two-word values and have normal and widening
990 multiplies of single-word values, we can do this with three smaller
991 multiplications. Note that we do not make a REG_NO_CONFLICT block here
992 because we are not operating on one word at a time.
994 The multiplication proceeds as follows:
995 _______________________
996 [__op0_high_|__op0_low__]
997 _______________________
998 * [__op1_high_|__op1_low__]
999 _______________________________________________
1000 _______________________
1001 (1) [__op0_low__*__op1_low__]
1002 _______________________
1003 (2a) [__op0_low__*__op1_high_]
1004 _______________________
1005 (2b) [__op0_high_*__op1_low__]
1006 _______________________
1007 (3) [__op0_high_*__op1_high_]
1010 This gives a 4-word result. Since we are only interested in the
1011 lower 2 words, partial result (3) and the upper words of (2a) and
1012 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1013 calculated using non-widening multiplication.
1015 (1), however, needs to be calculated with an unsigned widening
1016 multiplication. If this operation is not directly supported we
1017 try using a signed widening multiplication and adjust the result.
1018 This adjustment works as follows:
1020 If both operands are positive then no adjustment is needed.
1022 If the operands have different signs, for example op0_low < 0 and
1023 op1_low >= 0, the instruction treats the most significant bit of
1024 op0_low as a sign bit instead of a bit with significance
1025 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1026 with 2**BITS_PER_WORD - op0_low, and two's complements the
1027 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1028 the result.
1030 Similarly, if both operands are negative, we need to add
1031 (op0_low + op1_low) * 2**BITS_PER_WORD.
1033 We use a trick to adjust quickly. We logically shift op0_low right
1034 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1035 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1036 logical shift exists, we do an arithmetic right shift and subtract
1037 the 0 or -1. */
1039 if (binoptab == smul_optab
1040 && class == MODE_INT
1041 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1042 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1043 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1044 && ((umul_widen_optab->handlers[(int) mode].insn_code
1045 != CODE_FOR_nothing)
1046 || (smul_widen_optab->handlers[(int) mode].insn_code
1047 != CODE_FOR_nothing)))
1049 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1050 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1051 rtx op0_high = operand_subword_force (op0, high, mode);
1052 rtx op0_low = operand_subword_force (op0, low, mode);
1053 rtx op1_high = operand_subword_force (op1, high, mode);
1054 rtx op1_low = operand_subword_force (op1, low, mode);
1055 rtx product = 0;
1056 rtx op0_xhigh;
1057 rtx op1_xhigh;
1059 /* If the target is the same as one of the inputs, don't use it. This
1060 prevents problems with the REG_EQUAL note. */
1061 if (target == op0 || target == op1
1062 || (target != 0 && GET_CODE (target) != REG))
1063 target = 0;
1065 /* Multiply the two lower words to get a double-word product.
1066 If unsigned widening multiplication is available, use that;
1067 otherwise use the signed form and compensate. */
1069 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1071 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1072 target, 1, OPTAB_DIRECT);
1074 /* If we didn't succeed, delete everything we did so far. */
1075 if (product == 0)
1076 delete_insns_since (last);
1077 else
1078 op0_xhigh = op0_high, op1_xhigh = op1_high;
1081 if (product == 0
1082 && smul_widen_optab->handlers[(int) mode].insn_code
1083 != CODE_FOR_nothing)
1085 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1086 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1087 target, 1, OPTAB_DIRECT);
1088 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1089 NULL_RTX, 1, next_methods);
1090 if (op0_xhigh)
1091 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1092 op0_xhigh, op0_xhigh, 0, next_methods);
1093 else
1095 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1096 NULL_RTX, 0, next_methods);
1097 if (op0_xhigh)
1098 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1099 op0_xhigh, op0_xhigh, 0,
1100 next_methods);
1103 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1104 NULL_RTX, 1, next_methods);
1105 if (op1_xhigh)
1106 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1107 op1_xhigh, op1_xhigh, 0, next_methods);
1108 else
1110 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1111 NULL_RTX, 0, next_methods);
1112 if (op1_xhigh)
1113 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1114 op1_xhigh, op1_xhigh, 0,
1115 next_methods);
1119 /* If we have been able to directly compute the product of the
1120 low-order words of the operands and perform any required adjustments
1121 of the operands, we proceed by trying two more multiplications
1122 and then computing the appropriate sum.
1124 We have checked above that the required addition is provided.
1125 Full-word addition will normally always succeed, especially if
1126 it is provided at all, so we don't worry about its failure. The
1127 multiplication may well fail, however, so we do handle that. */
1129 if (product && op0_xhigh && op1_xhigh)
1131 rtx product_high = operand_subword (product, high, 1, mode);
1132 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1133 NULL_RTX, 0, OPTAB_DIRECT);
1135 if (temp != 0)
1136 temp = expand_binop (word_mode, add_optab, temp, product_high,
1137 product_high, 0, next_methods);
1139 if (temp != 0 && temp != product_high)
1140 emit_move_insn (product_high, temp);
1142 if (temp != 0)
1143 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1144 NULL_RTX, 0, OPTAB_DIRECT);
1146 if (temp != 0)
1147 temp = expand_binop (word_mode, add_optab, temp,
1148 product_high, product_high,
1149 0, next_methods);
1151 if (temp != 0 && temp != product_high)
1152 emit_move_insn (product_high, temp);
1154 if (temp != 0)
1156 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1158 temp = emit_move_insn (product, product);
1159 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1160 gen_rtx (MULT, mode,
1161 copy_rtx (op0),
1162 copy_rtx (op1)),
1163 REG_NOTES (temp));
1165 return product;
1169 /* If we get here, we couldn't do it for some reason even though we
1170 originally thought we could. Delete anything we've emitted in
1171 trying to do it. */
1173 delete_insns_since (last);
1176 /* We need to open-code the complex type operations: '+, -, * and /' */
1178 /* At this point we allow operations between two similar complex
1179 numbers, and also if one of the operands is not a complex number
1180 but rather of MODE_FLOAT or MODE_INT. However, the caller
1181 must make sure that the MODE of the non-complex operand matches
1182 the SUBMODE of the complex operand. */
1184 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1186 rtx real0 = 0, imag0 = 0;
1187 rtx real1 = 0, imag1 = 0;
1188 rtx realr, imagr, res;
1189 rtx seq;
1190 rtx equiv_value;
1191 int ok = 0;
1193 /* Find the correct mode for the real and imaginary parts */
1194 enum machine_mode submode
1195 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1196 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1199 if (submode == BLKmode)
1200 abort ();
1202 if (! target)
1203 target = gen_reg_rtx (mode);
1205 start_sequence ();
1207 realr = gen_realpart (submode, target);
1208 imagr = gen_imagpart (submode, target);
1210 if (GET_MODE (op0) == mode)
1212 real0 = gen_realpart (submode, op0);
1213 imag0 = gen_imagpart (submode, op0);
1215 else
1216 real0 = op0;
1218 if (GET_MODE (op1) == mode)
1220 real1 = gen_realpart (submode, op1);
1221 imag1 = gen_imagpart (submode, op1);
1223 else
1224 real1 = op1;
1226 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1227 abort ();
1229 switch (binoptab->code)
1231 case PLUS:
1232 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1233 case MINUS:
1234 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1235 res = expand_binop (submode, binoptab, real0, real1,
1236 realr, unsignedp, methods);
1238 if (res == 0)
1239 break;
1240 else if (res != realr)
1241 emit_move_insn (realr, res);
1243 if (imag0 && imag1)
1244 res = expand_binop (submode, binoptab, imag0, imag1,
1245 imagr, unsignedp, methods);
1246 else if (imag0)
1247 res = imag0;
1248 else if (binoptab->code == MINUS)
1249 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1250 else
1251 res = imag1;
1253 if (res == 0)
1254 break;
1255 else if (res != imagr)
1256 emit_move_insn (imagr, res);
1258 ok = 1;
1259 break;
1261 case MULT:
1262 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1264 if (imag0 && imag1)
1266 rtx temp1, temp2;
1268 /* Don't fetch these from memory more than once. */
1269 real0 = force_reg (submode, real0);
1270 real1 = force_reg (submode, real1);
1271 imag0 = force_reg (submode, imag0);
1272 imag1 = force_reg (submode, imag1);
1274 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1275 unsignedp, methods);
1277 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1278 unsignedp, methods);
1280 if (temp1 == 0 || temp2 == 0)
1281 break;
1283 res = expand_binop (submode, sub_optab, temp1, temp2,
1284 realr, unsignedp, methods);
1286 if (res == 0)
1287 break;
1288 else if (res != realr)
1289 emit_move_insn (realr, res);
1291 temp1 = expand_binop (submode, binoptab, real0, imag1,
1292 NULL_RTX, unsignedp, methods);
1294 temp2 = expand_binop (submode, binoptab, real1, imag0,
1295 NULL_RTX, unsignedp, methods);
1297 if (temp1 == 0 || temp2 == 0)
1298 break;
1300 res = expand_binop (submode, add_optab, temp1, temp2,
1301 imagr, unsignedp, methods);
1303 if (res == 0)
1304 break;
1305 else if (res != imagr)
1306 emit_move_insn (imagr, res);
1308 ok = 1;
1310 else
1312 /* Don't fetch these from memory more than once. */
1313 real0 = force_reg (submode, real0);
1314 real1 = force_reg (submode, real1);
1316 res = expand_binop (submode, binoptab, real0, real1,
1317 realr, unsignedp, methods);
1318 if (res == 0)
1319 break;
1320 else if (res != realr)
1321 emit_move_insn (realr, res);
1323 if (imag0 != 0)
1324 res = expand_binop (submode, binoptab,
1325 real1, imag0, imagr, unsignedp, methods);
1326 else
1327 res = expand_binop (submode, binoptab,
1328 real0, imag1, imagr, unsignedp, methods);
1330 if (res == 0)
1331 break;
1332 else if (res != imagr)
1333 emit_move_insn (imagr, res);
1335 ok = 1;
1337 break;
1339 case DIV:
1340 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1342 if (imag1 == 0)
1344 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1346 /* Don't fetch these from memory more than once. */
1347 real1 = force_reg (submode, real1);
1349 /* Simply divide the real and imaginary parts by `c' */
1350 if (class == MODE_COMPLEX_FLOAT)
1351 res = expand_binop (submode, binoptab, real0, real1,
1352 realr, unsignedp, methods);
1353 else
1354 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1355 real0, real1, realr, unsignedp);
1357 if (res == 0)
1358 break;
1359 else if (res != realr)
1360 emit_move_insn (realr, res);
1362 if (class == MODE_COMPLEX_FLOAT)
1363 res = expand_binop (submode, binoptab, imag0, real1,
1364 imagr, unsignedp, methods);
1365 else
1366 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1367 imag0, real1, imagr, unsignedp);
1369 if (res == 0)
1370 break;
1371 else if (res != imagr)
1372 emit_move_insn (imagr, res);
1374 ok = 1;
1376 else
1378 /* Divisor is of complex type:
1379 X/(a+ib) */
1380 rtx divisor;
1381 rtx real_t, imag_t;
1382 rtx lhs, rhs;
1383 rtx temp1, temp2;
1385 /* Don't fetch these from memory more than once. */
1386 real0 = force_reg (submode, real0);
1387 real1 = force_reg (submode, real1);
1389 if (imag0 != 0)
1390 imag0 = force_reg (submode, imag0);
1392 imag1 = force_reg (submode, imag1);
1394 /* Divisor: c*c + d*d */
1395 temp1 = expand_binop (submode, smul_optab, real1, real1,
1396 NULL_RTX, unsignedp, methods);
1398 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1399 NULL_RTX, unsignedp, methods);
1401 if (temp1 == 0 || temp2 == 0)
1402 break;
1404 divisor = expand_binop (submode, add_optab, temp1, temp2,
1405 NULL_RTX, unsignedp, methods);
1406 if (divisor == 0)
1407 break;
1409 if (imag0 == 0)
1411 /* ((a)(c-id))/divisor */
1412 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1414 /* Calculate the dividend */
1415 real_t = expand_binop (submode, smul_optab, real0, real1,
1416 NULL_RTX, unsignedp, methods);
1418 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1419 NULL_RTX, unsignedp, methods);
1421 if (real_t == 0 || imag_t == 0)
1422 break;
1424 imag_t = expand_unop (submode, neg_optab, imag_t,
1425 NULL_RTX, unsignedp);
1427 else
1429 /* ((a+ib)(c-id))/divider */
1430 /* Calculate the dividend */
1431 temp1 = expand_binop (submode, smul_optab, real0, real1,
1432 NULL_RTX, unsignedp, methods);
1434 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1435 NULL_RTX, unsignedp, methods);
1437 if (temp1 == 0 || temp2 == 0)
1438 break;
1440 real_t = expand_binop (submode, add_optab, temp1, temp2,
1441 NULL_RTX, unsignedp, methods);
1443 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1444 NULL_RTX, unsignedp, methods);
1446 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1447 NULL_RTX, unsignedp, methods);
1449 if (temp1 == 0 || temp2 == 0)
1450 break;
1452 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1453 NULL_RTX, unsignedp, methods);
1455 if (real_t == 0 || imag_t == 0)
1456 break;
1459 if (class == MODE_COMPLEX_FLOAT)
1460 res = expand_binop (submode, binoptab, real_t, divisor,
1461 realr, unsignedp, methods);
1462 else
1463 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1464 real_t, divisor, realr, unsignedp);
1466 if (res == 0)
1467 break;
1468 else if (res != realr)
1469 emit_move_insn (realr, res);
1471 if (class == MODE_COMPLEX_FLOAT)
1472 res = expand_binop (submode, binoptab, imag_t, divisor,
1473 imagr, unsignedp, methods);
1474 else
1475 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1476 imag_t, divisor, imagr, unsignedp);
1478 if (res == 0)
1479 break;
1480 else if (res != imagr)
1481 emit_move_insn (imagr, res);
1483 ok = 1;
1485 break;
1487 default:
1488 abort ();
1491 seq = get_insns ();
1492 end_sequence ();
1494 if (ok)
1496 if (binoptab->code != UNKNOWN)
1497 equiv_value
1498 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1499 else
1500 equiv_value = 0;
1502 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1504 return target;
1508 /* It can't be open-coded in this mode.
1509 Use a library call if one is available and caller says that's ok. */
1511 if (binoptab->handlers[(int) mode].libfunc
1512 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1514 rtx insns;
1515 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1516 rtx op1x = op1;
1517 enum machine_mode op1_mode = mode;
1518 rtx value;
1520 start_sequence ();
1522 if (shift_op)
1524 op1_mode = word_mode;
1525 /* Specify unsigned here,
1526 since negative shift counts are meaningless. */
1527 op1x = convert_to_mode (word_mode, op1, 1);
1530 if (GET_MODE (op0) != VOIDmode
1531 && GET_MODE (op0) != mode)
1532 op0 = convert_to_mode (mode, op0, unsignedp);
1534 /* Pass 1 for NO_QUEUE so we don't lose any increments
1535 if the libcall is cse'd or moved. */
1536 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1537 NULL_RTX, 1, mode, 2,
1538 op0, mode, op1x, op1_mode);
1540 insns = get_insns ();
1541 end_sequence ();
1543 target = gen_reg_rtx (mode);
1544 emit_libcall_block (insns, target, value,
1545 gen_rtx (binoptab->code, mode, op0, op1));
1547 return target;
1550 delete_insns_since (last);
1552 /* It can't be done in this mode. Can we do it in a wider mode? */
1554 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1555 || methods == OPTAB_MUST_WIDEN))
1557 /* Caller says, don't even try. */
1558 delete_insns_since (entry_last);
1559 return 0;
1562 /* Compute the value of METHODS to pass to recursive calls.
1563 Don't allow widening to be tried recursively. */
1565 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1567 /* Look for a wider mode of the same class for which it appears we can do
1568 the operation. */
1570 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1572 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1573 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1575 if ((binoptab->handlers[(int) wider_mode].insn_code
1576 != CODE_FOR_nothing)
1577 || (methods == OPTAB_LIB
1578 && binoptab->handlers[(int) wider_mode].libfunc))
1580 rtx xop0 = op0, xop1 = op1;
1581 int no_extend = 0;
1583 /* For certain integer operations, we need not actually extend
1584 the narrow operands, as long as we will truncate
1585 the results to the same narrowness. */
1587 if ((binoptab == ior_optab || binoptab == and_optab
1588 || binoptab == xor_optab
1589 || binoptab == add_optab || binoptab == sub_optab
1590 || binoptab == smul_optab || binoptab == ashl_optab)
1591 && class == MODE_INT)
1592 no_extend = 1;
1594 xop0 = widen_operand (xop0, wider_mode, mode,
1595 unsignedp, no_extend);
1597 /* The second operand of a shift must always be extended. */
1598 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1599 no_extend && binoptab != ashl_optab);
1601 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1602 unsignedp, methods);
1603 if (temp)
1605 if (class != MODE_INT)
1607 if (target == 0)
1608 target = gen_reg_rtx (mode);
1609 convert_move (target, temp, 0);
1610 return target;
1612 else
1613 return gen_lowpart (mode, temp);
1615 else
1616 delete_insns_since (last);
1621 delete_insns_since (entry_last);
1622 return 0;
1625 /* Expand a binary operator which has both signed and unsigned forms.
1626 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1627 signed operations.
1629 If we widen unsigned operands, we may use a signed wider operation instead
1630 of an unsigned wider operation, since the result would be the same. */
1633 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1634 enum machine_mode mode;
1635 optab uoptab, soptab;
1636 rtx op0, op1, target;
1637 int unsignedp;
1638 enum optab_methods methods;
1640 register rtx temp;
1641 optab direct_optab = unsignedp ? uoptab : soptab;
1642 struct optab wide_soptab;
1644 /* Do it without widening, if possible. */
1645 temp = expand_binop (mode, direct_optab, op0, op1, target,
1646 unsignedp, OPTAB_DIRECT);
1647 if (temp || methods == OPTAB_DIRECT)
1648 return temp;
1650 /* Try widening to a signed int. Make a fake signed optab that
1651 hides any signed insn for direct use. */
1652 wide_soptab = *soptab;
1653 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1654 wide_soptab.handlers[(int) mode].libfunc = 0;
1656 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1657 unsignedp, OPTAB_WIDEN);
1659 /* For unsigned operands, try widening to an unsigned int. */
1660 if (temp == 0 && unsignedp)
1661 temp = expand_binop (mode, uoptab, op0, op1, target,
1662 unsignedp, OPTAB_WIDEN);
1663 if (temp || methods == OPTAB_WIDEN)
1664 return temp;
1666 /* Use the right width lib call if that exists. */
1667 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1668 if (temp || methods == OPTAB_LIB)
1669 return temp;
1671 /* Must widen and use a lib call, use either signed or unsigned. */
1672 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1673 unsignedp, methods);
1674 if (temp != 0)
1675 return temp;
1676 if (unsignedp)
1677 return expand_binop (mode, uoptab, op0, op1, target,
1678 unsignedp, methods);
1679 return 0;
1682 /* Generate code to perform an operation specified by BINOPTAB
1683 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1684 We assume that the order of the operands for the instruction
1685 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1686 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1688 Either TARG0 or TARG1 may be zero, but what that means is that
1689 that result is not actually wanted. We will generate it into
1690 a dummy pseudo-reg and discard it. They may not both be zero.
1692 Returns 1 if this operation can be performed; 0 if not. */
1695 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1696 optab binoptab;
1697 rtx op0, op1;
1698 rtx targ0, targ1;
1699 int unsignedp;
1701 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1702 enum mode_class class;
1703 enum machine_mode wider_mode;
1704 rtx entry_last = get_last_insn ();
1705 rtx last;
1707 class = GET_MODE_CLASS (mode);
1709 op0 = protect_from_queue (op0, 0);
1710 op1 = protect_from_queue (op1, 0);
1712 if (flag_force_mem)
1714 op0 = force_not_mem (op0);
1715 op1 = force_not_mem (op1);
1718 /* If we are inside an appropriately-short loop and one operand is an
1719 expensive constant, force it into a register. */
1720 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1721 && rtx_cost (op0, binoptab->code) > 2)
1722 op0 = force_reg (mode, op0);
1724 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1725 && rtx_cost (op1, binoptab->code) > 2)
1726 op1 = force_reg (mode, op1);
1728 if (targ0)
1729 targ0 = protect_from_queue (targ0, 1);
1730 else
1731 targ0 = gen_reg_rtx (mode);
1732 if (targ1)
1733 targ1 = protect_from_queue (targ1, 1);
1734 else
1735 targ1 = gen_reg_rtx (mode);
1737 /* Record where to go back to if we fail. */
1738 last = get_last_insn ();
1740 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1742 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1743 enum machine_mode mode0 = insn_operand_mode[icode][1];
1744 enum machine_mode mode1 = insn_operand_mode[icode][2];
1745 rtx pat;
1746 rtx xop0 = op0, xop1 = op1;
1748 /* In case this insn wants input operands in modes different from the
1749 result, convert the operands. */
1750 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1751 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1753 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1754 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1756 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1757 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1758 xop0 = copy_to_mode_reg (mode0, xop0);
1760 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1761 xop1 = copy_to_mode_reg (mode1, xop1);
1763 /* We could handle this, but we should always be called with a pseudo
1764 for our targets and all insns should take them as outputs. */
1765 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1766 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1767 abort ();
1769 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1770 if (pat)
1772 emit_insn (pat);
1773 return 1;
1775 else
1776 delete_insns_since (last);
1779 /* It can't be done in this mode. Can we do it in a wider mode? */
1781 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1783 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1784 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1786 if (binoptab->handlers[(int) wider_mode].insn_code
1787 != CODE_FOR_nothing)
1789 register rtx t0 = gen_reg_rtx (wider_mode);
1790 register rtx t1 = gen_reg_rtx (wider_mode);
1792 if (expand_twoval_binop (binoptab,
1793 convert_modes (wider_mode, mode, op0,
1794 unsignedp),
1795 convert_modes (wider_mode, mode, op1,
1796 unsignedp),
1797 t0, t1, unsignedp))
1799 convert_move (targ0, t0, unsignedp);
1800 convert_move (targ1, t1, unsignedp);
1801 return 1;
1803 else
1804 delete_insns_since (last);
1809 delete_insns_since (entry_last);
1810 return 0;
1813 /* Generate code to perform an operation specified by UNOPTAB
1814 on operand OP0, with result having machine-mode MODE.
1816 UNSIGNEDP is for the case where we have to widen the operands
1817 to perform the operation. It says to use zero-extension.
1819 If TARGET is nonzero, the value
1820 is generated there, if it is convenient to do so.
1821 In all cases an rtx is returned for the locus of the value;
1822 this may or may not be TARGET. */
1825 expand_unop (mode, unoptab, op0, target, unsignedp)
1826 enum machine_mode mode;
1827 optab unoptab;
1828 rtx op0;
1829 rtx target;
1830 int unsignedp;
1832 enum mode_class class;
1833 enum machine_mode wider_mode;
1834 register rtx temp;
1835 rtx last = get_last_insn ();
1836 rtx pat;
1838 class = GET_MODE_CLASS (mode);
1840 op0 = protect_from_queue (op0, 0);
1842 if (flag_force_mem)
1844 op0 = force_not_mem (op0);
1847 if (target)
1848 target = protect_from_queue (target, 1);
1850 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1852 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1853 enum machine_mode mode0 = insn_operand_mode[icode][1];
1854 rtx xop0 = op0;
1856 if (target)
1857 temp = target;
1858 else
1859 temp = gen_reg_rtx (mode);
1861 if (GET_MODE (xop0) != VOIDmode
1862 && GET_MODE (xop0) != mode0)
1863 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1865 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1867 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1868 xop0 = copy_to_mode_reg (mode0, xop0);
1870 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1871 temp = gen_reg_rtx (mode);
1873 pat = GEN_FCN (icode) (temp, xop0);
1874 if (pat)
1876 if (GET_CODE (pat) == SEQUENCE
1877 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1879 delete_insns_since (last);
1880 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1883 emit_insn (pat);
1885 return temp;
1887 else
1888 delete_insns_since (last);
1891 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1893 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1894 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1895 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1897 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1899 rtx xop0 = op0;
1901 /* For certain operations, we need not actually extend
1902 the narrow operand, as long as we will truncate the
1903 results to the same narrowness. */
1905 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1906 (unoptab == neg_optab
1907 || unoptab == one_cmpl_optab)
1908 && class == MODE_INT);
1910 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1911 unsignedp);
1913 if (temp)
1915 if (class != MODE_INT)
1917 if (target == 0)
1918 target = gen_reg_rtx (mode);
1919 convert_move (target, temp, 0);
1920 return target;
1922 else
1923 return gen_lowpart (mode, temp);
1925 else
1926 delete_insns_since (last);
1930 /* These can be done a word at a time. */
1931 if (unoptab == one_cmpl_optab
1932 && class == MODE_INT
1933 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1934 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1936 int i;
1937 rtx insns;
1939 if (target == 0 || target == op0)
1940 target = gen_reg_rtx (mode);
1942 start_sequence ();
1944 /* Do the actual arithmetic. */
1945 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1947 rtx target_piece = operand_subword (target, i, 1, mode);
1948 rtx x = expand_unop (word_mode, unoptab,
1949 operand_subword_force (op0, i, mode),
1950 target_piece, unsignedp);
1951 if (target_piece != x)
1952 emit_move_insn (target_piece, x);
1955 insns = get_insns ();
1956 end_sequence ();
1958 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1959 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1960 return target;
1963 /* Open-code the complex negation operation. */
1964 else if (unoptab == neg_optab
1965 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1967 rtx target_piece;
1968 rtx x;
1969 rtx seq;
1971 /* Find the correct mode for the real and imaginary parts */
1972 enum machine_mode submode
1973 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1974 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1977 if (submode == BLKmode)
1978 abort ();
1980 if (target == 0)
1981 target = gen_reg_rtx (mode);
1983 start_sequence ();
1985 target_piece = gen_imagpart (submode, target);
1986 x = expand_unop (submode, unoptab,
1987 gen_imagpart (submode, op0),
1988 target_piece, unsignedp);
1989 if (target_piece != x)
1990 emit_move_insn (target_piece, x);
1992 target_piece = gen_realpart (submode, target);
1993 x = expand_unop (submode, unoptab,
1994 gen_realpart (submode, op0),
1995 target_piece, unsignedp);
1996 if (target_piece != x)
1997 emit_move_insn (target_piece, x);
1999 seq = get_insns ();
2000 end_sequence ();
2002 emit_no_conflict_block (seq, target, op0, 0,
2003 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
2004 return target;
2007 /* Now try a library call in this mode. */
2008 if (unoptab->handlers[(int) mode].libfunc)
2010 rtx insns;
2011 rtx funexp = unoptab->handlers[(int) mode].libfunc;
2012 rtx value;
2014 start_sequence ();
2016 /* Pass 1 for NO_QUEUE so we don't lose any increments
2017 if the libcall is cse'd or moved. */
2018 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2019 NULL_RTX, 1, mode, 1, op0, mode);
2020 insns = get_insns ();
2021 end_sequence ();
2023 target = gen_reg_rtx (mode);
2024 emit_libcall_block (insns, target, value,
2025 gen_rtx (unoptab->code, mode, op0));
2027 return target;
2030 /* It can't be done in this mode. Can we do it in a wider mode? */
2032 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2034 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2035 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2037 if ((unoptab->handlers[(int) wider_mode].insn_code
2038 != CODE_FOR_nothing)
2039 || unoptab->handlers[(int) wider_mode].libfunc)
2041 rtx xop0 = op0;
2043 /* For certain operations, we need not actually extend
2044 the narrow operand, as long as we will truncate the
2045 results to the same narrowness. */
2047 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2048 (unoptab == neg_optab
2049 || unoptab == one_cmpl_optab)
2050 && class == MODE_INT);
2052 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2053 unsignedp);
2055 if (temp)
2057 if (class != MODE_INT)
2059 if (target == 0)
2060 target = gen_reg_rtx (mode);
2061 convert_move (target, temp, 0);
2062 return target;
2064 else
2065 return gen_lowpart (mode, temp);
2067 else
2068 delete_insns_since (last);
2073 /* If there is no negate operation, try doing a subtract from zero.
2074 The US Software GOFAST library needs this. */
2075 if (unoptab == neg_optab)
2077 rtx temp;
2078 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2079 target, unsignedp, OPTAB_LIB_WIDEN);
2080 if (temp)
2081 return temp;
2084 return 0;
2087 /* Emit code to compute the absolute value of OP0, with result to
2088 TARGET if convenient. (TARGET may be 0.) The return value says
2089 where the result actually is to be found.
2091 MODE is the mode of the operand; the mode of the result is
2092 different but can be deduced from MODE.
2094 UNSIGNEDP is relevant if extension is needed. */
2097 expand_abs (mode, op0, target, unsignedp, safe)
2098 enum machine_mode mode;
2099 rtx op0;
2100 rtx target;
2101 int unsignedp;
2102 int safe;
2104 rtx temp, op1;
2106 /* First try to do it with a special abs instruction. */
2107 temp = expand_unop (mode, abs_optab, op0, target, 0);
2108 if (temp != 0)
2109 return temp;
2111 /* If this machine has expensive jumps, we can do integer absolute
2112 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2113 where W is the width of MODE. */
2115 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2117 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2118 size_int (GET_MODE_BITSIZE (mode) - 1),
2119 NULL_RTX, 0);
2121 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2122 OPTAB_LIB_WIDEN);
2123 if (temp != 0)
2124 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2125 OPTAB_LIB_WIDEN);
2127 if (temp != 0)
2128 return temp;
2131 /* If that does not win, use conditional jump and negate. */
2133 /* It is safe to use the target if it is the same
2134 as the source if this is also a pseudo register */
2135 if (op0 == target && GET_CODE (op0) == REG
2136 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2137 safe = 1;
2139 op1 = gen_label_rtx ();
2140 if (target == 0 || ! safe
2141 || GET_MODE (target) != mode
2142 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2143 || (GET_CODE (target) == REG
2144 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2145 target = gen_reg_rtx (mode);
2147 emit_move_insn (target, op0);
2148 NO_DEFER_POP;
2150 /* If this mode is an integer too wide to compare properly,
2151 compare word by word. Rely on CSE to optimize constant cases. */
2152 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2153 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2154 NULL_RTX, op1);
2155 else
2157 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2158 NULL_RTX, 0);
2159 if (temp == const1_rtx)
2160 return target;
2161 else if (temp != const0_rtx)
2163 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2164 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2165 else
2166 abort ();
2170 op0 = expand_unop (mode, neg_optab, target, target, 0);
2171 if (op0 != target)
2172 emit_move_insn (target, op0);
2173 emit_label (op1);
2174 OK_DEFER_POP;
2175 return target;
2178 /* Emit code to compute the absolute value of OP0, with result to
2179 TARGET if convenient. (TARGET may be 0.) The return value says
2180 where the result actually is to be found.
2182 MODE is the mode of the operand; the mode of the result is
2183 different but can be deduced from MODE.
2185 UNSIGNEDP is relevant for complex integer modes. */
2188 expand_complex_abs (mode, op0, target, unsignedp)
2189 enum machine_mode mode;
2190 rtx op0;
2191 rtx target;
2192 int unsignedp;
2194 enum mode_class class = GET_MODE_CLASS (mode);
2195 enum machine_mode wider_mode;
2196 register rtx temp;
2197 rtx entry_last = get_last_insn ();
2198 rtx last;
2199 rtx pat;
2201 /* Find the correct mode for the real and imaginary parts. */
2202 enum machine_mode submode
2203 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2204 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2207 if (submode == BLKmode)
2208 abort ();
2210 op0 = protect_from_queue (op0, 0);
2212 if (flag_force_mem)
2214 op0 = force_not_mem (op0);
2217 last = get_last_insn ();
2219 if (target)
2220 target = protect_from_queue (target, 1);
2222 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2224 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2225 enum machine_mode mode0 = insn_operand_mode[icode][1];
2226 rtx xop0 = op0;
2228 if (target)
2229 temp = target;
2230 else
2231 temp = gen_reg_rtx (submode);
2233 if (GET_MODE (xop0) != VOIDmode
2234 && GET_MODE (xop0) != mode0)
2235 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2237 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2239 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2240 xop0 = copy_to_mode_reg (mode0, xop0);
2242 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2243 temp = gen_reg_rtx (submode);
2245 pat = GEN_FCN (icode) (temp, xop0);
2246 if (pat)
2248 if (GET_CODE (pat) == SEQUENCE
2249 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2251 delete_insns_since (last);
2252 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2255 emit_insn (pat);
2257 return temp;
2259 else
2260 delete_insns_since (last);
2263 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2265 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2266 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2268 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2270 rtx xop0 = op0;
2272 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2273 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2275 if (temp)
2277 if (class != MODE_COMPLEX_INT)
2279 if (target == 0)
2280 target = gen_reg_rtx (submode);
2281 convert_move (target, temp, 0);
2282 return target;
2284 else
2285 return gen_lowpart (submode, temp);
2287 else
2288 delete_insns_since (last);
2292 /* Open-code the complex absolute-value operation
2293 if we can open-code sqrt. Otherwise it's not worth while. */
2294 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2296 rtx real, imag, total;
2298 real = gen_realpart (submode, op0);
2299 imag = gen_imagpart (submode, op0);
2301 /* Square both parts. */
2302 real = expand_mult (submode, real, real, NULL_RTX, 0);
2303 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2305 /* Sum the parts. */
2306 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2307 0, OPTAB_LIB_WIDEN);
2309 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2310 target = expand_unop (submode, sqrt_optab, total, target, 0);
2311 if (target == 0)
2312 delete_insns_since (last);
2313 else
2314 return target;
2317 /* Now try a library call in this mode. */
2318 if (abs_optab->handlers[(int) mode].libfunc)
2320 rtx insns;
2321 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
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 else if (mode == SFmode)
2959 switch (comparison)
2961 case EQ:
2962 libfunc = eqsf2_libfunc;
2963 break;
2965 case NE:
2966 libfunc = nesf2_libfunc;
2967 break;
2969 case GT:
2970 libfunc = gtsf2_libfunc;
2971 break;
2973 case GE:
2974 libfunc = gesf2_libfunc;
2975 break;
2977 case LT:
2978 libfunc = ltsf2_libfunc;
2979 break;
2981 case LE:
2982 libfunc = lesf2_libfunc;
2983 break;
2985 else if (mode == DFmode)
2986 switch (comparison)
2988 case EQ:
2989 libfunc = eqdf2_libfunc;
2990 break;
2992 case NE:
2993 libfunc = nedf2_libfunc;
2994 break;
2996 case GT:
2997 libfunc = gtdf2_libfunc;
2998 break;
3000 case GE:
3001 libfunc = gedf2_libfunc;
3002 break;
3004 case LT:
3005 libfunc = ltdf2_libfunc;
3006 break;
3008 case LE:
3009 libfunc = ledf2_libfunc;
3010 break;
3012 else if (mode == XFmode)
3013 switch (comparison)
3015 case EQ:
3016 libfunc = eqxf2_libfunc;
3017 break;
3019 case NE:
3020 libfunc = nexf2_libfunc;
3021 break;
3023 case GT:
3024 libfunc = gtxf2_libfunc;
3025 break;
3027 case GE:
3028 libfunc = gexf2_libfunc;
3029 break;
3031 case LT:
3032 libfunc = ltxf2_libfunc;
3033 break;
3035 case LE:
3036 libfunc = lexf2_libfunc;
3037 break;
3039 else if (mode == TFmode)
3040 switch (comparison)
3042 case EQ:
3043 libfunc = eqtf2_libfunc;
3044 break;
3046 case NE:
3047 libfunc = netf2_libfunc;
3048 break;
3050 case GT:
3051 libfunc = gttf2_libfunc;
3052 break;
3054 case GE:
3055 libfunc = getf2_libfunc;
3056 break;
3058 case LT:
3059 libfunc = lttf2_libfunc;
3060 break;
3062 case LE:
3063 libfunc = letf2_libfunc;
3064 break;
3066 else
3068 enum machine_mode wider_mode;
3070 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3071 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3073 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3074 != CODE_FOR_nothing)
3075 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3077 x = protect_from_queue (x, 0);
3078 y = protect_from_queue (y, 0);
3079 x = convert_to_mode (wider_mode, x, 0);
3080 y = convert_to_mode (wider_mode, y, 0);
3081 emit_float_lib_cmp (x, y, comparison);
3082 return;
3085 abort ();
3088 if (libfunc == 0)
3089 abort ();
3091 emit_library_call (libfunc, 1,
3092 word_mode, 2, x, mode, y, mode);
3094 /* Immediately move the result of the libcall into a pseudo
3095 register so reload doesn't clobber the value if it needs
3096 the return register for a spill reg. */
3097 result = gen_reg_rtx (word_mode);
3098 emit_move_insn (result, hard_libcall_value (word_mode));
3100 emit_cmp_insn (result, const0_rtx, comparison,
3101 NULL_RTX, word_mode, 0, 0);
3104 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3106 void
3107 emit_indirect_jump (loc)
3108 rtx loc;
3110 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3111 (loc, Pmode)))
3112 loc = copy_to_mode_reg (Pmode, loc);
3114 emit_jump_insn (gen_indirect_jump (loc));
3115 emit_barrier ();
3118 #ifdef HAVE_conditional_move
3120 /* Emit a conditional move instruction if the machine supports one for that
3121 condition and machine mode.
3123 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3124 the mode to use should they be constants. If it is VOIDmode, they cannot
3125 both be constants.
3127 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3128 should be stored there. MODE is the mode to use should they be constants.
3129 If it is VOIDmode, they cannot both be constants.
3131 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3132 is not supported. */
3135 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3136 unsignedp)
3137 rtx target;
3138 enum rtx_code code;
3139 rtx op0, op1;
3140 enum machine_mode cmode;
3141 rtx op2, op3;
3142 enum machine_mode mode;
3143 int unsignedp;
3145 rtx tem, subtarget, comparison, insn;
3146 enum insn_code icode;
3148 /* If one operand is constant, make it the second one. Only do this
3149 if the other operand is not constant as well. */
3151 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3152 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3154 tem = op0;
3155 op0 = op1;
3156 op1 = tem;
3157 code = swap_condition (code);
3160 if (cmode == VOIDmode)
3161 cmode = GET_MODE (op0);
3163 if ((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3164 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3166 tem = op2;
3167 op2 = op3;
3168 op3 = tem;
3169 /* ??? This may not be appropriate (consider IEEE). Perhaps we should
3170 call can_reverse_comparison_p here and bail out if necessary.
3171 It's not clear whether we need to do this canonicalization though. */
3172 code = reverse_condition (code);
3175 if (mode == VOIDmode)
3176 mode = GET_MODE (op2);
3178 icode = movcc_gen_code[mode];
3180 if (icode == CODE_FOR_nothing)
3181 return 0;
3183 if (flag_force_mem)
3185 op2 = force_not_mem (op2);
3186 op3 = force_not_mem (op3);
3189 if (target)
3190 target = protect_from_queue (target, 1);
3191 else
3192 target = gen_reg_rtx (mode);
3194 subtarget = target;
3196 emit_queue ();
3198 op2 = protect_from_queue (op2, 0);
3199 op3 = protect_from_queue (op3, 0);
3201 /* If the insn doesn't accept these operands, put them in pseudos. */
3203 if (! (*insn_operand_predicate[icode][0])
3204 (subtarget, insn_operand_mode[icode][0]))
3205 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3207 if (! (*insn_operand_predicate[icode][2])
3208 (op2, insn_operand_mode[icode][2]))
3209 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3211 if (! (*insn_operand_predicate[icode][3])
3212 (op3, insn_operand_mode[icode][3]))
3213 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3215 /* Everything should now be in the suitable form, so emit the compare insn
3216 and then the conditional move. */
3218 comparison
3219 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3221 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3222 if (GET_CODE (comparison) != code)
3223 /* This shouldn't happen. */
3224 abort ();
3226 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3228 /* If that failed, then give up. */
3229 if (insn == 0)
3230 return 0;
3232 emit_insn (insn);
3234 if (subtarget != target)
3235 convert_move (target, subtarget, 0);
3237 return target;
3240 /* Return non-zero if a conditional move of mode MODE is supported.
3242 This function is for combine so it can tell whether an insn that looks
3243 like a conditional move is actually supported by the hardware. If we
3244 guess wrong we lose a bit on optimization, but that's it. */
3245 /* ??? sparc64 supports conditionally moving integers values based on fp
3246 comparisons, and vice versa. How do we handle them? */
3249 can_conditionally_move_p (mode)
3250 enum machine_mode mode;
3252 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3253 return 1;
3255 return 0;
3258 #endif /* HAVE_conditional_move */
3260 /* These three functions generate an insn body and return it
3261 rather than emitting the insn.
3263 They do not protect from queued increments,
3264 because they may be used 1) in protect_from_queue itself
3265 and 2) in other passes where there is no queue. */
3267 /* Generate and return an insn body to add Y to X. */
3270 gen_add2_insn (x, y)
3271 rtx x, y;
3273 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3275 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3276 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3277 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3278 abort ();
3280 return (GEN_FCN (icode) (x, x, y));
3284 have_add2_insn (mode)
3285 enum machine_mode mode;
3287 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3290 /* Generate and return an insn body to subtract Y from X. */
3293 gen_sub2_insn (x, y)
3294 rtx x, y;
3296 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3298 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3299 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3300 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3301 abort ();
3303 return (GEN_FCN (icode) (x, x, y));
3307 have_sub2_insn (mode)
3308 enum machine_mode mode;
3310 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3313 /* Generate the body of an instruction to copy Y into X.
3314 It may be a SEQUENCE, if one insn isn't enough. */
3317 gen_move_insn (x, y)
3318 rtx x, y;
3320 register enum machine_mode mode = GET_MODE (x);
3321 enum insn_code insn_code;
3322 rtx seq;
3324 if (mode == VOIDmode)
3325 mode = GET_MODE (y);
3327 insn_code = mov_optab->handlers[(int) mode].insn_code;
3329 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3330 find a mode to do it in. If we have a movcc, use it. Otherwise,
3331 find the MODE_INT mode of the same width. */
3333 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3335 enum machine_mode tmode = VOIDmode;
3336 rtx x1 = x, y1 = y;
3338 if (mode != CCmode
3339 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3340 tmode = CCmode;
3341 else
3342 for (tmode = QImode; tmode != VOIDmode;
3343 tmode = GET_MODE_WIDER_MODE (tmode))
3344 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3345 break;
3347 if (tmode == VOIDmode)
3348 abort ();
3350 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3351 may call change_address which is not appropriate if we were
3352 called when a reload was in progress. We don't have to worry
3353 about changing the address since the size in bytes is supposed to
3354 be the same. Copy the MEM to change the mode and move any
3355 substitutions from the old MEM to the new one. */
3357 if (reload_in_progress)
3359 x = gen_lowpart_common (tmode, x1);
3360 if (x == 0 && GET_CODE (x1) == MEM)
3362 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3363 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3364 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3365 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3366 copy_replacements (x1, x);
3369 y = gen_lowpart_common (tmode, y1);
3370 if (y == 0 && GET_CODE (y1) == MEM)
3372 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3373 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3374 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3375 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3376 copy_replacements (y1, y);
3379 else
3381 x = gen_lowpart (tmode, x);
3382 y = gen_lowpart (tmode, y);
3385 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3386 return (GEN_FCN (insn_code) (x, y));
3389 start_sequence ();
3390 emit_move_insn_1 (x, y);
3391 seq = gen_sequence ();
3392 end_sequence ();
3393 return seq;
3396 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3397 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3398 no such operation exists, CODE_FOR_nothing will be returned. */
3400 enum insn_code
3401 can_extend_p (to_mode, from_mode, unsignedp)
3402 enum machine_mode to_mode, from_mode;
3403 int unsignedp;
3405 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3408 /* Generate the body of an insn to extend Y (with mode MFROM)
3409 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3412 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3413 rtx x, y;
3414 enum machine_mode mto, mfrom;
3415 int unsignedp;
3417 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3420 /* can_fix_p and can_float_p say whether the target machine
3421 can directly convert a given fixed point type to
3422 a given floating point type, or vice versa.
3423 The returned value is the CODE_FOR_... value to use,
3424 or CODE_FOR_nothing if these modes cannot be directly converted.
3426 *TRUNCP_PTR is set to 1 if it is necessary to output
3427 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3429 static enum insn_code
3430 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3431 enum machine_mode fltmode, fixmode;
3432 int unsignedp;
3433 int *truncp_ptr;
3435 *truncp_ptr = 0;
3436 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3437 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3439 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3441 *truncp_ptr = 1;
3442 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3444 return CODE_FOR_nothing;
3447 static enum insn_code
3448 can_float_p (fltmode, fixmode, unsignedp)
3449 enum machine_mode fixmode, fltmode;
3450 int unsignedp;
3452 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3455 /* Generate code to convert FROM to floating point
3456 and store in TO. FROM must be fixed point and not VOIDmode.
3457 UNSIGNEDP nonzero means regard FROM as unsigned.
3458 Normally this is done by correcting the final value
3459 if it is negative. */
3461 void
3462 expand_float (to, from, unsignedp)
3463 rtx to, from;
3464 int unsignedp;
3466 enum insn_code icode;
3467 register rtx target = to;
3468 enum machine_mode fmode, imode;
3470 /* Crash now, because we won't be able to decide which mode to use. */
3471 if (GET_MODE (from) == VOIDmode)
3472 abort ();
3474 /* Look for an insn to do the conversion. Do it in the specified
3475 modes if possible; otherwise convert either input, output or both to
3476 wider mode. If the integer mode is wider than the mode of FROM,
3477 we can do the conversion signed even if the input is unsigned. */
3479 for (imode = GET_MODE (from); imode != VOIDmode;
3480 imode = GET_MODE_WIDER_MODE (imode))
3481 for (fmode = GET_MODE (to); fmode != VOIDmode;
3482 fmode = GET_MODE_WIDER_MODE (fmode))
3484 int doing_unsigned = unsignedp;
3486 icode = can_float_p (fmode, imode, unsignedp);
3487 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3488 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3490 if (icode != CODE_FOR_nothing)
3492 to = protect_from_queue (to, 1);
3493 from = protect_from_queue (from, 0);
3495 if (imode != GET_MODE (from))
3496 from = convert_to_mode (imode, from, unsignedp);
3498 if (fmode != GET_MODE (to))
3499 target = gen_reg_rtx (fmode);
3501 emit_unop_insn (icode, target, from,
3502 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3504 if (target != to)
3505 convert_move (to, target, 0);
3506 return;
3510 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3512 /* Unsigned integer, and no way to convert directly.
3513 Convert as signed, then conditionally adjust the result. */
3514 if (unsignedp)
3516 rtx label = gen_label_rtx ();
3517 rtx temp;
3518 REAL_VALUE_TYPE offset;
3520 emit_queue ();
3522 to = protect_from_queue (to, 1);
3523 from = protect_from_queue (from, 0);
3525 if (flag_force_mem)
3526 from = force_not_mem (from);
3528 /* Look for a usable floating mode FMODE wider than the source and at
3529 least as wide as the target. Using FMODE will avoid rounding woes
3530 with unsigned values greater than the signed maximum value. */
3532 for (fmode = GET_MODE (to); fmode != VOIDmode;
3533 fmode = GET_MODE_WIDER_MODE (fmode))
3534 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3535 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3536 break;
3538 if (fmode == VOIDmode)
3540 /* There is no such mode. Pretend the target is wide enough. */
3541 fmode = GET_MODE (to);
3543 /* Avoid double-rounding when TO is narrower than FROM. */
3544 if ((significand_size (fmode) + 1)
3545 < GET_MODE_BITSIZE (GET_MODE (from)))
3547 rtx temp1;
3548 rtx neglabel = gen_label_rtx ();
3550 /* Don't use TARGET if it isn't a register, is a hard register,
3551 or is the wrong mode. */
3552 if (GET_CODE (target) != REG
3553 || REGNO (target) < FIRST_PSEUDO_REGISTER
3554 || GET_MODE (target) != fmode)
3555 target = gen_reg_rtx (fmode);
3557 imode = GET_MODE (from);
3558 do_pending_stack_adjust ();
3560 /* Test whether the sign bit is set. */
3561 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3562 emit_jump_insn (gen_blt (neglabel));
3564 /* The sign bit is not set. Convert as signed. */
3565 expand_float (target, from, 0);
3566 emit_jump_insn (gen_jump (label));
3567 emit_barrier ();
3569 /* The sign bit is set.
3570 Convert to a usable (positive signed) value by shifting right
3571 one bit, while remembering if a nonzero bit was shifted
3572 out; i.e., compute (from & 1) | (from >> 1). */
3574 emit_label (neglabel);
3575 temp = expand_binop (imode, and_optab, from, const1_rtx,
3576 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3577 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3578 NULL_RTX, 1);
3579 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3580 OPTAB_LIB_WIDEN);
3581 expand_float (target, temp, 0);
3583 /* Multiply by 2 to undo the shift above. */
3584 temp = expand_binop (fmode, add_optab, target, target,
3585 target, 0, OPTAB_LIB_WIDEN);
3586 if (temp != target)
3587 emit_move_insn (target, temp);
3589 do_pending_stack_adjust ();
3590 emit_label (label);
3591 goto done;
3595 /* If we are about to do some arithmetic to correct for an
3596 unsigned operand, do it in a pseudo-register. */
3598 if (GET_MODE (to) != fmode
3599 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3600 target = gen_reg_rtx (fmode);
3602 /* Convert as signed integer to floating. */
3603 expand_float (target, from, 0);
3605 /* If FROM is negative (and therefore TO is negative),
3606 correct its value by 2**bitwidth. */
3608 do_pending_stack_adjust ();
3609 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3610 emit_jump_insn (gen_bge (label));
3612 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3613 Rather than setting up a dconst_dot_5, let's hope SCO
3614 fixes the bug. */
3615 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3616 temp = expand_binop (fmode, add_optab, target,
3617 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3618 target, 0, OPTAB_LIB_WIDEN);
3619 if (temp != target)
3620 emit_move_insn (target, temp);
3622 do_pending_stack_adjust ();
3623 emit_label (label);
3624 goto done;
3626 #endif
3628 /* No hardware instruction available; call a library routine to convert from
3629 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3631 rtx libfcn;
3632 rtx insns;
3633 rtx value;
3635 to = protect_from_queue (to, 1);
3636 from = protect_from_queue (from, 0);
3638 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3639 from = convert_to_mode (SImode, from, unsignedp);
3641 if (flag_force_mem)
3642 from = force_not_mem (from);
3644 if (GET_MODE (to) == SFmode)
3646 if (GET_MODE (from) == SImode)
3647 libfcn = floatsisf_libfunc;
3648 else if (GET_MODE (from) == DImode)
3649 libfcn = floatdisf_libfunc;
3650 else if (GET_MODE (from) == TImode)
3651 libfcn = floattisf_libfunc;
3652 else
3653 abort ();
3655 else if (GET_MODE (to) == DFmode)
3657 if (GET_MODE (from) == SImode)
3658 libfcn = floatsidf_libfunc;
3659 else if (GET_MODE (from) == DImode)
3660 libfcn = floatdidf_libfunc;
3661 else if (GET_MODE (from) == TImode)
3662 libfcn = floattidf_libfunc;
3663 else
3664 abort ();
3666 else if (GET_MODE (to) == XFmode)
3668 if (GET_MODE (from) == SImode)
3669 libfcn = floatsixf_libfunc;
3670 else if (GET_MODE (from) == DImode)
3671 libfcn = floatdixf_libfunc;
3672 else if (GET_MODE (from) == TImode)
3673 libfcn = floattixf_libfunc;
3674 else
3675 abort ();
3677 else if (GET_MODE (to) == TFmode)
3679 if (GET_MODE (from) == SImode)
3680 libfcn = floatsitf_libfunc;
3681 else if (GET_MODE (from) == DImode)
3682 libfcn = floatditf_libfunc;
3683 else if (GET_MODE (from) == TImode)
3684 libfcn = floattitf_libfunc;
3685 else
3686 abort ();
3688 else
3689 abort ();
3691 start_sequence ();
3693 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3694 GET_MODE (to),
3695 1, from, GET_MODE (from));
3696 insns = get_insns ();
3697 end_sequence ();
3699 emit_libcall_block (insns, target, value,
3700 gen_rtx (FLOAT, GET_MODE (to), from));
3703 done:
3705 /* Copy result to requested destination
3706 if we have been computing in a temp location. */
3708 if (target != to)
3710 if (GET_MODE (target) == GET_MODE (to))
3711 emit_move_insn (to, target);
3712 else
3713 convert_move (to, target, 0);
3717 /* expand_fix: generate code to convert FROM to fixed point
3718 and store in TO. FROM must be floating point. */
3720 static rtx
3721 ftruncify (x)
3722 rtx x;
3724 rtx temp = gen_reg_rtx (GET_MODE (x));
3725 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3728 void
3729 expand_fix (to, from, unsignedp)
3730 register rtx to, from;
3731 int unsignedp;
3733 enum insn_code icode;
3734 register rtx target = to;
3735 enum machine_mode fmode, imode;
3736 int must_trunc = 0;
3737 rtx libfcn = 0;
3739 /* We first try to find a pair of modes, one real and one integer, at
3740 least as wide as FROM and TO, respectively, in which we can open-code
3741 this conversion. If the integer mode is wider than the mode of TO,
3742 we can do the conversion either signed or unsigned. */
3744 for (imode = GET_MODE (to); imode != VOIDmode;
3745 imode = GET_MODE_WIDER_MODE (imode))
3746 for (fmode = GET_MODE (from); fmode != VOIDmode;
3747 fmode = GET_MODE_WIDER_MODE (fmode))
3749 int doing_unsigned = unsignedp;
3751 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3752 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3753 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3755 if (icode != CODE_FOR_nothing)
3757 to = protect_from_queue (to, 1);
3758 from = protect_from_queue (from, 0);
3760 if (fmode != GET_MODE (from))
3761 from = convert_to_mode (fmode, from, 0);
3763 if (must_trunc)
3764 from = ftruncify (from);
3766 if (imode != GET_MODE (to))
3767 target = gen_reg_rtx (imode);
3769 emit_unop_insn (icode, target, from,
3770 doing_unsigned ? UNSIGNED_FIX : FIX);
3771 if (target != to)
3772 convert_move (to, target, unsignedp);
3773 return;
3777 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3778 /* For an unsigned conversion, there is one more way to do it.
3779 If we have a signed conversion, we generate code that compares
3780 the real value to the largest representable positive number. If if
3781 is smaller, the conversion is done normally. Otherwise, subtract
3782 one plus the highest signed number, convert, and add it back.
3784 We only need to check all real modes, since we know we didn't find
3785 anything with a wider integer mode. */
3787 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3788 for (fmode = GET_MODE (from); fmode != VOIDmode;
3789 fmode = GET_MODE_WIDER_MODE (fmode))
3790 /* Make sure we won't lose significant bits doing this. */
3791 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3792 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3793 &must_trunc))
3795 int bitsize;
3796 REAL_VALUE_TYPE offset;
3797 rtx limit, lab1, lab2, insn;
3799 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3800 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3801 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3802 lab1 = gen_label_rtx ();
3803 lab2 = gen_label_rtx ();
3805 emit_queue ();
3806 to = protect_from_queue (to, 1);
3807 from = protect_from_queue (from, 0);
3809 if (flag_force_mem)
3810 from = force_not_mem (from);
3812 if (fmode != GET_MODE (from))
3813 from = convert_to_mode (fmode, from, 0);
3815 /* See if we need to do the subtraction. */
3816 do_pending_stack_adjust ();
3817 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3818 emit_jump_insn (gen_bge (lab1));
3820 /* If not, do the signed "fix" and branch around fixup code. */
3821 expand_fix (to, from, 0);
3822 emit_jump_insn (gen_jump (lab2));
3823 emit_barrier ();
3825 /* Otherwise, subtract 2**(N-1), convert to signed number,
3826 then add 2**(N-1). Do the addition using XOR since this
3827 will often generate better code. */
3828 emit_label (lab1);
3829 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3830 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3831 expand_fix (to, target, 0);
3832 target = expand_binop (GET_MODE (to), xor_optab, to,
3833 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3834 to, 1, OPTAB_LIB_WIDEN);
3836 if (target != to)
3837 emit_move_insn (to, target);
3839 emit_label (lab2);
3841 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
3842 != CODE_FOR_nothing)
3844 /* Make a place for a REG_NOTE and add it. */
3845 insn = emit_move_insn (to, to);
3846 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3847 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3848 copy_rtx (from)),
3849 REG_NOTES (insn));
3851 return;
3853 #endif
3855 /* We can't do it with an insn, so use a library call. But first ensure
3856 that the mode of TO is at least as wide as SImode, since those are the
3857 only library calls we know about. */
3859 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3861 target = gen_reg_rtx (SImode);
3863 expand_fix (target, from, unsignedp);
3865 else if (GET_MODE (from) == SFmode)
3867 if (GET_MODE (to) == SImode)
3868 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3869 else if (GET_MODE (to) == DImode)
3870 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3871 else if (GET_MODE (to) == TImode)
3872 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3873 else
3874 abort ();
3876 else if (GET_MODE (from) == DFmode)
3878 if (GET_MODE (to) == SImode)
3879 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3880 else if (GET_MODE (to) == DImode)
3881 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3882 else if (GET_MODE (to) == TImode)
3883 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3884 else
3885 abort ();
3887 else if (GET_MODE (from) == XFmode)
3889 if (GET_MODE (to) == SImode)
3890 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3891 else if (GET_MODE (to) == DImode)
3892 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3893 else if (GET_MODE (to) == TImode)
3894 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3895 else
3896 abort ();
3898 else if (GET_MODE (from) == TFmode)
3900 if (GET_MODE (to) == SImode)
3901 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3902 else if (GET_MODE (to) == DImode)
3903 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3904 else if (GET_MODE (to) == TImode)
3905 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3906 else
3907 abort ();
3909 else
3910 abort ();
3912 if (libfcn)
3914 rtx insns;
3915 rtx value;
3917 to = protect_from_queue (to, 1);
3918 from = protect_from_queue (from, 0);
3920 if (flag_force_mem)
3921 from = force_not_mem (from);
3923 start_sequence ();
3925 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3927 1, from, GET_MODE (from));
3928 insns = get_insns ();
3929 end_sequence ();
3931 emit_libcall_block (insns, target, value,
3932 gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3933 GET_MODE (to), from));
3936 if (target != to)
3938 if (GET_MODE (to) == GET_MODE (target))
3939 emit_move_insn (to, target);
3940 else
3941 convert_move (to, target, 0);
3945 static optab
3946 init_optab (code)
3947 enum rtx_code code;
3949 int i;
3950 optab op = (optab) xmalloc (sizeof (struct optab));
3951 op->code = code;
3952 for (i = 0; i < NUM_MACHINE_MODES; i++)
3954 op->handlers[i].insn_code = CODE_FOR_nothing;
3955 op->handlers[i].libfunc = 0;
3958 if (code != UNKNOWN)
3959 code_to_optab[(int) code] = op;
3961 return op;
3964 /* Initialize the libfunc fields of an entire group of entries in some
3965 optab. Each entry is set equal to a string consisting of a leading
3966 pair of underscores followed by a generic operation name followed by
3967 a mode name (downshifted to lower case) followed by a single character
3968 representing the number of operands for the given operation (which is
3969 usually one of the characters '2', '3', or '4').
3971 OPTABLE is the table in which libfunc fields are to be initialized.
3972 FIRST_MODE is the first machine mode index in the given optab to
3973 initialize.
3974 LAST_MODE is the last machine mode index in the given optab to
3975 initialize.
3976 OPNAME is the generic (string) name of the operation.
3977 SUFFIX is the character which specifies the number of operands for
3978 the given generic operation.
3981 static void
3982 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3983 register optab optable;
3984 register int first_mode;
3985 register int last_mode;
3986 register char *opname;
3987 register int suffix;
3989 register int mode;
3990 register unsigned opname_len = strlen (opname);
3992 for (mode = first_mode; (int) mode <= (int) last_mode;
3993 mode = (enum machine_mode) ((int) mode + 1))
3995 register char *mname = mode_name[(int) mode];
3996 register unsigned mname_len = strlen (mname);
3997 register char *libfunc_name
3998 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
3999 register char *p;
4000 register char *q;
4002 p = libfunc_name;
4003 *p++ = '_';
4004 *p++ = '_';
4005 for (q = opname; *q; )
4006 *p++ = *q++;
4007 for (q = mname; *q; q++)
4008 *p++ = tolower (*q);
4009 *p++ = suffix;
4010 *p++ = '\0';
4011 optable->handlers[(int) mode].libfunc
4012 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
4016 /* Initialize the libfunc fields of an entire group of entries in some
4017 optab which correspond to all integer mode operations. The parameters
4018 have the same meaning as similarly named ones for the `init_libfuncs'
4019 routine. (See above). */
4021 static void
4022 init_integral_libfuncs (optable, opname, suffix)
4023 register optab optable;
4024 register char *opname;
4025 register int suffix;
4027 init_libfuncs (optable, SImode, TImode, opname, suffix);
4030 /* Initialize the libfunc fields of an entire group of entries in some
4031 optab which correspond to all real 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_floating_libfuncs (optable, opname, suffix)
4037 register optab optable;
4038 register char *opname;
4039 register int suffix;
4041 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4044 /* Initialize the libfunc fields of an entire group of entries in some
4045 optab which correspond to all complex floating modes. The parameters
4046 have the same meaning as similarly named ones for the `init_libfuncs'
4047 routine. (See above). */
4049 static void
4050 init_complex_libfuncs (optable, opname, suffix)
4051 register optab optable;
4052 register char *opname;
4053 register int suffix;
4055 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
4058 /* Call this once to initialize the contents of the optabs
4059 appropriately for the current target machine. */
4061 void
4062 init_optabs ()
4064 int i, j;
4065 enum insn_code *p;
4067 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4069 for (p = fixtab[0][0];
4070 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4071 p++)
4072 *p = CODE_FOR_nothing;
4074 for (p = fixtrunctab[0][0];
4075 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4076 p++)
4077 *p = CODE_FOR_nothing;
4079 for (p = floattab[0][0];
4080 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4081 p++)
4082 *p = CODE_FOR_nothing;
4084 for (p = extendtab[0][0];
4085 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4086 p++)
4087 *p = CODE_FOR_nothing;
4089 for (i = 0; i < NUM_RTX_CODE; i++)
4090 setcc_gen_code[i] = CODE_FOR_nothing;
4092 #ifdef HAVE_conditional_move
4093 for (i = 0; i < NUM_MACHINE_MODES; i++)
4094 movcc_gen_code[i] = CODE_FOR_nothing;
4095 #endif
4097 add_optab = init_optab (PLUS);
4098 sub_optab = init_optab (MINUS);
4099 smul_optab = init_optab (MULT);
4100 smul_highpart_optab = init_optab (UNKNOWN);
4101 umul_highpart_optab = init_optab (UNKNOWN);
4102 smul_widen_optab = init_optab (UNKNOWN);
4103 umul_widen_optab = init_optab (UNKNOWN);
4104 sdiv_optab = init_optab (DIV);
4105 sdivmod_optab = init_optab (UNKNOWN);
4106 udiv_optab = init_optab (UDIV);
4107 udivmod_optab = init_optab (UNKNOWN);
4108 smod_optab = init_optab (MOD);
4109 umod_optab = init_optab (UMOD);
4110 flodiv_optab = init_optab (DIV);
4111 ftrunc_optab = init_optab (UNKNOWN);
4112 and_optab = init_optab (AND);
4113 ior_optab = init_optab (IOR);
4114 xor_optab = init_optab (XOR);
4115 ashl_optab = init_optab (ASHIFT);
4116 ashr_optab = init_optab (ASHIFTRT);
4117 lshr_optab = init_optab (LSHIFTRT);
4118 rotl_optab = init_optab (ROTATE);
4119 rotr_optab = init_optab (ROTATERT);
4120 smin_optab = init_optab (SMIN);
4121 smax_optab = init_optab (SMAX);
4122 umin_optab = init_optab (UMIN);
4123 umax_optab = init_optab (UMAX);
4124 mov_optab = init_optab (UNKNOWN);
4125 movstrict_optab = init_optab (UNKNOWN);
4126 cmp_optab = init_optab (UNKNOWN);
4127 ucmp_optab = init_optab (UNKNOWN);
4128 tst_optab = init_optab (UNKNOWN);
4129 neg_optab = init_optab (NEG);
4130 abs_optab = init_optab (ABS);
4131 one_cmpl_optab = init_optab (NOT);
4132 ffs_optab = init_optab (FFS);
4133 sqrt_optab = init_optab (SQRT);
4134 sin_optab = init_optab (UNKNOWN);
4135 cos_optab = init_optab (UNKNOWN);
4136 strlen_optab = init_optab (UNKNOWN);
4138 for (i = 0; i < NUM_MACHINE_MODES; i++)
4140 movstr_optab[i] = CODE_FOR_nothing;
4141 clrstr_optab[i] = CODE_FOR_nothing;
4143 #ifdef HAVE_SECONDARY_RELOADS
4144 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4145 #endif
4148 /* Fill in the optabs with the insns we support. */
4149 init_all_optabs ();
4151 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4152 /* This flag says the same insns that convert to a signed fixnum
4153 also convert validly to an unsigned one. */
4154 for (i = 0; i < NUM_MACHINE_MODES; i++)
4155 for (j = 0; j < NUM_MACHINE_MODES; j++)
4156 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4157 #endif
4159 #ifdef EXTRA_CC_MODES
4160 init_mov_optab ();
4161 #endif
4163 /* Initialize the optabs with the names of the library functions. */
4164 init_integral_libfuncs (add_optab, "add", '3');
4165 init_floating_libfuncs (add_optab, "add", '3');
4166 init_integral_libfuncs (sub_optab, "sub", '3');
4167 init_floating_libfuncs (sub_optab, "sub", '3');
4168 init_integral_libfuncs (smul_optab, "mul", '3');
4169 init_floating_libfuncs (smul_optab, "mul", '3');
4170 init_integral_libfuncs (sdiv_optab, "div", '3');
4171 init_integral_libfuncs (udiv_optab, "udiv", '3');
4172 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4173 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4174 init_integral_libfuncs (smod_optab, "mod", '3');
4175 init_integral_libfuncs (umod_optab, "umod", '3');
4176 init_floating_libfuncs (flodiv_optab, "div", '3');
4177 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4178 init_integral_libfuncs (and_optab, "and", '3');
4179 init_integral_libfuncs (ior_optab, "ior", '3');
4180 init_integral_libfuncs (xor_optab, "xor", '3');
4181 init_integral_libfuncs (ashl_optab, "ashl", '3');
4182 init_integral_libfuncs (ashr_optab, "ashr", '3');
4183 init_integral_libfuncs (lshr_optab, "lshr", '3');
4184 init_integral_libfuncs (smin_optab, "min", '3');
4185 init_floating_libfuncs (smin_optab, "min", '3');
4186 init_integral_libfuncs (smax_optab, "max", '3');
4187 init_floating_libfuncs (smax_optab, "max", '3');
4188 init_integral_libfuncs (umin_optab, "umin", '3');
4189 init_integral_libfuncs (umax_optab, "umax", '3');
4190 init_integral_libfuncs (neg_optab, "neg", '2');
4191 init_floating_libfuncs (neg_optab, "neg", '2');
4192 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4193 init_integral_libfuncs (ffs_optab, "ffs", '2');
4195 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4196 init_integral_libfuncs (cmp_optab, "cmp", '2');
4197 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4198 init_floating_libfuncs (cmp_optab, "cmp", '2');
4200 #ifdef MULSI3_LIBCALL
4201 smul_optab->handlers[(int) SImode].libfunc
4202 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4203 #endif
4204 #ifdef MULDI3_LIBCALL
4205 smul_optab->handlers[(int) DImode].libfunc
4206 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4207 #endif
4209 #ifdef DIVSI3_LIBCALL
4210 sdiv_optab->handlers[(int) SImode].libfunc
4211 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4212 #endif
4213 #ifdef DIVDI3_LIBCALL
4214 sdiv_optab->handlers[(int) DImode].libfunc
4215 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4216 #endif
4218 #ifdef UDIVSI3_LIBCALL
4219 udiv_optab->handlers[(int) SImode].libfunc
4220 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4221 #endif
4222 #ifdef UDIVDI3_LIBCALL
4223 udiv_optab->handlers[(int) DImode].libfunc
4224 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4225 #endif
4227 #ifdef MODSI3_LIBCALL
4228 smod_optab->handlers[(int) SImode].libfunc
4229 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4230 #endif
4231 #ifdef MODDI3_LIBCALL
4232 smod_optab->handlers[(int) DImode].libfunc
4233 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4234 #endif
4236 #ifdef UMODSI3_LIBCALL
4237 umod_optab->handlers[(int) SImode].libfunc
4238 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4239 #endif
4240 #ifdef UMODDI3_LIBCALL
4241 umod_optab->handlers[(int) DImode].libfunc
4242 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4243 #endif
4245 /* Use cabs for DC complex abs, since systems generally have cabs.
4246 Don't define any libcall for SCmode, so that cabs will be used. */
4247 abs_optab->handlers[(int) DCmode].libfunc
4248 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4250 /* The ffs function operates on `int'. */
4251 #ifndef INT_TYPE_SIZE
4252 #define INT_TYPE_SIZE BITS_PER_WORD
4253 #endif
4254 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4255 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4257 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4258 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4259 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4260 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4261 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4263 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4264 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4265 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4266 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4267 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4269 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4270 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4271 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4272 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4273 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4274 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4276 throw_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__throw");
4277 sjthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjthrow");
4278 sjpopnthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjpopnthrow");
4279 terminate_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__terminate");
4280 #ifndef DONT_USE_BUILTIN_SETJMP
4281 setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_setjmp");
4282 longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_longjmp");
4283 #else
4284 setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "setjmp");
4285 longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "longjmp");
4286 #endif
4287 get_dynamic_handler_chain_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__get_dynamic_handler_chain");
4289 eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4290 nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4291 gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4292 gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4293 lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4294 lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4296 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4297 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4298 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4299 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4300 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4301 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4303 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4304 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4305 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4306 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4307 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4308 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4310 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4311 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4312 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4313 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4314 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4315 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4317 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4318 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4319 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4320 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4321 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4322 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4324 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4325 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4326 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4328 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4329 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4330 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4332 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4333 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4334 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4336 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4337 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4338 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4340 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4341 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4342 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4344 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4345 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4346 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4348 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4349 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4350 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4352 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4353 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4354 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4356 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4357 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4358 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4360 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4361 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4362 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4364 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4365 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4366 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4368 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4369 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4370 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4372 #ifdef INIT_TARGET_OPTABS
4373 /* Allow the target to add more libcalls or rename some, etc. */
4374 INIT_TARGET_OPTABS;
4375 #endif
4378 #ifdef BROKEN_LDEXP
4380 /* SCO 3.2 apparently has a broken ldexp. */
4382 double
4383 ldexp(x,n)
4384 double x;
4385 int n;
4387 if (n > 0)
4388 while (n--)
4389 x *= 2;
4391 return x;
4393 #endif /* BROKEN_LDEXP */