* except.c (expand_start_catch_block): We only need the rethrow
[official-gcc.git] / gcc / optabs.c
bloba5f2e7ed064311f71f45fec0ee4d6f0aa095bebd
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 rtx chkr_check_addr_libfunc;
213 rtx chkr_set_right_libfunc;
214 rtx chkr_copy_bitmap_libfunc;
215 rtx chkr_check_exec_libfunc;
217 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
218 gives the gen_function to make a branch to test that condition. */
220 rtxfun bcc_gen_fctn[NUM_RTX_CODE];
222 /* Indexed by the rtx-code for a conditional (eg. EQ, LT,...)
223 gives the insn code to make a store-condition insn
224 to test that condition. */
226 enum insn_code setcc_gen_code[NUM_RTX_CODE];
228 #ifdef HAVE_conditional_move
229 /* Indexed by the machine mode, gives the insn code to make a conditional
230 move insn. This is not indexed by the rtx-code like bcc_gen_fctn and
231 setcc_gen_code to cut down on the number of named patterns. Consider a day
232 when a lot more rtx codes are conditional (eg: for the ARM). */
234 enum insn_code movcc_gen_code[NUM_MACHINE_MODES];
235 #endif
237 static int add_equal_note PROTO((rtx, rtx, enum rtx_code, rtx, rtx));
238 static rtx widen_operand PROTO((rtx, enum machine_mode,
239 enum machine_mode, int, int));
240 static enum insn_code can_fix_p PROTO((enum machine_mode, enum machine_mode,
241 int, int *));
242 static enum insn_code can_float_p PROTO((enum machine_mode, enum machine_mode,
243 int));
244 static rtx ftruncify PROTO((rtx));
245 static optab init_optab PROTO((enum rtx_code));
246 static void init_libfuncs PROTO((optab, int, int, char *, int));
247 static void init_integral_libfuncs PROTO((optab, char *, int));
248 static void init_floating_libfuncs PROTO((optab, char *, int));
249 static void init_complex_libfuncs PROTO((optab, char *, int));
251 /* Add a REG_EQUAL note to the last insn in SEQ. TARGET is being set to
252 the result of operation CODE applied to OP0 (and OP1 if it is a binary
253 operation).
255 If the last insn does not set TARGET, don't do anything, but return 1.
257 If a previous insn sets TARGET and TARGET is one of OP0 or OP1,
258 don't add the REG_EQUAL note but return 0. Our caller can then try
259 again, ensuring that TARGET is not one of the operands. */
261 static int
262 add_equal_note (seq, target, code, op0, op1)
263 rtx seq;
264 rtx target;
265 enum rtx_code code;
266 rtx op0, op1;
268 rtx set;
269 int i;
270 rtx note;
272 if ((GET_RTX_CLASS (code) != '1' && GET_RTX_CLASS (code) != '2'
273 && GET_RTX_CLASS (code) != 'c' && GET_RTX_CLASS (code) != '<')
274 || GET_CODE (seq) != SEQUENCE
275 || (set = single_set (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))) == 0
276 || GET_CODE (target) == ZERO_EXTRACT
277 || (! rtx_equal_p (SET_DEST (set), target)
278 /* For a STRICT_LOW_PART, the REG_NOTE applies to what is inside the
279 SUBREG. */
280 && (GET_CODE (SET_DEST (set)) != STRICT_LOW_PART
281 || ! rtx_equal_p (SUBREG_REG (XEXP (SET_DEST (set), 0)),
282 target))))
283 return 1;
285 /* If TARGET is in OP0 or OP1, check if anything in SEQ sets TARGET
286 besides the last insn. */
287 if (reg_overlap_mentioned_p (target, op0)
288 || (op1 && reg_overlap_mentioned_p (target, op1)))
289 for (i = XVECLEN (seq, 0) - 2; i >= 0; i--)
290 if (reg_set_p (target, XVECEXP (seq, 0, i)))
291 return 0;
293 if (GET_RTX_CLASS (code) == '1')
294 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0));
295 else
296 note = gen_rtx (code, GET_MODE (target), copy_rtx (op0), copy_rtx (op1));
298 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1))
299 = gen_rtx (EXPR_LIST, REG_EQUAL, note,
300 REG_NOTES (XVECEXP (seq, 0, XVECLEN (seq, 0) - 1)));
302 return 1;
305 /* Widen OP to MODE and return the rtx for the widened operand. UNSIGNEDP
306 says whether OP is signed or unsigned. NO_EXTEND is nonzero if we need
307 not actually do a sign-extend or zero-extend, but can leave the
308 higher-order bits of the result rtx undefined, for example, in the case
309 of logical operations, but not right shifts. */
311 static rtx
312 widen_operand (op, mode, oldmode, unsignedp, no_extend)
313 rtx op;
314 enum machine_mode mode, oldmode;
315 int unsignedp;
316 int no_extend;
318 rtx result;
320 /* If we must extend do so. If OP is either a constant or a SUBREG
321 for a promoted object, also extend since it will be more efficient to
322 do so. */
323 if (! no_extend
324 || GET_MODE (op) == VOIDmode
325 || (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op)))
326 return convert_modes (mode, oldmode, op, unsignedp);
328 /* If MODE is no wider than a single word, we return a paradoxical
329 SUBREG. */
330 if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
331 return gen_rtx (SUBREG, mode, force_reg (GET_MODE (op), op), 0);
333 /* Otherwise, get an object of MODE, clobber it, and set the low-order
334 part to OP. */
336 result = gen_reg_rtx (mode);
337 emit_insn (gen_rtx (CLOBBER, VOIDmode, result));
338 emit_move_insn (gen_lowpart (GET_MODE (op), result), op);
339 return result;
342 /* Generate code to perform an operation specified by BINOPTAB
343 on operands OP0 and OP1, with result having machine-mode MODE.
345 UNSIGNEDP is for the case where we have to widen the operands
346 to perform the operation. It says to use zero-extension.
348 If TARGET is nonzero, the value
349 is generated there, if it is convenient to do so.
350 In all cases an rtx is returned for the locus of the value;
351 this may or may not be TARGET. */
354 expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
355 enum machine_mode mode;
356 optab binoptab;
357 rtx op0, op1;
358 rtx target;
359 int unsignedp;
360 enum optab_methods methods;
362 enum optab_methods next_methods
363 = (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN
364 ? OPTAB_WIDEN : methods);
365 enum mode_class class;
366 enum machine_mode wider_mode;
367 register rtx temp;
368 int commutative_op = 0;
369 int shift_op = (binoptab->code == ASHIFT
370 || binoptab->code == ASHIFTRT
371 || binoptab->code == LSHIFTRT
372 || binoptab->code == ROTATE
373 || binoptab->code == ROTATERT);
374 rtx entry_last = get_last_insn ();
375 rtx last;
377 class = GET_MODE_CLASS (mode);
379 op0 = protect_from_queue (op0, 0);
380 op1 = protect_from_queue (op1, 0);
381 if (target)
382 target = protect_from_queue (target, 1);
384 if (flag_force_mem)
386 op0 = force_not_mem (op0);
387 op1 = force_not_mem (op1);
390 /* If subtracting an integer constant, convert this into an addition of
391 the negated constant. */
393 if (binoptab == sub_optab && GET_CODE (op1) == CONST_INT)
395 op1 = negate_rtx (mode, op1);
396 binoptab = add_optab;
399 /* If we are inside an appropriately-short loop and one operand is an
400 expensive constant, force it into a register. */
401 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
402 && rtx_cost (op0, binoptab->code) > 2)
403 op0 = force_reg (mode, op0);
405 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
406 && ! shift_op && rtx_cost (op1, binoptab->code) > 2)
407 op1 = force_reg (mode, op1);
409 /* Record where to delete back to if we backtrack. */
410 last = get_last_insn ();
412 /* If operation is commutative,
413 try to make the first operand a register.
414 Even better, try to make it the same as the target.
415 Also try to make the last operand a constant. */
416 if (GET_RTX_CLASS (binoptab->code) == 'c'
417 || binoptab == smul_widen_optab
418 || binoptab == umul_widen_optab
419 || binoptab == smul_highpart_optab
420 || binoptab == umul_highpart_optab)
422 commutative_op = 1;
424 if (((target == 0 || GET_CODE (target) == REG)
425 ? ((GET_CODE (op1) == REG
426 && GET_CODE (op0) != REG)
427 || target == op1)
428 : rtx_equal_p (op1, target))
429 || GET_CODE (op0) == CONST_INT)
431 temp = op1;
432 op1 = op0;
433 op0 = temp;
437 /* If we can do it with a three-operand insn, do so. */
439 if (methods != OPTAB_MUST_WIDEN
440 && binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
442 int icode = (int) binoptab->handlers[(int) mode].insn_code;
443 enum machine_mode mode0 = insn_operand_mode[icode][1];
444 enum machine_mode mode1 = insn_operand_mode[icode][2];
445 rtx pat;
446 rtx xop0 = op0, xop1 = op1;
448 if (target)
449 temp = target;
450 else
451 temp = gen_reg_rtx (mode);
453 /* If it is a commutative operator and the modes would match
454 if we would swap the operands, we can save the conversions. */
455 if (commutative_op)
457 if (GET_MODE (op0) != mode0 && GET_MODE (op1) != mode1
458 && GET_MODE (op0) == mode1 && GET_MODE (op1) == mode0)
460 register rtx tmp;
462 tmp = op0; op0 = op1; op1 = tmp;
463 tmp = xop0; xop0 = xop1; xop1 = tmp;
467 /* In case the insn wants input operands in modes different from
468 the result, convert the operands. */
470 if (GET_MODE (op0) != VOIDmode
471 && GET_MODE (op0) != mode0
472 && mode0 != VOIDmode)
473 xop0 = convert_to_mode (mode0, xop0, unsignedp);
475 if (GET_MODE (xop1) != VOIDmode
476 && GET_MODE (xop1) != mode1
477 && mode1 != VOIDmode)
478 xop1 = convert_to_mode (mode1, xop1, unsignedp);
480 /* Now, if insn's predicates don't allow our operands, put them into
481 pseudo regs. */
483 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0)
484 && mode0 != VOIDmode)
485 xop0 = copy_to_mode_reg (mode0, xop0);
487 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1)
488 && mode1 != VOIDmode)
489 xop1 = copy_to_mode_reg (mode1, xop1);
491 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
492 temp = gen_reg_rtx (mode);
494 pat = GEN_FCN (icode) (temp, xop0, xop1);
495 if (pat)
497 /* If PAT is a multi-insn sequence, try to add an appropriate
498 REG_EQUAL note to it. If we can't because TEMP conflicts with an
499 operand, call ourselves again, this time without a target. */
500 if (GET_CODE (pat) == SEQUENCE
501 && ! add_equal_note (pat, temp, binoptab->code, xop0, xop1))
503 delete_insns_since (last);
504 return expand_binop (mode, binoptab, op0, op1, NULL_RTX,
505 unsignedp, methods);
508 emit_insn (pat);
509 return temp;
511 else
512 delete_insns_since (last);
515 /* If this is a multiply, see if we can do a widening operation that
516 takes operands of this mode and makes a wider mode. */
518 if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
519 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
520 ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
521 != CODE_FOR_nothing))
523 temp = expand_binop (GET_MODE_WIDER_MODE (mode),
524 unsignedp ? umul_widen_optab : smul_widen_optab,
525 op0, op1, NULL_RTX, unsignedp, OPTAB_DIRECT);
527 if (temp != 0)
529 if (GET_MODE_CLASS (mode) == MODE_INT)
530 return gen_lowpart (mode, temp);
531 else
532 return convert_to_mode (mode, temp, unsignedp);
536 /* Look for a wider mode of the same class for which we think we
537 can open-code the operation. Check for a widening multiply at the
538 wider mode as well. */
540 if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
541 && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
542 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
543 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
545 if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
546 || (binoptab == smul_optab
547 && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
548 && (((unsignedp ? umul_widen_optab : smul_widen_optab)
549 ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
550 != CODE_FOR_nothing)))
552 rtx xop0 = op0, xop1 = op1;
553 int no_extend = 0;
555 /* For certain integer operations, we need not actually extend
556 the narrow operands, as long as we will truncate
557 the results to the same narrowness. */
559 if ((binoptab == ior_optab || binoptab == and_optab
560 || binoptab == xor_optab
561 || binoptab == add_optab || binoptab == sub_optab
562 || binoptab == smul_optab || binoptab == ashl_optab)
563 && class == MODE_INT)
564 no_extend = 1;
566 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp, no_extend);
568 /* The second operand of a shift must always be extended. */
569 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
570 no_extend && binoptab != ashl_optab);
572 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
573 unsignedp, OPTAB_DIRECT);
574 if (temp)
576 if (class != MODE_INT)
578 if (target == 0)
579 target = gen_reg_rtx (mode);
580 convert_move (target, temp, 0);
581 return target;
583 else
584 return gen_lowpart (mode, temp);
586 else
587 delete_insns_since (last);
591 /* These can be done a word at a time. */
592 if ((binoptab == and_optab || binoptab == ior_optab || binoptab == xor_optab)
593 && class == MODE_INT
594 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
595 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
597 int i;
598 rtx insns;
599 rtx equiv_value;
601 /* If TARGET is the same as one of the operands, the REG_EQUAL note
602 won't be accurate, so use a new target. */
603 if (target == 0 || target == op0 || target == op1)
604 target = gen_reg_rtx (mode);
606 start_sequence ();
608 /* Do the actual arithmetic. */
609 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
611 rtx target_piece = operand_subword (target, i, 1, mode);
612 rtx x = expand_binop (word_mode, binoptab,
613 operand_subword_force (op0, i, mode),
614 operand_subword_force (op1, i, mode),
615 target_piece, unsignedp, next_methods);
617 if (x == 0)
618 break;
620 if (target_piece != x)
621 emit_move_insn (target_piece, x);
624 insns = get_insns ();
625 end_sequence ();
627 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
629 if (binoptab->code != UNKNOWN)
630 equiv_value
631 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
632 else
633 equiv_value = 0;
635 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
636 return target;
640 /* Synthesize double word shifts from single word shifts. */
641 if ((binoptab == lshr_optab || binoptab == ashl_optab
642 || binoptab == ashr_optab)
643 && class == MODE_INT
644 && GET_CODE (op1) == CONST_INT
645 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
646 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
647 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
648 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
650 rtx insns, inter, equiv_value;
651 rtx into_target, outof_target;
652 rtx into_input, outof_input;
653 int shift_count, left_shift, outof_word;
655 /* If TARGET is the same as one of the operands, the REG_EQUAL note
656 won't be accurate, so use a new target. */
657 if (target == 0 || target == op0 || target == op1)
658 target = gen_reg_rtx (mode);
660 start_sequence ();
662 shift_count = INTVAL (op1);
664 /* OUTOF_* is the word we are shifting bits away from, and
665 INTO_* is the word that we are shifting bits towards, thus
666 they differ depending on the direction of the shift and
667 WORDS_BIG_ENDIAN. */
669 left_shift = binoptab == ashl_optab;
670 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
672 outof_target = operand_subword (target, outof_word, 1, mode);
673 into_target = operand_subword (target, 1 - outof_word, 1, mode);
675 outof_input = operand_subword_force (op0, outof_word, mode);
676 into_input = operand_subword_force (op0, 1 - outof_word, mode);
678 if (shift_count >= BITS_PER_WORD)
680 inter = expand_binop (word_mode, binoptab,
681 outof_input,
682 GEN_INT (shift_count - BITS_PER_WORD),
683 into_target, unsignedp, next_methods);
685 if (inter != 0 && inter != into_target)
686 emit_move_insn (into_target, inter);
688 /* For a signed right shift, we must fill the word we are shifting
689 out of with copies of the sign bit. Otherwise it is zeroed. */
690 if (inter != 0 && binoptab != ashr_optab)
691 inter = CONST0_RTX (word_mode);
692 else if (inter != 0)
693 inter = expand_binop (word_mode, binoptab,
694 outof_input,
695 GEN_INT (BITS_PER_WORD - 1),
696 outof_target, unsignedp, next_methods);
698 if (inter != 0 && inter != outof_target)
699 emit_move_insn (outof_target, inter);
701 else
703 rtx carries;
704 optab reverse_unsigned_shift, unsigned_shift;
706 /* For a shift of less then BITS_PER_WORD, to compute the carry,
707 we must do a logical shift in the opposite direction of the
708 desired shift. */
710 reverse_unsigned_shift = (left_shift ? lshr_optab : ashl_optab);
712 /* For a shift of less than BITS_PER_WORD, to compute the word
713 shifted towards, we need to unsigned shift the orig value of
714 that word. */
716 unsigned_shift = (left_shift ? ashl_optab : lshr_optab);
718 carries = expand_binop (word_mode, reverse_unsigned_shift,
719 outof_input,
720 GEN_INT (BITS_PER_WORD - shift_count),
721 0, unsignedp, next_methods);
723 if (carries == 0)
724 inter = 0;
725 else
726 inter = expand_binop (word_mode, unsigned_shift, into_input,
727 op1, 0, unsignedp, next_methods);
729 if (inter != 0)
730 inter = expand_binop (word_mode, ior_optab, carries, inter,
731 into_target, unsignedp, next_methods);
733 if (inter != 0 && inter != into_target)
734 emit_move_insn (into_target, inter);
736 if (inter != 0)
737 inter = expand_binop (word_mode, binoptab, outof_input,
738 op1, outof_target, unsignedp, next_methods);
740 if (inter != 0 && inter != outof_target)
741 emit_move_insn (outof_target, inter);
744 insns = get_insns ();
745 end_sequence ();
747 if (inter != 0)
749 if (binoptab->code != UNKNOWN)
750 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
751 else
752 equiv_value = 0;
754 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
755 return target;
759 /* Synthesize double word rotates from single word shifts. */
760 if ((binoptab == rotl_optab || binoptab == rotr_optab)
761 && class == MODE_INT
762 && GET_CODE (op1) == CONST_INT
763 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
764 && ashl_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
765 && lshr_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
767 rtx insns, equiv_value;
768 rtx into_target, outof_target;
769 rtx into_input, outof_input;
770 rtx inter;
771 int shift_count, left_shift, outof_word;
773 /* If TARGET is the same as one of the operands, the REG_EQUAL note
774 won't be accurate, so use a new target. */
775 if (target == 0 || target == op0 || target == op1)
776 target = gen_reg_rtx (mode);
778 start_sequence ();
780 shift_count = INTVAL (op1);
782 /* OUTOF_* is the word we are shifting bits away from, and
783 INTO_* is the word that we are shifting bits towards, thus
784 they differ depending on the direction of the shift and
785 WORDS_BIG_ENDIAN. */
787 left_shift = (binoptab == rotl_optab);
788 outof_word = left_shift ^ ! WORDS_BIG_ENDIAN;
790 outof_target = operand_subword (target, outof_word, 1, mode);
791 into_target = operand_subword (target, 1 - outof_word, 1, mode);
793 outof_input = operand_subword_force (op0, outof_word, mode);
794 into_input = operand_subword_force (op0, 1 - outof_word, mode);
796 if (shift_count == BITS_PER_WORD)
798 /* This is just a word swap. */
799 emit_move_insn (outof_target, into_input);
800 emit_move_insn (into_target, outof_input);
801 inter = const0_rtx;
803 else
805 rtx into_temp1, into_temp2, outof_temp1, outof_temp2;
806 rtx first_shift_count, second_shift_count;
807 optab reverse_unsigned_shift, unsigned_shift;
809 reverse_unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
810 ? lshr_optab : ashl_optab);
812 unsigned_shift = (left_shift ^ (shift_count < BITS_PER_WORD)
813 ? ashl_optab : lshr_optab);
815 if (shift_count > BITS_PER_WORD)
817 first_shift_count = GEN_INT (shift_count - BITS_PER_WORD);
818 second_shift_count = GEN_INT (2*BITS_PER_WORD - shift_count);
820 else
822 first_shift_count = GEN_INT (BITS_PER_WORD - shift_count);
823 second_shift_count = GEN_INT (shift_count);
826 into_temp1 = expand_binop (word_mode, unsigned_shift,
827 outof_input, first_shift_count,
828 NULL_RTX, unsignedp, next_methods);
829 into_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
830 into_input, second_shift_count,
831 into_target, unsignedp, next_methods);
833 if (into_temp1 != 0 && into_temp2 != 0)
834 inter = expand_binop (word_mode, ior_optab, into_temp1, into_temp2,
835 into_target, unsignedp, next_methods);
836 else
837 inter = 0;
839 if (inter != 0 && inter != into_target)
840 emit_move_insn (into_target, inter);
842 outof_temp1 = expand_binop (word_mode, unsigned_shift,
843 into_input, first_shift_count,
844 NULL_RTX, unsignedp, next_methods);
845 outof_temp2 = expand_binop (word_mode, reverse_unsigned_shift,
846 outof_input, second_shift_count,
847 outof_target, unsignedp, next_methods);
849 if (inter != 0 && outof_temp1 != 0 && outof_temp2 != 0)
850 inter = expand_binop (word_mode, ior_optab,
851 outof_temp1, outof_temp2,
852 outof_target, unsignedp, next_methods);
854 if (inter != 0 && inter != outof_target)
855 emit_move_insn (outof_target, inter);
858 insns = get_insns ();
859 end_sequence ();
861 if (inter != 0)
863 if (binoptab->code != UNKNOWN)
864 equiv_value = gen_rtx (binoptab->code, mode, op0, op1);
865 else
866 equiv_value = 0;
868 /* We can't make this a no conflict block if this is a word swap,
869 because the word swap case fails if the input and output values
870 are in the same register. */
871 if (shift_count != BITS_PER_WORD)
872 emit_no_conflict_block (insns, target, op0, op1, equiv_value);
873 else
874 emit_insns (insns);
877 return target;
881 /* These can be done a word at a time by propagating carries. */
882 if ((binoptab == add_optab || binoptab == sub_optab)
883 && class == MODE_INT
884 && GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
885 && binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
887 int i;
888 rtx carry_tmp = gen_reg_rtx (word_mode);
889 optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
890 int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
891 rtx carry_in, carry_out;
892 rtx xop0, xop1;
894 /* We can handle either a 1 or -1 value for the carry. If STORE_FLAG
895 value is one of those, use it. Otherwise, use 1 since it is the
896 one easiest to get. */
897 #if STORE_FLAG_VALUE == 1 || STORE_FLAG_VALUE == -1
898 int normalizep = STORE_FLAG_VALUE;
899 #else
900 int normalizep = 1;
901 #endif
903 /* Prepare the operands. */
904 xop0 = force_reg (mode, op0);
905 xop1 = force_reg (mode, op1);
907 if (target == 0 || GET_CODE (target) != REG
908 || target == xop0 || target == xop1)
909 target = gen_reg_rtx (mode);
911 /* Indicate for flow that the entire target reg is being set. */
912 if (GET_CODE (target) == REG)
913 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
915 /* Do the actual arithmetic. */
916 for (i = 0; i < nwords; i++)
918 int index = (WORDS_BIG_ENDIAN ? nwords - i - 1 : i);
919 rtx target_piece = operand_subword (target, index, 1, mode);
920 rtx op0_piece = operand_subword_force (xop0, index, mode);
921 rtx op1_piece = operand_subword_force (xop1, index, mode);
922 rtx x;
924 /* Main add/subtract of the input operands. */
925 x = expand_binop (word_mode, binoptab,
926 op0_piece, op1_piece,
927 target_piece, unsignedp, next_methods);
928 if (x == 0)
929 break;
931 if (i + 1 < nwords)
933 /* Store carry from main add/subtract. */
934 carry_out = gen_reg_rtx (word_mode);
935 carry_out = emit_store_flag_force (carry_out,
936 (binoptab == add_optab
937 ? LTU : GTU),
938 x, op0_piece,
939 word_mode, 1, normalizep);
942 if (i > 0)
944 /* Add/subtract previous carry to main result. */
945 x = expand_binop (word_mode,
946 normalizep == 1 ? binoptab : otheroptab,
947 x, carry_in,
948 target_piece, 1, next_methods);
949 if (x == 0)
950 break;
951 else if (target_piece != x)
952 emit_move_insn (target_piece, x);
954 if (i + 1 < nwords)
956 /* THIS CODE HAS NOT BEEN TESTED. */
957 /* Get out carry from adding/subtracting carry in. */
958 carry_tmp = emit_store_flag_force (carry_tmp,
959 binoptab == add_optab
960 ? LTU : GTU,
961 x, carry_in,
962 word_mode, 1, normalizep);
964 /* Logical-ior the two poss. carry together. */
965 carry_out = expand_binop (word_mode, ior_optab,
966 carry_out, carry_tmp,
967 carry_out, 0, next_methods);
968 if (carry_out == 0)
969 break;
973 carry_in = carry_out;
976 if (i == GET_MODE_BITSIZE (mode) / BITS_PER_WORD)
978 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
980 rtx temp = emit_move_insn (target, target);
982 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
983 gen_rtx (binoptab->code, mode,
984 copy_rtx (xop0),
985 copy_rtx (xop1)),
986 REG_NOTES (temp));
988 return target;
990 else
991 delete_insns_since (last);
994 /* If we want to multiply two two-word values and have normal and widening
995 multiplies of single-word values, we can do this with three smaller
996 multiplications. Note that we do not make a REG_NO_CONFLICT block here
997 because we are not operating on one word at a time.
999 The multiplication proceeds as follows:
1000 _______________________
1001 [__op0_high_|__op0_low__]
1002 _______________________
1003 * [__op1_high_|__op1_low__]
1004 _______________________________________________
1005 _______________________
1006 (1) [__op0_low__*__op1_low__]
1007 _______________________
1008 (2a) [__op0_low__*__op1_high_]
1009 _______________________
1010 (2b) [__op0_high_*__op1_low__]
1011 _______________________
1012 (3) [__op0_high_*__op1_high_]
1015 This gives a 4-word result. Since we are only interested in the
1016 lower 2 words, partial result (3) and the upper words of (2a) and
1017 (2b) don't need to be calculated. Hence (2a) and (2b) can be
1018 calculated using non-widening multiplication.
1020 (1), however, needs to be calculated with an unsigned widening
1021 multiplication. If this operation is not directly supported we
1022 try using a signed widening multiplication and adjust the result.
1023 This adjustment works as follows:
1025 If both operands are positive then no adjustment is needed.
1027 If the operands have different signs, for example op0_low < 0 and
1028 op1_low >= 0, the instruction treats the most significant bit of
1029 op0_low as a sign bit instead of a bit with significance
1030 2**(BITS_PER_WORD-1), i.e. the instruction multiplies op1_low
1031 with 2**BITS_PER_WORD - op0_low, and two's complements the
1032 result. Conclusion: We need to add op1_low * 2**BITS_PER_WORD to
1033 the result.
1035 Similarly, if both operands are negative, we need to add
1036 (op0_low + op1_low) * 2**BITS_PER_WORD.
1038 We use a trick to adjust quickly. We logically shift op0_low right
1039 (op1_low) BITS_PER_WORD-1 steps to get 0 or 1, and add this to
1040 op0_high (op1_high) before it is used to calculate 2b (2a). If no
1041 logical shift exists, we do an arithmetic right shift and subtract
1042 the 0 or -1. */
1044 if (binoptab == smul_optab
1045 && class == MODE_INT
1046 && GET_MODE_SIZE (mode) == 2 * UNITS_PER_WORD
1047 && smul_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1048 && add_optab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing
1049 && ((umul_widen_optab->handlers[(int) mode].insn_code
1050 != CODE_FOR_nothing)
1051 || (smul_widen_optab->handlers[(int) mode].insn_code
1052 != CODE_FOR_nothing)))
1054 int low = (WORDS_BIG_ENDIAN ? 1 : 0);
1055 int high = (WORDS_BIG_ENDIAN ? 0 : 1);
1056 rtx op0_high = operand_subword_force (op0, high, mode);
1057 rtx op0_low = operand_subword_force (op0, low, mode);
1058 rtx op1_high = operand_subword_force (op1, high, mode);
1059 rtx op1_low = operand_subword_force (op1, low, mode);
1060 rtx product = 0;
1061 rtx op0_xhigh;
1062 rtx op1_xhigh;
1064 /* If the target is the same as one of the inputs, don't use it. This
1065 prevents problems with the REG_EQUAL note. */
1066 if (target == op0 || target == op1
1067 || (target != 0 && GET_CODE (target) != REG))
1068 target = 0;
1070 /* Multiply the two lower words to get a double-word product.
1071 If unsigned widening multiplication is available, use that;
1072 otherwise use the signed form and compensate. */
1074 if (umul_widen_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1076 product = expand_binop (mode, umul_widen_optab, op0_low, op1_low,
1077 target, 1, OPTAB_DIRECT);
1079 /* If we didn't succeed, delete everything we did so far. */
1080 if (product == 0)
1081 delete_insns_since (last);
1082 else
1083 op0_xhigh = op0_high, op1_xhigh = op1_high;
1086 if (product == 0
1087 && smul_widen_optab->handlers[(int) mode].insn_code
1088 != CODE_FOR_nothing)
1090 rtx wordm1 = GEN_INT (BITS_PER_WORD - 1);
1091 product = expand_binop (mode, smul_widen_optab, op0_low, op1_low,
1092 target, 1, OPTAB_DIRECT);
1093 op0_xhigh = expand_binop (word_mode, lshr_optab, op0_low, wordm1,
1094 NULL_RTX, 1, next_methods);
1095 if (op0_xhigh)
1096 op0_xhigh = expand_binop (word_mode, add_optab, op0_high,
1097 op0_xhigh, op0_xhigh, 0, next_methods);
1098 else
1100 op0_xhigh = expand_binop (word_mode, ashr_optab, op0_low, wordm1,
1101 NULL_RTX, 0, next_methods);
1102 if (op0_xhigh)
1103 op0_xhigh = expand_binop (word_mode, sub_optab, op0_high,
1104 op0_xhigh, op0_xhigh, 0,
1105 next_methods);
1108 op1_xhigh = expand_binop (word_mode, lshr_optab, op1_low, wordm1,
1109 NULL_RTX, 1, next_methods);
1110 if (op1_xhigh)
1111 op1_xhigh = expand_binop (word_mode, add_optab, op1_high,
1112 op1_xhigh, op1_xhigh, 0, next_methods);
1113 else
1115 op1_xhigh = expand_binop (word_mode, ashr_optab, op1_low, wordm1,
1116 NULL_RTX, 0, next_methods);
1117 if (op1_xhigh)
1118 op1_xhigh = expand_binop (word_mode, sub_optab, op1_high,
1119 op1_xhigh, op1_xhigh, 0,
1120 next_methods);
1124 /* If we have been able to directly compute the product of the
1125 low-order words of the operands and perform any required adjustments
1126 of the operands, we proceed by trying two more multiplications
1127 and then computing the appropriate sum.
1129 We have checked above that the required addition is provided.
1130 Full-word addition will normally always succeed, especially if
1131 it is provided at all, so we don't worry about its failure. The
1132 multiplication may well fail, however, so we do handle that. */
1134 if (product && op0_xhigh && op1_xhigh)
1136 rtx product_high = operand_subword (product, high, 1, mode);
1137 rtx temp = expand_binop (word_mode, binoptab, op0_low, op1_xhigh,
1138 NULL_RTX, 0, OPTAB_DIRECT);
1140 if (temp != 0)
1141 temp = expand_binop (word_mode, add_optab, temp, product_high,
1142 product_high, 0, next_methods);
1144 if (temp != 0 && temp != product_high)
1145 emit_move_insn (product_high, temp);
1147 if (temp != 0)
1148 temp = expand_binop (word_mode, binoptab, op1_low, op0_xhigh,
1149 NULL_RTX, 0, OPTAB_DIRECT);
1151 if (temp != 0)
1152 temp = expand_binop (word_mode, add_optab, temp,
1153 product_high, product_high,
1154 0, next_methods);
1156 if (temp != 0 && temp != product_high)
1157 emit_move_insn (product_high, temp);
1159 if (temp != 0)
1161 if (mov_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1163 temp = emit_move_insn (product, product);
1164 REG_NOTES (temp) = gen_rtx (EXPR_LIST, REG_EQUAL,
1165 gen_rtx (MULT, mode,
1166 copy_rtx (op0),
1167 copy_rtx (op1)),
1168 REG_NOTES (temp));
1170 return product;
1174 /* If we get here, we couldn't do it for some reason even though we
1175 originally thought we could. Delete anything we've emitted in
1176 trying to do it. */
1178 delete_insns_since (last);
1181 /* We need to open-code the complex type operations: '+, -, * and /' */
1183 /* At this point we allow operations between two similar complex
1184 numbers, and also if one of the operands is not a complex number
1185 but rather of MODE_FLOAT or MODE_INT. However, the caller
1186 must make sure that the MODE of the non-complex operand matches
1187 the SUBMODE of the complex operand. */
1189 if (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT)
1191 rtx real0 = 0, imag0 = 0;
1192 rtx real1 = 0, imag1 = 0;
1193 rtx realr, imagr, res;
1194 rtx seq;
1195 rtx equiv_value;
1196 int ok = 0;
1198 /* Find the correct mode for the real and imaginary parts */
1199 enum machine_mode submode
1200 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1201 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1204 if (submode == BLKmode)
1205 abort ();
1207 if (! target)
1208 target = gen_reg_rtx (mode);
1210 start_sequence ();
1212 realr = gen_realpart (submode, target);
1213 imagr = gen_imagpart (submode, target);
1215 if (GET_MODE (op0) == mode)
1217 real0 = gen_realpart (submode, op0);
1218 imag0 = gen_imagpart (submode, op0);
1220 else
1221 real0 = op0;
1223 if (GET_MODE (op1) == mode)
1225 real1 = gen_realpart (submode, op1);
1226 imag1 = gen_imagpart (submode, op1);
1228 else
1229 real1 = op1;
1231 if (real0 == 0 || real1 == 0 || ! (imag0 != 0|| imag1 != 0))
1232 abort ();
1234 switch (binoptab->code)
1236 case PLUS:
1237 /* (a+ib) + (c+id) = (a+c) + i(b+d) */
1238 case MINUS:
1239 /* (a+ib) - (c+id) = (a-c) + i(b-d) */
1240 res = expand_binop (submode, binoptab, real0, real1,
1241 realr, unsignedp, methods);
1243 if (res == 0)
1244 break;
1245 else if (res != realr)
1246 emit_move_insn (realr, res);
1248 if (imag0 && imag1)
1249 res = expand_binop (submode, binoptab, imag0, imag1,
1250 imagr, unsignedp, methods);
1251 else if (imag0)
1252 res = imag0;
1253 else if (binoptab->code == MINUS)
1254 res = expand_unop (submode, neg_optab, imag1, imagr, unsignedp);
1255 else
1256 res = imag1;
1258 if (res == 0)
1259 break;
1260 else if (res != imagr)
1261 emit_move_insn (imagr, res);
1263 ok = 1;
1264 break;
1266 case MULT:
1267 /* (a+ib) * (c+id) = (ac-bd) + i(ad+cb) */
1269 if (imag0 && imag1)
1271 rtx temp1, temp2;
1273 /* Don't fetch these from memory more than once. */
1274 real0 = force_reg (submode, real0);
1275 real1 = force_reg (submode, real1);
1276 imag0 = force_reg (submode, imag0);
1277 imag1 = force_reg (submode, imag1);
1279 temp1 = expand_binop (submode, binoptab, real0, real1, NULL_RTX,
1280 unsignedp, methods);
1282 temp2 = expand_binop (submode, binoptab, imag0, imag1, NULL_RTX,
1283 unsignedp, methods);
1285 if (temp1 == 0 || temp2 == 0)
1286 break;
1288 res = expand_binop (submode, sub_optab, temp1, temp2,
1289 realr, unsignedp, methods);
1291 if (res == 0)
1292 break;
1293 else if (res != realr)
1294 emit_move_insn (realr, res);
1296 temp1 = expand_binop (submode, binoptab, real0, imag1,
1297 NULL_RTX, unsignedp, methods);
1299 temp2 = expand_binop (submode, binoptab, real1, imag0,
1300 NULL_RTX, unsignedp, methods);
1302 if (temp1 == 0 || temp2 == 0)
1303 break;
1305 res = expand_binop (submode, add_optab, temp1, temp2,
1306 imagr, unsignedp, methods);
1308 if (res == 0)
1309 break;
1310 else if (res != imagr)
1311 emit_move_insn (imagr, res);
1313 ok = 1;
1315 else
1317 /* Don't fetch these from memory more than once. */
1318 real0 = force_reg (submode, real0);
1319 real1 = force_reg (submode, real1);
1321 res = expand_binop (submode, binoptab, real0, real1,
1322 realr, unsignedp, methods);
1323 if (res == 0)
1324 break;
1325 else if (res != realr)
1326 emit_move_insn (realr, res);
1328 if (imag0 != 0)
1329 res = expand_binop (submode, binoptab,
1330 real1, imag0, imagr, unsignedp, methods);
1331 else
1332 res = expand_binop (submode, binoptab,
1333 real0, imag1, imagr, unsignedp, methods);
1335 if (res == 0)
1336 break;
1337 else if (res != imagr)
1338 emit_move_insn (imagr, res);
1340 ok = 1;
1342 break;
1344 case DIV:
1345 /* (a+ib) / (c+id) = ((ac+bd)/(cc+dd)) + i((bc-ad)/(cc+dd)) */
1347 if (imag1 == 0)
1349 /* (a+ib) / (c+i0) = (a/c) + i(b/c) */
1351 /* Don't fetch these from memory more than once. */
1352 real1 = force_reg (submode, real1);
1354 /* Simply divide the real and imaginary parts by `c' */
1355 if (class == MODE_COMPLEX_FLOAT)
1356 res = expand_binop (submode, binoptab, real0, real1,
1357 realr, unsignedp, methods);
1358 else
1359 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1360 real0, real1, realr, unsignedp);
1362 if (res == 0)
1363 break;
1364 else if (res != realr)
1365 emit_move_insn (realr, res);
1367 if (class == MODE_COMPLEX_FLOAT)
1368 res = expand_binop (submode, binoptab, imag0, real1,
1369 imagr, unsignedp, methods);
1370 else
1371 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1372 imag0, real1, imagr, unsignedp);
1374 if (res == 0)
1375 break;
1376 else if (res != imagr)
1377 emit_move_insn (imagr, res);
1379 ok = 1;
1381 else
1383 /* Divisor is of complex type:
1384 X/(a+ib) */
1385 rtx divisor;
1386 rtx real_t, imag_t;
1387 rtx lhs, rhs;
1388 rtx temp1, temp2;
1390 /* Don't fetch these from memory more than once. */
1391 real0 = force_reg (submode, real0);
1392 real1 = force_reg (submode, real1);
1394 if (imag0 != 0)
1395 imag0 = force_reg (submode, imag0);
1397 imag1 = force_reg (submode, imag1);
1399 /* Divisor: c*c + d*d */
1400 temp1 = expand_binop (submode, smul_optab, real1, real1,
1401 NULL_RTX, unsignedp, methods);
1403 temp2 = expand_binop (submode, smul_optab, imag1, imag1,
1404 NULL_RTX, unsignedp, methods);
1406 if (temp1 == 0 || temp2 == 0)
1407 break;
1409 divisor = expand_binop (submode, add_optab, temp1, temp2,
1410 NULL_RTX, unsignedp, methods);
1411 if (divisor == 0)
1412 break;
1414 if (imag0 == 0)
1416 /* ((a)(c-id))/divisor */
1417 /* (a+i0) / (c+id) = (ac/(cc+dd)) + i(-ad/(cc+dd)) */
1419 /* Calculate the dividend */
1420 real_t = expand_binop (submode, smul_optab, real0, real1,
1421 NULL_RTX, unsignedp, methods);
1423 imag_t = expand_binop (submode, smul_optab, real0, imag1,
1424 NULL_RTX, unsignedp, methods);
1426 if (real_t == 0 || imag_t == 0)
1427 break;
1429 imag_t = expand_unop (submode, neg_optab, imag_t,
1430 NULL_RTX, unsignedp);
1432 else
1434 /* ((a+ib)(c-id))/divider */
1435 /* Calculate the dividend */
1436 temp1 = expand_binop (submode, smul_optab, real0, real1,
1437 NULL_RTX, unsignedp, methods);
1439 temp2 = expand_binop (submode, smul_optab, imag0, imag1,
1440 NULL_RTX, unsignedp, methods);
1442 if (temp1 == 0 || temp2 == 0)
1443 break;
1445 real_t = expand_binop (submode, add_optab, temp1, temp2,
1446 NULL_RTX, unsignedp, methods);
1448 temp1 = expand_binop (submode, smul_optab, imag0, real1,
1449 NULL_RTX, unsignedp, methods);
1451 temp2 = expand_binop (submode, smul_optab, real0, imag1,
1452 NULL_RTX, unsignedp, methods);
1454 if (temp1 == 0 || temp2 == 0)
1455 break;
1457 imag_t = expand_binop (submode, sub_optab, temp1, temp2,
1458 NULL_RTX, unsignedp, methods);
1460 if (real_t == 0 || imag_t == 0)
1461 break;
1464 if (class == MODE_COMPLEX_FLOAT)
1465 res = expand_binop (submode, binoptab, real_t, divisor,
1466 realr, unsignedp, methods);
1467 else
1468 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1469 real_t, divisor, realr, unsignedp);
1471 if (res == 0)
1472 break;
1473 else if (res != realr)
1474 emit_move_insn (realr, res);
1476 if (class == MODE_COMPLEX_FLOAT)
1477 res = expand_binop (submode, binoptab, imag_t, divisor,
1478 imagr, unsignedp, methods);
1479 else
1480 res = expand_divmod (0, TRUNC_DIV_EXPR, submode,
1481 imag_t, divisor, imagr, unsignedp);
1483 if (res == 0)
1484 break;
1485 else if (res != imagr)
1486 emit_move_insn (imagr, res);
1488 ok = 1;
1490 break;
1492 default:
1493 abort ();
1496 seq = get_insns ();
1497 end_sequence ();
1499 if (ok)
1501 if (binoptab->code != UNKNOWN)
1502 equiv_value
1503 = gen_rtx (binoptab->code, mode, copy_rtx (op0), copy_rtx (op1));
1504 else
1505 equiv_value = 0;
1507 emit_no_conflict_block (seq, target, op0, op1, equiv_value);
1509 return target;
1513 /* It can't be open-coded in this mode.
1514 Use a library call if one is available and caller says that's ok. */
1516 if (binoptab->handlers[(int) mode].libfunc
1517 && (methods == OPTAB_LIB || methods == OPTAB_LIB_WIDEN))
1519 rtx insns;
1520 rtx funexp = binoptab->handlers[(int) mode].libfunc;
1521 rtx op1x = op1;
1522 enum machine_mode op1_mode = mode;
1523 rtx value;
1525 start_sequence ();
1527 if (shift_op)
1529 op1_mode = word_mode;
1530 /* Specify unsigned here,
1531 since negative shift counts are meaningless. */
1532 op1x = convert_to_mode (word_mode, op1, 1);
1535 if (GET_MODE (op0) != VOIDmode
1536 && GET_MODE (op0) != mode)
1537 op0 = convert_to_mode (mode, op0, unsignedp);
1539 /* Pass 1 for NO_QUEUE so we don't lose any increments
1540 if the libcall is cse'd or moved. */
1541 value = emit_library_call_value (binoptab->handlers[(int) mode].libfunc,
1542 NULL_RTX, 1, mode, 2,
1543 op0, mode, op1x, op1_mode);
1545 insns = get_insns ();
1546 end_sequence ();
1548 target = gen_reg_rtx (mode);
1549 emit_libcall_block (insns, target, value,
1550 gen_rtx (binoptab->code, mode, op0, op1));
1552 return target;
1555 delete_insns_since (last);
1557 /* It can't be done in this mode. Can we do it in a wider mode? */
1559 if (! (methods == OPTAB_WIDEN || methods == OPTAB_LIB_WIDEN
1560 || methods == OPTAB_MUST_WIDEN))
1562 /* Caller says, don't even try. */
1563 delete_insns_since (entry_last);
1564 return 0;
1567 /* Compute the value of METHODS to pass to recursive calls.
1568 Don't allow widening to be tried recursively. */
1570 methods = (methods == OPTAB_LIB_WIDEN ? OPTAB_LIB : OPTAB_DIRECT);
1572 /* Look for a wider mode of the same class for which it appears we can do
1573 the operation. */
1575 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1577 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1578 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1580 if ((binoptab->handlers[(int) wider_mode].insn_code
1581 != CODE_FOR_nothing)
1582 || (methods == OPTAB_LIB
1583 && binoptab->handlers[(int) wider_mode].libfunc))
1585 rtx xop0 = op0, xop1 = op1;
1586 int no_extend = 0;
1588 /* For certain integer operations, we need not actually extend
1589 the narrow operands, as long as we will truncate
1590 the results to the same narrowness. */
1592 if ((binoptab == ior_optab || binoptab == and_optab
1593 || binoptab == xor_optab
1594 || binoptab == add_optab || binoptab == sub_optab
1595 || binoptab == smul_optab || binoptab == ashl_optab)
1596 && class == MODE_INT)
1597 no_extend = 1;
1599 xop0 = widen_operand (xop0, wider_mode, mode,
1600 unsignedp, no_extend);
1602 /* The second operand of a shift must always be extended. */
1603 xop1 = widen_operand (xop1, wider_mode, mode, unsignedp,
1604 no_extend && binoptab != ashl_optab);
1606 temp = expand_binop (wider_mode, binoptab, xop0, xop1, NULL_RTX,
1607 unsignedp, methods);
1608 if (temp)
1610 if (class != MODE_INT)
1612 if (target == 0)
1613 target = gen_reg_rtx (mode);
1614 convert_move (target, temp, 0);
1615 return target;
1617 else
1618 return gen_lowpart (mode, temp);
1620 else
1621 delete_insns_since (last);
1626 delete_insns_since (entry_last);
1627 return 0;
1630 /* Expand a binary operator which has both signed and unsigned forms.
1631 UOPTAB is the optab for unsigned operations, and SOPTAB is for
1632 signed operations.
1634 If we widen unsigned operands, we may use a signed wider operation instead
1635 of an unsigned wider operation, since the result would be the same. */
1638 sign_expand_binop (mode, uoptab, soptab, op0, op1, target, unsignedp, methods)
1639 enum machine_mode mode;
1640 optab uoptab, soptab;
1641 rtx op0, op1, target;
1642 int unsignedp;
1643 enum optab_methods methods;
1645 register rtx temp;
1646 optab direct_optab = unsignedp ? uoptab : soptab;
1647 struct optab wide_soptab;
1649 /* Do it without widening, if possible. */
1650 temp = expand_binop (mode, direct_optab, op0, op1, target,
1651 unsignedp, OPTAB_DIRECT);
1652 if (temp || methods == OPTAB_DIRECT)
1653 return temp;
1655 /* Try widening to a signed int. Make a fake signed optab that
1656 hides any signed insn for direct use. */
1657 wide_soptab = *soptab;
1658 wide_soptab.handlers[(int) mode].insn_code = CODE_FOR_nothing;
1659 wide_soptab.handlers[(int) mode].libfunc = 0;
1661 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1662 unsignedp, OPTAB_WIDEN);
1664 /* For unsigned operands, try widening to an unsigned int. */
1665 if (temp == 0 && unsignedp)
1666 temp = expand_binop (mode, uoptab, op0, op1, target,
1667 unsignedp, OPTAB_WIDEN);
1668 if (temp || methods == OPTAB_WIDEN)
1669 return temp;
1671 /* Use the right width lib call if that exists. */
1672 temp = expand_binop (mode, direct_optab, op0, op1, target, unsignedp, OPTAB_LIB);
1673 if (temp || methods == OPTAB_LIB)
1674 return temp;
1676 /* Must widen and use a lib call, use either signed or unsigned. */
1677 temp = expand_binop (mode, &wide_soptab, op0, op1, target,
1678 unsignedp, methods);
1679 if (temp != 0)
1680 return temp;
1681 if (unsignedp)
1682 return expand_binop (mode, uoptab, op0, op1, target,
1683 unsignedp, methods);
1684 return 0;
1687 /* Generate code to perform an operation specified by BINOPTAB
1688 on operands OP0 and OP1, with two results to TARG1 and TARG2.
1689 We assume that the order of the operands for the instruction
1690 is TARG0, OP0, OP1, TARG1, which would fit a pattern like
1691 [(set TARG0 (operate OP0 OP1)) (set TARG1 (operate ...))].
1693 Either TARG0 or TARG1 may be zero, but what that means is that
1694 that result is not actually wanted. We will generate it into
1695 a dummy pseudo-reg and discard it. They may not both be zero.
1697 Returns 1 if this operation can be performed; 0 if not. */
1700 expand_twoval_binop (binoptab, op0, op1, targ0, targ1, unsignedp)
1701 optab binoptab;
1702 rtx op0, op1;
1703 rtx targ0, targ1;
1704 int unsignedp;
1706 enum machine_mode mode = GET_MODE (targ0 ? targ0 : targ1);
1707 enum mode_class class;
1708 enum machine_mode wider_mode;
1709 rtx entry_last = get_last_insn ();
1710 rtx last;
1712 class = GET_MODE_CLASS (mode);
1714 op0 = protect_from_queue (op0, 0);
1715 op1 = protect_from_queue (op1, 0);
1717 if (flag_force_mem)
1719 op0 = force_not_mem (op0);
1720 op1 = force_not_mem (op1);
1723 /* If we are inside an appropriately-short loop and one operand is an
1724 expensive constant, force it into a register. */
1725 if (CONSTANT_P (op0) && preserve_subexpressions_p ()
1726 && rtx_cost (op0, binoptab->code) > 2)
1727 op0 = force_reg (mode, op0);
1729 if (CONSTANT_P (op1) && preserve_subexpressions_p ()
1730 && rtx_cost (op1, binoptab->code) > 2)
1731 op1 = force_reg (mode, op1);
1733 if (targ0)
1734 targ0 = protect_from_queue (targ0, 1);
1735 else
1736 targ0 = gen_reg_rtx (mode);
1737 if (targ1)
1738 targ1 = protect_from_queue (targ1, 1);
1739 else
1740 targ1 = gen_reg_rtx (mode);
1742 /* Record where to go back to if we fail. */
1743 last = get_last_insn ();
1745 if (binoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1747 int icode = (int) binoptab->handlers[(int) mode].insn_code;
1748 enum machine_mode mode0 = insn_operand_mode[icode][1];
1749 enum machine_mode mode1 = insn_operand_mode[icode][2];
1750 rtx pat;
1751 rtx xop0 = op0, xop1 = op1;
1753 /* In case this insn wants input operands in modes different from the
1754 result, convert the operands. */
1755 if (GET_MODE (op0) != VOIDmode && GET_MODE (op0) != mode0)
1756 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1758 if (GET_MODE (op1) != VOIDmode && GET_MODE (op1) != mode1)
1759 xop1 = convert_to_mode (mode1, xop1, unsignedp);
1761 /* Now, if insn doesn't accept these operands, put them into pseudos. */
1762 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1763 xop0 = copy_to_mode_reg (mode0, xop0);
1765 if (! (*insn_operand_predicate[icode][2]) (xop1, mode1))
1766 xop1 = copy_to_mode_reg (mode1, xop1);
1768 /* We could handle this, but we should always be called with a pseudo
1769 for our targets and all insns should take them as outputs. */
1770 if (! (*insn_operand_predicate[icode][0]) (targ0, mode)
1771 || ! (*insn_operand_predicate[icode][3]) (targ1, mode))
1772 abort ();
1774 pat = GEN_FCN (icode) (targ0, xop0, xop1, targ1);
1775 if (pat)
1777 emit_insn (pat);
1778 return 1;
1780 else
1781 delete_insns_since (last);
1784 /* It can't be done in this mode. Can we do it in a wider mode? */
1786 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1788 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1789 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1791 if (binoptab->handlers[(int) wider_mode].insn_code
1792 != CODE_FOR_nothing)
1794 register rtx t0 = gen_reg_rtx (wider_mode);
1795 register rtx t1 = gen_reg_rtx (wider_mode);
1797 if (expand_twoval_binop (binoptab,
1798 convert_modes (wider_mode, mode, op0,
1799 unsignedp),
1800 convert_modes (wider_mode, mode, op1,
1801 unsignedp),
1802 t0, t1, unsignedp))
1804 convert_move (targ0, t0, unsignedp);
1805 convert_move (targ1, t1, unsignedp);
1806 return 1;
1808 else
1809 delete_insns_since (last);
1814 delete_insns_since (entry_last);
1815 return 0;
1818 /* Generate code to perform an operation specified by UNOPTAB
1819 on operand OP0, with result having machine-mode MODE.
1821 UNSIGNEDP is for the case where we have to widen the operands
1822 to perform the operation. It says to use zero-extension.
1824 If TARGET is nonzero, the value
1825 is generated there, if it is convenient to do so.
1826 In all cases an rtx is returned for the locus of the value;
1827 this may or may not be TARGET. */
1830 expand_unop (mode, unoptab, op0, target, unsignedp)
1831 enum machine_mode mode;
1832 optab unoptab;
1833 rtx op0;
1834 rtx target;
1835 int unsignedp;
1837 enum mode_class class;
1838 enum machine_mode wider_mode;
1839 register rtx temp;
1840 rtx last = get_last_insn ();
1841 rtx pat;
1843 class = GET_MODE_CLASS (mode);
1845 op0 = protect_from_queue (op0, 0);
1847 if (flag_force_mem)
1849 op0 = force_not_mem (op0);
1852 if (target)
1853 target = protect_from_queue (target, 1);
1855 if (unoptab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
1857 int icode = (int) unoptab->handlers[(int) mode].insn_code;
1858 enum machine_mode mode0 = insn_operand_mode[icode][1];
1859 rtx xop0 = op0;
1861 if (target)
1862 temp = target;
1863 else
1864 temp = gen_reg_rtx (mode);
1866 if (GET_MODE (xop0) != VOIDmode
1867 && GET_MODE (xop0) != mode0)
1868 xop0 = convert_to_mode (mode0, xop0, unsignedp);
1870 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
1872 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
1873 xop0 = copy_to_mode_reg (mode0, xop0);
1875 if (! (*insn_operand_predicate[icode][0]) (temp, mode))
1876 temp = gen_reg_rtx (mode);
1878 pat = GEN_FCN (icode) (temp, xop0);
1879 if (pat)
1881 if (GET_CODE (pat) == SEQUENCE
1882 && ! add_equal_note (pat, temp, unoptab->code, xop0, NULL_RTX))
1884 delete_insns_since (last);
1885 return expand_unop (mode, unoptab, op0, NULL_RTX, unsignedp);
1888 emit_insn (pat);
1890 return temp;
1892 else
1893 delete_insns_since (last);
1896 /* It can't be done in this mode. Can we open-code it in a wider mode? */
1898 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
1899 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
1900 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
1902 if (unoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
1904 rtx xop0 = op0;
1906 /* For certain operations, we need not actually extend
1907 the narrow operand, as long as we will truncate the
1908 results to the same narrowness. */
1910 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
1911 (unoptab == neg_optab
1912 || unoptab == one_cmpl_optab)
1913 && class == MODE_INT);
1915 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
1916 unsignedp);
1918 if (temp)
1920 if (class != MODE_INT)
1922 if (target == 0)
1923 target = gen_reg_rtx (mode);
1924 convert_move (target, temp, 0);
1925 return target;
1927 else
1928 return gen_lowpart (mode, temp);
1930 else
1931 delete_insns_since (last);
1935 /* These can be done a word at a time. */
1936 if (unoptab == one_cmpl_optab
1937 && class == MODE_INT
1938 && GET_MODE_SIZE (mode) > UNITS_PER_WORD
1939 && unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
1941 int i;
1942 rtx insns;
1944 if (target == 0 || target == op0)
1945 target = gen_reg_rtx (mode);
1947 start_sequence ();
1949 /* Do the actual arithmetic. */
1950 for (i = 0; i < GET_MODE_BITSIZE (mode) / BITS_PER_WORD; i++)
1952 rtx target_piece = operand_subword (target, i, 1, mode);
1953 rtx x = expand_unop (word_mode, unoptab,
1954 operand_subword_force (op0, i, mode),
1955 target_piece, unsignedp);
1956 if (target_piece != x)
1957 emit_move_insn (target_piece, x);
1960 insns = get_insns ();
1961 end_sequence ();
1963 emit_no_conflict_block (insns, target, op0, NULL_RTX,
1964 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
1965 return target;
1968 /* Open-code the complex negation operation. */
1969 else if (unoptab == neg_optab
1970 && (class == MODE_COMPLEX_FLOAT || class == MODE_COMPLEX_INT))
1972 rtx target_piece;
1973 rtx x;
1974 rtx seq;
1976 /* Find the correct mode for the real and imaginary parts */
1977 enum machine_mode submode
1978 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
1979 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
1982 if (submode == BLKmode)
1983 abort ();
1985 if (target == 0)
1986 target = gen_reg_rtx (mode);
1988 start_sequence ();
1990 target_piece = gen_imagpart (submode, target);
1991 x = expand_unop (submode, unoptab,
1992 gen_imagpart (submode, op0),
1993 target_piece, unsignedp);
1994 if (target_piece != x)
1995 emit_move_insn (target_piece, x);
1997 target_piece = gen_realpart (submode, target);
1998 x = expand_unop (submode, unoptab,
1999 gen_realpart (submode, op0),
2000 target_piece, unsignedp);
2001 if (target_piece != x)
2002 emit_move_insn (target_piece, x);
2004 seq = get_insns ();
2005 end_sequence ();
2007 emit_no_conflict_block (seq, target, op0, 0,
2008 gen_rtx (unoptab->code, mode, copy_rtx (op0)));
2009 return target;
2012 /* Now try a library call in this mode. */
2013 if (unoptab->handlers[(int) mode].libfunc)
2015 rtx insns;
2016 rtx funexp = unoptab->handlers[(int) mode].libfunc;
2017 rtx value;
2019 start_sequence ();
2021 /* Pass 1 for NO_QUEUE so we don't lose any increments
2022 if the libcall is cse'd or moved. */
2023 value = emit_library_call_value (unoptab->handlers[(int) mode].libfunc,
2024 NULL_RTX, 1, mode, 1, op0, mode);
2025 insns = get_insns ();
2026 end_sequence ();
2028 target = gen_reg_rtx (mode);
2029 emit_libcall_block (insns, target, value,
2030 gen_rtx (unoptab->code, mode, op0));
2032 return target;
2035 /* It can't be done in this mode. Can we do it in a wider mode? */
2037 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2039 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2040 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2042 if ((unoptab->handlers[(int) wider_mode].insn_code
2043 != CODE_FOR_nothing)
2044 || unoptab->handlers[(int) wider_mode].libfunc)
2046 rtx xop0 = op0;
2048 /* For certain operations, we need not actually extend
2049 the narrow operand, as long as we will truncate the
2050 results to the same narrowness. */
2052 xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
2053 (unoptab == neg_optab
2054 || unoptab == one_cmpl_optab)
2055 && class == MODE_INT);
2057 temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
2058 unsignedp);
2060 if (temp)
2062 if (class != MODE_INT)
2064 if (target == 0)
2065 target = gen_reg_rtx (mode);
2066 convert_move (target, temp, 0);
2067 return target;
2069 else
2070 return gen_lowpart (mode, temp);
2072 else
2073 delete_insns_since (last);
2078 /* If there is no negate operation, try doing a subtract from zero.
2079 The US Software GOFAST library needs this. */
2080 if (unoptab == neg_optab)
2082 rtx temp;
2083 temp = expand_binop (mode, sub_optab, CONST0_RTX (mode), op0,
2084 target, unsignedp, OPTAB_LIB_WIDEN);
2085 if (temp)
2086 return temp;
2089 return 0;
2092 /* Emit code to compute the absolute value of OP0, with result to
2093 TARGET if convenient. (TARGET may be 0.) The return value says
2094 where the result actually is to be found.
2096 MODE is the mode of the operand; the mode of the result is
2097 different but can be deduced from MODE.
2099 UNSIGNEDP is relevant if extension is needed. */
2102 expand_abs (mode, op0, target, unsignedp, safe)
2103 enum machine_mode mode;
2104 rtx op0;
2105 rtx target;
2106 int unsignedp;
2107 int safe;
2109 rtx temp, op1;
2111 /* First try to do it with a special abs instruction. */
2112 temp = expand_unop (mode, abs_optab, op0, target, 0);
2113 if (temp != 0)
2114 return temp;
2116 /* If this machine has expensive jumps, we can do integer absolute
2117 value of X as (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)),
2118 where W is the width of MODE. */
2120 if (GET_MODE_CLASS (mode) == MODE_INT && BRANCH_COST >= 2)
2122 rtx extended = expand_shift (RSHIFT_EXPR, mode, op0,
2123 size_int (GET_MODE_BITSIZE (mode) - 1),
2124 NULL_RTX, 0);
2126 temp = expand_binop (mode, xor_optab, extended, op0, target, 0,
2127 OPTAB_LIB_WIDEN);
2128 if (temp != 0)
2129 temp = expand_binop (mode, sub_optab, temp, extended, target, 0,
2130 OPTAB_LIB_WIDEN);
2132 if (temp != 0)
2133 return temp;
2136 /* If that does not win, use conditional jump and negate. */
2138 /* It is safe to use the target if it is the same
2139 as the source if this is also a pseudo register */
2140 if (op0 == target && GET_CODE (op0) == REG
2141 && REGNO (op0) >= FIRST_PSEUDO_REGISTER)
2142 safe = 1;
2144 op1 = gen_label_rtx ();
2145 if (target == 0 || ! safe
2146 || GET_MODE (target) != mode
2147 || (GET_CODE (target) == MEM && MEM_VOLATILE_P (target))
2148 || (GET_CODE (target) == REG
2149 && REGNO (target) < FIRST_PSEUDO_REGISTER))
2150 target = gen_reg_rtx (mode);
2152 emit_move_insn (target, op0);
2153 NO_DEFER_POP;
2155 /* If this mode is an integer too wide to compare properly,
2156 compare word by word. Rely on CSE to optimize constant cases. */
2157 if (GET_MODE_CLASS (mode) == MODE_INT && ! can_compare_p (mode))
2158 do_jump_by_parts_greater_rtx (mode, 0, target, const0_rtx,
2159 NULL_RTX, op1);
2160 else
2162 temp = compare_from_rtx (target, CONST0_RTX (mode), GE, 0, mode,
2163 NULL_RTX, 0);
2164 if (temp == const1_rtx)
2165 return target;
2166 else if (temp != const0_rtx)
2168 if (bcc_gen_fctn[(int) GET_CODE (temp)] != 0)
2169 emit_jump_insn ((*bcc_gen_fctn[(int) GET_CODE (temp)]) (op1));
2170 else
2171 abort ();
2175 op0 = expand_unop (mode, neg_optab, target, target, 0);
2176 if (op0 != target)
2177 emit_move_insn (target, op0);
2178 emit_label (op1);
2179 OK_DEFER_POP;
2180 return target;
2183 /* Emit code to compute the absolute value of OP0, with result to
2184 TARGET if convenient. (TARGET may be 0.) The return value says
2185 where the result actually is to be found.
2187 MODE is the mode of the operand; the mode of the result is
2188 different but can be deduced from MODE.
2190 UNSIGNEDP is relevant for complex integer modes. */
2193 expand_complex_abs (mode, op0, target, unsignedp)
2194 enum machine_mode mode;
2195 rtx op0;
2196 rtx target;
2197 int unsignedp;
2199 enum mode_class class = GET_MODE_CLASS (mode);
2200 enum machine_mode wider_mode;
2201 register rtx temp;
2202 rtx entry_last = get_last_insn ();
2203 rtx last;
2204 rtx pat;
2206 /* Find the correct mode for the real and imaginary parts. */
2207 enum machine_mode submode
2208 = mode_for_size (GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT,
2209 class == MODE_COMPLEX_INT ? MODE_INT : MODE_FLOAT,
2212 if (submode == BLKmode)
2213 abort ();
2215 op0 = protect_from_queue (op0, 0);
2217 if (flag_force_mem)
2219 op0 = force_not_mem (op0);
2222 last = get_last_insn ();
2224 if (target)
2225 target = protect_from_queue (target, 1);
2227 if (abs_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2229 int icode = (int) abs_optab->handlers[(int) mode].insn_code;
2230 enum machine_mode mode0 = insn_operand_mode[icode][1];
2231 rtx xop0 = op0;
2233 if (target)
2234 temp = target;
2235 else
2236 temp = gen_reg_rtx (submode);
2238 if (GET_MODE (xop0) != VOIDmode
2239 && GET_MODE (xop0) != mode0)
2240 xop0 = convert_to_mode (mode0, xop0, unsignedp);
2242 /* Now, if insn doesn't accept our operand, put it into a pseudo. */
2244 if (! (*insn_operand_predicate[icode][1]) (xop0, mode0))
2245 xop0 = copy_to_mode_reg (mode0, xop0);
2247 if (! (*insn_operand_predicate[icode][0]) (temp, submode))
2248 temp = gen_reg_rtx (submode);
2250 pat = GEN_FCN (icode) (temp, xop0);
2251 if (pat)
2253 if (GET_CODE (pat) == SEQUENCE
2254 && ! add_equal_note (pat, temp, abs_optab->code, xop0, NULL_RTX))
2256 delete_insns_since (last);
2257 return expand_unop (mode, abs_optab, op0, NULL_RTX, unsignedp);
2260 emit_insn (pat);
2262 return temp;
2264 else
2265 delete_insns_since (last);
2268 /* It can't be done in this mode. Can we open-code it in a wider mode? */
2270 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2271 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2273 if (abs_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
2275 rtx xop0 = op0;
2277 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2278 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2280 if (temp)
2282 if (class != MODE_COMPLEX_INT)
2284 if (target == 0)
2285 target = gen_reg_rtx (submode);
2286 convert_move (target, temp, 0);
2287 return target;
2289 else
2290 return gen_lowpart (submode, temp);
2292 else
2293 delete_insns_since (last);
2297 /* Open-code the complex absolute-value operation
2298 if we can open-code sqrt. Otherwise it's not worth while. */
2299 if (sqrt_optab->handlers[(int) submode].insn_code != CODE_FOR_nothing)
2301 rtx real, imag, total;
2303 real = gen_realpart (submode, op0);
2304 imag = gen_imagpart (submode, op0);
2306 /* Square both parts. */
2307 real = expand_mult (submode, real, real, NULL_RTX, 0);
2308 imag = expand_mult (submode, imag, imag, NULL_RTX, 0);
2310 /* Sum the parts. */
2311 total = expand_binop (submode, add_optab, real, imag, NULL_RTX,
2312 0, OPTAB_LIB_WIDEN);
2314 /* Get sqrt in TARGET. Set TARGET to where the result is. */
2315 target = expand_unop (submode, sqrt_optab, total, target, 0);
2316 if (target == 0)
2317 delete_insns_since (last);
2318 else
2319 return target;
2322 /* Now try a library call in this mode. */
2323 if (abs_optab->handlers[(int) mode].libfunc)
2325 rtx insns;
2326 rtx funexp = abs_optab->handlers[(int) mode].libfunc;
2327 rtx value;
2329 start_sequence ();
2331 /* Pass 1 for NO_QUEUE so we don't lose any increments
2332 if the libcall is cse'd or moved. */
2333 value = emit_library_call_value (abs_optab->handlers[(int) mode].libfunc,
2334 NULL_RTX, 1, submode, 1, op0, mode);
2335 insns = get_insns ();
2336 end_sequence ();
2338 target = gen_reg_rtx (submode);
2339 emit_libcall_block (insns, target, value,
2340 gen_rtx (abs_optab->code, mode, op0));
2342 return target;
2345 /* It can't be done in this mode. Can we do it in a wider mode? */
2347 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2348 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2350 if ((abs_optab->handlers[(int) wider_mode].insn_code
2351 != CODE_FOR_nothing)
2352 || abs_optab->handlers[(int) wider_mode].libfunc)
2354 rtx xop0 = op0;
2356 xop0 = convert_modes (wider_mode, mode, xop0, unsignedp);
2358 temp = expand_complex_abs (wider_mode, xop0, NULL_RTX, unsignedp);
2360 if (temp)
2362 if (class != MODE_COMPLEX_INT)
2364 if (target == 0)
2365 target = gen_reg_rtx (submode);
2366 convert_move (target, temp, 0);
2367 return target;
2369 else
2370 return gen_lowpart (submode, temp);
2372 else
2373 delete_insns_since (last);
2377 delete_insns_since (entry_last);
2378 return 0;
2381 /* Generate an instruction whose insn-code is INSN_CODE,
2382 with two operands: an output TARGET and an input OP0.
2383 TARGET *must* be nonzero, and the output is always stored there.
2384 CODE is an rtx code such that (CODE OP0) is an rtx that describes
2385 the value that is stored into TARGET. */
2387 void
2388 emit_unop_insn (icode, target, op0, code)
2389 int icode;
2390 rtx target;
2391 rtx op0;
2392 enum rtx_code code;
2394 register rtx temp;
2395 enum machine_mode mode0 = insn_operand_mode[icode][1];
2396 rtx pat;
2398 temp = target = protect_from_queue (target, 1);
2400 op0 = protect_from_queue (op0, 0);
2402 /* Sign and zero extension from memory is often done specially on
2403 RISC machines, so forcing into a register here can pessimize
2404 code. */
2405 if (flag_force_mem && code != SIGN_EXTEND && code != ZERO_EXTEND)
2406 op0 = force_not_mem (op0);
2408 /* Now, if insn does not accept our operands, put them into pseudos. */
2410 if (! (*insn_operand_predicate[icode][1]) (op0, mode0))
2411 op0 = copy_to_mode_reg (mode0, op0);
2413 if (! (*insn_operand_predicate[icode][0]) (temp, GET_MODE (temp))
2414 || (flag_force_mem && GET_CODE (temp) == MEM))
2415 temp = gen_reg_rtx (GET_MODE (temp));
2417 pat = GEN_FCN (icode) (temp, op0);
2419 if (GET_CODE (pat) == SEQUENCE && code != UNKNOWN)
2420 add_equal_note (pat, temp, code, op0, NULL_RTX);
2422 emit_insn (pat);
2424 if (temp != target)
2425 emit_move_insn (target, temp);
2428 /* Emit code to perform a series of operations on a multi-word quantity, one
2429 word at a time.
2431 Such a block is preceded by a CLOBBER of the output, consists of multiple
2432 insns, each setting one word of the output, and followed by a SET copying
2433 the output to itself.
2435 Each of the insns setting words of the output receives a REG_NO_CONFLICT
2436 note indicating that it doesn't conflict with the (also multi-word)
2437 inputs. The entire block is surrounded by REG_LIBCALL and REG_RETVAL
2438 notes.
2440 INSNS is a block of code generated to perform the operation, not including
2441 the CLOBBER and final copy. All insns that compute intermediate values
2442 are first emitted, followed by the block as described above.
2444 TARGET, OP0, and OP1 are the output and inputs of the operations,
2445 respectively. OP1 may be zero for a unary operation.
2447 EQUIV, if non-zero, is an expression to be placed into a REG_EQUAL note
2448 on the last insn.
2450 If TARGET is not a register, INSNS is simply emitted with no special
2451 processing. Likewise if anything in INSNS is not an INSN or if
2452 there is a libcall block inside INSNS.
2454 The final insn emitted is returned. */
2457 emit_no_conflict_block (insns, target, op0, op1, equiv)
2458 rtx insns;
2459 rtx target;
2460 rtx op0, op1;
2461 rtx equiv;
2463 rtx prev, next, first, last, insn;
2465 if (GET_CODE (target) != REG || reload_in_progress)
2466 return emit_insns (insns);
2467 else
2468 for (insn = insns; insn; insn = NEXT_INSN (insn))
2469 if (GET_CODE (insn) != INSN
2470 || find_reg_note (insn, REG_LIBCALL, NULL_RTX))
2471 return emit_insns (insns);
2473 /* First emit all insns that do not store into words of the output and remove
2474 these from the list. */
2475 for (insn = insns; insn; insn = next)
2477 rtx set = 0;
2478 int i;
2480 next = NEXT_INSN (insn);
2482 if (GET_CODE (PATTERN (insn)) == SET)
2483 set = PATTERN (insn);
2484 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
2486 for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
2487 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
2489 set = XVECEXP (PATTERN (insn), 0, i);
2490 break;
2494 if (set == 0)
2495 abort ();
2497 if (! reg_overlap_mentioned_p (target, SET_DEST (set)))
2499 if (PREV_INSN (insn))
2500 NEXT_INSN (PREV_INSN (insn)) = next;
2501 else
2502 insns = next;
2504 if (next)
2505 PREV_INSN (next) = PREV_INSN (insn);
2507 add_insn (insn);
2511 prev = get_last_insn ();
2513 /* Now write the CLOBBER of the output, followed by the setting of each
2514 of the words, followed by the final copy. */
2515 if (target != op0 && target != op1)
2516 emit_insn (gen_rtx (CLOBBER, VOIDmode, target));
2518 for (insn = insns; insn; insn = next)
2520 next = NEXT_INSN (insn);
2521 add_insn (insn);
2523 if (op1 && GET_CODE (op1) == REG)
2524 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op1,
2525 REG_NOTES (insn));
2527 if (op0 && GET_CODE (op0) == REG)
2528 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_NO_CONFLICT, op0,
2529 REG_NOTES (insn));
2532 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2533 != CODE_FOR_nothing)
2535 last = emit_move_insn (target, target);
2536 if (equiv)
2537 REG_NOTES (last)
2538 = gen_rtx (EXPR_LIST, REG_EQUAL, equiv, REG_NOTES (last));
2540 else
2541 last = get_last_insn ();
2543 if (prev == 0)
2544 first = get_insns ();
2545 else
2546 first = NEXT_INSN (prev);
2548 /* Encapsulate the block so it gets manipulated as a unit. */
2549 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2550 REG_NOTES (first));
2551 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2553 return last;
2556 /* Emit code to make a call to a constant function or a library call.
2558 INSNS is a list containing all insns emitted in the call.
2559 These insns leave the result in RESULT. Our block is to copy RESULT
2560 to TARGET, which is logically equivalent to EQUIV.
2562 We first emit any insns that set a pseudo on the assumption that these are
2563 loading constants into registers; doing so allows them to be safely cse'ed
2564 between blocks. Then we emit all the other insns in the block, followed by
2565 an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
2566 note with an operand of EQUIV.
2568 Moving assignments to pseudos outside of the block is done to improve
2569 the generated code, but is not required to generate correct code,
2570 hence being unable to move an assignment is not grounds for not making
2571 a libcall block. There are two reasons why it is safe to leave these
2572 insns inside the block: First, we know that these pseudos cannot be
2573 used in generated RTL outside the block since they are created for
2574 temporary purposes within the block. Second, CSE will not record the
2575 values of anything set inside a libcall block, so we know they must
2576 be dead at the end of the block.
2578 Except for the first group of insns (the ones setting pseudos), the
2579 block is delimited by REG_RETVAL and REG_LIBCALL notes. */
2581 void
2582 emit_libcall_block (insns, target, result, equiv)
2583 rtx insns;
2584 rtx target;
2585 rtx result;
2586 rtx equiv;
2588 rtx prev, next, first, last, insn;
2590 /* First emit all insns that set pseudos. Remove them from the list as
2591 we go. Avoid insns that set pseudos which were referenced in previous
2592 insns. These can be generated by move_by_pieces, for example,
2593 to update an address. Similarly, avoid insns that reference things
2594 set in previous insns. */
2596 for (insn = insns; insn; insn = next)
2598 rtx set = single_set (insn);
2600 next = NEXT_INSN (insn);
2602 if (set != 0 && GET_CODE (SET_DEST (set)) == REG
2603 && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
2604 && (insn == insns
2605 || (! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
2606 && ! reg_used_between_p (SET_DEST (set), insns, insn)
2607 && ! modified_in_p (SET_SRC (set), insns)
2608 && ! modified_between_p (SET_SRC (set), insns, insn))))
2610 if (PREV_INSN (insn))
2611 NEXT_INSN (PREV_INSN (insn)) = next;
2612 else
2613 insns = next;
2615 if (next)
2616 PREV_INSN (next) = PREV_INSN (insn);
2618 add_insn (insn);
2622 prev = get_last_insn ();
2624 /* Write the remaining insns followed by the final copy. */
2626 for (insn = insns; insn; insn = next)
2628 next = NEXT_INSN (insn);
2630 add_insn (insn);
2633 last = emit_move_insn (target, result);
2634 if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
2635 != CODE_FOR_nothing)
2636 REG_NOTES (last) = gen_rtx (EXPR_LIST,
2637 REG_EQUAL, copy_rtx (equiv), REG_NOTES (last));
2639 if (prev == 0)
2640 first = get_insns ();
2641 else
2642 first = NEXT_INSN (prev);
2644 /* Encapsulate the block so it gets manipulated as a unit. */
2645 REG_NOTES (first) = gen_rtx (INSN_LIST, REG_LIBCALL, last,
2646 REG_NOTES (first));
2647 REG_NOTES (last) = gen_rtx (INSN_LIST, REG_RETVAL, first, REG_NOTES (last));
2650 /* Generate code to store zero in X. */
2652 void
2653 emit_clr_insn (x)
2654 rtx x;
2656 emit_move_insn (x, const0_rtx);
2659 /* Generate code to store 1 in X
2660 assuming it contains zero beforehand. */
2662 void
2663 emit_0_to_1_insn (x)
2664 rtx x;
2666 emit_move_insn (x, const1_rtx);
2669 /* Generate code to compare X with Y
2670 so that the condition codes are set.
2672 MODE is the mode of the inputs (in case they are const_int).
2673 UNSIGNEDP nonzero says that X and Y are unsigned;
2674 this matters if they need to be widened.
2676 If they have mode BLKmode, then SIZE specifies the size of both X and Y,
2677 and ALIGN specifies the known shared alignment of X and Y.
2679 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.).
2680 It is ignored for fixed-point and block comparisons;
2681 it is used only for floating-point comparisons. */
2683 void
2684 emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
2685 rtx x, y;
2686 enum rtx_code comparison;
2687 rtx size;
2688 enum machine_mode mode;
2689 int unsignedp;
2690 int align;
2692 enum mode_class class;
2693 enum machine_mode wider_mode;
2695 class = GET_MODE_CLASS (mode);
2697 /* They could both be VOIDmode if both args are immediate constants,
2698 but we should fold that at an earlier stage.
2699 With no special code here, this will call abort,
2700 reminding the programmer to implement such folding. */
2702 if (mode != BLKmode && flag_force_mem)
2704 x = force_not_mem (x);
2705 y = force_not_mem (y);
2708 /* If we are inside an appropriately-short loop and one operand is an
2709 expensive constant, force it into a register. */
2710 if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
2711 x = force_reg (mode, x);
2713 if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
2714 y = force_reg (mode, y);
2716 /* Don't let both operands fail to indicate the mode. */
2717 if (GET_MODE (x) == VOIDmode && GET_MODE (y) == VOIDmode)
2718 x = force_reg (mode, x);
2720 /* Handle all BLKmode compares. */
2722 if (mode == BLKmode)
2724 emit_queue ();
2725 x = protect_from_queue (x, 0);
2726 y = protect_from_queue (y, 0);
2728 if (size == 0)
2729 abort ();
2730 #ifdef HAVE_cmpstrqi
2731 if (HAVE_cmpstrqi
2732 && GET_CODE (size) == CONST_INT
2733 && INTVAL (size) < (1 << GET_MODE_BITSIZE (QImode)))
2735 enum machine_mode result_mode
2736 = insn_operand_mode[(int) CODE_FOR_cmpstrqi][0];
2737 rtx result = gen_reg_rtx (result_mode);
2738 emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
2739 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2740 result_mode, 0, 0);
2742 else
2743 #endif
2744 #ifdef HAVE_cmpstrhi
2745 if (HAVE_cmpstrhi
2746 && GET_CODE (size) == CONST_INT
2747 && INTVAL (size) < (1 << GET_MODE_BITSIZE (HImode)))
2749 enum machine_mode result_mode
2750 = insn_operand_mode[(int) CODE_FOR_cmpstrhi][0];
2751 rtx result = gen_reg_rtx (result_mode);
2752 emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
2753 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2754 result_mode, 0, 0);
2756 else
2757 #endif
2758 #ifdef HAVE_cmpstrsi
2759 if (HAVE_cmpstrsi)
2761 enum machine_mode result_mode
2762 = insn_operand_mode[(int) CODE_FOR_cmpstrsi][0];
2763 rtx result = gen_reg_rtx (result_mode);
2764 size = protect_from_queue (size, 0);
2765 emit_insn (gen_cmpstrsi (result, x, y,
2766 convert_to_mode (SImode, size, 1),
2767 GEN_INT (align)));
2768 emit_cmp_insn (result, const0_rtx, comparison, NULL_RTX,
2769 result_mode, 0, 0);
2771 else
2772 #endif
2774 rtx result;
2776 #ifdef TARGET_MEM_FUNCTIONS
2777 emit_library_call (memcmp_libfunc, 0,
2778 TYPE_MODE (integer_type_node), 3,
2779 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2780 convert_to_mode (TYPE_MODE (sizetype), size,
2781 TREE_UNSIGNED (sizetype)),
2782 TYPE_MODE (sizetype));
2783 #else
2784 emit_library_call (bcmp_libfunc, 0,
2785 TYPE_MODE (integer_type_node), 3,
2786 XEXP (x, 0), Pmode, XEXP (y, 0), Pmode,
2787 convert_to_mode (TYPE_MODE (integer_type_node),
2788 size,
2789 TREE_UNSIGNED (integer_type_node)),
2790 TYPE_MODE (integer_type_node));
2791 #endif
2793 /* Immediately move the result of the libcall into a pseudo
2794 register so reload doesn't clobber the value if it needs
2795 the return register for a spill reg. */
2796 result = gen_reg_rtx (TYPE_MODE (integer_type_node));
2797 emit_move_insn (result,
2798 hard_libcall_value (TYPE_MODE (integer_type_node)));
2799 emit_cmp_insn (result,
2800 const0_rtx, comparison, NULL_RTX,
2801 TYPE_MODE (integer_type_node), 0, 0);
2803 return;
2806 /* Handle some compares against zero. */
2808 if (y == CONST0_RTX (mode)
2809 && tst_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2811 int icode = (int) tst_optab->handlers[(int) mode].insn_code;
2813 emit_queue ();
2814 x = protect_from_queue (x, 0);
2815 y = protect_from_queue (y, 0);
2817 /* Now, if insn does accept these operands, put them into pseudos. */
2818 if (! (*insn_operand_predicate[icode][0])
2819 (x, insn_operand_mode[icode][0]))
2820 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2822 emit_insn (GEN_FCN (icode) (x));
2823 return;
2826 /* Handle compares for which there is a directly suitable insn. */
2828 if (cmp_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing)
2830 int icode = (int) cmp_optab->handlers[(int) mode].insn_code;
2832 emit_queue ();
2833 x = protect_from_queue (x, 0);
2834 y = protect_from_queue (y, 0);
2836 /* Now, if insn doesn't accept these operands, put them into pseudos. */
2837 if (! (*insn_operand_predicate[icode][0])
2838 (x, insn_operand_mode[icode][0]))
2839 x = copy_to_mode_reg (insn_operand_mode[icode][0], x);
2841 if (! (*insn_operand_predicate[icode][1])
2842 (y, insn_operand_mode[icode][1]))
2843 y = copy_to_mode_reg (insn_operand_mode[icode][1], y);
2845 emit_insn (GEN_FCN (icode) (x, y));
2846 return;
2849 /* Try widening if we can find a direct insn that way. */
2851 if (class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
2853 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
2854 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
2856 if (cmp_optab->handlers[(int) wider_mode].insn_code
2857 != CODE_FOR_nothing)
2859 x = protect_from_queue (x, 0);
2860 y = protect_from_queue (y, 0);
2861 x = convert_modes (wider_mode, mode, x, unsignedp);
2862 y = convert_modes (wider_mode, mode, y, unsignedp);
2863 emit_cmp_insn (x, y, comparison, NULL_RTX,
2864 wider_mode, unsignedp, align);
2865 return;
2870 /* Handle a lib call just for the mode we are using. */
2872 if (cmp_optab->handlers[(int) mode].libfunc
2873 && class != MODE_FLOAT)
2875 rtx libfunc = cmp_optab->handlers[(int) mode].libfunc;
2876 rtx result;
2878 /* If we want unsigned, and this mode has a distinct unsigned
2879 comparison routine, use that. */
2880 if (unsignedp && ucmp_optab->handlers[(int) mode].libfunc)
2881 libfunc = ucmp_optab->handlers[(int) mode].libfunc;
2883 emit_library_call (libfunc, 1,
2884 word_mode, 2, x, mode, y, mode);
2886 /* Immediately move the result of the libcall into a pseudo
2887 register so reload doesn't clobber the value if it needs
2888 the return register for a spill reg. */
2889 result = gen_reg_rtx (word_mode);
2890 emit_move_insn (result, hard_libcall_value (word_mode));
2892 /* Integer comparison returns a result that must be compared against 1,
2893 so that even if we do an unsigned compare afterward,
2894 there is still a value that can represent the result "less than". */
2895 emit_cmp_insn (result, const1_rtx,
2896 comparison, NULL_RTX, word_mode, unsignedp, 0);
2897 return;
2900 if (class == MODE_FLOAT)
2901 emit_float_lib_cmp (x, y, comparison);
2903 else
2904 abort ();
2907 /* Nonzero if a compare of mode MODE can be done straightforwardly
2908 (without splitting it into pieces). */
2911 can_compare_p (mode)
2912 enum machine_mode mode;
2916 if (cmp_optab->handlers[(int)mode].insn_code != CODE_FOR_nothing)
2917 return 1;
2918 mode = GET_MODE_WIDER_MODE (mode);
2919 } while (mode != VOIDmode);
2921 return 0;
2924 /* Emit a library call comparison between floating point X and Y.
2925 COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */
2927 void
2928 emit_float_lib_cmp (x, y, comparison)
2929 rtx x, y;
2930 enum rtx_code comparison;
2932 enum machine_mode mode = GET_MODE (x);
2933 rtx libfunc = 0;
2934 rtx result;
2936 if (mode == HFmode)
2937 switch (comparison)
2939 case EQ:
2940 libfunc = eqhf2_libfunc;
2941 break;
2943 case NE:
2944 libfunc = nehf2_libfunc;
2945 break;
2947 case GT:
2948 libfunc = gthf2_libfunc;
2949 break;
2951 case GE:
2952 libfunc = gehf2_libfunc;
2953 break;
2955 case LT:
2956 libfunc = lthf2_libfunc;
2957 break;
2959 case LE:
2960 libfunc = lehf2_libfunc;
2961 break;
2963 else if (mode == SFmode)
2964 switch (comparison)
2966 case EQ:
2967 libfunc = eqsf2_libfunc;
2968 break;
2970 case NE:
2971 libfunc = nesf2_libfunc;
2972 break;
2974 case GT:
2975 libfunc = gtsf2_libfunc;
2976 break;
2978 case GE:
2979 libfunc = gesf2_libfunc;
2980 break;
2982 case LT:
2983 libfunc = ltsf2_libfunc;
2984 break;
2986 case LE:
2987 libfunc = lesf2_libfunc;
2988 break;
2990 else if (mode == DFmode)
2991 switch (comparison)
2993 case EQ:
2994 libfunc = eqdf2_libfunc;
2995 break;
2997 case NE:
2998 libfunc = nedf2_libfunc;
2999 break;
3001 case GT:
3002 libfunc = gtdf2_libfunc;
3003 break;
3005 case GE:
3006 libfunc = gedf2_libfunc;
3007 break;
3009 case LT:
3010 libfunc = ltdf2_libfunc;
3011 break;
3013 case LE:
3014 libfunc = ledf2_libfunc;
3015 break;
3017 else if (mode == XFmode)
3018 switch (comparison)
3020 case EQ:
3021 libfunc = eqxf2_libfunc;
3022 break;
3024 case NE:
3025 libfunc = nexf2_libfunc;
3026 break;
3028 case GT:
3029 libfunc = gtxf2_libfunc;
3030 break;
3032 case GE:
3033 libfunc = gexf2_libfunc;
3034 break;
3036 case LT:
3037 libfunc = ltxf2_libfunc;
3038 break;
3040 case LE:
3041 libfunc = lexf2_libfunc;
3042 break;
3044 else if (mode == TFmode)
3045 switch (comparison)
3047 case EQ:
3048 libfunc = eqtf2_libfunc;
3049 break;
3051 case NE:
3052 libfunc = netf2_libfunc;
3053 break;
3055 case GT:
3056 libfunc = gttf2_libfunc;
3057 break;
3059 case GE:
3060 libfunc = getf2_libfunc;
3061 break;
3063 case LT:
3064 libfunc = lttf2_libfunc;
3065 break;
3067 case LE:
3068 libfunc = letf2_libfunc;
3069 break;
3071 else
3073 enum machine_mode wider_mode;
3075 for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
3076 wider_mode = GET_MODE_WIDER_MODE (wider_mode))
3078 if ((cmp_optab->handlers[(int) wider_mode].insn_code
3079 != CODE_FOR_nothing)
3080 || (cmp_optab->handlers[(int) wider_mode].libfunc != 0))
3082 x = protect_from_queue (x, 0);
3083 y = protect_from_queue (y, 0);
3084 x = convert_to_mode (wider_mode, x, 0);
3085 y = convert_to_mode (wider_mode, y, 0);
3086 emit_float_lib_cmp (x, y, comparison);
3087 return;
3090 abort ();
3093 if (libfunc == 0)
3094 abort ();
3096 emit_library_call (libfunc, 1,
3097 word_mode, 2, x, mode, y, mode);
3099 /* Immediately move the result of the libcall into a pseudo
3100 register so reload doesn't clobber the value if it needs
3101 the return register for a spill reg. */
3102 result = gen_reg_rtx (word_mode);
3103 emit_move_insn (result, hard_libcall_value (word_mode));
3105 emit_cmp_insn (result, const0_rtx, comparison,
3106 NULL_RTX, word_mode, 0, 0);
3109 /* Generate code to indirectly jump to a location given in the rtx LOC. */
3111 void
3112 emit_indirect_jump (loc)
3113 rtx loc;
3115 if (! ((*insn_operand_predicate[(int)CODE_FOR_indirect_jump][0])
3116 (loc, Pmode)))
3117 loc = copy_to_mode_reg (Pmode, loc);
3119 emit_jump_insn (gen_indirect_jump (loc));
3120 emit_barrier ();
3123 #ifdef HAVE_conditional_move
3125 /* Emit a conditional move instruction if the machine supports one for that
3126 condition and machine mode.
3128 OP0 and OP1 are the operands that should be compared using CODE. CMODE is
3129 the mode to use should they be constants. If it is VOIDmode, they cannot
3130 both be constants.
3132 OP2 should be stored in TARGET if the comparison is true, otherwise OP3
3133 should be stored there. MODE is the mode to use should they be constants.
3134 If it is VOIDmode, they cannot both be constants.
3136 The result is either TARGET (perhaps modified) or NULL_RTX if the operation
3137 is not supported. */
3140 emit_conditional_move (target, code, op0, op1, cmode, op2, op3, mode,
3141 unsignedp)
3142 rtx target;
3143 enum rtx_code code;
3144 rtx op0, op1;
3145 enum machine_mode cmode;
3146 rtx op2, op3;
3147 enum machine_mode mode;
3148 int unsignedp;
3150 rtx tem, subtarget, comparison, insn;
3151 enum insn_code icode;
3153 /* If one operand is constant, make it the second one. Only do this
3154 if the other operand is not constant as well. */
3156 if ((CONSTANT_P (op0) && ! CONSTANT_P (op1))
3157 || (GET_CODE (op0) == CONST_INT && GET_CODE (op1) != CONST_INT))
3159 tem = op0;
3160 op0 = op1;
3161 op1 = tem;
3162 code = swap_condition (code);
3165 if (cmode == VOIDmode)
3166 cmode = GET_MODE (op0);
3168 if ((CONSTANT_P (op2) && ! CONSTANT_P (op3))
3169 || (GET_CODE (op2) == CONST_INT && GET_CODE (op3) != CONST_INT))
3171 tem = op2;
3172 op2 = op3;
3173 op3 = tem;
3174 /* ??? This may not be appropriate (consider IEEE). Perhaps we should
3175 call can_reverse_comparison_p here and bail out if necessary.
3176 It's not clear whether we need to do this canonicalization though. */
3177 code = reverse_condition (code);
3180 if (mode == VOIDmode)
3181 mode = GET_MODE (op2);
3183 icode = movcc_gen_code[mode];
3185 if (icode == CODE_FOR_nothing)
3186 return 0;
3188 if (flag_force_mem)
3190 op2 = force_not_mem (op2);
3191 op3 = force_not_mem (op3);
3194 if (target)
3195 target = protect_from_queue (target, 1);
3196 else
3197 target = gen_reg_rtx (mode);
3199 subtarget = target;
3201 emit_queue ();
3203 op2 = protect_from_queue (op2, 0);
3204 op3 = protect_from_queue (op3, 0);
3206 /* If the insn doesn't accept these operands, put them in pseudos. */
3208 if (! (*insn_operand_predicate[icode][0])
3209 (subtarget, insn_operand_mode[icode][0]))
3210 subtarget = gen_reg_rtx (insn_operand_mode[icode][0]);
3212 if (! (*insn_operand_predicate[icode][2])
3213 (op2, insn_operand_mode[icode][2]))
3214 op2 = copy_to_mode_reg (insn_operand_mode[icode][2], op2);
3216 if (! (*insn_operand_predicate[icode][3])
3217 (op3, insn_operand_mode[icode][3]))
3218 op3 = copy_to_mode_reg (insn_operand_mode[icode][3], op3);
3220 /* Everything should now be in the suitable form, so emit the compare insn
3221 and then the conditional move. */
3223 comparison
3224 = compare_from_rtx (op0, op1, code, unsignedp, cmode, NULL_RTX, 0);
3226 /* ??? Watch for const0_rtx (nop) and const_true_rtx (unconditional)? */
3227 if (GET_CODE (comparison) != code)
3228 /* This shouldn't happen. */
3229 abort ();
3231 insn = GEN_FCN (icode) (subtarget, comparison, op2, op3);
3233 /* If that failed, then give up. */
3234 if (insn == 0)
3235 return 0;
3237 emit_insn (insn);
3239 if (subtarget != target)
3240 convert_move (target, subtarget, 0);
3242 return target;
3245 /* Return non-zero if a conditional move of mode MODE is supported.
3247 This function is for combine so it can tell whether an insn that looks
3248 like a conditional move is actually supported by the hardware. If we
3249 guess wrong we lose a bit on optimization, but that's it. */
3250 /* ??? sparc64 supports conditionally moving integers values based on fp
3251 comparisons, and vice versa. How do we handle them? */
3254 can_conditionally_move_p (mode)
3255 enum machine_mode mode;
3257 if (movcc_gen_code[mode] != CODE_FOR_nothing)
3258 return 1;
3260 return 0;
3263 #endif /* HAVE_conditional_move */
3265 /* These three functions generate an insn body and return it
3266 rather than emitting the insn.
3268 They do not protect from queued increments,
3269 because they may be used 1) in protect_from_queue itself
3270 and 2) in other passes where there is no queue. */
3272 /* Generate and return an insn body to add Y to X. */
3275 gen_add2_insn (x, y)
3276 rtx x, y;
3278 int icode = (int) add_optab->handlers[(int) GET_MODE (x)].insn_code;
3280 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3281 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3282 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3283 abort ();
3285 return (GEN_FCN (icode) (x, x, y));
3289 have_add2_insn (mode)
3290 enum machine_mode mode;
3292 return add_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3295 /* Generate and return an insn body to subtract Y from X. */
3298 gen_sub2_insn (x, y)
3299 rtx x, y;
3301 int icode = (int) sub_optab->handlers[(int) GET_MODE (x)].insn_code;
3303 if (! (*insn_operand_predicate[icode][0]) (x, insn_operand_mode[icode][0])
3304 || ! (*insn_operand_predicate[icode][1]) (x, insn_operand_mode[icode][1])
3305 || ! (*insn_operand_predicate[icode][2]) (y, insn_operand_mode[icode][2]))
3306 abort ();
3308 return (GEN_FCN (icode) (x, x, y));
3312 have_sub2_insn (mode)
3313 enum machine_mode mode;
3315 return sub_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing;
3318 /* Generate the body of an instruction to copy Y into X.
3319 It may be a SEQUENCE, if one insn isn't enough. */
3322 gen_move_insn (x, y)
3323 rtx x, y;
3325 register enum machine_mode mode = GET_MODE (x);
3326 enum insn_code insn_code;
3327 rtx seq;
3329 if (mode == VOIDmode)
3330 mode = GET_MODE (y);
3332 insn_code = mov_optab->handlers[(int) mode].insn_code;
3334 /* Handle MODE_CC modes: If we don't have a special move insn for this mode,
3335 find a mode to do it in. If we have a movcc, use it. Otherwise,
3336 find the MODE_INT mode of the same width. */
3338 if (GET_MODE_CLASS (mode) == MODE_CC && insn_code == CODE_FOR_nothing)
3340 enum machine_mode tmode = VOIDmode;
3341 rtx x1 = x, y1 = y;
3343 if (mode != CCmode
3344 && mov_optab->handlers[(int) CCmode].insn_code != CODE_FOR_nothing)
3345 tmode = CCmode;
3346 else
3347 for (tmode = QImode; tmode != VOIDmode;
3348 tmode = GET_MODE_WIDER_MODE (tmode))
3349 if (GET_MODE_SIZE (tmode) == GET_MODE_SIZE (mode))
3350 break;
3352 if (tmode == VOIDmode)
3353 abort ();
3355 /* Get X and Y in TMODE. We can't use gen_lowpart here because it
3356 may call change_address which is not appropriate if we were
3357 called when a reload was in progress. We don't have to worry
3358 about changing the address since the size in bytes is supposed to
3359 be the same. Copy the MEM to change the mode and move any
3360 substitutions from the old MEM to the new one. */
3362 if (reload_in_progress)
3364 x = gen_lowpart_common (tmode, x1);
3365 if (x == 0 && GET_CODE (x1) == MEM)
3367 x = gen_rtx (MEM, tmode, XEXP (x1, 0));
3368 RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (x1);
3369 MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (x1);
3370 MEM_VOLATILE_P (x) = MEM_VOLATILE_P (x1);
3371 copy_replacements (x1, x);
3374 y = gen_lowpart_common (tmode, y1);
3375 if (y == 0 && GET_CODE (y1) == MEM)
3377 y = gen_rtx (MEM, tmode, XEXP (y1, 0));
3378 RTX_UNCHANGING_P (y) = RTX_UNCHANGING_P (y1);
3379 MEM_IN_STRUCT_P (y) = MEM_IN_STRUCT_P (y1);
3380 MEM_VOLATILE_P (y) = MEM_VOLATILE_P (y1);
3381 copy_replacements (y1, y);
3384 else
3386 x = gen_lowpart (tmode, x);
3387 y = gen_lowpart (tmode, y);
3390 insn_code = mov_optab->handlers[(int) tmode].insn_code;
3391 return (GEN_FCN (insn_code) (x, y));
3394 start_sequence ();
3395 emit_move_insn_1 (x, y);
3396 seq = gen_sequence ();
3397 end_sequence ();
3398 return seq;
3401 /* Return the insn code used to extend FROM_MODE to TO_MODE.
3402 UNSIGNEDP specifies zero-extension instead of sign-extension. If
3403 no such operation exists, CODE_FOR_nothing will be returned. */
3405 enum insn_code
3406 can_extend_p (to_mode, from_mode, unsignedp)
3407 enum machine_mode to_mode, from_mode;
3408 int unsignedp;
3410 return extendtab[(int) to_mode][(int) from_mode][unsignedp];
3413 /* Generate the body of an insn to extend Y (with mode MFROM)
3414 into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */
3417 gen_extend_insn (x, y, mto, mfrom, unsignedp)
3418 rtx x, y;
3419 enum machine_mode mto, mfrom;
3420 int unsignedp;
3422 return (GEN_FCN (extendtab[(int) mto][(int) mfrom][unsignedp]) (x, y));
3425 /* can_fix_p and can_float_p say whether the target machine
3426 can directly convert a given fixed point type to
3427 a given floating point type, or vice versa.
3428 The returned value is the CODE_FOR_... value to use,
3429 or CODE_FOR_nothing if these modes cannot be directly converted.
3431 *TRUNCP_PTR is set to 1 if it is necessary to output
3432 an explicit FTRUNC insn before the fix insn; otherwise 0. */
3434 static enum insn_code
3435 can_fix_p (fixmode, fltmode, unsignedp, truncp_ptr)
3436 enum machine_mode fltmode, fixmode;
3437 int unsignedp;
3438 int *truncp_ptr;
3440 *truncp_ptr = 0;
3441 if (fixtrunctab[(int) fltmode][(int) fixmode][unsignedp] != CODE_FOR_nothing)
3442 return fixtrunctab[(int) fltmode][(int) fixmode][unsignedp];
3444 if (ftrunc_optab->handlers[(int) fltmode].insn_code != CODE_FOR_nothing)
3446 *truncp_ptr = 1;
3447 return fixtab[(int) fltmode][(int) fixmode][unsignedp];
3449 return CODE_FOR_nothing;
3452 static enum insn_code
3453 can_float_p (fltmode, fixmode, unsignedp)
3454 enum machine_mode fixmode, fltmode;
3455 int unsignedp;
3457 return floattab[(int) fltmode][(int) fixmode][unsignedp];
3460 /* Generate code to convert FROM to floating point
3461 and store in TO. FROM must be fixed point and not VOIDmode.
3462 UNSIGNEDP nonzero means regard FROM as unsigned.
3463 Normally this is done by correcting the final value
3464 if it is negative. */
3466 void
3467 expand_float (to, from, unsignedp)
3468 rtx to, from;
3469 int unsignedp;
3471 enum insn_code icode;
3472 register rtx target = to;
3473 enum machine_mode fmode, imode;
3475 /* Crash now, because we won't be able to decide which mode to use. */
3476 if (GET_MODE (from) == VOIDmode)
3477 abort ();
3479 /* Look for an insn to do the conversion. Do it in the specified
3480 modes if possible; otherwise convert either input, output or both to
3481 wider mode. If the integer mode is wider than the mode of FROM,
3482 we can do the conversion signed even if the input is unsigned. */
3484 for (imode = GET_MODE (from); imode != VOIDmode;
3485 imode = GET_MODE_WIDER_MODE (imode))
3486 for (fmode = GET_MODE (to); fmode != VOIDmode;
3487 fmode = GET_MODE_WIDER_MODE (fmode))
3489 int doing_unsigned = unsignedp;
3491 icode = can_float_p (fmode, imode, unsignedp);
3492 if (icode == CODE_FOR_nothing && imode != GET_MODE (from) && unsignedp)
3493 icode = can_float_p (fmode, imode, 0), doing_unsigned = 0;
3495 if (icode != CODE_FOR_nothing)
3497 to = protect_from_queue (to, 1);
3498 from = protect_from_queue (from, 0);
3500 if (imode != GET_MODE (from))
3501 from = convert_to_mode (imode, from, unsignedp);
3503 if (fmode != GET_MODE (to))
3504 target = gen_reg_rtx (fmode);
3506 emit_unop_insn (icode, target, from,
3507 doing_unsigned ? UNSIGNED_FLOAT : FLOAT);
3509 if (target != to)
3510 convert_move (to, target, 0);
3511 return;
3515 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3517 /* Unsigned integer, and no way to convert directly.
3518 Convert as signed, then conditionally adjust the result. */
3519 if (unsignedp)
3521 rtx label = gen_label_rtx ();
3522 rtx temp;
3523 REAL_VALUE_TYPE offset;
3525 emit_queue ();
3527 to = protect_from_queue (to, 1);
3528 from = protect_from_queue (from, 0);
3530 if (flag_force_mem)
3531 from = force_not_mem (from);
3533 /* Look for a usable floating mode FMODE wider than the source and at
3534 least as wide as the target. Using FMODE will avoid rounding woes
3535 with unsigned values greater than the signed maximum value. */
3537 for (fmode = GET_MODE (to); fmode != VOIDmode;
3538 fmode = GET_MODE_WIDER_MODE (fmode))
3539 if (GET_MODE_BITSIZE (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
3540 && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
3541 break;
3543 if (fmode == VOIDmode)
3545 /* There is no such mode. Pretend the target is wide enough. */
3546 fmode = GET_MODE (to);
3548 /* Avoid double-rounding when TO is narrower than FROM. */
3549 if ((significand_size (fmode) + 1)
3550 < GET_MODE_BITSIZE (GET_MODE (from)))
3552 rtx temp1;
3553 rtx neglabel = gen_label_rtx ();
3555 /* Don't use TARGET if it isn't a register, is a hard register,
3556 or is the wrong mode. */
3557 if (GET_CODE (target) != REG
3558 || REGNO (target) < FIRST_PSEUDO_REGISTER
3559 || GET_MODE (target) != fmode)
3560 target = gen_reg_rtx (fmode);
3562 imode = GET_MODE (from);
3563 do_pending_stack_adjust ();
3565 /* Test whether the sign bit is set. */
3566 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, imode, 0, 0);
3567 emit_jump_insn (gen_blt (neglabel));
3569 /* The sign bit is not set. Convert as signed. */
3570 expand_float (target, from, 0);
3571 emit_jump_insn (gen_jump (label));
3572 emit_barrier ();
3574 /* The sign bit is set.
3575 Convert to a usable (positive signed) value by shifting right
3576 one bit, while remembering if a nonzero bit was shifted
3577 out; i.e., compute (from & 1) | (from >> 1). */
3579 emit_label (neglabel);
3580 temp = expand_binop (imode, and_optab, from, const1_rtx,
3581 NULL_RTX, 1, OPTAB_LIB_WIDEN);
3582 temp1 = expand_shift (RSHIFT_EXPR, imode, from, integer_one_node,
3583 NULL_RTX, 1);
3584 temp = expand_binop (imode, ior_optab, temp, temp1, temp, 1,
3585 OPTAB_LIB_WIDEN);
3586 expand_float (target, temp, 0);
3588 /* Multiply by 2 to undo the shift above. */
3589 temp = expand_binop (fmode, add_optab, target, target,
3590 target, 0, OPTAB_LIB_WIDEN);
3591 if (temp != target)
3592 emit_move_insn (target, temp);
3594 do_pending_stack_adjust ();
3595 emit_label (label);
3596 goto done;
3600 /* If we are about to do some arithmetic to correct for an
3601 unsigned operand, do it in a pseudo-register. */
3603 if (GET_MODE (to) != fmode
3604 || GET_CODE (to) != REG || REGNO (to) < FIRST_PSEUDO_REGISTER)
3605 target = gen_reg_rtx (fmode);
3607 /* Convert as signed integer to floating. */
3608 expand_float (target, from, 0);
3610 /* If FROM is negative (and therefore TO is negative),
3611 correct its value by 2**bitwidth. */
3613 do_pending_stack_adjust ();
3614 emit_cmp_insn (from, const0_rtx, GE, NULL_RTX, GET_MODE (from), 0, 0);
3615 emit_jump_insn (gen_bge (label));
3617 /* On SCO 3.2.1, ldexp rejects values outside [0.5, 1).
3618 Rather than setting up a dconst_dot_5, let's hope SCO
3619 fixes the bug. */
3620 offset = REAL_VALUE_LDEXP (dconst1, GET_MODE_BITSIZE (GET_MODE (from)));
3621 temp = expand_binop (fmode, add_optab, target,
3622 CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode),
3623 target, 0, OPTAB_LIB_WIDEN);
3624 if (temp != target)
3625 emit_move_insn (target, temp);
3627 do_pending_stack_adjust ();
3628 emit_label (label);
3629 goto done;
3631 #endif
3633 /* No hardware instruction available; call a library routine to convert from
3634 SImode, DImode, or TImode into SFmode, DFmode, XFmode, or TFmode. */
3636 rtx libfcn;
3637 rtx insns;
3638 rtx value;
3640 to = protect_from_queue (to, 1);
3641 from = protect_from_queue (from, 0);
3643 if (GET_MODE_SIZE (GET_MODE (from)) < GET_MODE_SIZE (SImode))
3644 from = convert_to_mode (SImode, from, unsignedp);
3646 if (flag_force_mem)
3647 from = force_not_mem (from);
3649 if (GET_MODE (to) == SFmode)
3651 if (GET_MODE (from) == SImode)
3652 libfcn = floatsisf_libfunc;
3653 else if (GET_MODE (from) == DImode)
3654 libfcn = floatdisf_libfunc;
3655 else if (GET_MODE (from) == TImode)
3656 libfcn = floattisf_libfunc;
3657 else
3658 abort ();
3660 else if (GET_MODE (to) == DFmode)
3662 if (GET_MODE (from) == SImode)
3663 libfcn = floatsidf_libfunc;
3664 else if (GET_MODE (from) == DImode)
3665 libfcn = floatdidf_libfunc;
3666 else if (GET_MODE (from) == TImode)
3667 libfcn = floattidf_libfunc;
3668 else
3669 abort ();
3671 else if (GET_MODE (to) == XFmode)
3673 if (GET_MODE (from) == SImode)
3674 libfcn = floatsixf_libfunc;
3675 else if (GET_MODE (from) == DImode)
3676 libfcn = floatdixf_libfunc;
3677 else if (GET_MODE (from) == TImode)
3678 libfcn = floattixf_libfunc;
3679 else
3680 abort ();
3682 else if (GET_MODE (to) == TFmode)
3684 if (GET_MODE (from) == SImode)
3685 libfcn = floatsitf_libfunc;
3686 else if (GET_MODE (from) == DImode)
3687 libfcn = floatditf_libfunc;
3688 else if (GET_MODE (from) == TImode)
3689 libfcn = floattitf_libfunc;
3690 else
3691 abort ();
3693 else
3694 abort ();
3696 start_sequence ();
3698 value = emit_library_call_value (libfcn, NULL_RTX, 1,
3699 GET_MODE (to),
3700 1, from, GET_MODE (from));
3701 insns = get_insns ();
3702 end_sequence ();
3704 emit_libcall_block (insns, target, value,
3705 gen_rtx (FLOAT, GET_MODE (to), from));
3708 done:
3710 /* Copy result to requested destination
3711 if we have been computing in a temp location. */
3713 if (target != to)
3715 if (GET_MODE (target) == GET_MODE (to))
3716 emit_move_insn (to, target);
3717 else
3718 convert_move (to, target, 0);
3722 /* expand_fix: generate code to convert FROM to fixed point
3723 and store in TO. FROM must be floating point. */
3725 static rtx
3726 ftruncify (x)
3727 rtx x;
3729 rtx temp = gen_reg_rtx (GET_MODE (x));
3730 return expand_unop (GET_MODE (x), ftrunc_optab, x, temp, 0);
3733 void
3734 expand_fix (to, from, unsignedp)
3735 register rtx to, from;
3736 int unsignedp;
3738 enum insn_code icode;
3739 register rtx target = to;
3740 enum machine_mode fmode, imode;
3741 int must_trunc = 0;
3742 rtx libfcn = 0;
3744 /* We first try to find a pair of modes, one real and one integer, at
3745 least as wide as FROM and TO, respectively, in which we can open-code
3746 this conversion. If the integer mode is wider than the mode of TO,
3747 we can do the conversion either signed or unsigned. */
3749 for (imode = GET_MODE (to); imode != VOIDmode;
3750 imode = GET_MODE_WIDER_MODE (imode))
3751 for (fmode = GET_MODE (from); fmode != VOIDmode;
3752 fmode = GET_MODE_WIDER_MODE (fmode))
3754 int doing_unsigned = unsignedp;
3756 icode = can_fix_p (imode, fmode, unsignedp, &must_trunc);
3757 if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp)
3758 icode = can_fix_p (imode, fmode, 0, &must_trunc), doing_unsigned = 0;
3760 if (icode != CODE_FOR_nothing)
3762 to = protect_from_queue (to, 1);
3763 from = protect_from_queue (from, 0);
3765 if (fmode != GET_MODE (from))
3766 from = convert_to_mode (fmode, from, 0);
3768 if (must_trunc)
3769 from = ftruncify (from);
3771 if (imode != GET_MODE (to))
3772 target = gen_reg_rtx (imode);
3774 emit_unop_insn (icode, target, from,
3775 doing_unsigned ? UNSIGNED_FIX : FIX);
3776 if (target != to)
3777 convert_move (to, target, unsignedp);
3778 return;
3782 #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
3783 /* For an unsigned conversion, there is one more way to do it.
3784 If we have a signed conversion, we generate code that compares
3785 the real value to the largest representable positive number. If if
3786 is smaller, the conversion is done normally. Otherwise, subtract
3787 one plus the highest signed number, convert, and add it back.
3789 We only need to check all real modes, since we know we didn't find
3790 anything with a wider integer mode. */
3792 if (unsignedp && GET_MODE_BITSIZE (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
3793 for (fmode = GET_MODE (from); fmode != VOIDmode;
3794 fmode = GET_MODE_WIDER_MODE (fmode))
3795 /* Make sure we won't lose significant bits doing this. */
3796 if (GET_MODE_BITSIZE (fmode) > GET_MODE_BITSIZE (GET_MODE (to))
3797 && CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0,
3798 &must_trunc))
3800 int bitsize;
3801 REAL_VALUE_TYPE offset;
3802 rtx limit, lab1, lab2, insn;
3804 bitsize = GET_MODE_BITSIZE (GET_MODE (to));
3805 offset = REAL_VALUE_LDEXP (dconst1, bitsize - 1);
3806 limit = CONST_DOUBLE_FROM_REAL_VALUE (offset, fmode);
3807 lab1 = gen_label_rtx ();
3808 lab2 = gen_label_rtx ();
3810 emit_queue ();
3811 to = protect_from_queue (to, 1);
3812 from = protect_from_queue (from, 0);
3814 if (flag_force_mem)
3815 from = force_not_mem (from);
3817 if (fmode != GET_MODE (from))
3818 from = convert_to_mode (fmode, from, 0);
3820 /* See if we need to do the subtraction. */
3821 do_pending_stack_adjust ();
3822 emit_cmp_insn (from, limit, GE, NULL_RTX, GET_MODE (from), 0, 0);
3823 emit_jump_insn (gen_bge (lab1));
3825 /* If not, do the signed "fix" and branch around fixup code. */
3826 expand_fix (to, from, 0);
3827 emit_jump_insn (gen_jump (lab2));
3828 emit_barrier ();
3830 /* Otherwise, subtract 2**(N-1), convert to signed number,
3831 then add 2**(N-1). Do the addition using XOR since this
3832 will often generate better code. */
3833 emit_label (lab1);
3834 target = expand_binop (GET_MODE (from), sub_optab, from, limit,
3835 NULL_RTX, 0, OPTAB_LIB_WIDEN);
3836 expand_fix (to, target, 0);
3837 target = expand_binop (GET_MODE (to), xor_optab, to,
3838 GEN_INT ((HOST_WIDE_INT) 1 << (bitsize - 1)),
3839 to, 1, OPTAB_LIB_WIDEN);
3841 if (target != to)
3842 emit_move_insn (to, target);
3844 emit_label (lab2);
3846 if (mov_optab->handlers[(int) GET_MODE (to)].insn_code
3847 != CODE_FOR_nothing)
3849 /* Make a place for a REG_NOTE and add it. */
3850 insn = emit_move_insn (to, to);
3851 REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
3852 gen_rtx (UNSIGNED_FIX, GET_MODE (to),
3853 copy_rtx (from)),
3854 REG_NOTES (insn));
3856 return;
3858 #endif
3860 /* We can't do it with an insn, so use a library call. But first ensure
3861 that the mode of TO is at least as wide as SImode, since those are the
3862 only library calls we know about. */
3864 if (GET_MODE_SIZE (GET_MODE (to)) < GET_MODE_SIZE (SImode))
3866 target = gen_reg_rtx (SImode);
3868 expand_fix (target, from, unsignedp);
3870 else if (GET_MODE (from) == SFmode)
3872 if (GET_MODE (to) == SImode)
3873 libfcn = unsignedp ? fixunssfsi_libfunc : fixsfsi_libfunc;
3874 else if (GET_MODE (to) == DImode)
3875 libfcn = unsignedp ? fixunssfdi_libfunc : fixsfdi_libfunc;
3876 else if (GET_MODE (to) == TImode)
3877 libfcn = unsignedp ? fixunssfti_libfunc : fixsfti_libfunc;
3878 else
3879 abort ();
3881 else if (GET_MODE (from) == DFmode)
3883 if (GET_MODE (to) == SImode)
3884 libfcn = unsignedp ? fixunsdfsi_libfunc : fixdfsi_libfunc;
3885 else if (GET_MODE (to) == DImode)
3886 libfcn = unsignedp ? fixunsdfdi_libfunc : fixdfdi_libfunc;
3887 else if (GET_MODE (to) == TImode)
3888 libfcn = unsignedp ? fixunsdfti_libfunc : fixdfti_libfunc;
3889 else
3890 abort ();
3892 else if (GET_MODE (from) == XFmode)
3894 if (GET_MODE (to) == SImode)
3895 libfcn = unsignedp ? fixunsxfsi_libfunc : fixxfsi_libfunc;
3896 else if (GET_MODE (to) == DImode)
3897 libfcn = unsignedp ? fixunsxfdi_libfunc : fixxfdi_libfunc;
3898 else if (GET_MODE (to) == TImode)
3899 libfcn = unsignedp ? fixunsxfti_libfunc : fixxfti_libfunc;
3900 else
3901 abort ();
3903 else if (GET_MODE (from) == TFmode)
3905 if (GET_MODE (to) == SImode)
3906 libfcn = unsignedp ? fixunstfsi_libfunc : fixtfsi_libfunc;
3907 else if (GET_MODE (to) == DImode)
3908 libfcn = unsignedp ? fixunstfdi_libfunc : fixtfdi_libfunc;
3909 else if (GET_MODE (to) == TImode)
3910 libfcn = unsignedp ? fixunstfti_libfunc : fixtfti_libfunc;
3911 else
3912 abort ();
3914 else
3915 abort ();
3917 if (libfcn)
3919 rtx insns;
3920 rtx value;
3922 to = protect_from_queue (to, 1);
3923 from = protect_from_queue (from, 0);
3925 if (flag_force_mem)
3926 from = force_not_mem (from);
3928 start_sequence ();
3930 value = emit_library_call_value (libfcn, NULL_RTX, 1, GET_MODE (to),
3932 1, from, GET_MODE (from));
3933 insns = get_insns ();
3934 end_sequence ();
3936 emit_libcall_block (insns, target, value,
3937 gen_rtx (unsignedp ? UNSIGNED_FIX : FIX,
3938 GET_MODE (to), from));
3941 if (target != to)
3943 if (GET_MODE (to) == GET_MODE (target))
3944 emit_move_insn (to, target);
3945 else
3946 convert_move (to, target, 0);
3950 static optab
3951 init_optab (code)
3952 enum rtx_code code;
3954 int i;
3955 optab op = (optab) xmalloc (sizeof (struct optab));
3956 op->code = code;
3957 for (i = 0; i < NUM_MACHINE_MODES; i++)
3959 op->handlers[i].insn_code = CODE_FOR_nothing;
3960 op->handlers[i].libfunc = 0;
3963 if (code != UNKNOWN)
3964 code_to_optab[(int) code] = op;
3966 return op;
3969 /* Initialize the libfunc fields of an entire group of entries in some
3970 optab. Each entry is set equal to a string consisting of a leading
3971 pair of underscores followed by a generic operation name followed by
3972 a mode name (downshifted to lower case) followed by a single character
3973 representing the number of operands for the given operation (which is
3974 usually one of the characters '2', '3', or '4').
3976 OPTABLE is the table in which libfunc fields are to be initialized.
3977 FIRST_MODE is the first machine mode index in the given optab to
3978 initialize.
3979 LAST_MODE is the last machine mode index in the given optab to
3980 initialize.
3981 OPNAME is the generic (string) name of the operation.
3982 SUFFIX is the character which specifies the number of operands for
3983 the given generic operation.
3986 static void
3987 init_libfuncs (optable, first_mode, last_mode, opname, suffix)
3988 register optab optable;
3989 register int first_mode;
3990 register int last_mode;
3991 register char *opname;
3992 register int suffix;
3994 register int mode;
3995 register unsigned opname_len = strlen (opname);
3997 for (mode = first_mode; (int) mode <= (int) last_mode;
3998 mode = (enum machine_mode) ((int) mode + 1))
4000 register char *mname = mode_name[(int) mode];
4001 register unsigned mname_len = strlen (mname);
4002 register char *libfunc_name
4003 = (char *) xmalloc (2 + opname_len + mname_len + 1 + 1);
4004 register char *p;
4005 register char *q;
4007 p = libfunc_name;
4008 *p++ = '_';
4009 *p++ = '_';
4010 for (q = opname; *q; )
4011 *p++ = *q++;
4012 for (q = mname; *q; q++)
4013 *p++ = tolower (*q);
4014 *p++ = suffix;
4015 *p++ = '\0';
4016 optable->handlers[(int) mode].libfunc
4017 = gen_rtx (SYMBOL_REF, Pmode, libfunc_name);
4021 /* Initialize the libfunc fields of an entire group of entries in some
4022 optab which correspond to all integer mode operations. The parameters
4023 have the same meaning as similarly named ones for the `init_libfuncs'
4024 routine. (See above). */
4026 static void
4027 init_integral_libfuncs (optable, opname, suffix)
4028 register optab optable;
4029 register char *opname;
4030 register int suffix;
4032 init_libfuncs (optable, SImode, TImode, opname, suffix);
4035 /* Initialize the libfunc fields of an entire group of entries in some
4036 optab which correspond to all real mode operations. The parameters
4037 have the same meaning as similarly named ones for the `init_libfuncs'
4038 routine. (See above). */
4040 static void
4041 init_floating_libfuncs (optable, opname, suffix)
4042 register optab optable;
4043 register char *opname;
4044 register int suffix;
4046 init_libfuncs (optable, SFmode, TFmode, opname, suffix);
4049 /* Initialize the libfunc fields of an entire group of entries in some
4050 optab which correspond to all complex floating modes. The parameters
4051 have the same meaning as similarly named ones for the `init_libfuncs'
4052 routine. (See above). */
4054 static void
4055 init_complex_libfuncs (optable, opname, suffix)
4056 register optab optable;
4057 register char *opname;
4058 register int suffix;
4060 init_libfuncs (optable, SCmode, TCmode, opname, suffix);
4063 /* Call this once to initialize the contents of the optabs
4064 appropriately for the current target machine. */
4066 void
4067 init_optabs ()
4069 int i, j;
4070 enum insn_code *p;
4072 /* Start by initializing all tables to contain CODE_FOR_nothing. */
4074 for (p = fixtab[0][0];
4075 p < fixtab[0][0] + sizeof fixtab / sizeof (fixtab[0][0][0]);
4076 p++)
4077 *p = CODE_FOR_nothing;
4079 for (p = fixtrunctab[0][0];
4080 p < fixtrunctab[0][0] + sizeof fixtrunctab / sizeof (fixtrunctab[0][0][0]);
4081 p++)
4082 *p = CODE_FOR_nothing;
4084 for (p = floattab[0][0];
4085 p < floattab[0][0] + sizeof floattab / sizeof (floattab[0][0][0]);
4086 p++)
4087 *p = CODE_FOR_nothing;
4089 for (p = extendtab[0][0];
4090 p < extendtab[0][0] + sizeof extendtab / sizeof extendtab[0][0][0];
4091 p++)
4092 *p = CODE_FOR_nothing;
4094 for (i = 0; i < NUM_RTX_CODE; i++)
4095 setcc_gen_code[i] = CODE_FOR_nothing;
4097 #ifdef HAVE_conditional_move
4098 for (i = 0; i < NUM_MACHINE_MODES; i++)
4099 movcc_gen_code[i] = CODE_FOR_nothing;
4100 #endif
4102 add_optab = init_optab (PLUS);
4103 sub_optab = init_optab (MINUS);
4104 smul_optab = init_optab (MULT);
4105 smul_highpart_optab = init_optab (UNKNOWN);
4106 umul_highpart_optab = init_optab (UNKNOWN);
4107 smul_widen_optab = init_optab (UNKNOWN);
4108 umul_widen_optab = init_optab (UNKNOWN);
4109 sdiv_optab = init_optab (DIV);
4110 sdivmod_optab = init_optab (UNKNOWN);
4111 udiv_optab = init_optab (UDIV);
4112 udivmod_optab = init_optab (UNKNOWN);
4113 smod_optab = init_optab (MOD);
4114 umod_optab = init_optab (UMOD);
4115 flodiv_optab = init_optab (DIV);
4116 ftrunc_optab = init_optab (UNKNOWN);
4117 and_optab = init_optab (AND);
4118 ior_optab = init_optab (IOR);
4119 xor_optab = init_optab (XOR);
4120 ashl_optab = init_optab (ASHIFT);
4121 ashr_optab = init_optab (ASHIFTRT);
4122 lshr_optab = init_optab (LSHIFTRT);
4123 rotl_optab = init_optab (ROTATE);
4124 rotr_optab = init_optab (ROTATERT);
4125 smin_optab = init_optab (SMIN);
4126 smax_optab = init_optab (SMAX);
4127 umin_optab = init_optab (UMIN);
4128 umax_optab = init_optab (UMAX);
4129 mov_optab = init_optab (UNKNOWN);
4130 movstrict_optab = init_optab (UNKNOWN);
4131 cmp_optab = init_optab (UNKNOWN);
4132 ucmp_optab = init_optab (UNKNOWN);
4133 tst_optab = init_optab (UNKNOWN);
4134 neg_optab = init_optab (NEG);
4135 abs_optab = init_optab (ABS);
4136 one_cmpl_optab = init_optab (NOT);
4137 ffs_optab = init_optab (FFS);
4138 sqrt_optab = init_optab (SQRT);
4139 sin_optab = init_optab (UNKNOWN);
4140 cos_optab = init_optab (UNKNOWN);
4141 strlen_optab = init_optab (UNKNOWN);
4143 for (i = 0; i < NUM_MACHINE_MODES; i++)
4145 movstr_optab[i] = CODE_FOR_nothing;
4146 clrstr_optab[i] = CODE_FOR_nothing;
4148 #ifdef HAVE_SECONDARY_RELOADS
4149 reload_in_optab[i] = reload_out_optab[i] = CODE_FOR_nothing;
4150 #endif
4153 /* Fill in the optabs with the insns we support. */
4154 init_all_optabs ();
4156 #ifdef FIXUNS_TRUNC_LIKE_FIX_TRUNC
4157 /* This flag says the same insns that convert to a signed fixnum
4158 also convert validly to an unsigned one. */
4159 for (i = 0; i < NUM_MACHINE_MODES; i++)
4160 for (j = 0; j < NUM_MACHINE_MODES; j++)
4161 fixtrunctab[i][j][1] = fixtrunctab[i][j][0];
4162 #endif
4164 #ifdef EXTRA_CC_MODES
4165 init_mov_optab ();
4166 #endif
4168 /* Initialize the optabs with the names of the library functions. */
4169 init_integral_libfuncs (add_optab, "add", '3');
4170 init_floating_libfuncs (add_optab, "add", '3');
4171 init_integral_libfuncs (sub_optab, "sub", '3');
4172 init_floating_libfuncs (sub_optab, "sub", '3');
4173 init_integral_libfuncs (smul_optab, "mul", '3');
4174 init_floating_libfuncs (smul_optab, "mul", '3');
4175 init_integral_libfuncs (sdiv_optab, "div", '3');
4176 init_integral_libfuncs (udiv_optab, "udiv", '3');
4177 init_integral_libfuncs (sdivmod_optab, "divmod", '4');
4178 init_integral_libfuncs (udivmod_optab, "udivmod", '4');
4179 init_integral_libfuncs (smod_optab, "mod", '3');
4180 init_integral_libfuncs (umod_optab, "umod", '3');
4181 init_floating_libfuncs (flodiv_optab, "div", '3');
4182 init_floating_libfuncs (ftrunc_optab, "ftrunc", '2');
4183 init_integral_libfuncs (and_optab, "and", '3');
4184 init_integral_libfuncs (ior_optab, "ior", '3');
4185 init_integral_libfuncs (xor_optab, "xor", '3');
4186 init_integral_libfuncs (ashl_optab, "ashl", '3');
4187 init_integral_libfuncs (ashr_optab, "ashr", '3');
4188 init_integral_libfuncs (lshr_optab, "lshr", '3');
4189 init_integral_libfuncs (smin_optab, "min", '3');
4190 init_floating_libfuncs (smin_optab, "min", '3');
4191 init_integral_libfuncs (smax_optab, "max", '3');
4192 init_floating_libfuncs (smax_optab, "max", '3');
4193 init_integral_libfuncs (umin_optab, "umin", '3');
4194 init_integral_libfuncs (umax_optab, "umax", '3');
4195 init_integral_libfuncs (neg_optab, "neg", '2');
4196 init_floating_libfuncs (neg_optab, "neg", '2');
4197 init_integral_libfuncs (one_cmpl_optab, "one_cmpl", '2');
4198 init_integral_libfuncs (ffs_optab, "ffs", '2');
4200 /* Comparison libcalls for integers MUST come in pairs, signed/unsigned. */
4201 init_integral_libfuncs (cmp_optab, "cmp", '2');
4202 init_integral_libfuncs (ucmp_optab, "ucmp", '2');
4203 init_floating_libfuncs (cmp_optab, "cmp", '2');
4205 #ifdef MULSI3_LIBCALL
4206 smul_optab->handlers[(int) SImode].libfunc
4207 = gen_rtx (SYMBOL_REF, Pmode, MULSI3_LIBCALL);
4208 #endif
4209 #ifdef MULDI3_LIBCALL
4210 smul_optab->handlers[(int) DImode].libfunc
4211 = gen_rtx (SYMBOL_REF, Pmode, MULDI3_LIBCALL);
4212 #endif
4214 #ifdef DIVSI3_LIBCALL
4215 sdiv_optab->handlers[(int) SImode].libfunc
4216 = gen_rtx (SYMBOL_REF, Pmode, DIVSI3_LIBCALL);
4217 #endif
4218 #ifdef DIVDI3_LIBCALL
4219 sdiv_optab->handlers[(int) DImode].libfunc
4220 = gen_rtx (SYMBOL_REF, Pmode, DIVDI3_LIBCALL);
4221 #endif
4223 #ifdef UDIVSI3_LIBCALL
4224 udiv_optab->handlers[(int) SImode].libfunc
4225 = gen_rtx (SYMBOL_REF, Pmode, UDIVSI3_LIBCALL);
4226 #endif
4227 #ifdef UDIVDI3_LIBCALL
4228 udiv_optab->handlers[(int) DImode].libfunc
4229 = gen_rtx (SYMBOL_REF, Pmode, UDIVDI3_LIBCALL);
4230 #endif
4232 #ifdef MODSI3_LIBCALL
4233 smod_optab->handlers[(int) SImode].libfunc
4234 = gen_rtx (SYMBOL_REF, Pmode, MODSI3_LIBCALL);
4235 #endif
4236 #ifdef MODDI3_LIBCALL
4237 smod_optab->handlers[(int) DImode].libfunc
4238 = gen_rtx (SYMBOL_REF, Pmode, MODDI3_LIBCALL);
4239 #endif
4241 #ifdef UMODSI3_LIBCALL
4242 umod_optab->handlers[(int) SImode].libfunc
4243 = gen_rtx (SYMBOL_REF, Pmode, UMODSI3_LIBCALL);
4244 #endif
4245 #ifdef UMODDI3_LIBCALL
4246 umod_optab->handlers[(int) DImode].libfunc
4247 = gen_rtx (SYMBOL_REF, Pmode, UMODDI3_LIBCALL);
4248 #endif
4250 /* Use cabs for DC complex abs, since systems generally have cabs.
4251 Don't define any libcall for SCmode, so that cabs will be used. */
4252 abs_optab->handlers[(int) DCmode].libfunc
4253 = gen_rtx (SYMBOL_REF, Pmode, "cabs");
4255 /* The ffs function operates on `int'. */
4256 #ifndef INT_TYPE_SIZE
4257 #define INT_TYPE_SIZE BITS_PER_WORD
4258 #endif
4259 ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)] .libfunc
4260 = gen_rtx (SYMBOL_REF, Pmode, "ffs");
4262 extendsfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfdf2");
4263 extendsfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsfxf2");
4264 extendsftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extendsftf2");
4265 extenddfxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddfxf2");
4266 extenddftf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__extenddftf2");
4268 truncdfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncdfsf2");
4269 truncxfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfsf2");
4270 trunctfsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfsf2");
4271 truncxfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__truncxfdf2");
4272 trunctfdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__trunctfdf2");
4274 memcpy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcpy");
4275 bcopy_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bcopy");
4276 memcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memcmp");
4277 bcmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gcc_bcmp");
4278 memset_libfunc = gen_rtx (SYMBOL_REF, Pmode, "memset");
4279 bzero_libfunc = gen_rtx (SYMBOL_REF, Pmode, "bzero");
4281 throw_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__throw");
4282 sjthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjthrow");
4283 sjpopnthrow_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__sjpopnthrow");
4284 terminate_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__terminate");
4285 #ifndef DONT_USE_BUILTIN_SETJMP
4286 setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_setjmp");
4287 longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__builtin_longjmp");
4288 #else
4289 setjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "setjmp");
4290 longjmp_libfunc = gen_rtx (SYMBOL_REF, Pmode, "longjmp");
4291 #endif
4292 get_dynamic_handler_chain_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__get_dynamic_handler_chain");
4294 eqhf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqhf2");
4295 nehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nehf2");
4296 gthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gthf2");
4297 gehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gehf2");
4298 lthf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lthf2");
4299 lehf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lehf2");
4301 eqsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqsf2");
4302 nesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nesf2");
4303 gtsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtsf2");
4304 gesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gesf2");
4305 ltsf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltsf2");
4306 lesf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lesf2");
4308 eqdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqdf2");
4309 nedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nedf2");
4310 gtdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtdf2");
4311 gedf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gedf2");
4312 ltdf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltdf2");
4313 ledf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ledf2");
4315 eqxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqxf2");
4316 nexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__nexf2");
4317 gtxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gtxf2");
4318 gexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gexf2");
4319 ltxf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__ltxf2");
4320 lexf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lexf2");
4322 eqtf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__eqtf2");
4323 netf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__netf2");
4324 gttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__gttf2");
4325 getf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__getf2");
4326 lttf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__lttf2");
4327 letf2_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__letf2");
4329 floatsisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsisf");
4330 floatdisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdisf");
4331 floattisf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattisf");
4333 floatsidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsidf");
4334 floatdidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdidf");
4335 floattidf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattidf");
4337 floatsixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsixf");
4338 floatdixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatdixf");
4339 floattixf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattixf");
4341 floatsitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatsitf");
4342 floatditf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floatditf");
4343 floattitf_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__floattitf");
4345 fixsfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfsi");
4346 fixsfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfdi");
4347 fixsfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixsfti");
4349 fixdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfsi");
4350 fixdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfdi");
4351 fixdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixdfti");
4353 fixxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfsi");
4354 fixxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfdi");
4355 fixxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixxfti");
4357 fixtfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfsi");
4358 fixtfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfdi");
4359 fixtfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixtfti");
4361 fixunssfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfsi");
4362 fixunssfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfdi");
4363 fixunssfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunssfti");
4365 fixunsdfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfsi");
4366 fixunsdfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfdi");
4367 fixunsdfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsdfti");
4369 fixunsxfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfsi");
4370 fixunsxfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfdi");
4371 fixunsxfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunsxfti");
4373 fixunstfsi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfsi");
4374 fixunstfdi_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfdi");
4375 fixunstfti_libfunc = gen_rtx (SYMBOL_REF, Pmode, "__fixunstfti");
4377 /* For check-memory-usage. */
4378 chkr_check_addr_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_addr");
4379 chkr_set_right_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_set_right");
4380 chkr_copy_bitmap_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_copy_bitmap");
4381 chkr_check_exec_libfunc = gen_rtx (SYMBOL_REF, VOIDmode, "chkr_check_exec");
4383 #ifdef INIT_TARGET_OPTABS
4384 /* Allow the target to add more libcalls or rename some, etc. */
4385 INIT_TARGET_OPTABS;
4386 #endif
4389 #ifdef BROKEN_LDEXP
4391 /* SCO 3.2 apparently has a broken ldexp. */
4393 double
4394 ldexp(x,n)
4395 double x;
4396 int n;
4398 if (n > 0)
4399 while (n--)
4400 x *= 2;
4402 return x;
4404 #endif /* BROKEN_LDEXP */